信息收集及Python脚本编写

在渗透测试中,信息收集显得尤为重要,在信息收集阶段,渗透测试团队可以利用各种方法获取关于目标网络的拓扑、系统配置等信息。信息的完善与否将会严重影响后续渗透测试的速度与深度。

  1. 信息搜集的两种方式
    • 主动收集:通过主动的发送探测数据包与被测目标系统有直接交互
    • 被动收集:在目标不易察觉的情况下,通过搜索引擎、社交媒体等方式对目标的信息进行搜集,与目标系统没有直接交互
  2. 信息搜集的主要内容:
    • IP资源
    • 域名发现
    • 服务器信息收集
    • 人力资源情报收集
    • 网站关键信息识别
    • 历史漏洞
  3. 被动信息搜集

主动信息搜集

基于ICMP协议的主机发现

  1. ICMP协议介绍
    ICMP协议工作在网络层,用来在IP主机、路由器之间传递控制信息。
    ICMP报文
    1. 差错报告报文
      • 终点不可达(3)
      • 源抑制(4)
      • 重定向(5)
      • 超时(11)
      • 参数失灵(12)
    2. 查询报文
      • 响应请求/应答(8/0)
      • 时间戳请求/应答(13/14)
      • 地址掩码请求/应答(17/18)
      • 路由器询问或通告(10/9)
        可见ICMP查询报文有请求也有响应,所以可以用来做主机发现。
  2. 响应请求和应答实现主机发现
    原理是主机A给主机B发送一个ICMP报文type=8的回显请求,主机B收到报文后将type=0,然后返回给A;所以,若果目标给出了回应则说明目标机处于活跃状态。其中最典型的就是ping命令,但是由于早期ping命令的滥用,导致很多主机的防火墙等安全设备直接隔绝ICMP报文通过。

nmap
nmap -sn -PE 172.20.65.49
-sn 只探测目标主机状态
-PE 使用ICMP响应请求和应答实现发现主机

Python代码实现

#导包
from  scapy.all import *
from scapy.layers.inet import ICMP, IP
target = '192.168.1.1'
#构造ICMP请求数据包
ans, unans = sr(IP(dst=target)/ICMP())
for request, answer in ans:
    print(answer.sprintf("%IP.src% is alive"))
  1. ICMP时间戳请求和应答
    ICMP实践戳请求允许向另一台主机查询当前时间,返回协调世界时。因此,如果我们想知道目标主机B是否活跃,我们可以通过主机A向B发送查询时间请求,若得到响应(这里不强调响应的内容,只看是否收到来自主机B的响应)说明主机B位活跃状态。

    namp
    nmap -sn -PP 202.196.96.199 --packet-trace
    此处的目标机实际是活跃的,但是为什么探测状态为不活跃正式印证了上边所说的对ICMP报文的过滤。

    1. ICMP地址掩码请求和应答
      ICMP地址掩码请求由源主机发送,用于在无盘系统的引导时获取自己的子网掩码,RFC规定必须是地址掩码的授权代理才可以发送地址掩码应答,但是大部分主机在收到获取子网掩码的请求时还是会给一个响应,我们可以利用这一特点实现主机发现。

基于ARP协议的主机发现

ARP协议工作在网络层,用于实现从IP地址(逻辑地址)到MAC地址(物理地址)的转换,工作过程就是加入主机A想给主机B(假设IP为172.20.65.49)发送消息,主机A以广播的形式发送ARP请求包(就是在局域网中问问谁是172.20.65.49,把你的MAC地址告诉我),但是只有IP为172.20.65.49的主机会发送响应。因此我们可以利用这一过程实现主机发现。

namp 在这里插入图片描述

代码实现

from scapy.all import *

from scapy.layers.l2 import ARP, Ether
target = '192.168.1.1'
pkt = Ether(dst='ff:ff:ff:ff:ff:ff') / ARP(pdst=target)
ans,unans = srp(pkt, timeout=1)
for  s,r in ans:          #s中存放发出的包,r中存放收到的包
    print("Target is alive")
    print(s.sprintf("%Ether.src% - %ARP.psrc%"))
    print(r.sprintf("%Ether.src% - %ARP.psrc%"))

基于TCP协议的主机发现

TCP是工作在传输层的一种面向连接的、可靠的、基于字节流的协议。谈到TCP必须要说的就是三次握手了,大概就是描述了这样的一个故事——主动段发出SYN信号说我想跟你建立连接,被动端在收到请求后给出ACK确认同时自己也发出SYN包,当主动端收到被动端的回复后再一次发出ACK告诉被动端的确是自己连上了。
在这里插入图片描述

