只是记录
学习笔记
参考:这个
四层发现优缺点
- 使用TCP/UDP协议(TCP、UDP各65535个端口)
优点:
- 可路由且结果可靠;
- 不太可能被防火墙过滤掉;
- 甚至可以发现所有端口都被过滤的主机
缺点:
- 基于状态过滤的防火墙可能过滤扫描;
- 全端口扫描速度慢
原理:
- 二、三、四层发现的目的都是发现网络中存活的IP地址。
- 四层发现 针对 端口的探测 来识别主机是否在线,
- 目标IP某个端口没有开放,会给我返回一个端口不可达数据包,由此确定IP是在线的
- 并不对端口状态进行识别,其本质是利用四层协议来识别目标IP是否在线。
TCP发现
正常的TCP连接是通过三次握手建立通信过程:
- 客户端(C)先给服务器(S)发送SYN包
- S给C发送SYN、ACK包
- 最后C给S发送ACK包,从而建立TCP连接。
未经请求的ACK(直接发送一个ACK):
- 主机在线——会回一个RST,中断这种不正常的通信;
- 主机不在线——则不会有响应。
基于正常的TCP连接:
- 先发一个SYN包给目标主机
- 主机在线、端口开放——会回一个SYN/ACK包
- 主机在线、端口关闭——则会发RST包;
- 主机不在线——则不会有响应。
使用 scapy 定刢数据包迕行高级扫描——发送3、4层组合包头
i=IP()
t=TCP()
r=(i/t)
r.display()
r[IP].dst="192.168.98.1"
r[TCP].flags='A' //使用TCP ACK进行扫描
r.display()
a=sr1(r)
a.display()
└─# scapy 100 ⨯
INFO: Can't import PyX. Won't be able to use psdump() or pdfdump().
aSPY//YASa
apyyyyCY//YCa |
sY//YSpcs scpCY//Pp | Welcome to Scapy
ayp ayyyyyyySCP//Pp syY//C | Version 2.4.4
AYAsAYYYYYYYY///Ps cY//S |
pCCCCY//p cSSps y//Y | https://github.com/secdev/scapy
SPPPP///a pP///AC//Y |
A//A cyPC | Have fun!
p///Ac sC///a |
PYCpc A//A | Wanna support scapy? Rate it on
scccccp///pSP///p p//Y | sectools!
sY/y caa S//P | http://sectools.org/tool/scapy/
cayCyayP//Ya pY/Ya | -- Satoshi Nakamoto
sY/PsYYCc aC//Yp |
sc sccaCY//PCypaapyCP//YSs
spCPY//YPSps
ccaacs
using IPython 7.20.0
>>> i=IP()
>>> t=TCP()
>>> r=(i/t)
>>>
>>> r.display()
###[ IP ]###
version= 4
ihl= None
tos= 0x0
len= None
id= 1
flags=
frag= 0
ttl= 64
proto= tcp
chksum= None
src= 127.0.0.1
dst= 127.0.0.1
\options\
###[ TCP ]###
sport= ftp_data
dport= http
seq= 0
ack= 0
dataofs= None
reserved= 0
flags= S
window= 8192
chksum= None
urgptr= 0
options= []
>>> r[IP].dst="192.168.98.164"
>>> r[TCP].flags='A'
>>> r.display()
###[ IP ]###
version= 4
ihl= None
tos= 0x0
len= None
id= 1
flags=
frag= 0
ttl= 64
proto= tcp
chksum= None
src= 192.168.98.161
dst= 192.168.98.164
\options\
###[ TCP ]###
sport= ftp_data
dport= http
seq= 0
ack= 0
dataofs= None
reserved= 0
flags= A
window= 8192
chksum= None
urgptr= 0
options= []
>>> a=sr1(r)
Begin emission:
Finished sending 1 packets.
.*
Received 2 packets, got 1 answers, remaining 0 packets
>>> a.display()
###[ IP ]###
version= 4
ihl= 5
tos= 0x0
len= 40
id= 0
flags= DF
frag= 0
ttl= 64
proto= tcp
chksum= 0xf439
src= 192.168.98.164
dst= 192.168.98.161
\options\
###[ TCP ]###
sport= http
dport= ftp_data
seq= 0
ack= 0
dataofs= 5
reserved= 0
flags= R
window= 0
chksum= 0x68e6
urgptr= 0
options= []
###[ Padding ]###
load= '\x00\x00\x00\x00\x00\x00'
>>>
长组合语句
思路依然是定制包,发送,根据返回信息判断端口是否开放
>>> >>> a=sr1(IP(dst='192.168.98.164')/TCP(dport=80,flags='A'),timeout=1)
Begin emission:
Finished sending 1 packets.
.*
Received 2 packets, got 1 answers, remaining 0 packets
>>> a
<IP version=4 ihl=5 tos=0x0 len=40 id=0 flags=DF frag=0 ttl=64 proto=tcp chksum=0xf439 src=192.168.98.164 dst=192.168.98.161 |<TCP sport=http dport=ftp_data seq=0 ack=0 dataofs=5 reserved=0 flags=R window=0 chksum=0x68e6 urgptr=0 |<Padding load='\x00\x00\x00\x00\x00\x00' |>>>
>>>
python脚本
#!/usr/bin/python
from scapy.all import *
import sys
address=sys.argv[1]
prefix=address.split(".")[0] + '.' + address.split(".")[1] + '.' +address.split(".")[2] + '.'
for addr in range(1,254):
answer=sr1(IP(dst=prefix+str(addr))/TCP(dport=80,flags='A'),timeout=1,verbose=0)
try:
if int(answer[TCP].flags) == 4:
print prefix+str(addr)
except:
pass
UDP
- UDP不需要进行三次握手
- UDP使用的是尽力转发的传输机制
- 因此进行主机发现的难度较高。
- 目标IP不在线,发送UDP包,则不会有任何响应
- 目标IP在线,目标端口开放,发送数据包且目标主机接收到后也不会有响应
- 目标IP在线,且目标端口不开放时,目标主机会返回一个ICMP端口不可达数据包
>>> i=IP()
>>> u=UDP()
>>> r=(i/u)
>>> r.display()
proto= udp //udp协议
chksum= None
src= 127.0.0.1
dst= 127.0.0.1
\options\
>>> r[IP].dst='192.168.247.129'
>>> r[UDP].dport=7345
>>> r.display()
>>> a=sr1(r)
Begin emission:
.*Finished to send 1 packets.
Received 2 packets, got 1 answers, remaining 0 packets
>>> a.display()
proto= icmp //目标主机存活,且端口不开放,回包的协议为icmp
chksum= 0x8afb
src= 192.168.247.129
dst= 192.168.247.157
\options\
###[ ICMP ]###
type= dest-unreach
code= port-unreachable //icmp端口不可达
chksum= 0x6d87
reserved= 0
length= 0
nexthopmtu= 0
###[ IP in ICMP ]###
version= 4L
ihl= 5L
tos= 0x0
len= 28
id= 1
flags=
frag= 0L
ttl= 64
proto= udp
chksum= 0xa60
src= 192.168.247.157
dst= 192.168.247.129
\options\
###[ UDP in ICMP ]###
sport= domain
dport= 7345
len= 8
chksum= 0x7287
脚本
#!/usr/bin/python
from scapy.all import *
import sys
address=sys.argv[1]
prefix=address.split(".")[0] + '.' + address.split(".")[1] + '.' +address.split(".")[2] + '.'
for addr in range(1,254):
answer=sr1(IP(dst=prefix+str(addr))/UDP(dport=7345),timeout=1,verbose=0)
try:
if int(answer[IP].proto) == 1: //该语句可判断目标主机是否返回ICMP端口不可达数据包
print prefix+str(addr)
except:
pass
总结:
tcp:
基于正常的TCP连接:
- 先发一个SYN包给目标主机
- 主机在线、端口开放——会回一个SYN/ACK包
- 主机在线、端口关闭——则会发RST包;
- 主机不在线——则不会有响应。
udp:
- UDP不需要进行三次握手
- UDP使用的是尽力转发的传输机制
- 因此进行主机发现的难度较高。
- 目标IP不在线——不会有任何响应
- 目标IP在线,目标端口开放,——不会有响应
- 目标IP在线,且目标端口不开放时,——目标主机会返回一个ICMP端口不可达数据包