python扫描局域网主机

一、开发环境

windows7 32位,python3.7

二,安装netaddr模块

netaddr模块能方便的对子网和IP地址进行操作。

三,工作原理

通过构建套接字对象对网络接口上的数据包嗅探,windows与linux的区别是windows允许我们嗅探所有协议的所有数据包,而linux只能嗅探到ICMP数据。当我们发送UDP数据到活动主机关闭的端口上时,会产生ICMP响应,ICMP响应的数据属性中,有一个类型值(type)和代码值(code),当这两个值都为3时,代表主机端口不可达。

四,代码

import socket
import os
import struct
import threading

from netaddr import IPNetwork,IPAddress
from ctypes import *

# host to listen on
host   = "192.168.0.149"
# subnet to target
subnet = "192.168.0.0/24"
# magic we'll check ICMP responses for
magic_message = "PYTHONRULES!"
def udp_sender(subnet,magic_message):
    sender = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    for ip in IPNetwork(subnet):
        try:
            sender.sendto(magic_message.encode(),("%s" % ip,65212))
        except Exception as e:
            raise(e)      
class IP(Structure): 
    _fields_ = [
        ("ihl",           c_ubyte, 4),
        ("version",       c_ubyte, 4),
        ("tos",           c_ubyte),
        ("len",           c_ushort),
        ("id",            c_ushort),
        ("offset",        c_ushort),
        ("ttl",           c_ubyte),
        ("protocol_num",  c_ubyte),
        ("sum",           c_ushort),
        ("src",           c_ulong),
        ("dst",           c_ulong)
    ]  
    def __new__(self, socket_buffer=None):
            return self.from_buffer_copy(socket_buffer)         
    def __init__(self, socket_buffer=None):
        # map protocol constants to their names
        self.protocol_map = {1:"ICMP", 6:"TCP", 17:"UDP"}  
        # human readable IP addresses
        self.src_address = socket.inet_ntoa(struct.pack(" %s" % (ip_header.protocol, ip_header.src_address, ip_header.dst_address)
        # if it's ICMP we want it
        if ip_header.protocol == "ICMP": 
            # calculate where our ICMP packet starts
            offset = ip_header.ihl * 4
            buf = raw_buffer[offset:offset + sizeof(ICMP)] 
            # create our ICMP structure
            icmp_header = ICMP(buf)
            #print("ICMP -> Type: %d Code: %d ip:%s" % (icmp_header.type, icmp_header.code,ip_header.src_address))
            # now check for the TYPE 3 and CODE 3 which indicates
            # a host is up but no port available to talk to           
            if icmp_header.code == 3 and icmp_header.type == 3:
                # check to make sure we are receiving the response 
                # that lands in our subnet
                if IPAddress(ip_header.src_address) in IPNetwork(subnet):
                    # test for our magic message
                    if raw_buffer[len(raw_buffer)-len(magic_message):] == magic_message.encode():
                        print("Host Up: %s" % ip_header.src_address)
# handle CTRL-C
except KeyboardInterrupt:
    # if we're on Windows turn off promiscuous mode
    if os.name == "nt":
        sniffer.ioctl(socket.SIO_RCVALL, socket.RCVALL_OFF)

上面代码出自《Black Hat Python》,但我是在win7 32的python3上运行的,代码稍微有点改动。运行结果如下“

python扫描局域网主机_第1张图片

 

 

你可能感兴趣的:(python)