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)//保存抓包结果
开放
、关闭
和 过滤
状态时的程序执行结果UDP
扫描中,我们可以看到课本中提供的只是在收到UDP包的情况下可以确认端口为开放状态下,编程实现的过程中还可以通过ICMP包中是否包含UDP包进行判断端口是否为开放状态。这是由于编程实现可以更加详细的分析抓到的包。nmap
的上述扫描技术实现的命令行参数开关(每种扫描测试一种状态,且后面专门用nmap进行了扫描实验)实验预期获得的结果:倘若攻击者向靶机发送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))==""):过于复杂,很不[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 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):
print ("Filtered")
elif(pkts.haslayer(TCP)):
if(pkts.getlayer(TCP).flags == 0x12):
send_rst = sr(IP(dst=dst_ip)/TCP(dport=dst_port,flags="R"),timeout=10)
print ("Open")
elif (pkts.getlayer(TCP).flags == 0x14):
print ("Closed")
elif(pkts.haslayer(ICMP)):
if(int(pkts.getlayer(ICMP).type)==3 and int(stealth_scan_resp.getlayer(ICMP).code) in [1,2,3,9,10,13]):
#code 1 : Host unreachable error.
#code 2 : Protocol unreachable error.Sent when the designated transport protocol is not supported.
#code 3 : Port unreachable error. Sent when the designated transport protocol is unable to demultiplex the datagram but has no protocol mechanism to inform the sender.
#code 9 : The destination network is administratively prohibited.
#code 10 : The destination host is administratively prohibited.
#code 13 : Communication Administratively Prohibited.This is generated if a router cannot forward a packet due to administrative filtering.
print ("Filtered")
tcpconnect_scan('172.16.111.141',80)
紧接着上面实验的过滤
状态可得
去掉过滤条件并开启
端口80后(此处开启apache服务)
systemctl start apache2
iptables -I INPUT -p tcp --dport 80 -j ACCPET//需要注意的是记得关闭过滤规则,否则无法开启
使用nmap命令进行扫描,发现得到结果一致
nmap -sS -p 80 -n -vv 172.16.111.141
之后把端口80关闭
,得到以下结果
先修知识:这是一种隐蔽性扫描,当处于端口处于关闭状态时,会回复一个RST包;其余所有状态都将不回复
代码如下:
def Xmas_scan(dst_ip , dst_port , timeout = 10):
pkts = sr1(IP(dst=dst_ip)/TCP(dport=dst_port,flags="FPU"),timeout=10)#发送FIN,PUSH,URG
if (pkts is None):#未收到任何包可能为这两种状态
print ("Open|Filtered")
elif(pkts.haslayer(TCP)):
if(pkts.getlayer(TCP).flags == 0x14):
print ("Closed")#收到RST包即为端口关闭状态
elif(pkts.haslayer(ICMP)):
if(int(pkts.getlayer(ICMP).type)==3 and int(pkts.getlayer(ICMP).code) in [1,2,3,9,10,13]):
print ("Filtered")
Xmas_scan('172.16.111.141',80)
端口处于关闭
状态下(由于上一个实验正关闭着)
端口处于开启
状态下:(与其他状态不同的是,这里没有arp包,我认为是本应该有,也许用了缓存–可通过arp -n查看缓存来判断,由于环境改变了无法复现,但提供了一种排错的方式)
另外,我们分析这个包,发现收到的包确实包含了FPU三个字段
端口处于开启状态下时,使用nmap进行扫描
nmap -sX -p 80 -n -vv 172.16.111.141
端口处于过滤
状态,注意,此时抓到的包是ARP包,并不是TCP包
先修知识:仅发送FIN包,FIN数据包能够通过只监测SYN包的包过滤器,隐蔽性较SYN扫描更⾼,此扫描与Xmas扫描也较为相似,只是发送的包未FIN包,同理,收到RST包说明端口处于关闭状态;反之说明为开启/过滤状态。
代码如下:
def fin_scan(dst_ip , dst_port , timeout = 10):
pkts = sr1(IP(dst=dst_ip)/TCP(dport=dst_port,flags="F"),timeout=10)#发送FIN包
if (pkts is None):#未收到任何包可能为这两种状态
print ("Open|Filtered")
elif(pkts.haslayer(TCP)):
if(pkts.getlayer(TCP).flags == 0x14):
print ("Closed")#收到RST包即为端口关闭状态
elif(pkts.haslayer(ICMP)):
if(int(pkts.getlayer(ICMP).type)==3 and int(pkts.getlayer(ICMP).code) in [1,2,3,9,10,13]):
print ("Filtered")
fin_scan('172.16.111.141',80)
还是延续上个实验的过滤
状态
端口处于开启
状态
另外,分析包后发现确实只发送了FIN包
用nmap进行扫描,得到的结果也是过滤/开启状态
nmap -sF -p 80 -n -vv 172.16.111.141
端口处于关闭
状态
实验先修知识:发送的包中关闭所有TCP报⽂头标记,实验结果预期还是同理:收到RST包说明端口为关闭状态,未收到包即为开启/过滤状态
代码如下:
def null_scan(dst_ip , dst_port , timeout = 10):
pkts = sr1(IP(dst=dst_ip)/TCP(dport=dst_port,flags=""),timeout=10)#发送FIN包
if (pkts is None):#未收到任何包可能为这两种状态
print ("Open|Filtered")
elif(pkts.haslayer(TCP)):
if(pkts.getlayer(TCP).flags == 0x14):
print ("Closed")#收到RST包即为端口关闭状态
elif(pkts.haslayer(ICMP)):
if(int(pkts.getlayer(ICMP).type)==3 and int(pkts.getlayer(ICMP).code) in [1,2,3,9,10,13]):
print ("Filtered")
null_scan('172.16.111.141',80)
端口为关闭
状态下:
端口为开启
状态下:
另外,对包进行分析,抓到的包确实flag为空
用nmap进行扫描,结果确实一致
nmap -sN -p 80 -n -vv 172.16.111.141
端口为过滤
状态下:
实验先修知识:这是一种开放式扫描,通过发送UDP包进行扫描。当收到UDP回复时,该端口为开启状态;否则即为关闭/过滤状态
代码如下:
def udp_scan(dst_ip,dst_port,dst_timeout = 10):
#发送udp包
udp_scan_resp = sr1(IP(dst=dst_ip)/UDP(dport=dst_port),timeout=dst_timeout)
#未收到UDP回复则为open/filter
if (udp_scan_resp is None):
print("Open|Filtered")
#收到UDP回复则为开启状态
elif (udp_scan_resp.haslayer(UDP)):
print("Open")
elif(udp_scan_resp.haslayer(ICMP)):
#the server responds with an ICMP port unreachable error type 3 and code 3, meaning that the port is closed on the server.
if(int(udp_scan_resp.getlayer(ICMP).type)==3 and int(udp_scan_resp.getlayer(ICMP).code)==3):
print("Closed")
#If the server responds to the client with an ICMP error type 3 and code 1, 2, 9, 10, or 13, then that port on the server is filtered.
elif(int(udp_scan_resp.getlayer(ICMP).type)==3 and int(udp_scan_resp.getlayer(ICMP).code) in [1,2,9,10,13]):
print("Filtered")
elif(udp_scan_resp.haslayer(IP) and udp_scan_resp.getlayer(IP).proto==IP_PROTOS.udp):
print("Open")
udp_scan('172.16.111.141',53)
端口处于关闭
状态下,可以看到抓到的ICMP包type/code均为3,且确实未收到UDP回复包
端口处于开启
状态下:注意,udp端口为53
nc -l -u -p 53 < /etc/passwd //开启53端口
端口处于过滤
状态下:iptables -I INPUT -p udp --dport 53 -j DROP
用nmap进行验证结果,得到的确实为开放/过滤状态
nmap -sU -p 53 -n -vv 172.16.111.141
iptables -A INPUT -p tcp --dport 80 -j DROP没反应,后来发现这行代码应该在靶机中执行而不是攻击者中
if(str(type(pkts))=="" )://此行代码一直执行不成功,是由于该包是空的导致,可以通过type(pkts)可以查看包的类型,经输出后发现pkts是个class类,将代码改为if(str(type(pkts))=="" ):,当然这是比较复杂的语法,不推荐,建议改简单,详见上面代码注释
使用nc -l -u -p
53命令未达到预期结果,加上< /etc/passwd
后成功
扫描实验中,TCP connect/TCP stealth扫描属于开放扫描,TCP Xmas/TCP FIN/TCP NULL扫描属于隐蔽扫描,UDP 扫描也属于开放扫描。我认为TCP隐蔽扫描
能有效避免对⽅⼊侵检测系统和防⽕墙的检测,但这种扫描使用的数据包在通过⽹络时容易被丢弃从⽽产⽣错误的探测信息,而开放扫描
会产⽣⼤量审计数据,容易被对⽅发现,但其可靠性⾼。
总结各种扫描方式所对应的状态
扫描方式/端口状态 | 开放 | 关闭 | 过滤 |
---|---|---|---|
TCP connect/TCP stealth | 完整的三次握手,能抓到ACK&RST包 | 只收到一个RST包 | 收不到任何TCP包 |
TCP Xmas/TCP FIN/TCP NULL | 收不到TCP回复包 | 收到一个RST包 | 收不到TCP回复包 |
UDP | 收到UDP回复包 | 收不到UDP回复包 | 收不到UDP回复包 |
nmap是一款强大的网络扫描工具,使用起来很方便,能实现很多编程能实现的功能
scapy的功能也很强大,可以很容易的构造出一些伪造包或者伪造源的包,很容易实现对靶机的伤害
端口的开放与关闭是防火墙的角度,scapy编程只是判断可达不可达,监听更多是从进程的角度,而UDP本身没有开放和关闭这些状态,只是为了观察我们模仿TCP(经老师上课补充总结)
查看⼀下自⼰的IP地址,为后续探测做准备
扫描内⽹存活的主机,选择目标主机
nmap -sP -A 4 +目标主机 //仅进行ping扫描,没有进行进一步测试
扫描结果如下,可以看出999个端口都是关闭的
扫描该目标主机常见服务,并同时进行抓包,nmap可以扫描到目标主机常见端口服务
nmap +目标主机
扫描目标主机的操作系统 ,查看目标主机各个服务详细版本信息 ,奇怪的是,这里没有扫描到该有的信息,我们打开目标主机的apache服务后,再次进行扫描,发现得到了80端口的服务信息,而且得到的信息显示debian
nmap -sV -O +目标主机ip
#-O : Enable OS detection
#-sV : Probe open ports to determine service/version info
Nmap是⼀个⽹络探测和安全扫描程序,系统管理者和个⼈可以使用这个软件扫描⼤型⽹络,获取目标主机运⾏和提⾼的服务信息
尽量在root用户权限下使用Nmap ,否则容易实现不了预期的结果。 这个是因为操作系统限制了「构造畸形包」这一行为,换句话说只有root
用户有这个权限。所谓畸形包就是协议之外产生的包。操作系统知道你好好的凭空发RA
这种肯定有问题的。那么如果是root
用户那么操作系统认为你知道自己在做什么,否则操作系统拒绝往外发RA
这种包
我们使用非管理员权限使用nmap进行扫描,当然在此之前,我们要在kali中新建一个非root用户
使用该用户(test)进行nmap扫描,我们发现TCP connect可以正常扫描,但是其他受到了权限的限制,查询资料发现确实如此,TCP connect scan不需要管理员权限,详见权限信息
Nmap运⾏通常会得到被扫描主机端⼝的列表
由于zmap很容易造成服务器瘫痪,老师录屏中也不推荐做这个实验
ns_chap0x01所用拓扑
网关以及两台受害者网卡设置
安装scapy
利用scapy进行简单编程
很容易就构造了一个源地址并成功发送了一个包,因此互联网中要设置源地址的白名单,从而防止遭受拒绝服务攻击
验证网关natnetwork网络的连通性,实验证明,当网关网卡换为NAT模式以后,发出去的包不会再有回应,这是官方的一个bug,这我们无法解决,因此我们实验想连互联网还是用NAT网络模式进行。
安装scapy
利用scapy进行简单编程
很容易就构造了一个源地址并成功发送了一个包,因此互联网中要设置源地址的白名单,从而防止遭受拒绝服务攻击
验证网关natnetwork网络的连通性,实验证明,当网关网卡换为NAT模式以后,发出去的包不会再有回应,这是官方的一个bug,这我们无法解决,因此我们实验想连互联网还是用NAT网络模式进行。