信息收集

信息收集

被动信息收集

  • 主要通过各种公开渠道获取目标系统的信息,比如站长工具,搜索引擎,来获取目标网站的信息。
  • 特点是尽量不与目标系统产生直接交互,从而避免留下痕迹。缺点是有可能收集到的是一些过时信息,不够准确。

主动信息收集

  • 直接与目标网站进行交互通讯,从而得到更为准确的及时信息。比如利用各种漏洞扫描工具对目标进行扫描。
  • 不可避免的会在目标系统留下痕迹,有可能会被封杀。

## 系统层面的主动信息收集

  • 主要内容
    • 主机发现,端口扫描,指纹映射。
  • 主动信息收集主要通过扫描实现,扫描可以在不同的网络层次实行。
    • 二层主机发现,三层主机发现,四层主机发现。
  • 每部分内容中,都将先介绍如何通过nmap来实现该功能,然后再通过编写Python脚步来实现同样功能。

主要使用的模块

  • scapy
    • 可以构建各种类型的数据包,进行发送并接收回应。
  • socket
    • 可以构建C/S模式的客服端和服务端。
  • 相关脚步
    • ARP诈骗,MAC泛洪,交互式Shell…

Scapy模块使用

主要功能

  • 可以根据自己的需求定义一系列的报文,并通过scapy发送出去,最后再接收回应。
  • sacpy的优势一方面是可以自由构建报文,另一方是对接收到的回应只解码而不解释,它只会如实显示响应报文的内容,而不提供结论,如可来判断和利用这些响应报文,完全由我们来自己决定。
  • scapy主要基于二,三,四层工作。

基本用法

  • 安装和使用scapy
# 安装
root@kali:~# pip install scapy
root@kali:~# pip install scapy
DEPRECATION: Python 2.7 reached the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 is no longer maintained. pip 21.0 will drop support for Python 2.7 in January 2021. More details about Python 2 support in pip can be found at https://pip.pypa.io/en/latest/development/release-process/#python-2-support pip 21.0 will remove support for this functionality.
Collecting scapy
  Downloading scapy-2.4.4.tar.gz (1.0 MB)
     |████████████████████████████████| 1.0 MB 237 kB/s 
Building wheels for collected packages: scapy
  Building wheel for scapy (setup.py) ... done
  Created wheel for scapy: filename=scapy-2.4.4-py2.py3-none-any.whl size=1189182 sha256=5f40c0900c41635cfa0f837d569b16003f756683ebd193a56d8c5eefafb4b85e
  Stored in directory: /root/.cache/pip/wheels/54/7f/78/f171363d7702a91ddabc3a1503e2fd43618fa0f9f55e401720
Successfully built scapy
Installing collected packages: scapy
Successfully installed scapy-2.4.4
# 使用
root@kali:~# scapy
INFO: Can't import matplotlib. Won't be able to plot.
INFO: Can't import PyX. Won't be able to use psdump() or pdfdump().
INFO: Can't import python-cryptography v1.7+. Disabled WEP decryption/encryption. (Dot11)
INFO: Can't import python-cryptography v1.7+. Disabled IPsec encryption/authentication.
WARNING: IPython not available. Using standard Python shell instead.
AutoCompletion, History are disabled.

                     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            cyP////C   | Have fun!
              p///Ac            sC///a   |
              P////YCpc           A//A   | What is dead may never die!
       scccccp///pSP///p          p//Y   |                     -- Python 2
      sY/////////y  caa           S//P   |
       cayCyayP//Ya              pY/Ya
        sY/PsY////YCc          aC//Yp 
         sc  sccaCY//PCypaapyCP//YSs  
                  spCPY//////YPSps    
                       ccaacs         

>>> 
  • scapy除了可以作为Python库被调用之外,也可以作为单独的工具使用。
from scapy.all import *
a=ARP # 将ARP类实例化为对象a
  • ls()可以列出scapy支持的所有协议,每个协议都是一个类。
>>> ls()
AH         : AH
AKMSuite   : AKM suite
ARP        : ARP
ASN1P_INTEGER : None
ASN1P_OID  : None
ASN1P_PRIVSEQ : None
ASN1_Packet : None
ATT_Error_Response : Error Response
ATT_Exchange_MTU_Request : Exchange MTU Request
ATT_Exchange_MTU_Response : Exchange MTU Response
ATT_Execute_Write_Request : Execute Write Request
ATT_Execute_Write_Response : Execute Write Response
ATT_Find_By_Type_Value_Request : Find By Type Value Request
ATT_Find_By_Type_Value_Response : Find By Type Value Response
ATT_Find_Information_Request : Find Information Request
ATT_Find_Information_Response : Find Information Response
ATT_Handle : ATT Short Handle
ATT_Handle_UUID128 : ATT Handle (UUID 128)
ATT_Handle_Value_Indication : Handle Value Indication
ATT_Handle_Value_Notification : Handle Value Notification
ATT_Handle_Variable : None
ATT_Hdr    : ATT header
ATT_Prepare_Write_Request : Prepare Write Request
ATT_Prepare_Write_Response : Prepare Write Response
ATT_Read_Blob_Request : Read Blob Request
ATT_Read_Blob_Response : Read Blob Response
ATT_Read_By_Group_Type_Request : Read By Group Type Request
ATT_Read_By_Group_Type_Response : Read By Group Type Response
ATT_Read_By_Type_Request : Read By Type Request
ATT_Read_By_Type_Request_128bit : Read By Type Request
ATT_Read_By_Type_Response : Read By Type Response
ATT_Read_Multiple_Request : Read Multiple Request
...
  • lsc()可以列出scapy支持的所有方法。
