菜鸟渗透日记29---python渗透测试编程之信息收集1-主机发现

目录

简述信息收集

主机状态扫描

基于ARP的活跃主机发现

ARP协议分析

利用ARP实现活跃主机的扫描python程序

基于ICMP的活跃主机发现

ICMP协议分析

利用ICMP实现活跃主机的扫描python程序

基于TCP的活跃主机发现

TCP协议分析

利用TCP实现活跃主机的扫描python程序

基于UDP的活跃主机发现

UDP协议分析

利用UDP实现活跃主机的扫描python程序


简述信息收集

信息收集主要分为两类,一种是被动扫描,一种是主动扫描。

什么叫被动扫描?指的是在目标无法察觉的情况下,进行的信息收集,例如,在找一个人的信息时候,可以上网百度这个人的名字,找到相关的信息,这就叫被动扫描。kali中集成了很多被动扫描的工具例如:Recon-NG、Shodan等等

相比被动扫描,主动扫描的范围小得多,一般都是针对目标发送特制的数据包,根据目标的反应来获得信息。这种扫描方式的技术性比较强,通常会使用专业的扫描工具来对目标进行扫描。扫描后获得的信息包括:目标的网络结构,目标网络所使用设备的类型,目标的操作系统,目标主机开放的端口,目标主机所提供的服务。

这就需要大量的用到nmap模块。nmap的使用非常简单,一般命令格式为nmap+参数即可完成。

一些基本语法如下:

       nmap IP

       nmap 域名

       nmap ip-ip 范围扫描

       nmap ip0/24 全网段扫描

对于特定的端口进行扫描的语法

       nmap -p 端口号 ip

       nmap -p 端口号-端口号 ip

       对目标端口的状态进行扫描

              nmap -sT ip  //使用TCP的全开扫描

              nmap -sS ip  //使用TCP的半开扫描

              nmap -sU -p 端口 ip 使用UDP扫描

关于什么是全开扫描什么是半开扫描和UDP扫描,这里建议访问

https://blog.csdn.net/wwl012345/article/details/96304163

前辈的文章查看即可。

       对目标的操作系统和运行服务进行扫描

              nmap -O ip  //扫描目标主机的操作系统

              nmap -sV ip  //扫描目标主机的服务版本

主机状态扫描

首先提一个问题,我们怎么联网的?

很明显,这一切都要归功于网络协议。网络协议通常是按照不同的层次开发出来的,每个层次的功能也不同。目前的分层模型有OSI和TCP/IP两种。本系列文章全部以TCP/IP分层结构来讲解。

在日常生活中,我们想知道某人是否在线,我们可以在聊天软件中给他发一句,在吗?

正常情况下,他如果回复,在。那就表明对方在线。(不考虑特殊情况!)这个步骤在TCP协议中的实现就是通过三次握手。我们的半开扫描就是给对方发送一个SYN包,对方回复一个ACK则说明对方在线,如果收到RST则说明对面不存在。在三次握手的步骤里这只执行了第一步和第二步。如果执行第三步我给对面再回复一个ACK和RST的话,就说明执行了全开扫描。

这么说的意思是就是我们如果要知道对面是否活跃,就需要给对面发包,根据对面的回复来判断对面是否存在。

基于ARP的活跃主机发现

ARP协议分析

ARP的中文名字是“地址解析协议”,主要用于以太网中,而所有主机在互联网中的通信的时候使用的时IP地址,而在以太网中通信时使用的却是MAC地址。

目前,绝大多数网络应用都没有考虑过硬件地址大部分都是依靠IP地址来进行通信。

这个时候在以太网中并没有用IP地址进行通信,所以我们用到了一个ARP的协议,用来将IP地址和MAC地址进行相互转换。

如图所示,这个时候以太网内所有的主机IP地址已知,PC0要向PC1进行通信。却不知道PC1MAC地址,那么他们是怎么通信的呢?

菜鸟渗透日记29---python渗透测试编程之信息收集1-主机发现

 

这个时候就需要通过以太广播报文,向网络的每一台主机发送ARP请求。

协议类型:ARP Request

源主机IP地址:192.168.65.3

目的主机IP地址:192.168.65.2

源主机的硬件地址:44:44:44:44:44:44

目标主机的MAC地址:ff:ff:ff:ff:ff:ff

当其余主机接收到这个ARP请求的数据包之后,它会用自己的IP地址与包中头部目标主机的IP进行比较,如果不匹配,就不会有回应。这个时候若192.168.65.2的设备接收到这个请求,就会给发送IP的PC0主机回复一个ARP回应数据包。格式如下:

