2015-06-13 22 views
6

Tôi muốn tunnel một lệnh phụ thông qua kết nối bằng cách nghe một cổng, chạy lệnh phụ (để kết nối với cổng đó), và sau đó chuyển tiếp dữ liệu thông qua kết nối:Tác động an ninh của cuộc đua ổ cắm khi đường hầm một lệnh phụ

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) 

Tuy nhiên, có một chủng tộc ở đây giữa thời điểm đó chúng tôi bắt đầu nghe và thời gian khi các tiểu lệnh thực sự kết nối với người nghe, nơi quá trình khác có thể kết nối với người nghe. Tôi tin rằng cuộc đua này có thể được khai thác bởi kẻ tấn công để giao tiếp với quá trình ở đầu kia của kết nối và đạt được kết quả mà nếu không yêu cầu leo ​​thang đặc quyền để thực hiện (ví dụ: các cuộc tấn công yêu cầu quyền đặc biệt sẽ thay thế lệnh git bằng chương trình độc hại hoặc chỉ cần đọc nội dung của thư mục được nhân bản, trong trường hợp này).

Đây có phải là mối quan tâm không? Nếu vậy, có cách nào nó có thể được ngăn chặn không? Mặc dù câu hỏi được yêu cầu bằng cách sử dụng Go làm ví dụ, câu trả lời và nhận xét bằng mọi ngôn ngữ đều được chào đón.

Trả lời

0

Vâng, đó là mối quan tâm. Nó có thể được ngăn chặn bằng cách sử dụng một số hình thức xác thực để máy chủ của bạn chỉ cho phép các kết nối từ các máy khách hợp pháp.

+1

Làm cách nào để xác thực có thể được thêm vào trong trường hợp này, vì tôi không thể sửa đổi ứng dụng khách? –

0

Mở rộng câu trả lời của Warren Dew, giả sử đầu kia của đường hầm kết nối với máy chủ SSH, điều này sẽ thực hiện xác thực máy chủ/máy khách Git. Một cách tiếp cận tổng quát hơn để "thêm" xác thực vào một lệnh phụ cho mục đích này là để bọc lệnh phụ trong một container như docker và có đường hầm sub-command thông qua một kết nối xác thực chính nó. Mặc dù điều kiện chủng tộc của đường hầm vẫn tồn tại, nó ở mức "cao hơn" (tức là bên trong container), có nghĩa là kẻ tấn công không có đặc quyền sẽ không thể khai thác điều kiện cuộc đua trong hệ thống cơ bản. Nhược điểm của phương pháp này là độ phức tạp vốn có của nó và chi phí (mặc dù tối thiểu) của việc chạy lệnh phụ trong một thùng chứa.

Các vấn đề liên quan