我们会发现根据前面我们是通过请求和应答来实现主机发现的原则,在TCP协议的三次我手中我们有两种情况可以利用,如下:

  1. TCP的SYN扫描
    原理:在对目标主机进行探测时,我们向目标主机发送一个SYN建立连接的请求,如果目标主机的端口允许访问则按照三次握手的规则返回给发送方SYN/ACK包,如果目标主机的端口没有开放也会返回一个RST数据包给发送方,由于我们这里不关心端口的情况,所以只要收到数据包就说明目标是活跃的,收不到数据包就说明目标不在线。
    注:TCP是端到端的,两端是套接字(ip+port)

nmapSYN扫描
在这里插入图片描述

代码实现Python

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

targetIP = '192.168.1.1'
targetPort=80
#构造数据包
ans, unans = sr(IP(dst=targetIP) / TCP(dport=80, flags='S'),timeout = 1)
for s,r in ans:
    print(r.sprintf("%IP.src% is alive"))
for s in unans:
    print(s.sprintf("%IP.dst% is not alive"))

ACK扫描
原理:直接给目标发送ACK数据包,由于这不符合三次握手先发SYN的原则所以无法建立连接,因此目标如果是活跃的就会返回一个RST标志位的数据包表示无法建立连接。
namp:nmap -PA[port,port,…] ip

基于UDP的活跃设备发现

UDP(用户数据报协议)是一种无连接的传输层协议,正常情况下当我们给目标主机以UDP发送消息时,目标主机不回给我们任何数据包,但是目标主机时活跃的,但是端口不可达,这时会给我们发送ICMP数据包,而如果目标主机不活跃我们也收不到任何数据包。

代码实现

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

targetIP = '192.168.1.1'
targetPort = 54763
#构造数据包
ans, unans = sr(IP(dst=targetIP) / UDP(dport=targetPort), timeout=1)
for s,r in ans:
    print(r.sprinf("%IP.src% is alive"))
for s in unans:
    print(s.sprintf("%IP.dst% is not alive"))

端口扫描技术

基于TCP全开的端口扫描技术

(正常的三次握手)如果目标主机的目标端口是开放的,当我们发出SYN请求后,目标会返回SYN+ACK数据包,我们再发送一个ACK数据包就成功建立连接。
如果目标端口是关闭的,我么你在发送SYN数据包后会收到RST数据包,表示不接受这次连接请求。
此外目标端口关闭还有另一种情况就是我们发出了SYN数据包后收不到任何回应,造成这种情况的原因很多,比如目标主机处于非活跃状态,或者安全一些设备屏蔽了对某些端口的SYN数据包。

代码实现

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

dst_ip = '192.168.1.1'
src_port = RandShort()
dst_port = 80
resp =sr1(IP(dst=dst_ip) / TCP(sport=src_port,dport=dst_port,flags='S'),timeout=1)      #flags='S'表示SYN请求
if str(type(resp)) == "<class 'NoneType'>":
    print("The port %s is Closed" %(dst_port))
elif (resp.haslayer(TCP)):
    if resp.getlayer(TCP).flags == 'SA':
        seq1 = resp.ack
        ack1 = resp.seq+1
        pkt = IP(dst=dst_ip) / TCP(sport=src_port,dport=dst_port,flags='A')
        send(pkt)  #只发不收
        print("The port %s is Open" %(dst_port))
    elif resp.getlayer(TCP).flags == '0X14':
        print("The port %s is Closed" %(dst_port))

基于TCP半开的端口扫描

正常的TCP是要三次连接的,但是我们的目的是端口扫描,只要收到SYN+ACK数据包就好了,第三次握手的ACK是不必要的。
具体的过程:我们发送SYN连接请求,收到SYN+ACK数据包后,我们不用真的和其建立连接,所以我们发送RST数据包(我们不用自己发,也可以不发),这样我们并没真的建立连接,故称为半开。

代码实现

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

dst_ip = "192.168.1.1"
src_port = RandShort()
dst_port= 1900
pkt= IP(dst=dst_ip)/TCP(sport=src_port,dport=dst_port,flags="S")
resp=sr1(pkt,timeout=1)
if(str(type(resp))=="<class 'NoneType'>"):
    print("The port %s is Closed"  %( dst_port))
elif (resp.haslayer(TCP)):
    if(resp.getlayer(TCP).flags == 0x12):
        print("The port %s is Open"  %( dst_port))
    elif (resp.getlayer(TCP).flags == 0x14):
        print("The port %s is Closed"  %( dst_port))
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值