隧道子命令时套接字竞争的安全隐患

Sea*_*her 6 sockets security network-programming tunnel race-condition

我想通过侦听端口,运行子命令(连接到该端口),然后通过连接转发数据来通过连接隧道子命令:

package main

import (
    "fmt"
    "net"
    "os"
    "os/exec"
)

func main() {
    ln, err := net.ListenTCP("tcp4", &net.TCPAddr{IP: localhost})
    if err != nil {
        fmt.Fprintln(os.Stderr, err)
        os.Exit(1)
    }
    defer ln.Close()

    port := ln.Addr().(*net.TCPAddr).Port

    cmd := exec.Command(
        "git",
        "clone",
        fmt.Sprintf("git://127.0.0.1:%d/project.git", port),
    )

    cmd.Stdout = os.Stdout
    cmd.Stderr = os.Stderr

    if err := cmd.Start(); err != nil {
        fmt.Fprintln(os.Stderr, err)
        os.Exit(1)
    }
    defer cmd.Process.Kill()

    errs := make(chan error, 1)
    go func() {
        errs <- cmd.Wait()
    }()

    conns := make(chan net.Conn, 1)
    go func() {
        conn, err := ln.Accept()
        if err == nil {
            conns <- conn
        } else {
            fmt.Println(err)
            errs <- err
        }
    }()

    select {
    case err := <-errs:
        fmt.Fprintln(os.Stderr, err)
        os.Exit(1)
    case conn := <-conns:
        defer conn.Close()
        // TODO Tunnel data from `conn` through another connection.
    }

    fmt.Println("done.")
}

var localhost = net.IPv4(127, 0, 0, 1)
Run Code Online (Sandbox Code Playgroud)

但是,在我们开始侦听的时间和子命令实际连接到侦听器的时间之间存在争用,其中另一个进程可以连接到侦听器.我相信攻击者可利用此种族与连接另一端的进程进行通信,并获得原本需要权限提升才能执行的结果(需要特殊权限的示例攻击正在用git恶意程序替换命令或简单地读取克隆目录的内容,在本例中).

这应该是一个问题吗?如果是这样,有没有办法可以预防?虽然使用Go作为示例询问问题,但欢迎任何语言的答案和评论.

War*_*Dew 0

是的,这是一个问题。可以通过使用某种形式的身份验证来防止这种情况,以便您的服务器仅允许来自合法客户端的连接。