主动信息收集
- 直接与目标系统交互通信
- 无法避免留下访问的痕迹
- 使用受控的第三方电脑进行探测
- 使用代理或已被控制的主机
- 做好被封杀的准备
- 使用噪声迷惑目标,淹没真实的探测流量
- 扫描
- 发送不同的探测,根据返回结果判断目标状态
- 识别活着的主机
- 潜在的被攻击目标
- 输出一个 IP 地址列表
有些网络设备(路由器/防火墙等等)会过滤不规则数据包,使探测失效
1. 二层发现
概览
- 优点:扫描速度块、可靠
- 缺点:不可路由,只能发现本网段内
- 协议:ARP
arping
1
2
3arping 1.1.1.1 -c 1
arping 1.1.1.1 -d
ping 1.1.1.1 -c 1 | grep "bytes from" | cut -d " " -f 4 | cut -d ":" -f 1- -c 发送数据包的数量,1 表示只发一个报文
- -d 发现重复IP。即不同 MAC地址 有同样 IP。(ARP地址欺骗)
- grep “bytes from” 筛选结果行
- cut -d “ “ -f 4 以空格分隔,筛选出第4段
arping 只能对某个IP探测,无法对网段探测,如需对整个网段探测,需要脚本
1
2
3
4
5
6
7
8
9
10
11
12
13!/bin/bash
if [ "$#" -ne 1 ]; then
echo "Usage - ./arping.sh [interface]"
echo "Example - ./arping.sh eth0"
echo "Example will perform an ARP scan of the local subnet to which eth0 is assigner"
exit
fi
interface = $1
prefix=$(ifconfig $interface | grep 'inet addr' | cut -d ':' -f 2 | cut - d ' ' -f 1 | cut -d '.' -f 1-3 )
for addr in $(seq 1 254); do
arping -c 1 $prefix.$addr | grep "bytes from" | cut -d ' ' -f 5 | cut -d '[' -f 2 | cut -d ']' -f 1
done1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19网段探测脚本
版本不同代码会有所不一样,此脚本在 kali 2021.1 上测试通过
!/bin/bash
if [ "$#" -ne 1 ]
"$#" 表示参数个数, -ne = not equal
if 后要有空格,[]内与表达式间也要有空格
if [ "$#" != 1 ] 也可以
then
echo "Usage - ./arping.sh [interface]"
echo "Example - ./arping.sh eth0"
echo "Example will perform an ARP scan of the local subnet to which eth0 is assigner"
exit
fi
interface=$1
prefix=$(ifconfig $interface | grep 'inet ' | cut -d ' ' -f 10 | cut -d '.' -f 1-3 )
for addr in $(seq 1 254); do
arping -c 1 $prefix.$addr | grep "bytes from" | cut -d ' ' -f 5 | cut -d '(' -f 2 | cut -d ')' -f 1
donenmap 二层发现
nmap 二层发现用的参数 -sn
1
2
3
4
5
6扫描网段下主机
nmap -sn 192.168.1.0/24
nmap -sn 192.168.1.1-254
根据 ip list 扫描,一行一个地址
namp -iL iplist.txt -snNetdiscover
- 专用于二层发现
- 可用于无线和交换网络环境
- 主动
- netdiscover -i eth0 -r 1.1.1.0/24
- netdiscover -l iplist.txt
- 被动
- netdiscover -p
- 原理:将网卡置成混杂模式,收取给本网卡 ip/mac 地址的数据包
- 主动 arp 容易出发报警
- netdiscover -p
Scapy
- pyhon 库、也可作为单独的工具使用:抓包、分析、创建包、修改、注入网路流量
- ARP().display(),显示 ARP 包
- ARP() 可以对包的各字段丢该,如 ARP().pdst = “192.168.1.1”
- sr1(), 发送包:ar1(arp=ARP())
2. 三层发现
IP、icmp 协议
优点:可路由、速度比较快
缺点:速度比二层慢,被边界防火墙过滤
ping
- ping 1.1.1.1 -c 2 # 发2个包
1
2
3
4
5
6
7
8
9
10
11!/bin/bash
if[ "$#" -ne 1 ]; then
echo "Usage - ./pinger.sh [/24 network address]"
echo "Example - ./pinger.sh 1.1.1.0"
echo "Example will perform an ICMP ping sweep of the 1.1.1.0/24 range"
exit
fi
prefix=$(echo $1 | cut -d '.' -f 1-3)
for addr in $(seq 1 254); do
ping -c 1 $prefix.$addr | grep "bytes from" | cut -d '' -f 4 | cut -d '.' -f 1 &
done
- ping 1.1.1.1 -c 2 # 发2个包
traceroute 路由追踪
- 通过 ttl 值实现,ttl 先设为1,第一跳会反馈一个包,再发一个包,ttl = 2
- traceroute 返回路由器离主机较近的那个网卡的 ip
- ping -R 返回路由器离主机较远的那个网卡的 ip
- 通过 ttl 值实现,ttl 先设为1,第一跳会反馈一个包,再发一个包,ttl = 2
scapy
1
2
3
4
5
6
7ip = IP()
ip.dst = "1.1.1.1"
ping = ICMP()
resp = sr1( ip/ping, timeout=1)
resp.display()
与上面等价
sr1(IP(dst="1.1.1.1")/ICMP(), timeout=1)1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28# python 脚本
#!/usr/bin/python
import logging
import subprocess
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
from scapy.all import *
if len(sys.argv) !=2 :
print "Usage - ./pinger.sh [/24 network address]"
print "Example - ./pinger.sh 1.1.1.0"
print "Example will perform an ICMP ping sweep of the 1.1.1.0/24 range"
sys.exit()
address=str(sys.argv[1])
prefix=address.split(".")[0] + "." + address.split(".")[1] + "."+ address.split(".")[2] + "."
# file : ip_list
# filename=str(sys.argv[1])
# file = open(filename, 'r')
# for addr in file :
for addr in range(1,254):
a = sr1(IP(dst=prefix+str(addr)) / ICMP(), timeout=0.1, verbose = 0)
if a == Node:
pass
else :
print prefix + str(addr)nmap
1
2
3与二层发现一样用 -sn,如果目标与本主机在同一网段,发 arp 包,不在同一网段则发 ICMP 包
nmap 一般会综合各层来实现
nmap -sn 1.1.1.1-255fping
ping 本身不支持对 ip 段发 ping 包
1
2
3
4fping 1.1.1.1 -c 1
fping -g 1.1.1.1 1.1.1.2
fping -g 1.1.1.0/24
fping -f iplist.txthping
- 能过发送几乎任意 TCP/IP 包
- 功能强大但每次只能扫描一个目标
1
2
3
4hping3 1.1.1.1 --icmp -c 2
for addr in $(seq 1 254); do
hping3 1.1.1.$addr --icmp -c 1 >> handle.txt & done
3. 四层发现
判断 ip 是否在线,不对端口做精确判断
- 优点
- 可路由且结果可靠
- 不太可能被防火墙过滤
- 甚至可以发现所有端口都被过滤的主机,准确度比3层高
- 缺点
- 基于状态过滤的防火墙可能过滤扫描
- 全端口扫描速度慢
- TCP
- TCP未建立连接直接发 ACK,会回复RST
- SYN——SYN/ACK、RST
- UDP
- 端口未开放时,发送UDP,会回复ICMP 端口不可达
1. scapy
TCP
未建立连接,直接发 ACK 包,会回复 RST
- scapy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39i=IP()
i.dst="1.1.1.1"
t=TCP()
t.flags='A'
r=(i/t) # 请求,完成的3层4层包
a = sr1(r, timeout=1)
a.display()
等价于
a = sr1(IP(dst="1.1.1.1")/TCP(dport=80, flags='A'), timeout=1)
```
```python
ACK_Ping
!/usr/bin/python
import logging
logging.getLogger("scapy.running").setLevel(logging.ERROR)
from scapy.all import *
if len(sys.argv) !=2 :
print "Usage - ./ACK_Ping.py [/24 network address]"
print "Example - ./ACK_Ping.py 1.1.1.0"
print "Example will perform a TCP ACK ping scan of the 1.1.1.0/24 range"
sys.exit()
address=str(sys.argv[1])
prefix=address.split(".")[0] + "." + address.split(".")[1] + "."+ address.split(".")[2] + "."
file : ip_list
filename=str(sys.argv[1])
file = open(filename, 'r')
for addr in file :
for addr in range(1,254):
response = sr1(IP(dst=prefix+str(addr)) / TCP(dport=2222, flags='A'), timeout=0.1, verbose = 0)
try:
if int(response[TCP].flags) == 4 :
print prefix + str(addr)
except:
pass
- scapy
UDP
端口未开放时,发送UDP,会回复ICMP 端口不可达
- scapy
1
a = sr1(IP(dst="1.1.1.1")/UDP(dport=33333), timeout=1)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27# python udp 四层探测
#!/usr/bin/python
import logging
logging.getLogger("scapy.running").setLevel(logging.ERROR)
from scapy.all import *
if len(sys.argv) !=2 :
print "Usage - ./UDP_Ping.py [/24 network address]"
print "Example - ./UDP_Ping.py 1.1.1.0"
print "Example will perform a UDP ping scan of the 1.1.1.0/24 range"
sys.exit()
address=str(sys.argv[1])
prefix=address.split(".")[0] + "." + address.split(".")[1] + "."+ address.split(".")[2] + "."
# file : ip_list
# filename=str(sys.argv[1])
# file = open(filename, 'r')
# for addr in file :
for addr in range(1,254):
response = sr1(IP(dst=prefix+str(addr)) / UDP(dport=2222 ), timeout=0.1, verbose = 0)
try:
if int(response[IP].proto) == 1 :
print prefix + str(addr)
except:
pass
- scapy
2. nmap
nmap 在 三、四层扫描很强
1 | -PU53 UDP IMCP 不可达 |
3. hping3
准确性不高
1 | 主机在线:ICMP Port Unreachable |
1 | 未验证 |
1 | TCP |
1 | !/bin/bash |
hping TCP 使用的是发送一个 flag 位全为0的包,如果返回的包 ACK、RST 为1说明主机在线
4. 端口扫描
4.1 UDP
1. Scapy
- 端口关闭:ICMP port unreachable
- 端口开放:没有回包
- 误判(路由器拦截)
1 | #!/usr/bin/python |
2. Nmap
1 | 扫描默认指定端口 |
- 不指定端口,默认使用常见的1000个端口
- 特征:ICMP host-unreachable
4.2 TCP
TCP 情况比 UDP 复杂很多
所有 TCP 扫描方式都是基于三次握手的变化来判断目标端口状态
- TCP 端口扫描
- 基于连接的协议
- 三次握手
- 隐蔽扫描
- 不建立完整连接(三次握手),或者不发 SYN 包
- 应用日志不记录扫描行为,应用层不会有记录
- 僵尸扫描(条件苛刻:闲置系统、系统使用递增的IPID)
- 扫描者先控制一台僵尸机,这台僵尸机要求足够闲置,很少发生甚至不发生网络行为;
- 扫描者向僵尸机发送一个 SYN/ACK 包,这时僵尸机会回复 RST 包,并且 IPID = x;
- 扫描者伪装僵尸机的 ip 发送给目标机一个 SYN 包,目标机会回复僵尸机 SYN/ACK 包,此时僵尸机会回复目标机 RST 包,并且 IPID=x+1;
- 扫描者向僵尸机发送 SYN/ACK 包,此时如果僵尸机收到过目标机的 SYN/ACK 包,并回复过 RST 包,此时回复扫描机的应该是 IPID=x+2 的 RST 包。
- 全连接扫描
1. 隐蔽端口扫描
scapy:
sr1(IP( dst=”192.168.60.3”)/TCP(dport=80), timeout=1, verbose=1 )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26#!/usr/bin/python
import logging
logging.getLogger("scapy.running").setLevel(logging.ERROR)
from scapy.all import *
import sys
if len(sys.argv) !=4 :
print "Usage - ./syn_scan.py [Target-IP] [First Port] [Last Port]"
print "Example - ./syn_scan.py 1.1.1.1 1 100"
print "Example will TCP SYN scan ports 1 through 100 on 1.1.1.1"
sys.exit()
ip=str(sys.argv[1])
start=int(sys.argv[2])
end=int[sys.argv[3]]
for port in range(start, end):
a=sr1(IP(dst=ip)/TCP(dport=port), timeout=5, verbose=0)
time.sleep()
if a==None:
pass
else:
if int(a[TCP].flag)==18:
print port
else:
passnmap
1
2
3
4nmap -sS 1.1.1.1 -p 80,21,25 # nmap 不加 -sS 参数端口扫描默认用的就是此方式
nmap -sS 1.1.1.1 -p -65535 --open
nmap -sS 1.1.1.1 -p- --open
nmap -sS -iL iplist.txt -p 80,21,22hping3
1
2
3
4hping3 1.1.1.1 --scan 80 -S # -S syn包
hping3 1.1.1.1 --scan 80,21 -S
hping3 1.1.1.1 --scan 0-65535 -S
hping3 -c 10 -S --spoof 1.1.1.2 -p ++1 1.1.3 # 伪造源地址,从端口1开始,每次递增1发10个包,且必须能想办法看到被伪装机的结果
2. 全连接端口扫描
很容易出发报警
- scapy
全连接扫描对 scapy 比较困难
1 | #!/usr/bin/python |
1 | #!/usr/bin/python |
nmap
1
2
3
4
5默认 1000 个常用端口
nmap -sT 1.1.1.1 -p 80
nmap -sT 1.1.1.1 -p 80,21,25
nmap -sT 1.1.1.1 -p 80-2000
nmap -sT -iL iplist.txt -p 80dmitry
- 功能简单,但是用简便
- 默认150个常用端口
1 | dmitry -p 1.1.1.1 |
- nc
1
2nc -nv -w 1 -z 1.1.1.1 1-100 # -w 1 超时时间 -z 超时尝试下一个端口
1 | 重新获得网卡地址 |