用Python编写简单的原始数据包嗅探器

3

首先,我是Python的初学者。我开发了一个简单的原始数据包嗅探器,利用在第二层操作的PF_PACKET接口。

这个嗅探器简单地找出以下内容... - 以太网头(源 - 目标 - 协议) - IP头(源IP - 目标IP) - TCP头(源端口 - 目标端口)

这是我目前为止编写的代码...

#!/usr/bin/env python
import struct
import socket
import binascii

rawSocket=socket.socket(socket.PF_PACKET,socket.SOCK_RAW,socket.htons(0x0800))
#ifconfig eth0 promisc up
receivedPacket=rawSocket.recv(2048)

#Ethernet Header...
ethernetHeader=receivedPacket[0][0:14]
ethrheader=struct.unpack("!6s6s2s",ethernetHeader)
destinationIP= binascii.hexlify(ethrheader[0])
sourceIP= binascii.hexlify(ethrheader[1])
protocol= binascii.hexlify(ethrheader[2])
print "Destinatiom: " + destinationIP
print "Souce: " + sourceIP
print "Protocol: "+ protocol

#IP Header... 
ipHeader=receivedPacket[0][14:34]
ipHdr=struct.unpack("!12s4s4s",ipHeader)
destinationIP=socket.inet_ntoa(ipHdr[2])
print "Source IP: " +sourceIP
print "Destination IP: "+destinationIP

#TCP Header...
tcpHeader=receivedPacket[0][34:54]
tcpHdr=struct.unpack("!2s2s16s",tcpHeader)
sourcePort=socket.inet_ntoa(tcpHdr[0])
destinationPort=socket.inet_ntoa(tcpHdr[1])
print "Source Port: " + sourcePort
print "Destination Port: " + destinationPort

我好像遇到了以太网头部分和解包方法的问题,但是我无法解决。提前谢谢您的帮助。


2
有什么问题吗?如果您遇到异常,请粘贴完整的异常输出。如果您得到了无效的结果,请发布实际和期望的输出。 - Peter Gibson
1
@PeterGibson struct.error: unpack需要一个长度为14的字符串参数。它在以太网部分。 - user3490561
2个回答

2
#!/usr/bin/env python
import struct
import sys,os
import socket
import binascii

rawSocket=socket.socket(socket.PF_PACKET,socket.SOCK_RAW,socket.htons(0x0800))
#ifconfig eth0 promisc up
receivedPacket=rawSocket.recv(2048)

#Ethernet Header...
ethernetHeader=receivedPacket[0:14]
ethrheader=struct.unpack("!6s6s2s",ethernetHeader)
destinationIP= binascii.hexlify(ethrheader[0])
sourceIP= binascii.hexlify(ethrheader[1])
protocol= binascii.hexlify(ethrheader[2])

print "Destination: " + destinationIP
print "Source: " + sourceIP
print "Protocol: "+ protocol

#IP Header... 
ipHeader=receivedPacket[14:34]
ipHdr=struct.unpack("!12s4s4s",ipHeader)
destinationIP=socket.inet_ntoa(ipHdr[2])
sourceIP=socket.inet_ntoa(ipHdr[1])
print "Source IP: " +sourceIP
print "Destination IP: "+destinationIP

#TCP Header...
tcpHeader=receivedPacket[34:54]
tcpHdr=struct.unpack("!2s2s16s",tcpHeader)
sourcePort=socket.inet_ntoa(tcpHdr[0])
destinationPort=socket.inet_ntoa(tcpHdr[1])
print "Source Port: " + sourcePort
print "Destination Port: " + destinationPort

谢谢您先生...非常感激 :) - user3490561

2
您的字符串切片语句中多了一个 [0]

ethernetHeader=receivedPacket[0][0:14]

应该只是这样

ethernetHeader=receivedPacket[0:14]

错误提示您需要传入一个长度为14的字符串给struct.unpack。如果您打印出要传入的字符串,可能会发现它只有长度=1。以下是一个示例:
>>> s = 'this is a test'
>>> s[0]
't'
>>> s[0][0:4]
't'
>>> s[0:4]
'this'

是的,您说得对。但是接收到的包不是元组吗?我需要解包第一部分才能检索这些信息。 - user3490561
1
不,socket.recv返回一个字符串(https://docs.python.org/2/library/socket.html#socket.socket.recv)。 - Peter Gibson
谢谢您,非常感激 :) - user3490561
1
你可能一直在想socket.recvfrom(https://docs.python.org/2/library/socket.html#socket.socket.recvfrom),它会返回一个元组`(string, address)`。 - Peter Gibson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接