隧道传输子命令时套接字竞争的安全隐患
Posted
技术标签:
【中文标题】隧道传输子命令时套接字竞争的安全隐患【英文标题】:Security implications of a socket race when tunnelling a sub-command 【发布时间】:2015-08-29 17:16:02 【问题描述】:我想通过监听一个端口,运行子命令(以连接到该端口),然后通过连接转发数据来通过连接隧道传输子命令:
package main
import (
"fmt"
"net"
"os"
"os/exec"
)
func main()
ln, err := net.ListenTCP("tcp4", &net.TCPAddrIP: 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)
但是,在我们开始侦听的时间与子命令实际连接到侦听器的时间之间存在竞争,另一个进程可以连接到侦听器。我相信攻击者可能会利用这种竞争与连接另一端的进程进行通信,并获得原本需要特权升级才能执行的结果(例如,需要特殊权限的攻击将git
命令替换为恶意程序或简单地读取克隆目录的内容,在这种情况下)。
这应该是一个问题吗?如果是这样,有什么方法可以预防吗?尽管以 Go 为例提出问题,但欢迎使用任何语言的答案和 cmets。
【问题讨论】:
【参考方案1】:是的,这是一个问题。可以通过使用某种形式的身份验证来防止这种情况发生,以便您的服务器只允许来自合法客户端的连接。
【讨论】:
在这种情况下如何添加身份验证,因为我无法修改客户端?【参考方案2】:扩展 Warren Dew 的回答,假设隧道的另一端连接到 SSH 服务器,那么这将执行 Git 服务器/客户端的身份验证。
为此目的向子命令“添加”身份验证的更通用方法是将子命令包装在 docker 等容器中,并让子命令通过连接进行身份验证。尽管隧道的竞争条件仍然存在,但它处于更高的“级别”(即在容器内),这意味着没有特权的攻击者将无法利用基础系统中的竞争条件。这种方法的缺点是其固有的复杂性和在容器中运行子命令的开销(尽管很小)。
【讨论】:
以上是关于隧道传输子命令时套接字竞争的安全隐患的主要内容,如果未能解决你的问题,请参考以下文章