python渗透测试入门——流量嗅探器

打印 上一主题 下一主题

主题 852|帖子 852|积分 2556

1.代码及代码讲解。
代码编写工具:VsCode
(1)socket嗅探器
首先第一个脚本是最简单的原始socket嗅探器,它只会读一个数据包,然后直接退出:
  1. import socket
  2. import os
  3. #host to listen on
  4. HOST = ''<br>#这里输入自己的IP地址<br>
  5. def main():
  6.     #create raw socket, bin to public interface
  7.     if os.name == 'nt':
  8.         socket_protocol = socket.IPPROTO_IP
  9.     else:
  10.         socket_protocol = socket.IPPROTO_ICMP
  11.    
  12.     sniffer = socket.socket(socket.AF_INET,socket.SOCK_RAW.socket_protocol)
  13.     sniffer.bind((HOST,0))
  14.     #include the IP header in the capture
  15.     sniffer.setsockopt(socket.IPPROTO_IP,socket.IP_HDRINCL,1)
  16.     if os.name =='nt':
  17.         sniffer.ioctl(socket.SIO_RCVALL,socket.RCVALL_ON)
  18.     #read one packet
  19.     print(sniffer.recvfrom(65565))
  20.     if os.name == 'nt':
  21.         sniffer.ioctl(socket.SIO_RCVALL,socket.RCVALL_OFF)
  22. if __name__ == '__main__':
  23.     main()
复制代码
注意:这里Windows和Linux的区别是,前者允许我们嗅探任何协议的所有流入数据,而后者强制我们指定一个协议来嗅探,这里指定的是ICMP。
上面这只是一个非常简单的嗅探器,那我们将对它的功能进行进一步的拓展。
(2)ip解码器
  1. import ipaddress
  2. import os
  3. import socket
  4. import struct
  5. import sys
  6. #定义了一个Python结构,把数据包的前20个字节映射到IP头对象中。展示目前的通信协议和通信双方的IP地址
  7. class IP:
  8.     def __init__(self, buff=None):
  9.         header = struct.unpack('<BHHHBBH4s4s', buff)
  10.         self.ver = header[0] >> 4
  11.         self.ihl = header[0] & 0xF
  12.         self.tos = header[1]
  13.         self.len = header[2]
  14.         self.id = header[3]
  15.         self.offset = header[4]
  16.         self.ttl = header[5]
  17.         self.protocol = header[6]
  18.         self.sum = header[7]
  19.         self.src = header[8]
  20.         self.dst = header[9]
  21.         # human readable IP addresses
  22.         #使用新打造的IP头结构,将抓包逻辑改成持续抓包和解析
  23.         self.src_address = ipaddress.ip_address(self.src)
  24.         self.dst_address = ipaddress.ip_address(self.dst)
  25.         # map protocol constants to their names
  26.         
  27.         self.protocol_map = {1: "ICMP", 6: "TCP", 17: "UDP"}
  28.         try:
  29.             self.protocol = self.protocol_map[self.protocol_num]
  30.         except Exception as e:
  31.             print('%s No protocol for %s' % (e, self.protocol_num))
  32.             self.protocol = str(self.protocol_num)
  33.     def sniff(host):
  34.         # should look familiar from previous example
  35.         if os.name == 'nt':
  36.             socket_protocol = socket.IPPROTO_IP
  37.         else:
  38.             socket_protocol = socket.IPPROTO_ICMP
  39.         sniffer = socket.socket(socket.AF_INET,socket.SOCK_RAW,socket_protocol)
  40.         sniffer.bind((host,0))
  41.         sniffer.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)
  42.         if os.name == 'nt':
  43.             sniffer.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON)
  44.         try:
  45.             while True:
  46.                 # read a packet
  47.                 #将前20字节转换成IP头对象
  48.                 raw_buffere = sniffer.recvfrom(65535)[0]
  49.                 # create an IP header from the first 20 bytes
  50.                 ip_header = IP(raw_buffere[0:20])
  51.                 # print the detected protocol and hosts
  52.                 #打印抓取信息
  53.                 print('Protocol: %s %s -> %s' % (ip_header.protocol, ip_header.src_address, ip_header.dst_address))
  54.         except KeyboardInterrupt:
  55.             # if we're on Windows, turn off promiscuous mode
  56.             if os.name == 'nt':
  57.                 sniffer.ioctl(socket.SIO_RCVALL,socket.RCVALL_OFF)
  58.             sys.exit()
  59. if __name__ == '__main':
  60.     if len(sys.argv) == 2:
  61.         host = sys.argv[1]
  62.     else:
  63.         host = ''
  64.     sniffer(host)
复制代码
在理解这一部分的内容之前,我们首先要了解一个python库。struct库:struct库提供了一些格式字符,用来定义二进制数据的结构。这个库在解码,密码学方面经常会用到。
注:在struct库里,不存在对应于nybble格式(即4个二进制位组成的数据块,也叫作nibble)的格式字符。
  1. self.ver = header[0] >> 4
复制代码
对于IP头的第一个字节,我们只想取高位nybble(整个字节里的第一个nybble)作为ver的值。取某字节高位nybble的常规方法是将其向右位移4位,相当于在该字节的开头填4个0,把其尾部的4位挤出去。这样我们就得到了原字节的第一个nybble。
  1. self.ihl = header[0] & 0xF
复制代码
我们想把低位nybble(或者说原字节的最后4个二进制位)填进hdrlen里,取某个字节低位nybble的常规方法是将其与数字0xF(00001111)进行按位与运算。它利用了0 AND 1 = 0的特性(0代表假,1代表真)。想要AND表达式为真,表达式两边都必须为真。所以这个操作相当于删除前4个二进制位,因为任何数AND 0都得0;它保持了最后4个二进制位不变,因为任何数AND 1还是原数字。
(3)解码ICMP
[code]import ipaddressimport os import socketimport structimport sys#定义了一个Python结构,把数据包的前20个字节映射到IP头对象中。展示目前的通信协议和通信双方的IP地址class IP:    def __init__(self, buff=None):        header = struct.unpack('
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

冬雨财经

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表