【安全攻防综合实验3】网络扫描

Posted by 慕念 on September 26, 2021

【实验目的】

  • 实现一种抗网络端口扫描的机制

  • 了解TCP、UDP端口扫描原理
  • 实践Socket编程
  • 实践Iptables防火墙的应用
  • 体验网络程序排错分析过程

【实验步骤】

一、Iptables防火墙设置

(一)TCP

根据提示“本实验就是要过滤掉输出链中的RST数据包和ICMP Port unreachable 数据包”。由于对于TCP端口扫描,目标机收到SYN包,系统会自动返回的RST数据包,为了伪造端口开放的假象,需要把该包drop。

命令:

iptables -A OUTPUT -p tcp --tcp-flags RST RST -j DROP

image2

测试:

image3

image4

可以看到,在启动防火墙后,由于drop了所有OUTPUT的RST报文,所以nmap扫描显示另外97个端口被过滤了,但是因为开着的端口在接收到SYN报文后会发送SYNACK,所以仍然可以检测到开放的端口。

(二)UDP

而对于UDP端口扫描,目标机收到一个发网关闭端口的数据包,会返回ICMP port unreachable数据包。若过滤掉这些数据包,扫描方将无法判断该UDP端口是否开放。

命令: iptables -A OUTPUT -p icmp --icmp 3 -j DROP (其中icmp类型为3代表所有的不可达情况)

image5

测试:

image6

image-20220703191229831

开启防火墙后,nmap无法判断UDP端口是否开放,显示为in ignored states。

二、Socket编程

Python代码:

from scapy.all import *
from scapy.layers.inet import IP, TCP


def send_ack(recv_pkt):
    # ip地址和端口号 src和dst对换
    
    ip_src = recv_pkt[IP].dst
    ip_dst = recv_pkt[IP].src
    tcp_sport = recv_pkt[TCP].dport
    tcp_dport = recv_pkt[TCP].sport
    tcp_seq = recv_pkt[TCP].seq
    tcp_ack = recv_pkt[TCP].seq + 1
    # 发回SYNACK数据包,flags置为SA
    
    packet = IP(src=ip_src, dst=ip_dst) / TCP(sport=tcp_sport, dport=tcp_dport, ack=tcp_ack, seq=tcp_seq, flags="SA")
    send(packet)


sniff(filter="tcp[tcpflags] & (tcp-syn) != 0 and tcp[tcpflags] & (tcp-ack) == 0", prn=send_ack, iface="ens33")
# 嗅探所有tcp flags中syn=1,ack=0的包,收到后执行send_ack函数,“ens33"是网卡的名字(可以通过ifconfig查看)

在centos上运行代码:

image8

image9

Nmap结果:

image10

三、一些思考

为了更加清晰地看到scan与antiscan之间的过程,通过wireshark抓TCP包,结果如下:

开启防火墙前:

image11

image12

​ 将wireshark中的过滤条件设为ip.src==192.168.1.103   ip.dst==192.168.1.103,可以看到在扫描方发送SYN后,关闭的端口会回应RST,ACK包,开放的端口会回复SYNACK。

​ 开启防火墙后,看不到RST包了:

image13

保留源地址为192.168.1.103的数据包,可以看到开放的端口仍然会发送SYNACK,并且由于nmap不会响应SYNACK所以发送方timeout后重传了SYNACK报文(图中的TCP Retransmission)。

image14

开启防火墙+运行raw_socket.py后:

在窗口可以看到wireshark抓到了自己构造出来的SYNACK包,所以nmap会认为该端口打开了。

image15

对于本身就是开着的端口比如说23号,可以看到抓到了4个SYNACK【不知道为什么抓到的centos发出的包都是两份的,可能是因为虚拟机的原因?】可以从窗口长度判断出,先发的是端口自己回的,后发的是python构造的,由于大部分情况下系统回的比较快,python运行的比较慢,所以这样并不影响正常连接的建立。

image16

UDP过滤前抓包,可以看到很多回复port unreachable的包:

image17

过滤后抓包,由于把icmp类型为3的unreachable destination的包都drop了就看不到回复的包了:

image18