2

我的问题如下:我想用scapy实现一个listen服务来刺激蜜罐(因为蜜罐使用的是假ip,所以不能使用OS sockets),我选择了scapy。

我实现了一个非常简单的 TCP 握手过程,但是有件事让我很沮丧:我使用 PSH 发送的数据包的一个字节被吃掉了。

例如,我将“abc”发送给客户端,但客户端的套接字(例如 netcat 或 wget)只接收“bc”。另一个例子是“HTTP/1.1 200 OK”变成“TTP/1.1 200 OK”。我捕获了数据包,wireshark 可以正确地将我的手工数据包识别为 HTTP,但客户端套接字仅缺少 1 个字节。我不知道为什么。

代码如下:192.168.1.100代表server(my) ip addr,9999是端口。例如,我在 192.168.1.100 上运行这个 python 脚本,然后我使用“nc 192.168.1.100 9999”。我希望得到“abc”,但我只能得到“bc”,但是在Wireshark中数据包似乎没有问题。太奇怪了。

    '''
    Created on Jun 2, 2012
    
    @author: root
    '''
    from scapy import all
    from scapy.layers.inet import IP, ICMP, TCP
    from scapy.packet import ls, Raw
    from scapy.sendrecv import sniff, send
    from scipy.signal.signaltools import lfilter
    import scapy.all
    HOSTADDR = "192.168.1.100"
    TCPPORT = 9999 'port to listen for'
    SEQ_NUM = 100
    
    ADD_TEST = "abc"
    
    
    def tcp_monitor_callback(pkt):
        global SEQ_NUM
        global TCPPORT
        if(pkt.payload.payload.flags == 2):
            'A syn situation, 2 for SYN'
            print("tcp incoming connection")
            ACK=TCP(sport=TCPPORT, dport=pkt.payload.payload.sport, flags="SA",ack=pkt.payload.payload.seq + 1,seq=0)
            send(IP(src=pkt.payload.dst,dst=pkt.payload.src)/ACK)
        if(pkt.payload.payload.flags & 8 !=0):
            'accept push from client, 8 for PSH flag'
            print("tcp push connection")
            pushLen = len(pkt.payload.payload.load)
            httpPart=TCP(sport=TCPPORT, dport=pkt.payload.payload.sport, flags="PA", ack=pkt.payload.payload.seq + pushLen)/Raw(load=ADD_TEST)
            'PROBLEM HERE!!!! If I send out abc, the client socket only receive bc, one byte disappers!!!But the packet received by client is CORRECT'
            send(IP(src=pkt.payload.dst,dst=pkt.payload.src)/httpPart)
        if(pkt.payload.payload.flags & 1 !=0):
            'accept fin from cilent'
            print ("tcp fin connection")
            FIN=TCP(sport=TCPPORT, dport=pkt.payload.payload.sport, flags="FA", ack=pkt.payload.payload.seq +1, seq = pkt.payload.payload.ack)
            send(IP(src=pkt.payload.dst,dst=pkt.payload.src)/FIN)
    def dispatcher_callback(pkt):
        print "packet incoming"
        global HOSTADDR
        global TCPPORT
        if(pkt.haslayer(TCP) and (pkt.payload.dst == HOSTADDR) and (pkt.payload.dport == TCPPORT)):
            tcp_monitor_callback(pkt)
        else:
            return
    if __name__ == '__main__':
        print "HoneyPot listen Module Test"
        scapy.all.conf.iface = "eth0"
        sniff(filter=("(tcp dst port %s) and dst host %s") % (TCPPORT,HOSTADDR), prn=dispatcher_callback)
        
4

2 回答 2

1

一些建议:

  1. 嗅探可能会在数据包的末尾附加一些有效负载,因此len(pkt.payload.payload.load)可能不是真正的有效负载长度。可以使用pkt[IP].len-40(40是IP+TCP的常用报头长度)。您也可以使用-len(pkt[IP].options)-len(pkt[TCP].options)以获得更准确的结果。
  2. 通常TCP上面的应用层使用换行符(“\r\n”)来分隔命令,所以你最好ADD_TEST改成"abc\r\n"

如果以上方法都不起作用,您可以升级到最新的 netcat 并重试。

于 2013-06-18T02:58:45.007 回答
0

我测试了你的代码,你错过了发送正确的 tcp 序列

httpPart=TCP(sport=TCPPORT, dport=pkt.payload.payload.sport, flags="PA", ack=pkt.payload.payload.seq + pushLen, seq=pkt.payload.payload.ack)/Raw(load =添加_测试)

应该解决这个问题,您可能有其他数据包长度问题,但吃掉的 1 个字节是由于缺少正确的 tcp 序列造成的

于 2015-07-10T21:17:02.930 回答