网络嗅探
Posted moonstars2333
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了网络嗅探相关的知识,希望对你有一定的参考价值。
网络嗅探
嗅探目标:基于UDP发现目标网络存活的主机
嗅探基础:当发送一个UDP数据包到主机上的某个关闭端口时,目标主机返回ICMP包指示目标端口不可达,证明目标主机存活,否则证明目标主机不存在
import socket
import os
import struct
import threading
import time
#导入netaddr包处理子网ip地址
from netaddr import IPNetwork,IPAdress
from ctypes import *
#扫描主机号
host="192.168.65.133"
#扫描子网号
subnet="192.168.65.0/24"
magic_message="PYTHONRULES"
def udp_sender(subnet,magic_message):
time.sleep(5)
sender=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
for ip in IPNetwork(subnet):
try:
#发送数据到子网内所有主机
sender.sendto(magic_message,("%s" % ip,65212))
except:
pass
#对Ip数据报报头进行解析
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_uint32),
("dst",c_uint32)
]
def __new__(self,socket_buffer=None):
return self.from_buffer_copy(socket_buffer)
def __init__(self,socket_buffer=None):
self.protocol_map={1:"ICMP",6:"TCP",17:"UDP"}
self.src_address=socket.inet_ntoa(struct.pack("@I",self.src))
self.dst_address=socket.inet_ntoa(struct.pack("@I",self.dst))
try:
self.protocol=self.protocol_map[self.protocol_num]
except:
self.protocol=str(self.protocol_num)
#对ICMP报头进行解析
class ICMP(Structure):
_fields_=[
("type",c_ubyte),
("code",c_ubyte),
("checksum",c_ushort),
("unused",c_ushort),
("next_hop_mtu",c_ushort)
]
def __new__(self,socket_buffer):
return self.from_buffer_copy(socket_buffer)
def __init__(self,socket_buffer):
pass
if os.name =="nt":
#windows下允许嗅探到所有数据包
socket_protocol=socket.IPPROTO_IP
else :
#linux下只能嗅探到ICMP包,所以区分进行参数设置
socket_protocol=socket.IPPROTO_ICMP
#套接字初始化,选择使用原始套接字sock_RAW
sniffer=socket.socket(socket.AF_INET,socket.SOCK_RAW,socket_protocol)
sniffer.bind((host,0))
sniffer.setsockopt(socket.IPPROTO_IP,socket.IP_HDRINCL,1)
if os.name=="nt":
#发送IOCTL数据到网卡驱动上启动混杂模式,混杂模式下可以嗅探网卡上流经的所有数据包
sniffer.ioctl(socket.SIO_RCVALL,socket.RCVALL_ON)
#启动向子网发送数据报的线程
t = threading.Thread(target=udp_sender,args=(subnet,magic_message))
t.start()
try:
while True:
#读取接收内容
raw_buffer=sniffer.recvfrom(65565)[0]
#前20字节为ip数据报报头
ip_header=IP(raw_buffer[0:20])
print ("Protocol:%s %s ->%s"% (ip_header.protocol,ip_header.src_address,ip_header.dst_address))
if ip_header.protocol == "ICMP":
#得到ip数据报报头真实长度,作为偏移量
offset = ip_header.ihl*4
#取ip数据报报头之后的数据
buf=raw_buffer[offset:offset+sizeof(ICMP)]
icmp_header=ICMP(buf)
print "ICMP -> Type:%d Code:%d" % (icmp_header.type,icmp_header.code)
#code和type都为3的时候,是目标不可达信息
if icmp_header.code==3 and icmp_header.type==3:
if ipaddress(ip_header.src_address) in IPNetwork(subnet):
if raw_buffer[len(raw_buffer)-len(magic_message):]==magic_message:
print ("Host Up: %s" % ip_header.src_address)
except KeyboardInterrupt:
if os.name=="nt":
sniffer.ioctl(socket.SIO_RCVALL,socket.RCVALL_OFF)
错误:在windows下报错:OSError: [WinError 10013] 以一种访问权限不允许的方式做了一个访问套接字的尝试。
解决:以管理员方式运行
参考资料:《Python黑帽子 黑客与渗透测试编程之道》第三章
以上是关于网络嗅探的主要内容,如果未能解决你的问题,请参考以下文章