第五章 网络扫描
课后作业:基于 Scapy 编写端口扫描器
实验目的
- 掌握网络扫描之端口状态探测的基本原理
实验环境
- python + scapy2.4
实验先修知识
-
kali中基本端口开启/关闭命令
nc -l -p 8888 -u//指定端口开启关闭(加-u是UDP监听,不加u是TCP监听进行监听) nestat -anop | grep ':80'(listen)//查看运行在指定端口的进程 netstat -tapln//查看端口监听情况的指令 lsof -i 4 -L -P -n//查看处于监听状态的端口
-
scapy编程基本使用
pkt=IP()/ICMP()//构造包
pkt.show()//显示包
ls()//查看包
lsc()//列举scapy内置函数
sr()//包含发送和接受包(网络层)
srp()//在第二层发送和接受包(数据链路层构造)
srp1()//只接受1个包
pkt=IP(dst='172.16.111.141')//目的地址指定
send(pkt)//只发送数据包
exit //退出编程模式回到命令行
ret[ICMP].type //访问数据包
ret[IP]//访问数据包
pkt=Ethernet/IP/ICMP//构造更下层的包
ret [Ether].fields//查看目的地址/源地址/包类型
pkt=Ether(src='',dst='')//可以构造局域网中的数据包
help(src) help(IP)//查看官方帮助信息
q //退出帮助信息
pkts=sniff(iface='eth0',count=100)//进行抓包,指定100个数据包
pkts.nsummary()//查看数据包
pkts[99][IP]//查了第99个包的数据
pkts[99][Padding]//查看padding信息
pkts[99][TCP].flag//查看标志位
pkts=rcap('')//查看抓的包的结果
help(wrpcap)//保存抓包结果
实验要求(完成度)
- 完成以下扫描技术的编程实现
- TCP connect scan / TCP stealth scan
- TCP Xmas scan / TCP fin scan / TCP null scan
- UDP scan
- 上述每种扫描技术的实现测试均需要测试端口状态为:
开放
、关闭
和过滤
状态时的程序执行结果 - 提供每一次扫描测试的抓包结果并分析与课本中的扫描方法原理是否相符?如果不同,试分析原因;
- 基本相符,但是在使用编程扫描的时候比课本中实现的更详细,例如
UDP
扫描中,我们可以看到课本中提供的只是在收到UDP包的情况下可以确认端口为开放状态下,编程实现的过程中还可以通过ICMP包中是否包含UDP包进行判断端口是否为开放状态。这是由于编程实现可以更加详细的分析抓到的包。 - 抓包结果附在附件中
- 基本相符,但是在使用编程扫描的时候比课本中实现的更详细,例如
- 在实验报告中详细说明实验网络环境拓扑、被测试 IP 的端口状态是如何模拟的
- (可选)复刻
nmap
的上述扫描技术实现的命令行参数开关(每种扫描测试一种状态,且后面专门用nmap进行了扫描实验)
实验过程
TCP connect scan
-
实验预期获得的结果:倘若攻击者向靶机发送SYN包,能完成三次握手,收到ACK,则端口为开发状态;若只收到一个RST包,则端口为关闭状态;倘若什么都没收到,即为端口过滤状态。
-
scapy编程python代码实现(代码是根据对包的观察进行编写的)
def tcpconnect_scan(dst_ip , dst_port , timeout = 10): pkts = sr1(IP(dst = dst_ip) / TCP(dport = dst_port , flags = "S") , timeout = timeout)#sr1()表示只接受一个包,此步在构造SYN包,flags="S"表示为SYN包 #if(str(type(pkts))=="<type 'NoneType'>"):过于复杂,很不[pythonic] if (pkts is None): print ("filter") elif (pkts.haslayer(TCP)): if (pkts[1].flags == 'AS'):#由经验可知,我们收到的第一个包即为第一个回来的tcp包,若为ACK包,则为开放状态 print ("Open") elif (pkts[1].flags == 'AR'):#收到的第一个包为RST包,则为关闭状态 print ("Close") tcpconnect_scan('172.16.111.141',80)
-
这是第一次执行代码的结果,显示端口为
关闭
,同时我们对抓包结果进行观察,发现结果为一致 -
接着将该端口
开启
后再执行代码(开启apache服务)systemctl start apache2
- 再执行刚刚的代码,并同时进行抓包,发现此时端口处于开启状态
-
用nmap命令进行扫描,发现结果一致
nmap -sT -p 80 -n -vv 172.16.111.141
-
在靶机中
过滤
80端口的tcp包iptables -A INPUT -p tcp --dport 80 -j DROP
-
再执行该代码,得到端口为过滤状态,抓包结果中确实只有一个接收到的TCP包
TCP stealth scan
-
与TCP connect scan扫描非常相似,因此此处实验简化一些步骤
-
def tcpstealth_scan(dst_ip , dst_port , timeout = 10): pkts = sr1(IP(dst=dst_ip)/TCP(sport=src_port,dport=dst_port,flags="S"),timeout=10) if (pkts is None)