Socket Race Security Implications for Subcommand Tunneling

I want to tunnel a subcommand through a connection, listening on a port, launching a subcommand (to connect to this port), and then sending data through the connection:

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) 

However, there is a race between the time we begin to listen to and the time when the subcommand actually connects to the listener, where another process can connect to the listener. I believe that this race can be used by an attacker to communicate with the process at the other end of the connection and achieve results that would otherwise require privilege escalation (for example, attacks requiring special permissions replace the git command with a malicious program or simply reading the contents of the cloned directory in this case).

Should this be a problem? If so, can this be prevented? Although the question is asked using Go as an example, answers and comments in any language are welcome.

+6
source share
2 answers

Yes, this is a concern. This can be prevented by using some form of authentication so that your server only allows connections from legitimate clients.

0
source

Turning to Warren Dew, answer, assuming the other end of the tunnel is connecting to the SSH server, then this will authenticate the Git server / client.

A more general approach to β€œadd” authentication to a subcommand for this purpose is to wrap the subcommand in a container, such as a docker, and have the subcommand tunnel through a connection that is authenticated itself. Although the tunnel race condition is still present, it is at a higher level (i.e. inside the container), which means that an attacker without privileges will not be able to use the race condition in the base system. The disadvantage of this approach is its inherent complexity and overhead (albeit minimal) for the execution of the subcommand in the container.

0
source

Source: https://habr.com/ru/post/989074/


All Articles