>>> lsc()
IPID_count          : Identify IP id values classes in a list of packets
arpcachepoison      : Poison target's cache with (your MAC,victim's IP) couple
arping              : Send ARP who-has requests to determine which hosts are up
arpleak             : Exploit ARP leak flaws, like NetBSD-SA2017-002.
bind_layers         : Bind 2 layers on some specific fields' values.
bridge_and_sniff    : Forward traffic between interfaces if1 and if2, sniff and return
chexdump            : Build a per byte hexadecimal representation
computeNIGroupAddr  : Compute the NI group Address. Can take a FQDN as input parameter
corrupt_bits        : 
corrupt_bytes       : 
defrag              : defrag(plist) -> ([not fragmented], [defragmented],
defragment          : defragment(plist) -> plist defragmented as much as possible 
dhcp_request        : Send a DHCP discover request and return the answer
dyndns_add          : Send a DNS add message to a nameserver for "name" to have a new "rdata"
dyndns_del          : Send a DNS delete message to a nameserver for "name"
etherleak           : Exploit Etherleak flaw
explore             : Function used to discover the Scapy layers and protocols.
fletcher16_checkbytes: Calculates the Fletcher-16 checkbytes returned as 2 byte binary-string.
fletcher16_checksum : Calculates Fletcher-16 checksum of the given buffer.
fragleak            : --
fragleak2           : --
fragment            : Fragment a big IP datagram
fuzz                : 
getmacbyip          : Return MAC address corresponding to a given IP address
getmacbyip6         : Returns the MAC address corresponding to an IPv6 address
hexdiff             : Show differences between 2 binary strings
hexdump             : Build a tcpdump like hexadecimal view
hexedit             : Run hexedit on a list of packets, then return the edited packets.
hexstr              : Build a fancy tcpdump like hex from bytes.
import_hexcap       : Imports a tcpdump like hexadecimal view
is_promisc          : Try to guess if target is in Promisc mode. The target is provided by its ip.
linehexdump         : Build an equivalent view of hexdump() on a single line
ls                  : List  available layers, or infos on a given layer class or name.
neighsol            : Sends and receive an ICMPv6 Neighbor Solicitation message
overlap_frag        : Build overlapping fragments to bypass NIPS
promiscping         : Send ARP who-has requests to determine which hosts are in promiscuous mode
rdpcap              : Read a pcap or pcapng file and return a packet list
report_ports        : portscan a target and output a LaTeX table
restart             : Restarts scapy
rfc                 : 
send                : 
sendp               : 
sendpfast           : Send packets at layer 2 using tcpreplay for performance
sniff               : 
split_layers        : Split 2 layers previously bound.
sr                  : 
sr1                 : 
sr1flood            : Flood and receive packets at layer 3 and return only the first answer
srbt                : send and receive using a bluetooth socket
srbt1               : send and receive 1 packet using a bluetooth socket
srflood             : Flood and receive packets at layer 3
srloop              : Send a packet at layer 3 in loop and print the answer each time
srp                 : 
srp1                : 
srp1flood           : Flood and receive packets at layer 2 and return only the first answer
srpflood            : Flood and receive packets at layer 2
srploop             : Send a packet at layer 2 in loop and print the answer each time
tcpdump             : Run tcpdump or tshark on a list of packets.
tdecode             : 
traceroute          : Instant TCP traceroute
traceroute6         : Instant TCP traceroute using IPv6
traceroute_map      : Util function to call traceroute on multiple targets, then
tshark              : Sniff packets and print them calling pkt.summary().
wireshark           : 
wrpcap              : Write a list of packets to a pcap file
>>> 
  • 用help()查看帮助信息。
>>> help("ARP")
Help on class ARP in module scapy.layers.l2:

class ARP(scapy.packet.Packet)
 |  Method resolution order:
 |      ARP
 |      scapy.packet.Packet
 |      scapy.base_classes.BasePacket
 |      scapy.base_classes.Gen
 |      scapy.base_classes._CanvasDumpExtended
 |      __builtin__.object
 |  
 |  Methods defined here:
 |  
 |  answers(self, other)
 |  
 |  extract_padding(self, s)
 |  
 |  hashret(self)
 |  
 |  mysummary(self)
 |  
 |  route(self)
 |  
 |  ----------------------------------------------------------------------
 |  Data and other attributes defined here:
 |  
 |  __all_slots__ = set(['_answered', '_pkt', 'default_fields', 'direction...
 |  
 |  aliastypes = [<class 'scapy.layers.l2.ARP'>, <class 'scapy.packet.Pack...
 |  
 |  fields_desc = [<Field (ARP).hwtype>, <Field (ARP).ptype>, <Field (ARP)...
 |  
 |  ----------------------------------------------------------------------
 |  Methods inherited from scapy.packet.Packet:
 |  
 |  __bool__ = __nonzero__(self)
 |  
 |  __bytes__(self)
 |  
 |  __contains__(self, cls)
 |      "cls in self" returns true if self has a layer which is an instance of cls.
 |  
 |  __deepcopy__(self, memo)
 |      Used by copy.deepcopy
 |  
 |  __delattr__(self, attr)
 |  
 |  __delitem__(self, cls)
 |  
 |  __dir__(self)
 |      Add fields to tab completion list.
 |  
 |  __div__(self, other)
 |  
 |  __eq__(self, other)
 |  
:
  • 用display()或show()方法查看属性信息。
>>> myARP = ARP()
>>> myARP.display()
###[ ARP ]### 
  hwtype= 0x1 # 数据包类型
  ptype= IPv4 # 协议类型
  hwlen= None # 数据包长度
  plen= None # 协议长度 
  op= who-has # 请求码
  hwsrc= 00:0c:29:7e:34:73 # 硬件原MAC地址
  psrc= 192.168.10.128 # 硬件原IP地址
  hwdst= 00:00:00:00:00:00 # 目标MAC地址
  pdst= 0.0.0.0 # 目标IP 

>>> myARP.show()
###[ ARP ]### 
  hwtype= 0x1
  ptype= IPv4
  hwlen= None
  plen= None
  op= who-has
  hwsrc= 00:0c:29:7e:34:73
  psrc= 192.168.10.128
  hwdst= 00:00:00:00:00:00
  pdst= 0.0.0.0

发送数据并接收回应

# 目标主机开机
>>> sendp(Ether(dst='00:00:00:00:00:00')/ARP(pdst='192.168.10.2',hwdst='00:00:00:00:00:00',op=2))    
.
Sent 1 packets.
# 目标主机关机
>>> sr1(ARP(pdst='192.168.10.23'),timeout=1)
Begin emission:
Finished sending 1 packets.
...
Received 3 packets, got 0 answers, remaining 1 packets

#### 发包和收包

  • 只发不收
    • send(),在第三层发包,不关心第二层的封装,第二层采用默认值。
    • sendp(),在第二层发包,需要手动指定第二层如何封装。
  • 发包且接收回复
    • sr()和sr1()都是在第三层发包,sr1表示只接收第一个回复。
    • srp()和srp1()都是在第二层发包,srp1表示只接收第一个回复。
  • 默认情况下,如果目标主机不通,那么将一直发包,所以可以加上timeout参数。

构建并发送ARP欺骗数据包

  • 构建并发送数据包(会泄露信息)
>>> pkt=ARP(pdst='192.168.10.129',psrc='192.168.10.2')
>>> send(pkt)
.
Sent 1 packets.

  • 构建并发送数据包,加上第二层封装。
>>> pkt=Ether(dst='ff:ff:ff:ff:ff:ff')/ARP(pdst='192.168.10.129')
>>> pkt=Ether()/ARP()
>>> pkt[Ether].dst='ff:ff:ff:ff:ff'
>>> sendp(pkt)
.
Sent 1 packets.

ARP欺骗脚本

#!coding:utf-8
from scapy.all import *
from scapy.layers.l2 import Ether, ARP


def arpspoof(ip1, ip2):
    try:
        pkt = Ether(dst='ff:ff:ff:ff:ff:ff') / ARP(pdst=ip1, psrc=ip2)
        sendp(pkt)
        return
    except:
        print("\n\r发送异常程序终止。")
        sys.exit()
    pass


def main():
    if len(sys.argv) != 3:
        print("使用方法:./filename 目标主机IP 被欺骗主机IP")
        sys.exit()

    ip1 = str(sys.argv[1]).strip()
    ip2 = str(sys.argv[2]).strip()
    while True:
        try:
            arpspoof(ip1,ip2)
            time.sleep(0.5)
        except KeyboardInterrupt:
            print("\n\r发送异常程序终止。")
            break
    pass


if "__main__" == __name__:
    main()
    pass

MAC泛洪

MAC泛洪攻击的核心问题是构造出MAC地址不断变化的大量数据帧,并不会不断发送。

利用RandMAC()和RandIP()方法可以产出随机的MAC和IP地址。

>>> print(RandMAC())
37:86:18:e7:08:cd
>>> print(RandIP())
80.85.24.73

构造一个MAC和IP都采用随机地址的ICMP包。

>>> pkt=Ether(dst=RandMAC(),src=RandMAC())/IP(dst=RandIP(),src=RandIP())/ICMP()
>>> pkt.show()                                                                                                                                                                                                    
###[ Ethernet ]###                                                                                                                                                                                                
  dst= 94:ad:ee:e2:2d:f8                                                                                                                                                                                          
  src= 79:f7:92:42:2a:f9                                                                                                                                                                                          
  type= IPv4                                                                                                                                                                                                      
###[ IP ]###                                                                                                                                                                                                      
     version= 4                                                                                                                                                                                                   
     ihl= None                                                                                                                                                                                                    
     tos= 0x0                                                                                                                                                                                                     
     len= None
     id= 1
     flags= 
     frag= 0
     ttl= 64
     proto= icmp
     chksum= None
     src= <RandIP>
     dst= <RandIP>
     \options\
###[ ICMP ]### 
        type= echo-request
        code= 0
        chksum= None
        id= 0x0
        seq= 0x0

>>> sendp(pkt)
.
Sent 1 packets.

循环发送数据包

在用sendp()方法发送时,可以用loop参数设置循环发送(默认值为0,值为1表示循环发送),用inter参数指定时间间隔。

>>> sendp(pkt,loop=1,inter=0.1)
...............................^C
Sent 31 packets.

可以用conut参数指定要发送的具体数量。

>>> sendp(pkt,count=10,inter=0.1)
..........
Sent 10 packets.

主机发现

二层主机发现

概念

  • 主机发现,即确认一个IP范围内存在的主机,从而找到潜在攻击目标。
    • 二层发现,三层发现,四层发现。
  • 二层主机发现可以利用ARP协议来找到。
    • 主要用于在内网进行探测,发现与攻击者在同一个网段内的主机。
  • 优点
    • 扫描速度快,可靠性高,缺点是不可路由。

arping

  • arping向外发送ARP响应包进行主机探测,准确性非常高,缺点不能夸网段扫描。
root@kali:~/桌面# arping 192.168.10.129
ARPING 192.168.10.129
60 bytes from 00:0c:29:cf:4c:09 (192.168.10.129): index=0 time=150.123 usec
60 bytes from 00:0c:29:cf:4c:09 (192.168.10.129): index=1 time=3.819 msec
60 bytes from 00:0c:29:cf:4c:09 (192.168.10.129): index=2 time=2.860 msec
60 bytes from 00:0c:29:cf:4c:09 (192.168.10.129): index=3 time=362.384 usec
^C
--- 192.168.10.129 statistics ---
4 packets transmitted, 4 packets received,   0% unanswered (0 extra)

image-20201230093212196

  • arping可以用-c选项设置发送几个包。

  • arping本身不具备扫描整个网段的功能。

subprocess模块

  • subprocess模块可以用来创建一个进程,并运行一个外部有程序。
    • 通常用subprocess模块中的check_output()方法来调用系统命令。
  • subprocess.check_output()
    • 父进程等子进程完成,并返回子进程向标准输出的输出结果。
a=subprocess.check_output("ls -l",shell=True)
  • shell参数
    • 当shell=True时,如果要执行的程序是一个字符串,那么函数就会直接调用系统的Shell来执行指定的程序。
用法:
>>> import subprocess                                                                                                                                                                                             
>>> ret = subprocess.check_output("arping -c 1 192.168.10.129", shell=True)                                                                                                                                       
>>> print(ret)                                                                                                                                                                                                    
ARPING 192.168.10.129                                                                                                                                                                                             
60 bytes from 00:0c:29:cf:4c:09 (192.168.10.129): index=0 time=370.296 usec                                                                                                                                       

--- 192.168.10.129 statistics ---                                                                                                                                                                                 
1 packets transmitted, 1 packets received,   0% unanswered (0 extra)                                                                                                                                              
rtt min/avg/max/std-dev = 0.370/0.370/0.370/0.000 ms

##### 调用arping实现二层发现

#!coding:utf-8
import subprocess
import sys
import time
from threading import Thread

def arPing(ip):
    try:
        subprocess.check_output("arping -c 1 " + str(ip), shell=True)
        print("arping -c 1 " + str(ip))
        time.sleep(0.1)
        print(ip, "在线")
        return
    except:
        return

def main():
    if len(sys.argv)<=1:
        print("请输入IP“)
        return
    host = str(sys.argv[1]).strip().split('.')
    addr = host[0] + '.' + host[1] + '.' + host[2] + '.'
    for i in range(1, 255):
        ip = addr + str(i)
        t = Thread(target=arPing, args=(ip,))
        t.start()

if __name__=="__main__":
    main()

使用:

(venv) root@kali:~/PycharmProjects/pythonProject# python main.py 192.168.10
arping -c 1 192.168.10.2
arping -c 1 192.168.10.1
192.168.10.1 在线
192.168.10.2 在线
arping -c 1 192.168.10.129
192.168.10.129 在线
arping -c 1 192.168.10.254
192.168.10.254 在线

netdisocver

netdisocver是一个专门用于二层主机发现的扫描工具,支持主动和被动扫描两种方法。

主动扫描,主动向外发送ARP广播。

netdiscover -r 192.168.10.0/24

被动扫描,不向外发送ARP广播,而是将网卡设置为混杂模式,接收网络中所有的ARP广播,从而起到隐蔽自身的作用。

netdiscover -p

nmap

nmap(Network Mapper)是一款开源的网络发现和安全审计工具,包含主机发现,端口扫描,版本检修,操作系统侦测,操作系统侦测四项基本功能。

nmap实现主机发现的关键,是nmap精心构造并发到主机的探测包。

-sn:执行ping扫描,但不扫描端口。

  • sn虽然名为ping扫描,但实际上是自适应,当被扫描的目标与当前主机在同一个网段时,会自动采用arp扫描,如果在不同网段则采用ping扫描。

-sn扫描本网段的抓包截图:

root@kali:~/桌面# nmap -sn 192.168.10.0/24
Starting Nmap 7.80 ( https://nmap.org ) at 2020-12-29 22:25 EST
Nmap scan report for 192.168.10.1
Host is up (0.00034s latency).
MAC Address: 00:50:56:C0:00:08 (VMware)
Nmap scan report for 192.168.10.2
Host is up (0.00011s latency).
MAC Address: 00:50:56:EE:4D:A2 (VMware)
Nmap scan report for 192.168.10.129
Host is up (0.00028s latency).
MAC Address: 00:0C:29:CF:4C:09 (VMware)
Nmap scan report for 192.168.10.254
Host is up (0.00044s latency).
MAC Address: 00:50:56:FC:F7:E6 (VMware)
Nmap scan report for 192.168.10.128
Host is up.
Nmap done: 256 IP addresses (5 hosts up) scanned in 1.59 seconds

nmap除了发送ARP请求之外,还进行DNS反向解析,可以加上-n选项,使之不做DNS解析,

root@kali:~/桌面# nmap -sn -n 192.168.10.0/24
Starting Nmap 7.80 ( https://nmap.org ) at 2020-12-29 22:28 EST
Nmap scan report for 192.168.10.1
Host is up (0.0013s latency).
MAC Address: 00:50:56:C0:00:08 (VMware)
Nmap scan report for 192.168.10.2
Host is up (0.00018s latency).
MAC Address: 00:50:56:EE:4D:A2 (VMware)
Nmap scan report for 192.168.10.129
Host is up (0.00014s latency).
MAC Address: 00:0C:29:CF:4C:09 (VMware)
Nmap scan report for 192.168.10.254
Host is up (0.00014s latency).
MAC Address: 00:50:56:FC:F7:E6 (VMware)
Nmap scan report for 192.168.10.128
Host is up.
Nmap done: 256 IP addresses (5 hosts up) scanned in 2.07 seconds

nmap批量扫描

root@kali:~/桌面# nmap 192.168.10.10, 192.168.20.20
root@kali:~/桌面# nmap 192.168.10.10-100
root@kali:~/桌面# nmap 192.168.10.0/24

-iL选项可以从事先准备好的文本文件中读取要扫描的地址列表:

root@kali:~/桌面# nmap -iL ip.txt

利用scapy实现ARP扫描

  • ARP扫描的基本原理
    • 向目标主机发送ARP请求,只要能收到ARP响应,就证明主机在线。
import os
import time
from scapy.all import *
from threading import Thread
from optparse import OptionParser

from scapy.layers.l2 import Ether, ARP


def main():
    usage = "Usage: %prog -f <filename> -i <ip address>"
    parser = OptionParser(usage)
    parser.add_option("-f", "--file", type="string", dest="filename", help="specify the IP address file")
    parser.add_option("-i", "--ip", type="string", dest="address", help="specify the IP address")
    (options, args)=parser.parse_args()
    filename=options.filename
    address=options.addrss
    if filename==None and address==None:
        print("请指定IP")
        sys.exit()
    pass

def sweep(ip):
    try:
        pakt=Ether(dst="ff:ff:ff:ff:ff:ff", src="00:0c:29:09:8c:d7")/ARP(hwsrc="00:0c:29:09:8c:d7", psrc="192.168.10.1", hwdst="00:00:00:00:00:00", pdst=ip)
        result=srp1(pakt, timeout=1, version=0)
        if result:
            time.sleep(0.1)
            print(ip, "在线")
            return
    except:
        return
    pass

if __name__=="__main__":
    main()

三层发现

  • 原理
    • 主要利用icmp协议。
  • 优点
    • 可路由,可以跨网段扫描。
  • 缺点
    • 有可能被防火墙过滤,扫描结果不准确。

#### ICMP协议(ping命令)介绍

ICMP,Internet控制消息协议,用于在网络中传递控制消息。

Ping命令利用了ICMP种类型的控制消息:echo,request,echo,reply。

C:\Users\Webb>ping 192.168.10.128

正在 Ping 192.168.10.128 具有 32 字节的数据:
来自 192.168.10.128 的回复: 字节=32 时间<1ms TTL=64
来自 192.168.10.128 的回复: 字节=32 时间<1ms TTL=64
来自 192.168.10.128 的回复: 字节=32 时间<1ms TTL=64
来自 192.168.10.128 的回复: 字节=32 时间<1ms TTL=64

192.168.10.128 的 Ping 统计信息:
    数据包: 已发送 = 4,已接收 = 4,丢失 = 0 (0% 丢失),
往返行程的估计时间(以毫秒为单位):
    最短 = 0ms,最长 = 0ms,平均 = 0ms

TTL值

  • TTL即数据包的生命周期,每个系统对其所发送的数据包都要赋一个TTL的初始值。
  • 默认情况下,Windows系统为128,Linux系统为64。
  • 数据包每进过一次路由,TTL值就要减1。
  • 通过TTL值,即可以大概推算出对方所用的操作系统,又可以推断出数据包在传输过程中经过了多少次路由。
  • tracert命令向指定的目的主机发送多次回显请求消息,并把封装该消息的数据包的TTL值从1开始递增。

fping

fping是增强型的ping命令,集成了很多ping命令所没有的功能。

  • 如果目标主机可达,那么它在收到一个应答之后,就立即停止发送请求。

  • 如果目标主机不可达,那么fping将尝试联系4次。

fping相比ping最大的优势是可以扫描一个指定的地址段,需要使用-g选项。

root@kali:~/桌面# fping -g 192.168.10.0/24 2>/dev/null | grep alive
192.168.10.2 is alive
192.168.10.128 is alive

scapy发送ICMP请求

root@kali:~/桌面# scapy
>>> pkt=IP()/ICMP()
>>> pkt[IP].dst="192.168.10.1"
>>> result=sr1(pkt)

TCP协议与三次握手

  • 原理
    • 利用TCP或UDP协议,向目标主机的相应端口发送构造好的数据包,从而获知主机是否在线。
  • 优点
    • 可以跨网段扫描,可以发现那些过滤了ICMP消息的主机。
  • 缺点
    • 很容易被防火墙拦截。

TCP协议

TCP是一种面向连接的,可靠的,基于字节流的传输层通信协议。

通信双方在通信之前必须先建立起连接。

TCP可以确保收方一定会收到发送方所发送出去的数据。

TCP会将应用层来的数据根据网络的拥堵情况分成一个个的数据段,然后再进行发送,因而称为”基于字节流“。

TCP头部

  • 序号和确认号
    • 在发送每个数据段必须要进行编号,在接收方会按照序号进行组装。
    • 接收方每收到一个数据段之后,都要向发送方发回一个确认号,等于接收到数据包的序号seq+数据包的长度len。

TCP标志位

  • flag标志位
    • FIN:断开连接,对应值位1;
    • SYN:同步信号,用于发起一个连接,对应值为2;
    • RST:重置连接,对应值为4;
    • ACK:确认消息,对应值为16;

TCP三次握手

三次握手的目的是同步连接双方的序列号和确认号,并交换TCP窗口大小信息。

TCP发现原理

如果向目标主机发送一个未经过的ACK,那么目标主机将会返回一个RST包,表示中断连接请求。

flags标志位的表示方法:

  • F=FIN,S=SYN,R=RST,A=ACK,默认是SYN.
  • 也可以用数值表示:F为1,S为2,R为4,A为16,所以ACK+SYN=18。
>>> pkt=IP()/TCP()
>>> pkt[TCP].dprot=22
>>> pkt[IP].dst="192.168.10.128"
>>> pkt[TCP].flag=18
>>> pkt.show()
###[ IP ]### 
  version= 4
  ihl= None
  tos= 0x0                                                                                                                                                                                                        
  len= None                                                                                                                                                                                                       
  id= 1                                                                                                                                                                                                           
  flags=                                                                                                                                                                                                          
  frag= 0                                                                                                                                                                                                         
  ttl= 64                                                                                                                                                                                                         
  proto= tcp                                                                                                                                                                                                      
  chksum= None                                                                                                                                                                                                    
  src= 192.168.10.129                                                                                                                                                                                             
  dst= 192.168.10.128                                                                                                                                                                                             
  \options\                                                                                                                                                                                                       
###[ TCP ]###                                                                                                                                                                                                     
     sport= ftp_data
     dport= http
     seq= 0
     ack= 0
     dataofs= None
     reserved= 0
     flags= S
     window= 8192
     chksum= None
     urgptr= 0
     options= []

>>> result=sr1(pkt)
Begin emission:
Finished sending 1 packets.

UDP发现原理

以返回包中IP部分proto参数的值作为判断条件,确认目标主机是否返回了ICMP消息。原理是IP包头中的Protocol部分用于标记上层协议类型,如果数值为1的话,表示ICMP。

>>> pkt=IP()/UDP()
>>> pkt["IP"].dst="192.168.10.129"
>>> sr1(pkt)
Begin emission:
Finished sending 1 packets.
.*
Received 2 packets, got 1 answers, remaining 0 packets
<IP  version=4 ihl=5 tos=0x0 len=56 id=1234 flags= frag=0 ttl=128 proto=icmp chksum=0x9fa1 src=192.168.10.129 dst=192.168.10.128 |<ICMP  type=dest-unreach code=port-unreachable chksum=0x9368 reserved=0 length=0 nexthopmtu=0 |<IPerror  version=4 ihl=5 tos=0x0 len=28 id=1 flags= frag=0 ttl=64 proto=udp chksum=0xe47e src=192.168.10.128 dst=192.168.10.129 |<UDPerror  sport=domain dport=domain len=8 chksum=0x6922 |>>>>
>>> 

namp进行四层发现

  • -PA,TCP ACK扫描。
    • 进行TCP,ACK扫描,但不做端口扫描。
root@kali:~/桌面# nmap -PA80 -sn 192.168.10.0/24 -oG -
# Nmap 7.80 scan initiated Thu Dec 31 22:10:51 2020 as: nmap -PA80 -sn -oG - 192.168.10.0/24
Host: 192.168.10.1 ()   Status: Up
Host: 192.168.10.2 ()   Status: Up
Host: 192.168.10.129 () Status: Up
Host: 192.168.10.254 () Status: Up
Host: 192.168.10.128 () Status: Up
# Nmap done at Thu Dec 31 22:10:59 2020 -- 256 IP addresses (5 hosts up) scanned in 7.98 seconds
  • -PU,UDP扫描。
    • 进行UDP扫描,但不做端口扫描。
root@kali:~/桌面# nmap -PU50000 -sn 192.168.10.1/24 -oG -
# Nmap 7.80 scan initiated Thu Dec 31 22:20:52 2020 as: nmap -PU50000 -sn -oG - 192.168.10.1/24
Host: 192.168.10.1 ()   Status: Up
Host: 192.168.10.2 ()   Status: Up
Host: 192.168.10.129 () Status: Up
Host: 192.168.10.254 () Status: Up
Host: 192.168.10.128 () Status: Up
# Nmap done at Thu Dec 31 22:20:54 2020 -- 256 IP addresses (5 hosts up) scanned in 2.04 seconds

端口扫描

TCP端口扫描

TCP端口扫描都是基于三次握手的变化来判断目标端口状态。

SYN半开式扫描,向目标端口发送SYN数据包,如果能收到SYN+ACK,则证明端口开放,但并不进一步发送第三次握手的ACK,所以称为半开式。

优点是速度快,而且比较隐蔽,不容易在目标主机中留下记录。

>>> res.show()
###[ IP ]### 
  version= 4
  ihl= 5
  tos= 0x0
  len= 44
  id= 0
  flags= DF
  frag= 0
  ttl= 64
  proto= tcp
  chksum= 0xa479
  src= 192.168.10.130
  dst= 192.168.10.128
  \options\
###[ TCP ]### 
     sport= ssh
     dport= ftp_data
     seq= 3291689171
     ack= 1
     dataofs= 6
     reserved= 0
     flags= SA
     window= 29200
     chksum= 0x9a81
     urgptr= 0
     options= [('MSS', 1460)]
###[ Padding ]### 
        load= '\x00\x00'

>>> res[TCP].flags
<Flag 18 (SA)>
利用nmap进行TCP端口扫描

利用sS选项实现SYN半开式扫描。nmap默认会扫描1000个端口。

root@kali:~/桌面# nmap -h | grep sS
  -sS/sT/sA/sW/sM: TCP SYN/Connect()/ACK/Window/Maimon scans
root@kali:~/桌面# nmap -sS 192.168.10.130
Starting Nmap 7.80 ( https://nmap.org ) at 2021-01-03 02:18 EST
Nmap scan report for 192.168.10.130
Host is up (0.00067s latency).
Not shown: 999 filtered ports
PORT   STATE SERVICE
22/tcp open  ssh
MAC Address: 00:0C:29:5A:65:9B (VMware)

Nmap done: 1 IP address (1 host up) scanned in 7.16 seconds
# 指定端口
root@kali:~/桌面# nmap -sS 192.168.10.130 -p 22,80,3306
Starting Nmap 7.80 ( https://nmap.org ) at 2021-01-03 02:19 EST
Nmap scan report for 192.168.10.130
Host is up (0.00045s latency).

PORT     STATE    SERVICE
22/tcp   open     ssh
80/tcp   filtered http
3306/tcp filtered mysql
MAC Address: 00:0C:29:5A:65:9B (VMware)

Nmap done: 1 IP address (1 host up) scanned in 0.18 seconds

UDP端口扫描

检测目标主机是否开放了相应的UDP端口。

向目标主机的相应端口发送UDP数据包,如果没有返回ICMP消息,则证明这个端口是开放的。

  • scapy
>>> res=sr1(IP(dst="192.168.80.130")/UDP(dport=53),timeout=1,verbose=0)
  • nmap
root@kali:~/桌面# nmap -sU 192.168.10.130 -p 53
Starting Nmap 7.80 ( https://nmap.org ) at 2021-01-03 02:41 EST
Nmap scan report for 192.168.10.130
Host is up (0.0014s latency).

PORT   STATE    SERVICE
53/udp filtered domain
MAC Address: 00:0C:29:5A:65:9B (VMware)

Nmap done: 1 IP address (1 host up) scanned in 0.19 seconds

Socket模块的使用

官方文档:https://docs.python.org/zh-cn/3/library/socket.html#socket.socket.connect

基本概念

  • 什么是socket

socket可以通过网络实现不同主机间进程通信,网络上各种各样的服务大都是基于socket来完成通信。

网络中的两台主机之间进行通信,本质上是主机中所运行的进程之间通信。两个进程如果需要进行通信,最基本的前提是每个进程要有一个唯一的表示。在本地进程通讯中可以使用PID来唯一标识一个进程,但是PID只在本地唯一。可以用“IP地址+协议+端口号”来唯一标识网络中的一个进程,这个就是socket。

无论使用何种网络协议,最本质上都是在进行数据的接收和发送,“发送”和“接收”,这个两个动作就是socket处理数据的主要方式。

socket的服务端和客户端

  • socket采用C/S模式,分为服务端和客户端。
  • 服务端的数据处理流程:
    • 插件socket->绑定到地址和端口->等待连接->开始通信->关闭连接。
  • 客户端的数据处理流程:
    • 插件socket->连接目标->开始通信->关闭连接。
  • 客户端在创建socket之后,并没有绑定到地址和端口,这是由于客户端进程采用的是随机端口,当客户端进程执行连接目标的操作时,会由系统自动分配一个端口号和自身的ip地址进行组合。

socket类的参数

  • socket.AF_INET表示socket使用IPv4地址进行主机之间的网络通信,socket.SOCK_STREAM表示使用TCP协议。

  • AF表示ADDRESS FAMILY地址族,除AF_INET外,还可以用AF_INET6表示IPv6地址,用AF_UNIX表示单一的Unix系统进程间通信。

  • TCP用SOCK_STREAM表示,UDP用SOCK_DGRAM表示。TCP在发送数据时会将数据进行拆分,数据好像水流一样在进行传输,因而称为stream。UDP是将数据整体发送,因而称为datagram数据报,简写为DGRAM。

  • 如果服务端和客户端要采用UDP进行通信,代码为:

    • s=socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
      
  • 两个参数的默认值分别为socket.AF_INET和socket.SOCK_STREAM

服务端

import socket
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('', 6000))
s.listen(1)
print("start server")
client, addr=s.accept()
print("Connected by:", addr)
client.send(b"Hello")
text=client.recv(1024)
print(text)
client.close()
s.close()
代码解析
  • s.bind((”, 6000))
    • 将socket绑定到IP和端口,在AF_INET模式下,要求以元组的形式表示IP和端口,如(‘192.168.1.1’, 6000),IP部分为空,则表示默认采用本地地址。
  • s.listen(1)
    • 开始监听TCP传入连接。1是指服务端允许的客户端最大连接数,该值至少为1,大部分应用程序设为5就可以了。
  • client, addr=s.accept()
    • s.accept()接受TCP连接并返回(conn, address),其中conn是新的套接对象,可以用来接收和发送数据,address是连接客户端的地址。
    • 由于s.accept()会接收两个数据,因而这里分别赋值给两个变量client和addr。
  • print(“Connected by:”, addr)
    • 输出客户端的IP地址和端口号。
  • client.send(“Welcom”)
    • 向连接上来的客户端发送数据。
    • 服务端与客户端之间不能直接发送列表,元组,字典,而只能发送字符串。
    • 发送数据还有sendall()方法,TCP协议有时可能会把要发送的数据线缓存,然后等一段时间之后再发送,send()方法不一定会立即发送数据,而sendall()方法可以立即发送。
  • text=client.recv(1024)

    • 接收TCP套接字的数据。数据已字符串形式返回,1024指定要接收的最大数据量。
  • print(text)
    • 将客户端发来的数据输出显示。
  • client.close()
    • 关闭与客户端所建立的连接。
  • s.close()
    • 关闭服务端程序。

#### 客户端

import socket
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('192.168.10.128', 6000))
ans=s.recv(1024)
print(ans)
s.send(b"Hello")
s.close()
代码解析
  • s.connect((‘192.168.10.128’, 6000))
    • 连接到192.168.10.128处的远程套接字。
  • ans=s.recv(1024)
    • 接收TCP套接字的数据。数据已字符串形式返回,1024指定要接收的最大数据量。
  • print(ans)
    • 将服务端发来的数据输出显示。
  • s.send(b”Hello”)
    • 向服务端端发送数据。
  • s.close()
    • 关闭客户端程序。

端口扫描

检测某个端口是否开启

import socket
s=socket.socket()
s.connect(('192.168.10.128', 6000))
s.close()
结果:
  • 端口开启或存在
kali@kali:~/Desktop$ python test.py 
  • 端口关闭或者不存在
kali@kali:~/Desktop$ python test.py 
Traceback (most recent call last):
  File "test.py", line 3, in <module>
    s.connect(('192.168.10.128', 6000))
  File "/usr/lib/python2.7/socket.py", line 228, in meth
    return getattr(self._sock,name)(*args)
socket.error: [Errno 111] Connection refused
代码优化:
import socket

def portScan(ip, port):
    c=None
    try:
        c=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        c.connect((ip, port))
        print("%s 's TCP port %d is open" %(ip, port))
    except:
        print("%s 's TCP port %d is closed "%(ip, port))
    finally:
        c.close()

def main():
    ip="192.168.10.128"
    port=22
    portScan(ip,port)

if __name__=="__main__":
    main()
再次优化
import socket
from optparse import OptionParser
from threading import Thread


def portScan(ip, port):
    c=None
    try:
        c=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        c.connect((ip, port))
        print("%s 's TCP port %d is open" %(ip, port))
    except:
        print("%s 's TCP port %d is closed "%(ip, port))
    finally:
        c.close()

def main():
    parser=OptionParser('usage: %prog -i <target host> -n <network> -p <target port>')
    parser.add_option("-i", type="string", dest="tgtIP", help="specify target host")
    parser.add_option("-n", type="string", dest="tgtNetwork", help="specify target network")
    parser.add_option("-p", type="string", dest="tgtPorts", help="specify target ports separated by comma")
    (options, args)=parser.parse_args()

    tgtIP=options.tgtIP
    tgtNetwork=options.tgtNetwork
    tgtPorts=options.tgtPorts
    if tgtPorts==None or tgtIP == None and tgtNetwork == None:
        print(parser.usage)
        quit(0)

    tgtPorts=tgtPorts.split(",")
    if tgtIP:
        for p in tgtPorts:
            portScan(tgtIP, int(p))

    if tgtNetwork:
        tgtNetwork=tgtNetwork.split(".")
        prefix=tgtNetwork[0]+"."+tgtNetwork[1]+"."+tgtNetwork[2]+"."
        for i in range(1, 255):
            try:
                ip=prefix+str(i)
                for p in tgtPorts:
                    t=Thread(target=portScan, args=(ip, int(p)))
                    t.start()
            except KeyboardInterrupt:
                quit(1)
if __name__=="__main__":
    main()

UDP通信

#### 服务器

import socket
s=socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind(('', 6000))
while True:
    data, addr=s.recvfrom(1024)
    print("Connected by ", addr)
    print("Recvied ", data)
    s.sendto(data, addr)
    if data=="exit":
        break
s.close()

服务端减少了listen()和accept(),不需要建立连接就直接接受客户端的数据。在发送数据时也与TCP不同,TCP发送数据时,建立好TCP连接,所以不需要指定地址。UDP是面向无连接,每次发送要指定是发送给谁。

客户端

import socket
c=socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

while True:
    text=raw_input("Please input:")
    c.sendto(text,("192.168.10.128", 6000))
    if text=="exit":
        break
    ans=c.recv(1024)
    print(ans)
c.close()

客户端少了connect(),同样直接通过sendto()给服务器发数据。

指纹识别

基本概念

  • 识别目标端口上的运行了什么服务。
    • 比如TCP21对应FTP服务,TCP445对应samba服务等。
    • 还要识别出这些服务的版本,比如探测到FTP服务的版本是2.3.4,或者smaba服务的版本是3.0.20,就可以知道这些版本的服务都是有漏洞。
  • 识别目标的操作系统类型
    • 一方面要探测出操作系统的类型,比如是Windows还是Linux,另一方面还要探测出操作系统的具体版本信息,比如Windows7sp1,或是操作系统的内核Linux 2.6.9等。

利用banner和nmap进行服务识别

通过获取banner进行服务识别

import socket
socket.setdefaulttimeout(2)
s=socket.socket()
s.connect(("192.168.10.128", 21))
ans=s.recv(1024)
s.close()
print(ans)

通过获取nmap进行服务识别

  • nmap通过向目标端口发送一系列复杂的探测包,并且根据返回的响应特征来分析识别服务。
    • 利用选项sV
kali@kali:~/Desktop$ nmap -sV 192.168.10.128
Starting Nmap 7.80 ( https://nmap.org ) at 2021-01-04 22:13 EST
Nmap scan report for 192.168.10.128
Host is up (0.00079s latency).
All 1000 scanned ports on 192.168.10.128 are closed

利用TTL和nmap进行操作系统识别

利用TTL进行操作系统识别

  • Linux系统1~64,Windows系统65~128,非常不严谨。
>>> res=sr1(IP(dst='192.168.10.132')/ICMP())
Begin emission:
Finished sending 1 packets.
.*
Received 2 packets, got 1 answers, remaining 0 packets
>>> res[IP].ttl
64
>>> res[IP].src
'192.168.10.132'
>>> res.haslayer(IP)
True
  • 使用Python来识别
from scapy.all
import * import logging
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
import sys

if len(sys.argv)!=2:
    print("Usage - fileName.py [IP Address]")
    print("Example - fileName.py 10.0.0.5")
    print("Example will perform ttl analysis to attempt to deter mine whether the system is Windows or Linux/Unix")
    sys.exit()
ip = sys.argvp[1]

ans = sr1(IP(dst=str(ip))/ICMP(), timeout=1, verbose=0)
if ans==None:
    print("No response was returned")
elif int(ans[IP].ttl)<=64:
    print("Host is Linux/Unix")
else:
    print("Host is Windos")

#### 利用nmap进行操作系统识别

  • nmap采用协议栈分析技术进行操作系统识别。
    • -O选项,探测目标主机的操作系统类型等信息。
    • -A选项,同时启动系统探测,端口扫描,应用程序版本探测。
root@kali:~/桌面# nmap -O 192.168.10.130
Starting Nmap 7.80 ( https://nmap.org ) at 2021-01-04 22:41 EST                                                                                                                                               
Nmap scan report for 192.168.10.130                                                                                                                                                                           
Host is up (0.00054s latency).                                                                                                                                                                                
Not shown: 999 filtered ports
PORT   STATE SERVICE
22/tcp open  ssh
MAC Address: 00:0C:29:5A:65:9B (VMware)
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Device type: general purpose
Running: Linux 3.X|4.X
OS CPE: cpe:/o:linux:linux_kernel:3 cpe:/o:linux:linux_kernel:4
OS details: Linux 3.10 - 4.11, Linux 3.2 - 4.9
Network Distance: 1 hop

OS detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 6.96 seconds
  • 最新的nmap除了能识别出操作系统之外,还能识别出手机,路由器,交换机等网络设备,共搜集了近1500个指纹。

Python使用nmap模块

##### 介绍:

  • 通过nmap模块,可以在Python脚本中直接使用nmap的全部功能。
安装:
  • Kali中默认并没有安装nmap模块,可以通过pip工具安装:
root@kali:~/桌面# pip install python-nmap                        
Collecting python-nmap
  Downloading python-nmap-0.6.1.tar.gz (41 kB)
     |████████████████████████████████| 41 kB 42 kB/s 
Building wheels for collected packages: python-nmap
  Building wheel for python-nmap (setup.py) ... done
  Created wheel for python-nmap: filename=python_nmap-0.6.1-py2-none-any.whl size=19324 sha256=78baae00e88b3c851b8e0df877a41e28287fd9347a92e7d74d24d6548fc10fa0
  Stored in directory: /root/.cache/pip/wheels/e4/0d/d6/73d4ef02093ed3cf69d569965ff99d127e2bc0bdf991a22a8e
Successfully built python-nmap
Installing collected packages: python-nmap
Successfully installed python-nmap-0.6.1
测试是否安装完成:
root@kali:~/桌面# python
Python 2.7.18 (default, Apr 20 2020, 20:30:41) 
[GCC 9.3.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import nmap
>>> exit()
实例:
  • 扫描某一台主机开启的服务。
root@kali:~/桌面# python
Python 2.7.18 (default, Apr 20 2020, 20:30:41) 
[GCC 9.3.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import nmap
>>> nm=nmap.PortScanner()
>>> result=nm.scan(hosts='192.168.10.129', arguments='-sV')
>>> import pprint
>>> pprint.pprint(result)
{'nmap': {'command_line': 'nmap -oX - -sV 192.168.10.129',
          'scaninfo': {'tcp': {'method': 'syn',
                               'services': '1,3-4,6-7,9,13,17,19-26,30,32-33,37,42-43,49,53,70,79-85,88-90,99-100,106,109-111,113,119,125,135,139,143-144,146,161,163,179,199,211-212,222,254-256,259,264,280,301,306,311,340,366,389,406-407,416-417,425,427,443-445,458,464-465,481,497,500,512-515,524,541,543-545,548,554-555,563,587,593,616-617,625,631,636,646,648,666-668,683,687,691,700,705,711,714,720,722,726,749,765,777,783,787,800-801,808,843,873,880,888,898,900-903,911-912,981,987,990,992-993,995,999-1002,1007,1009-1011,1021-1100,1102,1104-1108,1110-1114,1117,1119,1121-1124,1126,1130-1132,1137-1138,1141,1145,1147-1149,1151-1152,1154,1163-1166,1169,1174-1175,1183,1185-1187,1192,1198-1199,1201,1213,1216-1218,1233-1234,1236,1244,1247-1248,1259,1271-1272,1277,1287,1296,1300-1301,1309-1311,1322,1328,1334,1352,1417,1433-1434,1443,1455,1461,1494,1500-1501,1503,1521,1524,1533,1556,1580,1583,1594,1600,1641,1658,1666,1687-1688,1700,1717-1721,1723,1755,1761,1782-1783,1801,1805,1812,1839-1840,1862-1864,1875,1900,1914,1935,1947,1971-1972,1974,1984,1998-2010,2013,2020-2022,2030,2033-2035,2038,2040-2043,2045-2049,2065,2068,2099-2100,2103,2105-2107,2111,2119,2121,2126,2135,2144,2160-2161,2170,2179,2190-2191,2196,2200,2222,2251,2260,2288,2301,2323,2366,2381-2383,2393-2394,2399,2401,2492,2500,2522,2525,2557,2601-2602,2604-2605,2607-2608,2638,2701-2702,2710,2717-2718,2725,2800,2809,2811,2869,2875,2909-2910,2920,2967-2968,2998,3000-3001,3003,3005-3007,3011,3013,3017,3030-3031,3052,3071,3077,3128,3168,3211,3221,3260-3261,3268-3269,3283,3300-3301,3306,3322-3325,3333,3351,3367,3369-3372,3389-3390,3404,3476,3493,3517,3527,3546,3551,3580,3659,3689-3690,3703,3737,3766,3784,3800-3801,3809,3814,3826-3828,3851,3869,3871,3878,3880,3889,3905,3914,3918,3920,3945,3971,3986,3995,3998,4000-4006,4045,4111,4125-4126,4129,4224,4242,4279,4321,4343,4443-4446,4449,4550,4567,4662,4848,4899-4900,4998,5000-5004,5009,5030,5033,5050-5051,5054,5060-5061,5080,5087,5100-5102,5120,5190,5200,5214,5221-5222,5225-5226,5269,5280,5298,5357,5405,5414,5431-5432,5440,5500,5510,5544,5550,5555,5560,5566,5631,5633,5666,5678-5679,5718,5730,5800-5802,5810-5811,5815,5822,5825,5850,5859,5862,5877,5900-5904,5906-5907,5910-5911,5915,5922,5925,5950,5952,5959-5963,5987-5989,5998-6007,6009,6025,6059,6100-6101,6106,6112,6123,6129,6156,6346,6389,6502,6510,6543,6547,6565-6567,6580,6646,6666-6669,6689,6692,6699,6779,6788-6789,6792,6839,6881,6901,6969,7000-7002,7004,7007,7019,7025,7070,7100,7103,7106,7200-7201,7402,7435,7443,7496,7512,7625,7627,7676,7741,7777-7778,7800,7911,7920-7921,7937-7938,7999-8002,8007-8011,8021-8022,8031,8042,8045,8080-8090,8093,8099-8100,8180-8181,8192-8194,8200,8222,8254,8290-8292,8300,8333,8383,8400,8402,8443,8500,8600,8649,8651-8652,8654,8701,8800,8873,8888,8899,8994,9000-9003,9009-9011,9040,9050,9071,9080-9081,9090-9091,9099-9103,9110-9111,9200,9207,9220,9290,9415,9418,9485,9500,9502-9503,9535,9575,9593-9595,9618,9666,9876-9878,9898,9900,9917,9929,9943-9944,9968,9998-10004,10009-10010,10012,10024-10025,10082,10180,10215,10243,10566,10616-10617,10621,10626,10628-10629,10778,11110-11111,11967,12000,12174,12265,12345,13456,13722,13782-13783,14000,14238,14441-14442,15000,15002-15004,15660,15742,16000-16001,16012,16016,16018,16080,16113,16992-16993,17877,17988,18040,18101,18988,19101,19283,19315,19350,19780,19801,19842,20000,20005,20031,20221-20222,20828,21571,22939,23502,24444,24800,25734-25735,26214,27000,27352-27353,27355-27356,27715,28201,30000,30718,30951,31038,31337,32768-32785,33354,33899,34571-34573,35500,38292,40193,40911,41511,42510,44176,44442-44443,44501,45100,48080,49152-49161,49163,49165,49167,49175-49176,49400,49999-50003,50006,50300,50389,50500,50636,50800,51103,51493,52673,52822,52848,52869,54045,54328,55055-55056,55555,55600,56737-56738,57294,57797,58080,60020,60443,61532,61900,62078,63331,64623,64680,65000,65129,65389'}},
          'scanstats': {'downhosts': '0',
                        'elapsed': '9.34',
                        'timestr': 'Tue Jan  5 20:40:53 2021',
                        'totalhosts': '1',
                        'uphosts': '1'}},
 'scan': {'192.168.10.129': {'addresses': {'ipv4': '192.168.10.129',
                                           'mac': '00:0C:29:CF:4C:09'},
                             'hostnames': [{'name': '', 'type': ''}],
                             'status': {'reason': 'arp-response',
                                        'state': 'up'},
                             'tcp': {135: {'conf': '10',
                                           'cpe': 'cpe:/o:microsoft:windows',
                                           'extrainfo': '',
                                           'name': 'msrpc',
                                           'product': 'Microsoft Windows RPC',
                                           'reason': 'syn-ack',
                                           'state': 'open',
                                           'version': ''},
                                     139: {'conf': '10',
                                           'cpe': 'cpe:/o:microsoft:windows',
                                           'extrainfo': '',
                                           'name': 'netbios-ssn',
                                           'product': 'Microsoft Windows netbios-ssn',
                                           'reason': 'syn-ack',
                                           'state': 'open',
                                           'version': ''},
                                     445: {'conf': '10',
                                           'cpe': 'cpe:/o:microsoft:windows_server_2003',
                                           'extrainfo': '',
                                           'name': 'microsoft-ds',
                                           'product': 'Microsoft Windows 2003 or 2008 microsoft-ds',
                                           'reason': 'syn-ack',
                                           'state': 'open',
                                           'version': ''},
                                     1025: {'conf': '10',
                                            'cpe': 'cpe:/o:microsoft:windows',
                                            'extrainfo': '',
                                            'name': 'msrpc',
                                            'product': 'Microsoft Windows RPC',
                                            'reason': 'syn-ack',
                                            'state': 'open',
                                            'version': ''}},
                             'vendor': {'00:0C:29:CF:4C:09': 'VMware'}}}}
>>> 

##### nmap模块使用

  • nmap模块中最常用的是PortScanner()类。
>>> nm=nmap.PortScanner()
>>> # help()方法查看某个值得文档
>>> help(nmap.PortScanner())
>>> help(nm)
  • PortScanner()类中最常见的是scan()方法。
>>> scan(self, hosts='127.0.0.1', ports=None, arguments="-sV", sudo=False)
  • 比如要执行“nmap -O 192.168.10.129”命令来探测目标主机的操作系统类型:
>>> result=nm.scan(hosts='192.168.10.129', argments='-0')
  • nmap模块扫描得到的结果是一个非常复杂的字典,可以通过标准模块pprint中的pprint()方法进行格式化输出。
>>> import pprint
>>> pprint.pprint(result)
  • 在osmatech部分可以看到操作系统的版本信息。
>>> result=nm.scan(hosts='192.168.10.129', arguments="-O")
>>> pprint.pprint(result)
{'nmap': {'command_line': 'nmap -oX - -O 192.168.10.129',
          'scaninfo': {'tcp': {'method': 'syn',
                               'services': '1,3-4,6-7,9,13,17,19-26,30,32-33,37,42-43,49,53,70,79-85,88-90,99-100,106,109-111,113,119,125,135,139,143-144,146,161,163,179,199,211-212,222,254-256,259,264,280,301,306,311,340,366,389,406-407,416-417,425,427,443-445,458,464-465,481,497,500,512-515,524,541,543-545,548,554-555,563,587,593,616-617,625,631,636,646,648,666-668,683,687,691,700,705,711,714,720,722,726,749,765,777,783,787,800-801,808,843,873,880,888,898,900-903,911-912,981,987,990,992-993,995,999-1002,1007,1009-1011,1021-1100,1102,1104-1108,1110-1114,1117,1119,1121-1124,1126,1130-1132,1137-1138,1141,1145,1147-1149,1151-1152,1154,1163-1166,1169,1174-1175,1183,1185-1187,1192,1198-1199,1201,1213,1216-1218,1233-1234,1236,1244,1247-1248,1259,1271-1272,1277,1287,1296,1300-1301,1309-1311,1322,1328,1334,1352,1417,1433-1434,1443,1455,1461,1494,1500-1501,1503,1521,1524,1533,1556,1580,1583,1594,1600,1641,1658,1666,1687-1688,1700,1717-1721,1723,1755,1761,1782-1783,1801,1805,1812,1839-1840,1862-1864,1875,1900,1914,1935,1947,1971-1972,1974,1984,1998-2010,2013,2020-2022,2030,2033-2035,2038,2040-2043,2045-2049,2065,2068,2099-2100,2103,2105-2107,2111,2119,2121,2126,2135,2144,2160-2161,2170,2179,2190-2191,2196,2200,2222,2251,2260,2288,2301,2323,2366,2381-2383,2393-2394,2399,2401,2492,2500,2522,2525,2557,2601-2602,2604-2605,2607-2608,2638,2701-2702,2710,2717-2718,2725,2800,2809,2811,2869,2875,2909-2910,2920,2967-2968,2998,3000-3001,3003,3005-3007,3011,3013,3017,3030-3031,3052,3071,3077,3128,3168,3211,3221,3260-3261,3268-3269,3283,3300-3301,3306,3322-3325,3333,3351,3367,3369-3372,3389-3390,3404,3476,3493,3517,3527,3546,3551,3580,3659,3689-3690,3703,3737,3766,3784,3800-3801,3809,3814,3826-3828,3851,3869,3871,3878,3880,3889,3905,3914,3918,3920,3945,3971,3986,3995,3998,4000-4006,4045,4111,4125-4126,4129,4224,4242,4279,4321,4343,4443-4446,4449,4550,4567,4662,4848,4899-4900,4998,5000-5004,5009,5030,5033,5050-5051,5054,5060-5061,5080,5087,5100-5102,5120,5190,5200,5214,5221-5222,5225-5226,5269,5280,5298,5357,5405,5414,5431-5432,5440,5500,5510,5544,5550,5555,5560,5566,5631,5633,5666,5678-5679,5718,5730,5800-5802,5810-5811,5815,5822,5825,5850,5859,5862,5877,5900-5904,5906-5907,5910-5911,5915,5922,5925,5950,5952,5959-5963,5987-5989,5998-6007,6009,6025,6059,6100-6101,6106,6112,6123,6129,6156,6346,6389,6502,6510,6543,6547,6565-6567,6580,6646,6666-6669,6689,6692,6699,6779,6788-6789,6792,6839,6881,6901,6969,7000-7002,7004,7007,7019,7025,7070,7100,7103,7106,7200-7201,7402,7435,7443,7496,7512,7625,7627,7676,7741,7777-7778,7800,7911,7920-7921,7937-7938,7999-8002,8007-8011,8021-8022,8031,8042,8045,8080-8090,8093,8099-8100,8180-8181,8192-8194,8200,8222,8254,8290-8292,8300,8333,8383,8400,8402,8443,8500,8600,8649,8651-8652,8654,8701,8800,8873,8888,8899,8994,9000-9003,9009-9011,9040,9050,9071,9080-9081,9090-9091,9099-9103,9110-9111,9200,9207,9220,9290,9415,9418,9485,9500,9502-9503,9535,9575,9593-9595,9618,9666,9876-9878,9898,9900,9917,9929,9943-9944,9968,9998-10004,10009-10010,10012,10024-10025,10082,10180,10215,10243,10566,10616-10617,10621,10626,10628-10629,10778,11110-11111,11967,12000,12174,12265,12345,13456,13722,13782-13783,14000,14238,14441-14442,15000,15002-15004,15660,15742,16000-16001,16012,16016,16018,16080,16113,16992-16993,17877,17988,18040,18101,18988,19101,19283,19315,19350,19780,19801,19842,20000,20005,20031,20221-20222,20828,21571,22939,23502,24444,24800,25734-25735,26214,27000,27352-27353,27355-27356,27715,28201,30000,30718,30951,31038,31337,32768-32785,33354,33899,34571-34573,35500,38292,40193,40911,41511,42510,44176,44442-44443,44501,45100,48080,49152-49161,49163,49165,49167,49175-49176,49400,49999-50003,50006,50300,50389,50500,50636,50800,51103,51493,52673,52822,52848,52869,54045,54328,55055-55056,55555,55600,56737-56738,57294,57797,58080,60020,60443,61532,61900,62078,63331,64623,64680,65000,65129,65389'}},
          'scanstats': {'downhosts': '0',
                        'elapsed': '2.51',
                        'timestr': 'Tue Jan  5 21:02:29 2021',
                        'totalhosts': '1',
                        'uphosts': '1'}},
 'scan': {'192.168.10.129': {'addresses': {'ipv4': '192.168.10.129',
                                           'mac': '00:0C:29:CF:4C:09'},
                             'hostnames': [{'name': '', 'type': ''}],
                             'osmatch': [{'accuracy': '100',
                                          'line': '72476',
                                          'name': 'Microsoft Windows Server 2003 SP1 or SP2',
                                          'osclass': [{'accuracy': '100',
                                                       'cpe': ['cpe:/o:microsoft:windows_server_2003::sp1',
                                                               'cpe:/o:microsoft:windows_server_2003::sp2'],
                                                       'osfamily': 'Windows',
                                                       'osgen': '2003',
                                                       'type': 'general purpose',
                                                       'vendor': 'Microsoft'}]}],
                             'portused': [{'portid': '135',
                                           'proto': 'tcp',
                                           'state': 'open'},
                                          {'portid': '1',
                                           'proto': 'tcp',
                                           'state': 'closed'},
                                          {'portid': '44550',
                                           'proto': 'udp',
                                           'state': 'closed'}],
                             'status': {'reason': 'arp-response',
                                        'state': 'up'},
                             'tcp': {135: {'conf': '3',
                                           'cpe': '',
                                           'extrainfo': '',
                                           'name': 'msrpc',
                                           'product': '',
                                           'reason': 'syn-ack',
                                           'state': 'open',
                                           'version': ''},
                                     139: {'conf': '3',
                                           'cpe': '',
                                           'extrainfo': '',
                                           'name': 'netbios-ssn',
                                           'product': '',
                                           'reason': 'syn-ack',
                                           'state': 'open',
                                           'version': ''},
                                     445: {'conf': '3',
                                           'cpe': '',
                                           'extrainfo': '',
                                           'name': 'microsoft-ds',
                                           'product': '',
                                           'reason': 'syn-ack',
                                           'state': 'open',
                                           'version': ''},
                                     1025: {'conf': '3',
                                            'cpe': '',
                                            'extrainfo': '',
                                            'name': 'NFS-or-IIS',
                                            'product': '',
                                            'reason': 'syn-ack',
                                            'state': 'open',
                                            'version': ''}},
                             'vendor': {'00:0C:29:CF:4C:09': 'VMware'}}}}
  • 提取出操作系统的版本信息。
>>> result['scan']['192.168.10.129']['osmatch'][0]['name']
'Microsoft Windows Server 2003 SP1 or SP2'
  • 进行服务识别:
>>> result=nm.scan(hosts='192.168.10.129', arguments='-sV')
  • 只针对特定的服务进行识别:
>>> result=nm.scan(hosts='192.168.10.129', ports='21', arguments='-sV')
  • 获取服务版本信息:
>>> result['scan']['192.168.10.129']['tcp'][21]['version']
  • 进行端口扫描
>>> result=nm.scan(hosts='192.168.10.0/24', porst='80', arguments='-sS')
root@kali:~# nmap -sS -p 80 192.168.10.0/24
  • 获取目标端口的姿态:
>>> result['scan']['192.168.10.0']['tcp'][21]['state']
'open'