扫描器篇(五)之scapy构造UDP数据包完成主机发现

udp协议扫描

  • 发现原理

    向目标主机发送一个,没有开放的端口发送数据,目标主机会返回一个ICMP
    目标端口不可达的消息,通过该特征可以对主机进行判断是否在线
    
  • 注意事项

       如果目标主机端口不在线,或者在线且目标端口为开放状态,那么发送出去的UDP数据包不会收到任何回复
    
  • 判断条件

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

扫描器篇(五)之scapy构造UDP数据包完成主机发现_第1张图片

代码部分

  • 数据包构造扫描部分
    • 通过python发包神器scapy构造UDP数据包
      
    • 端口一定要选择没有开放的,不然会扫描不到主机
      
def scan(ip):
    try:					# 端口要求一定是没开放
      packet = IP(dst=ip)/UDP(dport=56789)
      result = sr1(packet,timeout=0.5,verbose=0)
      #result.show()

      if int(result[IP].proto) == 0x01: # 0x01 代表的ICMP字段值
          time.sleep(0.1)
          print(ip + ' ' + "on line")
    except:
        return
  • 参数获取部分
    • 通过optparse模块接收用户提供的参数,判断是扫描整个网段还是读取ip地址文件
      
    • 获取到地址后再通过Thread多线程去发送数据包
      

def main():
	# 生成帮助信息,以及接收用户输入的参数,并建立对象
    usage = "Usage: arp扫描.py -f  -i "
    parse = OptionParser(usage=usage)
    parse.add_option("-f", "--file", type="string", dest="filename", help="specify the IP address file")
    parse.add_option("-i", '--ip', type="string", dest="address", help="specify the IP address")
    (option, args) = parse.parse_args()
    filename = option.filename
    address = option.address
	# 判断是不是地址文件
    if filename:
        if not os.path.exists(filename):	#判断文件是否存在
            print("The file does not exist. Please enter it again")
            sys.exit()	
        with open(filename, "r") as f:	#读取文件
            for i in f.readlines():
                ip = i.strip()
                t = Thread(target=scan, args=(ip,))
                t.start()
	# 判断是不是整个网段
    if address:
        prefix = address.split(".")[0] + '.' + address.split(".")[1] + '.' + address.split(".")[2] + "."	# 将用户输入的地址以.作为分隔符
        for i in range(0, 255):	
            ip = prefix + str(i)	#构造扫描整个网段所需ip
            t = Thread(target=scan, args=(ip,))
            t.start()

整体代码

import os
import time
from optparse import OptionParser
from scapy.all import *


def scan(ip):
    try:
      packet = IP(dst=ip)/UDP(dport=56789)
      result = sr1(packet,timeout=0.5,verbose=0)
      #result.show()

      if int(result[IP].proto) == 0x01: # 0x01 代表的ICMP字段值
          time.sleep(0.1)
          print(ip + ' ' + "on line")
    except:
        return


def main():
	# 生成帮助信息,以及接收用户输入的参数,并建立对象
    usage = "Usage: arp扫描.py -f  -i "
    parse = OptionParser(usage=usage)
    parse.add_option("-f", "--file", type="string", dest="filename", help="specify the IP address file")
    parse.add_option("-i", '--ip', type="string", dest="address", help="specify the IP address")
    (option, args) = parse.parse_args()
    filename = option.filename
    address = option.address
	# 判断是不是地址文件
    if filename:
        if not os.path.exists(filename):	#判断文件是否存在
            print("The file does not exist. Please enter it again")
            sys.exit()
        with open(filename, "r") as f:		#读取文件
            for i in f.readlines():
                ip = i.strip()
                t = Thread(target=scan, args=(ip,))
                t.start()
	# 判断是不是整个网段
    if address:
        prefix = address.split(".")[0] + '.' + address.split(".")[1] + '.' + address.split(".")[2] + "."	# 将用户输入的地址以.作为分隔符
        for i in range(0, 255):	
            ip = prefix + str(i)	#构造扫描整个网段所需ip
            t = Thread(target=scan, args=(ip,))
            t.start()


if __name__ == '__main__':
    main()

运行效果

扫描器篇(五)之scapy构造UDP数据包完成主机发现_第2张图片

你可能感兴趣的:(Web渗透,python)