正如标题所说我在python 2.7中创建一个数据包嗅探器(出于兼容性目的需要为2.7)。
我获得了我想要的功能,使用TCP,UDP或ICMP嗅探所有传入或传出的流量,代码如下:
utils.py
是一个具有解析每种包的函数的模块以及一些其他辅助函数,创建套接字的函数是:
def socket_safe(*args):
# Sets up a socket using the specified args, taking care of any exceptions
# and returning the socket descriptor object
try:
sd = socket.socket(*args)
except error, msg:
print 'Error', msg[0], 'creating socket:', msg[0]
sys.exit()
return sd
def socket_universal():
# Uses the socket_safe function to set up a socket object that will capture
# any incoming or outgoing (including TCP, UDP and ICMP)
# 0x0003 is ETH_P_ALL
return socket_safe(socket.AF_PACKET , socket.SOCK_RAW , socket.ntohs(0x0003))
主要文件是:
from struct import *
from socket import *
from utils import *
eth_protocols = {'ip_protocol' : 8}
ip_protocols = {'tcp_protocol' : 6,
'icmp_protocol' : 1,
'udp_protocol' : 17}
# Create a socket descriptor object that will receive any type of packet.
# For details please see the function definition in utils.py
sd = socket_universal()
for _ in range(5):
print 'WAITING FOR PACKET...'
# Receive up to 65565 bytes of data from any available source
# as a tuple of the form (packet_contents, source_socket_info)
packet, \
source \
= sd.recvfrom(65565)
print 'PACKET RECEIVED : '
# Parse the destination and source MAC addresses and the protocol from the ethernet header.
# For details please see the function definition in utils.py
dest_mac, \
src_mac, \
eth_protocol \
= parse_ethernet_header(packet)
print '\tETHERNET HEADER : \n', \
'\t\tDestination MAC :', dest_mac, '\n', \
'\t\tSource MAC : ', src_mac, '\n', \
'\t\tEth. Protocol : ', eth_protocol
# Parse IP packets
if eth_protocol == eth_protocols['ip_protocol']:
# Parse all available information from the IP header of the packet.
# For details please see the function definition in utils.py
version, \
ihl, \
type_of_service, \
total_len, \
identification, \
ip_flags, \
offset, \
ttl, \
ip_protocol, \
ip_checksum, \
src_ip_addr, \
dest_ip_addr \
= parse_ip_header(packet)
print '\tIP HEADER : \n', \
'\t\tVersion : ', version, '\n', \
'\t\tIP Header Length : ', ihl, '\n', \
'\t\tType of Service : ', type_of_service, '\n', \
'\t\tTotal Length : ', total_len, '\n', \
'\t\tIdentification : ', identification, '\n', \
'\t\tFlags : ', ip_flags, '\n', \
'\t\tOffset : ', offset, '\n', \
'\t\tTime to Live : ', ttl , '\n', \
'\t\tIP Protocol : ', ip_protocol, '\n', \
'\t\tChecksum : ', ip_checksum, '\n', \
'\t\tSource Address : ', src_ip_addr, '\n', \
'\t\tDestination Address :', dest_ip_addr
# Parse TCP packets
if ip_protocol == ip_protocols['tcp_protocol']:
# Parse all available information from the TCP header of the packet.
# For details please see the function definition in utils.py
src_port, \
dest_port, \
seq_num, \
ack_num, \
data_offs, \
tcp_flags, \
window, \
tcp_checksum, \
urg_ptr, \
data \
= parse_tcp_header(packet, ihl)
print '\tTCP HEADER: \n', \
'\t\tSource Port : ', src_port, '\n', \
'\t\tDest Port : ', dest_port, '\n', \
'\t\tSequence Number : ', seq_num, '\n', \
'\t\tAcknowledgement : ', ack_num, '\n', \
'\t\tTCP header length :', data_offs, '\n', \
'\t\tFlags : ', tcp_flags, '\n', \
'\t\tWindow : ', window, '\n', \
'\t\tChecksum : ', tcp_checksum, '\n', \
'\t\tUrgen Pointer : ', urg_ptr, '\n', \
'\t\tData : ', data
# Parse ICMP packets
elif ip_protocol == ip_protocols['icmp_protocol']:
# Parse all available information from the ICMP header of the packet.
# For details please see the function definition in utils.py
icmp_type, \
code, \
icmp_checksum, \
data \
= dataparse_icmp_header(packet, ihl)
print '\tIMCP HEADER : \n', \
'\t\tType : ', icmp_type, '\n', \
'\t\tCode : ', code, '\n', \
'\t\tChecksum :', icmp_checksum, '\n', \
'\t\tData : ', data
# Parse UDP packets
elif ip_protocol == ip_protocols['udp_protocols']:
src_port, \
dest_port, \
length, \
udp_checksum, \
data \
= parse_udp_header(packet, ihl)
print '\tUDP HEADER : \n', \
'\t\tSource Port :', src_port, '\n', \
'\t\tDest Port : ', dest_port, '\n', \
'\t\tLength : ', length, '\n', \
'\t\tChecksum : ', udp_checksum, '\n', \
'\t\tData : ', data
else:
print '\tNOT A TCP, ICMP OR UDP PACKAGE. SKIPPING...'
print '\tEND OF PACKET.\n'
现在我需要做的就是只能在本地网络中嗅探包。
如果我只需要某些机器之间的软件包,我想可以通过使用所需机器的IP或MAC列表以及一些if
来快速解决,但我不确定我到底是怎么回事应该辨别哪些包代表本地网络中的流量。
我的猜测是我应该使用source
的{{1}}部分,因为我看到了这个名字可能是一个新的东西但是关于这个的文档是......根本就没有,至少没有在官方python文档中,没有引用手册页或任何类似的东西。
最重要的问题是:我应该如何限制'嗅探'仅限于本地网络?
提前谢谢!