2017-02-08 104 views
3

我正在做一些基於pwnat的思想的測試,它介紹了一種無第三方NAT穿越的方法:服務器發送ICMP迴應請求數據包到固定地址(例如,3.3.3.3),其中沒有迴應回覆將不會從客戶端返回,假裝成Internet上的一跳,向服務器發送一個ICMP Time Exceeded數據包,期望服務器前端的NAT將ICMP超時消息轉發給服務器。
後我ping通到3.3.3.3,然後我運行下面的代碼192.168.1.100中去聽聽ICMP消息:不能接收超時消息

package main 

import (
    "fmt" 
    "golang.org/x/net/icmp" 
    "golang.org/x/net/ipv4" 
) 

func main() { 
    c, err := icmp.ListenPacket("ip4:icmp", "0.0.0.0") 
    if err != nil { 
     fmt.Println("listen error", err) 
    } 
    rb := make([]byte, 1500) 

    for { 
     n, _, err := c.ReadFrom(rb) 
     if err != nil { 
      fmt.Printf("read err: %s\n", err) 
     } 
     reply, err := icmp.ParseMessage(1, rb[:n]) 
     if err != nil { 
      fmt.Println("parse icmp err:", err) 
      return 
     } 

     switch reply.Type { 
     case ipv4.ICMPTypeTimeExceeded: 
      if _, ok := reply.Body.(*icmp.TimeExceeded); ok { 
       // internet header(20 bytes) plus the first 64 bits of the original datagram's data 
       //fmt.Println("recv id ", binary.BigEndian.Uint16(timeExceed.Data[22:24])) 
       fmt.Printf("ttl exceeded\n") 
      } 
     default: 
     } 
    } 
} 

,並運行在192.168.2.100以僞造的時間超過了消息發送到192.168.1.100程序:

問題是192.168.1.100無法接收消息。可能的原因是什麼?

+0

不,我將'Dst'設置爲'3.3.3.3'是爲了假裝超時消息是由'192.168.2.100'發送給'3.3.3.3'的迴應請求造成的。 – user123

+0

好的。你的代碼適合我。服務器打印「ttl超出」。你確定你的機器在192.168.1.100和192.168.2.100之間有連接嗎?這些機器聽起來像他們可能在不同的子網,所以確保你可以在他們之間路由,沒有防火牆搞砸了。嘗試在客戶端和服務器上使用tcpdump進行調試,您將看到包是否出現,看起來應該如此。 – nos

+0

感謝您的回覆。這兩個子網之間有連接。看起來路由器丟棄wireshark的數據包。 – user123

回答

2

您的代碼沒有問題。如果你在同一個網絡中運行你的代碼(我的意思是沒有NAT /路由器的參與),程序將按照預期接收超時消息。原因是現在pwnat使用的理論不起作用。

  • 首先,你沒有得到由 192.168.2.1003.3.3.3發送的回波請求的標識符,該標識符將是唯一 通過NAPT映射到外部查詢ID(如果有的話),以便它可以路由 將來的ICMP Echo將相同的查詢ID回覆給發件人。據rfc 3022 ICMP error packet modifications section

    在NAPT設置,如果嵌入在ICMP的IP消息碰巧是 一個TCP,UDP或者ICMP查詢包,你還需要在TCP內修改 適當TU端口號/ UDP頭或ICMP查詢頭中的查詢標識符字段。

  • 其次,根據RFC 5508:

    如果NAT設備從私人領域, 接收一個ICMP錯誤分組和NAT不具有活性映射爲嵌入有效載荷, NAT應該靜靜地丟棄ICMP錯誤數據包。

所以僞造的時間超過了消息將無法通過。 Here是這方面的更多細節。