Desidero eseguire il tunneling di un sottocomando tramite una connessione ascoltando una porta, eseguendo il sottocomando (per connettersi a tale porta) e quindi inoltrando i dati attraverso il collegamento:Implicazioni di sicurezza di una corsa socket durante il tunneling di un sottocomando
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)
Tuttavia, c'è una gara qui tra il momento in cui iniziamo l'ascolto e il momento in cui il sub-comandi in realtà si collega per l'ascoltatore, in cui un altro processo in grado di connettersi a chi ascolta. Credo che questa razza possa essere sfruttata da un utente malintenzionato per comunicare con il processo all'altro estremo della connessione e ottenere risultati che altrimenti richiederebbero l'escalation dei privilegi (ad esempio gli attacchi che richiedono autorizzazioni speciali stanno sostituendo il comando git
con un programma dannoso o semplicemente leggendo il contenuto della directory clonata, in questo caso).
Questo dovrebbe essere un problema? Se è così, c'è un modo in cui può essere prevenuto? Sebbene la domanda venga posta usando Go come esempio, le risposte e i commenti in qualsiasi lingua sono ben accetti.
Come si può aggiungere l'autenticazione in questo caso, poiché non posso modificare il client? –