近期收到了电子工业出版社赠送的一本网络安全书籍《python黑帽子》,书中一共24个实验,今天复现第7个实验(UDP主机存活扫码),我的测试环境是mbp电脑+conda开发环境。只在Linux环境下进行C段主机存活扫描测试,发现C段里只有2台主机存活,使用这个脚本,可以轻松检查公司(或者实验室)里哪些人下班没有关电脑~
ailx10
网络安全优秀回答者
网络安全硕士
去咨询
1、只需要在mbp电脑上执行,就可以得到存活主机列表
参考代码:
# -*- coding: utf-8 -*-
# @Time : 2022/6/6 6:20 PM
# @Author : ailx10
# @File : scanner.py
import ipaddress
import os
import socket
import struct
import sys
import threading
import time
SUBNET = "10.134.181.0/24"
MESSAGE = "AILX10"
class IP:
def __init__(self,buff = None):
header = struct.unpack("<BBHHHBBH4s4s",buff)
self.ver = header[0] >> 4
self.ihl = header[0] & 0xF
self.tos= header[1]
self.len = header[2]
self.id = header[3]
self.offset = header[4]
self.ttl = header[5]
self.protocol_num = header[6]
self.sum = header[7]
self.src = header[8]
self.dst = header[9]
self.src_address = ipaddress.ip_address(self.src)
self.dst_address = ipaddress.ip_address(self.dst)
self.protocol_map = {1:"ICMP",6:"TCP",17:"UDP"}
try:
self.protocol = self.protocol_map[self.protocol_num]
except Exception as e:
print("%s No protocol for %s" % (e,self.protocol_num))
self.protocol = str(self.protocol_num)
class ICMP:
def __init__(self,buff):
header = struct.unpack("<BBHHH",buff)
self.type = header[0]
self.code = header[1]
self.sum = header[2]
self.id = header[3]
self.seq = header[4]
def udp_sender():
with socket.socket(socket.AF_INET,socket.SOCK_DGRAM) as sender:
for ip in ipaddress.ip_network(SUBNET).hosts():
sender.sendto(bytes(MESSAGE,"utf-8"),(str(ip),65212))
class Scanner:
def __init__(self,host):
self.host = host
if os.name == "nt":
socket_protocol = socket.IPPROTO_IP
else:
socket_protocol = socket.IPPROTO_ICMP
self.socket = socket.socket(socket.AF_INET,socket.SOCK_RAW,socket_protocol)
self.socket.bind((host,0))
self.socket.setsockopt(socket.IPPROTO_IP,socket.IP_HDRINCL,1)
if os.name == "nt":
self.socket.ioctl(socket.SIO_RCVALL,socket.RCVALL_ON)
def sniff(self):
hosts_up = set([f"{str(self.host)} *"])
try:
while True:
raw_buffer = self.socket.recvfrom(65535)[0]
ip_header = IP(raw_buffer[0:20])
if ip_header.protocol == "ICMP":
print("Protocol:%s %s->%s" % (ip_header.protocol, ip_header.src_address, ip_header.dst_address))
print(f"Version:{ip_header.ver}")
print(f"Header Length:{ip_header.ihl} TTL:{ip_header.ttl}")
offset = ip_header.ihl * 4
buff = raw_buffer[offset:offset + 8]
icmp_header = ICMP(buff)
if icmp_header.code == 3 and icmp_header.type == 3: # 端口不可达
if ipaddress.ip_address(ip_header.src_address) in ipaddress.IPv4Network(SUBNET):
if raw_buffer[len(raw_buffer) - len(MESSAGE):] == bytes(MESSAGE,"utf-8"):
tgt = str(ip_header.src_address)
if tgt != self.host and tgt not in hosts_up:
hosts_up.add(str(ip_header.src_address))
print(f"Host Up:{tgt}")
except KeyboardInterrupt:
if os.name == "nt":
self.socket.ioctl(socket.SIO_RCVALL, socket.RCVALL_OFF)
print("\nUser interrupted.")
if hosts_up:
print(f"\n\nSummary:Hosts up on {SUBNET}")
for host in sorted(hosts_up):
print(f"{host}")
print("")
sys.exit()
if __name__ == "__main__":
if len(sys.argv) == 2:
host = sys.argv[1]
else:
host = "192.168.0.102"
s = Scanner(host)
time.sleep(5)
t = threading.Thread(target=udp_sender)
t.start()
s.sniff()
发布于 2022-06-06 19:13