实验9:嗅探与欺骗实验
- Task1
使用ifconfig命令找到连接虚拟机和docker容器的网络网卡(br-0006f02104db)
Docker的网络模式如下,设置主机模式可以监听流经所有容器的数据包
- Set 1
- Task1.1A
数据包类型为echo-request,说明是ping程序发出的ICMP请求数据包
- Task1.1B
BPF是一种在内核中用于数据包过滤和网络分析的技术。它最初由伯克利大学开发,现在已经被广泛地应用在操作系统中,例如在Linux系统中用于tcpdump和Wireshark等网络工具中。
'src host 10.9.0.5 and tcp dst port 23'
注:实验时在VM主机上运行嗅探程序,docker容器中的所有数据包都会流经VM主机
使用其他不是ICMP协议(如:telnet登录请求)发出的数据包则不会被程序抓包
- Task1.2
Scapy是对数据包进行修改的工具,我们可以使用它来修改数据包中的任意字段,Task1.2的任务是修改数据包的IP地址字段,这样可以使用ICMP欺骗对面主机,隐藏自己的真实IP地址
编写以下代码,隐藏自己的真实IP为"123.123.123.123",欺骗IP为"10.0.2.3"的主机并发出ICMP Echo-request请求
- Task1.3
这里选取获得访问http://www.baidu.com的每一跳路由器的IP地址。首先定义目的IP和最大TTL(防止数据包在网络中不停地传输,其余字段scapy会帮我们补全),然后进入循环,构造数据包并发送,每次循环都让TTL+1;对每一次数据包发送后的响应报文都进行判断,如果响应报文返回TTL错误,就成功获取了当前这一跳的路由地址,如果没有响应,说明数据包丢失,如果成功到达目标IP就跳出循环
运行上面的程序,成功获取了访问百度网址的各级路由的IP地址
- Task1.4
该实验目的是通过嗅探器抓取当前子网内的所有ICMP数据包,针对每一个数据包都去构造一个伪响应,发出ICMP请求的主机收到响应后会错误认为对方主机处于开机状态,这会造成子网内的所有主机向任何互联网主机发送ICMP都会错误认为对方主机开机
首先使用scapy的嗅探器抓取ICMP数据包,使用回调函数使抓取到的每一个数据包都去执行产生伪响应的回调函数,然后修改数据包type字段为0(表示是ICMP reply),其他字段相同(IP地址记得互换),发送该数据包,代码如下:
在Attacker主机上执行该程序,攻击Host A,在Host A上执行Ping程序
执行该程序,并同时使用ping程序分别向不同的IP地址发出ICMP数据包
- ping 1.2.3.4
不运行我们的程序,去Ping1.2.3.4,发现Ping不通
运行程序后,发现虽然是一个互联网上不存在的地址,但依然成功返回ICMP回复报文,说明攻击程序执行成功
- ping 10.9.0.99
发现这是一个局域网内不存在的地址,所以数据包的转发不会经过主机提供的NAT映射服务以转发到外网,而是会顺着局域网内路由直接发送到对方主机,由于Attacker连接的是主机,所以Attacker收不到该ICMP请求,局域网内会直接返回不可达信息,表示局域网内不存在该主机
Attacker上的程序没有收到ICMP请求
- ping 8.8.8.8
8.8.8.8 是互联网上实际存在的主机地址,所以地址为8.8.8.8的主机会回复一次ICMP reply,而我们的攻击者程序也会回复一次ICMP reply,两个回复重复了,所以会有 DUP 标志,表示接收到了重复的 ICMP Echo Reply 报文,正常的ICMP reply则不会有DUP标志
ip route get 是一个用于查询特定目标 IP 地址的路由信息的命令。它可以告诉你关于发送数据包到目标 IP 地址的路由表条目,以及通过哪个网络接口发送数据包的详细信息
使用ip route get命令对三个地址分别进行查询
发现地址为1.2.3.4和8.8.8.8的路由信息都经过了10.9.0.1,即我们的Attacker主机,这是因为回复是由我们的程序所回复的,而地址为10.9.0.99的路由条目因为不经过网关,所以没有经过我们的程序
- ping 1.2.3.4
- Task2
- Task2.1
- Task2.1A
只需要更改对捕获数据包做处理的got_packet 函数即可,netinet/ip.h中有IP数据包结构体ip,使用指针访问结构体中存储地址的部分即可,注意要使用inet_ntop函数将网络地址转换为点分十进制形式的字符串
代码如下:
在HostA上使用Ping程序发出ICMP数据包
在Attacker上运行嗅探程序,成功抓到经过HostA的ICMP数据包,并打印出源IP和目的IP
Q1:具体解释如下:
- 使用 pcap_open_live 函数打开一个实时的网络数据包捕获会话,指定了抓取数据包的网卡名称。
- 调用 pcap_compile 和 pcap_setfilter 函数编译和设置过滤器规则,这里的过滤器规则是 "icmp",表示只捕获 ICMP 协议的数据包。
- 调用 pcap_loop 函数进入捕获数据包的循环,每捕获到一个数据包就会调用 got_packet 函数进行处理。
- 在 got_packet 函数中,对捕获到的数据包进行简单处理,并打印 源IP和目的IP。
Q2:这里嗅探到的数据包是整个局域网内的数据包,而不只是当前一个主机上的数据包,出于对数据安全的考虑,会对嗅探数据包的行为做出权限限制;
程序会在监听网卡处(pcap_open_live函数)失败,发生报错
Q3:首先修改pcap open live()函数的第三个参数为0,关闭混杂模式,ip -d link show dev 命令用于显示指定网络接口的详细信息,使用此命令查看发现混杂模式已经关闭
此时再使用抓包程序发现没有抓到HostA的ICMP数据包
使用混杂模式可以监听所在网段下其他机器的数据包,而关闭后程序只能嗅探到那些跟它直接有关的通信数据包
- Task2.1B
捕获两个特定主机之间的 ICMP 数据包
过滤表达式为:icmp and src host 10.9.0.5 and dst host 10.9.0.1
在HostA上使用Ping程序向10.9.0.1(即Attacker)发送ICMP数据包
在Attacker上运行带过滤器的嗅探程序,发现成功抓包,符合过滤器规则
而如果向10.9.0.6发送ICMP数据包,则没有被抓包,说明过滤器生效
捕捉目的端口在 10 到 100 之间的 TCP 包
过滤表达式为:tcp and dst portrange 10-100
在HostA上使用telnet程序指定99端口向10.9.0.1(即Attacker)发送端口号为23的数据包
在Attacker上运行带过滤器的嗅探程序,发现成功抓包,符合过滤器规则
而如果向10.9.0.1发送其他端口(101端口)的数据包,则没有被抓包,说明过滤器生效
- Task2.1C
先定位到IP数据包部分,然后通过IP结构体指针,将IP数据包的数据部分打印出来,使用is_print函数判断是否是可打印字符,不能打印的16进制数用"."代替
在Attacker上运行嗅探程序,嗅探到使用telnet协议登录的数据包;首先查找password字段,确定密码数据包的位置,然后读出后面收到的数据包的内容即是真实密码
这里可以读出密码是dees
- Task2.1B
- Task2.1A
- Task2.2
- Task2.2A
构造IP和TCP协议的头部字段,包括IP和端口、协议类型、偏移值、检验和等字段,
构造计算校验和的函数
注意TCP包的构造在计算校验和时需要构造一个伪报头
然后运行程序,向8.8.8.8主机的8900端口发送一个TCP数据包
使用wireshake抓包,成功抓到了我们发送的TCP包,查看发现目的IP和目的端口与我们设置的一样,判断确实是我们发出的数据包
- Task2.2B
在send_buf上构造ICMP数据包,包括地址、校验和、ICMP类型等字段,最后使用sendto函数发送send_buf即可
运行程序,向8.8.8.8主机发送一个ICMP echo request数据包
使用wireshake抓包,成功抓到了我们发送的ICMP包,查看发现成功收到了对方主机8.8.8.8回复的ICMP reply数据包
Q4
将代码中设置长度分别修改长度小于包大小和大于包大小,小于时wireshark 没 有 捕 捉 到 包 , 说 明 没 有 发 出 去 。
大于可以看到正常发送出去,且收到了相应。说明可以调大 length,不能调小 length
Q5
IP头部的校验和可以不计算,但是ICMP的头部校验和需要计算,UDP协议的校验和可以不计算,经过实验发现操作系统即使校验和不对也会将UDP包发送,但是TCP头部校验和必须计算正确操作系统才会将其发送出去。
Q6
使用原始套接字可以绕过操作系统的网络协议栈,直接访问网络层和传输层。可以构造和发送自定义的网络数据包,包括伪造源IP地址、欺骗、嗅探等操作。为了防止滥用和网络攻击,操作系统通常会限制原始套接字的使用权限只允许具有root权限的用户或特权进程进行操作,减少网络攻击的风险。
如果不是用root权限运行,程序在创建原始套接字时会出错
在创建套接字时添加输出错误信息的语句
- Task2.2A
- Task2.3
这道题的实验效果与之前的ICMP欺骗实验相同,就是抓取局域网内的ICMP数据包并回复,欺骗被攻击者询问的主机存活
依然使用上面的pcap框架,修改get_packet()函数,分别使用结构体指针访问数据包所在内存并修改对应的字段,其中ICMP数据包头部修改type和code为0,表示这是一个ICMP reply包,IP部分将源地址和目的地址互换,注意ICMP要计算校验和,具体代码如下:
然后构造原始套接字将数据包发送
在Attacker上运行我们的程序,并在HostA上使用Ping程序向一个不存在的IP地址发出ICMP请求数据包,
我们的程序成功抓到了数据包,并对每个数据包都做出了回复
发现在运行程序之后,之前ping不通的地址现在可以ping通了
- Task2.1
- 结论
Sniffing 原理:嗅探是指窃听网络中流经的数据包。在局域网中,数据包会以广播的形式广播到局域网内所有主机的网卡,网卡会检查数据帧头部的目的地址是否与本主机的 MAC 地址相匹配,若匹配,就会接收,否则只是进行简单的丢弃,在这种模式下我们的嗅探程序并不会监听到数据包。实际上,网卡有一种特殊的模式----'混杂模式',在该模式下,网卡会将从网络中接收到的每个数据帧,即使 MAC 与目标 MAC 并不匹配;在混杂模式下,嗅探程序便可正常工作。
Spoofing 原理:数据包的伪造一般由数据包的构造和发送数据包两个步骤构成。一般伪造会与嗅探结合使用,首先进行数据包的嗅探,然后根据捕获的数据包内容来伪造响应数据包,达到欺骗的目的。
嗅探和欺骗在实际中经常结合在一起使用,除了本实验中遇到的ICMP欺骗等,还有ARP欺骗等手段,都会造成非常严重的问题。工具scapy和pcap只是将一些常用的方法进行了封装,所有的内容都可以在原始套接字下完成,C语言为网络编程提供了完善的库,里面有各种协议数据包的结构体,所以工具并不重要,重要的是了解协议本身存在哪些安全漏洞,为什么会有安全漏洞,如网络欺骗就是因为之前的icmp、arp等协议缺少验证或鉴别机制,所以当我们制定网络协议时一定要充分考虑到安全需求。