信息收集之:主动信息收集——发现
信息收集之:主动信息收集——发现
郑重声明:
本笔记编写目的只用于安全知识提升,并与更多人共享安全知识,切勿使用笔记中的技术进行违法活动,利用笔记中的技术造成的后果与作者本人无关。倡导维护网络安全人人有责,共同维护网络文明和谐。
主动信息收集特点:
- 直接与目标系统交互通信,无法避免留下访问的痕迹
- 做好被封杀的准备:
- 使用受控的第三方电脑进行探测
- 使用代理或已被控制的主机
- 使用噪声迷惑目标,淹没真实的探测流量
- 扫描:发送不同的探测,根据返回结果判断目标状态
- 一般主动信息收集分为:二层扫描,三层扫描,四层扫描,端口扫描,服务扫描
1 发现
1.1 二层探测: 基于数据链路层的发现
- 数据链路层的数据单位为帧,主要分为逻辑链路控制(LLC)和介质访问控制(MAC)
- 其中主要的协议是 ARP 协议,ARP协议即地址解析协议,根据 IP 地址获取 MAC 地址的TCP/IP协议。它将 32 位 IP 地址解析为 48 位以太网地址,需要注意的是 ARP 协议对应二层广播包,而广播包是无法通过路由或网关访问外部地址的
- 原理: 向网段内所有主机发送 ARP 包,通过是否存在回包判断主机是否存活
二层探测特点:
- 优点:扫描速度快,可靠
- 缺点:不可路由
1.1.1 arping
arping 192.168.100.1 -c 1
# 只选取存活的 host IP
arping 192.168.100.1 -c 1 | grep 'bytes from' | cut -d ' ' -f 5 | cut -d '(' -f 2 | cut -d ')' -f 1
arping_int.sh
#!/bin/bash
# arping 查询接口 IP 网段
if [ "$#" -ne 1 ]
then
echo "Usage : ./arping_int.sh [Interface] \r\n eg: ./arping_int.sh eth1"
exit
fi
interface=$1
prefix=$(ifconfig $interface | grep 'inet '| cut -d 't' -f 2 | cut -d ' ' -f 2 | cut -d '.' -f 1-3)
for addr in $(seq 1 254)
do
echo $addr
arping -c 1 $prefix.$addr | grep "bytes from" | cut -d " " -f 5 | cut -d "(" -f 2 | cut -d ")" -f 1
done
#代码中的if语句中$#代表输入的参数,-ne表示不等于,即该语句的意思是当输入的参数个数不为1时,则输出提示正确的输入方式;后面将输入的接口值赋值给interface变量;prefix变量为前缀,在其中先进行对interface变量进行ifconfig命令然后通过管道和cut命令来将整个信息筛选到只剩前缀,如10.10.10;接着是for循环语句,addr变量从1到254逐渐遍历,里面执行arping命令,其中地址为prefix作为前缀、addr作为后缀来实现遍历整个网段,再通过管道符和cut命令将grep命令符合的IP(这里只有返回了“bytes from”的才是存活的地址)筛选出来。
arping_file.sh
#!/bin/bash
# arping 查询文档中的 IP 主机是否在线
if [ "$#" -ne 1 ]
then
echo "Usage : ./arping_file.sh [filename]\r\neg: ./arping_file.sh ipaddr.txt"
exit
fi
file=$1
for addr in $(cat $file)
do
echo $addr
arping -c 1 $addr | grep "bytes from" | cut -d " " -f 5 | cut -d "(" -f 2 | cut -d ")" -f 1
done
1.1.2 netdiscover
-
专用于二层发现
-
可用于无线和交换网络环境
-
主动和被动探测
- 主动: 容易触发报警
netdiscover ‐i eth0 ‐r 192.168.1.0/24 - 被动:
netdiscover ‐p ‐i eth0 ‐r 192.168.1.0/24- 通过监听网络环境中 arp 包来发现主机
- 主动: 容易触发报警
1.1.3 SCAPY 构造 ARP 探测数据包
- 可作为Python库进行调用,也可作为单独的工具使用
- 功能:抓包、分析、创建、修改、注入网络流量
# 查看当前 ARP 数据包信息
>>> ARP().display()
###[ ARP ]###
hwtype= 0x1
ptype= IPv4
hwlen= None
plen= None
op= who-has
hwsrc= 00:50:56:2b:0a:85
psrc= 172.30.54.33
hwdst= 00:00:00:00:00:00
pdst= 0.0.0.0
>>> arp=ARP()
# 修改 ARP 数据包信息
>>> arp.pdst='172.30.0.2'
>>> arp.display()
###[ ARP ]###
hwtype= 0x1
ptype= IPv4
hwlen= None
plen= None
op= who-has
hwsrc= 00:50:56:2b:0a:85
psrc= 172.30.54.33
hwdst= 00:00:00:00:00:00
pdst= 172.30.0.2
# 发送修改后的数据包
>>> sr1(arp)
Begin emission:
Finished sending 1 packets.
*
Received 1 packets, got 1 answers, remaining 0 packets
<ARP hwtype=0x1 ptype=IPv4 hwlen=6 plen=4 op=is-at hwsrc=80:05:88:41:de:c1 psrc=172.30.0.2 hwdst=00:50:56:2b:0a:85 pdst=172.30.54.33 |<Padding load='\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' |>>
>>>
# 保存接收到的数据
>>> recv=sr1(arp)
Begin emission:
Finished sending 1 packets.
*
Received 1 packets, got 1 answers, remaining 0 packets
# 打印保存的数据
>>> recv
<ARP hwtype=0x1 ptype=IPv4 hwlen=6 plen=4 op=is-at hwsrc=80:05:88:41:de:c1 psrc=172.30.0.2 hwdst=00:50:56:2b:0a:85 pdst=172.30.54.33 |<Padding load='\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' |>>
# 查看回包信息
>>> recv.display()
###[ ARP ]###
hwtype= 0x1
ptype= IPv4
hwlen= 6
plen= 4
op= is-at
hwsrc= 80:05:88:41:de:c1
psrc= 172.30.0.2
hwdst= 00:50:56:2b:0a:85
pdst= 172.30.54.33
###[ Padding ]###
load= '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
# 直接通过 ARP() 查询
>>> sr1(ARP(pdst='172.30.0.1'),timeout=1,verbose=0)
<ARP hwtype=0x1 ptype=IPv4 hwlen=6 plen=4 op=is-at hwsrc=00:74:9c:fd:7a:73 psrc=172.30.0.1 hwdst=00:50:56:2b:0a:85 pdst=172.30.54.33 |<Padding load='\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' |>>
>>>
1.2 三层探测:基于网络层的发现
- 使用 IP、ICMP 协议探测主机是否存在
- 优点:可路由
- 缺点:可能会发生被防火墙过滤的情况
1.2.1 ping
ping 8.8.8.8
ping -c 1 8.8.8.8 | grep 'bytes from' | cut -d ' ' -f 4 | cut -d ':' -f1
# ping 必须要输出结果后,才可以对数据进行处理
ping.sh
#!/bin/bash
# 批量 PING
if [ "$#" -ne 1 ]
then
echo "Usage : ./pinger.sh [/24 network address]"
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命令然后再管道到grep“bytes from”,只有包含该字符串的才是存活的主机,最后通过管道和cut命令将其筛选出来。
ping.py
#!/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 - ./ping1.py [/24 network address]")
print("Example - ./ping1.py 128.38.28.3")
sys.exit()
address = str(sys.argv[1])
prefix = address.split(".")[0]+'.'+address.split(".")[1]+'.'+address.split(".")[2]+"."
for addr in range(1, 254):
a=sr1(IP(dst=prefix+str(addr))/ICMP(),timeout=0.1,verbose=0)
if a == None:
pass
else:
print(prefix+str(addr))
1.2.2 NMAP
# -sn: Ping Scan
nmap -v -sn 172.30.0.1-5 | grep -v 'host down'
nmap -v -sn 172.30.0.0/24 | grep -v 'host down'
nmap -iL iplist.txt -sn
1.2.3 fping
fping 是一个类似 ping 的程序,与 ping 不同的是你可以同时指定多个要 ping 的目标。fping 发送完 ping 包后不等待回应,而是继续下一个目标.
fping 172.30.0.1 -c 1
fping -g 172.30.0.1 172.30.0.2
fping -g 172.30.0/24
fping -f iplist.txt
1.2.4 Hping
- hping 是 面向命令行的用于生成和解析TCP/IP协议数据包汇编/分析的开源工具。目前最新版是 hping3,它支持TCP,UDP,ICMP和RAW-IP协议,具有跟踪路由模式,能够在覆盖的信道之间发送文件以及许多其他功能。
- hping是安全审计、防火墙测试等工作的标配工具。
- hping 优势在于能够定制数据包的各个部分,因此用户可以灵活对目标机进行细致地探测。
hping3 -1 172.30.0.1
default mode TCP
-0 --rawip RAW IP mode
-1 --icmp ICMP mode
-2 --udp UDP mode
-8 --scan SCAN mode.
Example: hping --scan 1-30,70-90 -S www.target.host
-9 --listen listen mode
1.3 四层探测:基于传输层的发现
- 优点:可路由,结果可靠,不太可能被防火墙过滤
- 缺点:基于状态过滤的防火墙可能会过滤扫描,全端口扫描速度慢
- 原理:
- TCP:ACK、RST,将TCP包头的flag位设定为ACK,然后发送给一个目标/端口,最后判断是否收到RST响应包,以此确定目标是否存在!。完整的是SYN、SYN/ACK、RST
- UDP: 存在则为 ICMP 端口不可达、不存在则没有回包。
1.3.1 Scapy 构造四层 TCP 探测数据包
>>> ip=IP()
>>> tcp=TCP()
>>> send=(ip/tcp)
>>> send[IP].dst='172.30.26.130' #设置目标Ip地址
>>> send[TCP].flags='A' #设置TCPflags为”ACK“
>>> send.display()
###[ IP ]###
version= 4
ihl= None
tos= 0x0
len= None
id= 1
flags=
frag= 0
ttl= 64
proto= tcp
chksum= None
src= 172.30.54.33
dst= 172.30.26.130
\options\
###[ TCP ]###
sport= ftp_data
dport= http # 默认探测的是 TCP 80 端口
seq= 0
ack= 0
dataofs= None
reserved= 0
flags= A
window= 8192
chksum= None
urgptr= 0
options= []
>>> recv=sr1(send)
# 回包信息查询
>>> recv.display()
###[ IP ]###
version= 4
ihl= 5
tos= 0x0
len= 40
id= 0
flags= DF
frag= 0
ttl= 64
proto= tcp
chksum= 0x91f0
src= 172.30.26.130
dst= 172.30.54.33
\options\
###[ TCP ]###
sport= http
dport= ftp_data
seq= 0
ack= 0
dataofs= 5
reserved= 0
flags= R # flags 位为 R
window= 0
chksum= 0x69d
urgptr= 0
options= []
###[ Padding ]###
load= '\x00\x00\x00\x00\x00\x00'
>>> recv
<IP version=4 ihl=5 tos=0x0 len=40 id=0 flags=DF frag=0 ttl=64 proto=tcp chksum=0x91f0 src=172.30.26.130 dst=172.30.54.33 |<TCP sport=http dport=ftp_data seq=0 ack=0 dataofs=5 reserved=0 flags=R window=0 chksum=0x69d urgptr=0 |<Padding load='\x00\x00\x00\x00\x00\x00' |>>>
# 使用一条语句
recv=sr1(IP(dst="172.30.26.130")/TCP(flags='A'),timeout=1,verbose=0)
过程:
-
先发送 TCP 中 flags 为“A”的包,若收到的包中TCP的flags位化整数为 4 时,则目标主机存活、输出 IP。至于为啥flags位的整数值要为4,这里可以用Wireshark抓包看看:
Python 脚本实现 TCP 四层探测
#!/usr/bin/python
import logging
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
from scapy.all import *
if len(sys.argv) != 2:
print("Usage : ./tcp_ping.py [/24 network address]")
sys.exit()
address = str(sys.argv[1])
prefix = address.split('.')[0] + '.' + address.split('.')[1] + '.' + address.split('.')[2] + '.'
for addr in range(130, 131):
response = sr1(IP(dst=prefix + str(addr)) / TCP(dport=1234, flags='A'), timeout=0.1, verbose=0)
try:
if int(response[TCP].flags) == 4:
print(prefix + str(addr))
except:
pass
1.3.2 Scapy 构造四层 UDP 探测数据包
注:UDP 发现不可靠
>>> ip=IP()
>>> udp=UDP()
>>> send=(ip/udp)
>>> send[IP].dst='172.30.0.1'
>>> send.display()
###[ IP ]###
version= 4
ihl= None
tos= 0x0
len= None
id= 1
flags=
frag= 0
ttl= 64
proto= udp
chksum= None
src= 172.30.54.33
dst= 172.30.0.1
\options\
###[ UDP ]###
sport= domain
dport= domain
len= None
chksum= None
>>> recv=sr1(send,timeout=1,verbose=1)
Begin emission:
Finished sending 1 packets.
Received 2 packets, got 1 answers, remaining 0 packets
>>> recv.display()
###[ IP ]###
version= 4
ihl= 5
tos= 0xc0
len= 56
id= 58443
flags=
frag= 0
ttl= 64
proto= icmp # 协议为 ICMP
chksum= 0x75b
src= 172.30.0.1
dst= 172.30.54.33
\options\
###[ ICMP ]###
type= dest-unreach
code= port-unreachable
chksum= 0x8b75
reserved= 0
length= 0
nexthopmtu= 0
###[ IP in ICMP ]###
version= 4
ihl= 5
tos= 0x0
len= 28
id= 1
flags=
frag= 0
ttl= 64
proto= udp
chksum= 0xec71
src= 172.30.54.33
dst= 172.30.0.1
\options\
###[ UDP in ICMP ]###
sport= domain
dport= domain
len= 8
chksum= 0x7115
# 使用一条语句
recv=sr1(IP(dst="192.168.0.1")/UDP(dport=53),timeout=1,verbose=1)
Python 脚本实现 UDP 四层探测
#!/usr/bin/python
import logging
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
from scapy.all import *
if len(sys.argv) != 2:
print("Usage - ./ping1.py [/24 network address]")
print("Example - ./ping1.py 128.38.28.3")
sys.exit()
address = str(sys.argv[1])
prefix = address.split(".")[0] + '.' + address.split(".")[1] + '.' + address.split(".")[2] + '.'
for addr in range(1, 254):
response = sr1(IP(dst=prefix + str(addr)) / UDP(dport=7634), timeout=0.1, verbose=0)
try:
if int(response[IP].proto) == 1: # 为何是protoco=1,
# 通过wireshark抓包可以发现
# ip层有protocol字段,指向它的上层协议,TCP为6,ICMP为1,IJMP
# 为2,UDP为17,
# 由此我们可以知道ip上层协议不一定除了tcp,就是udp,
# 还可以是其它的很多类型的协议,在这里我们发送了一个udp包给
# 目标,我们由是否接受到来自目标的icmp包来判断ip是否存活
print(prefix + str(addr))
except:
pass
1.3.3 NMAP
# UDP 探测
nmap -sn -PU1234 172.30.26.130
# TCP 探测
nmap -sn -PA80 172.30.26.130
nmap -sn -PA80 -iL iplist.txt
1.3.4 hping
# hping3 默认 TCP
hping3 -c 1 172.30.26.130
# hping3 设置为 UDP 探测
hping3 -2 -c 1 172.30.26.130
shell 脚本实现 TCP 主机发现
#!/bin/bash
if [ "$#" -ne 1 ]
then
echo "Usage : ./TCP_hping.sh [/24 network address]"
exit
fi
prefix=$(echo $1 | cut -d'.' -f 1-3)
for addr in $(seq 1 254)
do
hping3 -c 1 $prefix.$addr>> r.txt;
done
grep ^len r.txt | cut -d " " -f 2 | cut -d "=" -f 2 >> TCP_hping.txt
rm r.txt
shell 脚本实现 UDP 主机发现
#!/bin/bash
if [ "$#" -ne 1 ]
then
echo "Usage : ./UDP_hping.sh [/24 network address]"
exit
fi
prefix=$(echo $1 | cut -d'.' -f 1-3)
for addr in $(seq 1 254)
do
hping3 -2 -c 1 $prefix.$addr>> r.txt;
done
grep Unreachable r.txt | cut -d " " -f 5 | cut -d "=" -f 2 >> UDP_hping.txt
rm r.txt