协议类型:ARP Reply

源主机IP地址:192.168.65.2

目的主机IP地址:192.168.65.3

源主机的硬件地址:22:22:22:22:22:22

目标主机的MAC地址:44:44:44:44:44:44

这个包不是广播包,当主机收到这个回应之后,就会把这个结果放在ARP缓存表中。缓存格式

IP地址                                硬件地址                                   类型

192.168.65.2                22:22:22:22:22:22                动态

 

以后当PC0需要再次和PC1进行通讯时,只需要查询这个ARP的缓存表,找到对应的内容,按照这个硬件地址发送出去即可。

当目标主机与我们处于同一个以太网的时候,利用ARP进行扫描是最好的选择。

ARP扫描的图例:

第一步:向目标发送一个ARP Request

菜鸟渗透日记29---python渗透测试编程之信息收集1-主机发现

第二步:如果目标主机处于活跃状态,它一定会回复一个ARP Reply

菜鸟渗透日记29---python渗透测试编程之信息收集1-主机发现

第三步:如果目标主机处于非活跃状态,它不会给任何回应。

菜鸟渗透日记29---python渗透测试编程之信息收集1-主机发现

根据这些特性,下面来进行利用。

利用ARP实现活跃主机的扫描python程序

首先借用Scapy库来完成,核心思路就是产生一个ARP请求,然后发送出去,接着对回应进行监听,如果得到回应,证明主机在线,并且打印出主机的MAC地址。

根据Scapy的特性,我们需要

创建一个ARP的请求数据包并且将其发送出去

ans,unans=srp(Ether(dst=”ff:ff:ff:ff:ff:ff”)/ARP(pdst=”192.168.65.2”),timeout=3)

//这行代码中,我们分析一下,为什么既要用Ether,又要用ARP两个参数。

在ARP中我们只需要设定的只有目标地址也就是pdst,在Scapy中,只有第二次Ether参数可以用来发送MAC地址。所以我们用了Ether参数和ARP参数。所以这行代码的意思就是发送了一个ARP目标地址为192.168.65.2的广播报文。等待时间3秒。

监听请求的回应,如果有回应证明目标在线并且输出目的地址和MAC地址。

根据Scapy的特点,代码如下

关于怎么设置的

我们需要在scapy模块下

输入“ls(Ether)”即可查看所有的参数信息。然后根据我们的需要进行配置即可。后面都是这个思路,不再次重复。

如果在ans列表里面存在发送包和返回包,就说明这个主机存活,将他的主机IP地址和MAC输出。

 

完整的代码如下:

import sys

if len(sys.argv) !=2:

    print "Usage <IP>\n eg: py 192.168.65.1"

    sys.exit(1)

from scapy.all import *

ans,unans = srp(Ether(dst="ff:ff:ff:ff:ff:ff")/ARP(pdst=sys.argv[1]),timeout=3)

for snd,rcv in ans:

    print("Target is alive")

    print rcv.sprint("%Ether.src% - %ARP.psrc%")

 

接下来用nmap模块进行操作

这个库的核心类为PortScanner,-PR表示使用了ARP,-sn表示测试主机状态

完整的代码如下:

import sys

if len(sys.argv) !=2:

    print "Usage <IP>\n eg: py 192.168.65.1"

    sys.exit(1)

import nmap

nm = nmap.PortScanner()

nm.scan(sys.argv[1],arguments='-sn -PR')

for host in nm.all_hosts():

    print('------------------')

    print('HOST : %s (%s)' %(host,nm[host].hostname()))

    print('State : %s' % nm[host].state())

这个程序的执行结果如图:

菜鸟渗透日记29---python渗透测试编程之信息收集1-主机发现

ip部分可以设置一个主机,也可以设置一个网段。

在AptanaStudio3中设置IP方法为:

菜鸟渗透日记29---python渗透测试编程之信息收集1-主机发现

菜鸟渗透日记29---python渗透测试编程之信息收集1-主机发现

 

ARP的局限在于,仅仅能够扫描同一个网段的主机,对于不同网段的主机无法扫描。这里就需要用到其他的探测方法了。

基于ICMP的活跃主机发现

ICMP协议分析

ICMP的全称为(Internet Control Message Protocol),这种协议和他的名字一样,主要是为了发现和处理互联网中的错误。当然也可以用来利用进行主机发现。虽然相比ARP更为复杂,但是其扫描地原理都是一样的。

ICMP中有多个报文,这些报文又分为两大类:差错报文和查询报文。其中查询报文都是由一个请求和一个应答构成。其中查询报文都是由一个请求和一个应答构成的。如果向目标发送了一个请求包,收到了来自目标的回应,就可以判断,和ARP扫描的原理相同。

与ARP扫描不同的地方是,ICMP的查询报文有4中,分别是响应请求或应答、时间戳请求或应答、地址掩码请求或应答、路由器查询或应答。在实际应用中,主要用第一种,响应请求和应答。一般的经典应用就是ping。

如果要判断192.168.65.2是否为活跃主机,就需要对其发送一个ICMP请求,请求的内容如下:

IP层内容

源IP地址: 192.168.65.3

目的IP地址: 192.168.65.2

ICMP层内容

Type:8(表示请求)

 

如果192.168.65.2是处于活跃状态,它收到这个请求之后,就会给出一个回应,回应的内容如下:

IP层内容

源IP地址:192.168.65.2

目的IP地址: 192.168.65.3

ICMP层内容

Type:0(表示应答)

以图的形式来演示一下这个扫描过程。

 

第一步:向目标发送一个ICMP Request

菜鸟渗透日记29---python渗透测试编程之信息收集1-主机发现

第二步:如果目标主机处于活跃状态,在正常情况下,它就会回应一个ICMP Reply

菜鸟渗透日记29---python渗透测试编程之信息收集1-主机发现

注意一点,目前很多网安设备或机制会屏蔽ICMP,这种情况下,即使目标主机处于活跃状态,也收不到任何回应。

第三步:如果目标主机处于非活跃状态,它不会给出任何回应。

菜鸟渗透日记29---python渗透测试编程之信息收集1-主机发现

 

也就是说,只要收到了ICMP的回应,就可以判断该主机为活跃状态。

利用ICMP实现活跃主机的扫描python程序

利用Scapy的核心思想就是产生一个ICMP的请求,并且发送出去。

ans,unans=sr(IP(dst=”192.168.65.3”)/ICMP())

接着对这个回应进行监听,如果得到了回应,就说明主机在线。

ans.summary(lambda(s,r):r.sprintf(“%IP.src% is alive”))

完整的代码如下:

import sys

if len(sys.argv) !=2:

    print "Usage <IP>\n eg: py 192.168.65.1"

    sys.exit(1)

from scapy.all import *

ans,unans=sr(IP(dst=sys.argv[1])/ICMP())

for snd,rcv in ans:

    print rcv.sprint(“%IP.src% is alive")

 

使用nmap库来实现这个功能更简单。-PE表示使用ICMP,-sn表示只测试该主机的状态。在Nmap中使用ICMP进行扫描的语法格式为:

Nmap -PE -sn [ip]

其完整代码如下:

import sys

if len(sys.argv) !=2:

    print "Usage <IP>\n eg: py 192.168.65.1"

    sys.exit(1)

import nmap

nm = nmap.PortScanner()

nm.scan(sys.argv[1],arguments='-sn -PE')

for host in nm.all_hosts():

print('------------------')

print('HOST : %s (%s)' %(host,nm[host].hostname()))

       print('State : %s' % nm[host].state())

基于TCP的活跃主机发现

TCP协议分析

TCP(Transmission Control Protocol 传输控制协议)是一个位于传输层的协议。它是一种面向连接的、可靠的、基于字节流的传输层通信协议。特点是通过三次握手协议建立连接。

其过程如下所示:

第一步:客户端发送SYN(SEQ=X)数据包给服务器端,进入SYT_SEND状态

菜鸟渗透日记29---python渗透测试编程之信息收集1-主机发现

第二步:服务器端收到SYN数据包,回应一个SYN(SEQ=y)+ACK(ACK=x+1)数据包,

进入SYN_RECV状态

菜鸟渗透日记29---python渗透测试编程之信息收集1-主机发现

第三步:客户端收到服务器端的SYN数据包,回应一个ACK(ACK=y+1)数据包,进入Established状态。三次握手完成,TCP客户端和服务器成功建立联系,可以进行传输。

菜鸟渗透日记29---python渗透测试编程之信息收集1-主机发现

TCP和上面的ARP、ICMP并不处于同一层,而是位于传输层。在这一层出现了端口的概念。可以认为是设备与外界进行通信交流的出口。端口分为虚拟端口和物理端口。这里指的是虚拟端口,指的是计算机内部或交换机路由器内的端口。例如常见端口:80、88、21、3306、443端口,这些服务都是通过“IP地址+端口号”来区分。

同样的,如果检测到某台主机的某个端口有回应,也一样可以判断这台主机是活跃主机,注意,如果一个主机是活跃的,那么即使端口是关闭的,在收到请求时也会给一个回应,数据包为“RST”

这样的话检测主机是否活跃时候,向端口发送一个SYN数据包,之后的情形可能有三种

第一种:主机发送的SYN数据包到达了目标的端口,但是目标端口关闭了,这时候会返回一个RST数据包。

菜鸟渗透日记29---python渗透测试编程之信息收集1-主机发现

第二种:主机发送的SYN数据包到达目标端口,而且目标端口开放。这时候会返回一个“SYN+ACK”数据包

菜鸟渗透日记29---python渗透测试编程之信息收集1-主机发现

第三种:主机发送的SYN数据包未到达目标,这时不会收到任何回应。

菜鸟渗透日记29---python渗透测试编程之信息收集1-主机发现

也就是说,只要收到了TCP的回应,就可以判断该主机为活跃状态。

利用TCP实现活跃主机的扫描python程序

利用Scapy的核心思想和上面一样,都是通过Scapy库,产生一个TCP请求,然后监听这个回应,如果得到了回应就说明,目标在线。

构建的TCP数据包格式如下:

ans,unans=sr(IP(dst=”192.168.65.2”)/TCP(dport=80,flags=”S”))

其完整代码如下:

import sys

if len(sys.argv) !=3:

    print "Usage <IP>\n eg: py 192.168.65.1 80"

    sys.exit(1)

from scapy.all import *

ans,unans=sr(IP(dst=sys.argv[1])/TCP(dport=int(sys.argv[2]),flags=”S”))

for snd,rcv in ans:

    print rcv.sprint(“%IP.src% is alive")

使用nmap库来实现功能。在NMAP中使用-sT表示使用TCP这里不需要使用-sn选项了,因为这样会跳过端口扫描。在Nmap中使用TCP选项进行扫描的语法格式为:

nm.scan(“ip”,arguments=’-sT’)

完整代码如下:

import sys

if len(sys.argv) !=2:

    print "Usage <IP>\n eg: py 192.168.65.1"

    sys.exit(1)

import nmap

nm = nmap.PortScanner()

nm.scan(sys.argv[1],arguments='-sT')

for host in nm.all_hosts():

print('------------------')

print('HOST : %s (%s)' %(host,nm[host].hostname()))

       print('State : %s' % nm[host].state())

TCP扫描的可靠性好比较有效。

基于UDP的活跃主机发现

UDP协议分析

UDP全称是用户数据报协议,在网络中和TCP同样用于处理数据包,是一种无连接的协议。UDP和TCP不同的是,当目标处于活跃状态,收到来自主机的一个UDP数据包后,目标不会返回任何UDP数据包,但是,当目标处于活跃状态,而目标端口是关闭的时候,可以返回一个ICMP数据表,含义为”unreacheable”

所以一般利用UDP时候,都会把端口尽量往大了写。

其过程如下图:

菜鸟渗透日记29---python渗透测试编程之信息收集1-主机发现

如果目标不处于活跃状态,这时是收不到任何回应的,其过程如下图:

菜鸟渗透日记29---python渗透测试编程之信息收集1-主机发现

 

利用UDP实现活跃主机的扫描python程序

就接下来按照我们之前的思路,构造一个发往192.168.65.142 6888端口的UDP数据包

ans,unans=sr(IP(dst=”192.168.65.142”)/UDP(dport=8888))

接下来进行监听即可。

其完整代码如下:

import sys

if len(sys.argv) !=3:

    print "Usage <IP>\n eg: py 192.168.65.1 80"

    sys.exit(1)

from scapy.all import *

ans,unans=sr(IP(dst= sys.argv[1])/UDP(dport=int(sys.argv[2]))

for snd,rcv in ans:

    print rcv.sprint(“%IP.src% is alive")

 使用nmap库来实现功能。在NMAP中使用-PU表示使用TCP这里也不需要使用-sn选项了,因为这样会跳过端口扫描。在Nmap中使用TCP选项进行扫描的语法格式为:

 nm.scan(“ip”,arguments=’-PU’)

其完整代码如下:

import sys

if len(sys.argv) !=2:

    print "Usage <IP>\n eg: py 192.168.65.1"

    sys.exit(1)

import nmap

nm = nmap.PortScanner()

nm.scan(sys.argv[1],arguments='-PU')

for host in nm.all_hosts():

print('------------------')

print('HOST : %s (%s)' %(host,nm[host].hostname()))

       print('State : %s' % nm[host].state())