Black Hat Python书中的Python嗅探

Four_0h_Three:
import socket
import os
import struct
import sys
from ctypes import *

# host to listen on
host   = sys.argv[1]

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("<L",self.src))
        self.dst_address = socket.inet_ntoa(struct.pack("<L",self.dst))

        # human readable protocol
        try:
            self.protocol = self.protocol_map[self.protocol_num]
        except:
            self.protocol = str(self.protocol_num)

# create a raw socket and bind it to the public interface
if os.name == "nt":
    socket_protocol = socket.IPPROTO_IP 
else:
    socket_protocol = socket.IPPROTO_ICMP

sniffer = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket_protocol)

sniffer.bind((host, 0))

# we want the IP headers included in the capture
sniffer.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)

# if we're on Windows we need to send some ioctls
# to setup promiscuous mode
if os.name == "nt":
    sniffer.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON)

try:
    while True:

        # read in a single packet
        raw_buffer = sniffer.recvfrom(65565)[0]

        # create an IP header from the first 20 bytes of the buffer
        ip_header = IP(raw_buffer[0:20])

        print "Protocol: %s %s -> %s" % (ip_header.protocol, ip_header.src_address, ip_header.dst_address)

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》一书的代码。该代码应与原始套接字一起嗅探并显示IP标头中的信息。在Windows(使用Windows 8.1 64位)上对我来说效果很好。当我尝试在Linux(Kali linux 1.1.0-amd64)上运行此命令时,出现以下错误

ValueError: Buffer size too small (20 instead of at least 32 bytes)

为了解决这个问题,我像这样向缓冲区添加了12个空格

ip_header = IP(raw_buffer[0:20]+' '*12)

当我这样做时,出现以下错误

struct.error: 'L' format requires 0 <= number <= 4294967295

这发生在线

self.src_address = socket.inet_ntoa(struct.pack("<L",self.src))

我尝试将L之前的符号更改为>和!我只用L就尝试了,所有人都给我同样的问题。我也尝试将self.src包裹在ntohs中,就像这样

self.src_address = socket.inet_ntoa(struct.pack("<L",socket.ntohs(self.src)))

我认为这与字节序有关,但我不确定。任何帮助将不胜感激。

注意:由于原始套接字,在Windows上必须以管理员身份运行,而在Linux上则必须以超级用户身份运行。如果您在Linux上运行此命令,请打开另一个终端并ping www.google.com,以便可以生成一些ICMP数据包以供捕获。

编辑:我也尝试过反转缓冲区

ip_header = IP(raw_buffer[0:20][::-1]+' '*12)

编辑2:在做任何其他我在这里列出的项目之前,我确实在下面的行中尝试了65535和65534。

raw_buffer = sniffer.recvfrom(65565)[0]

编辑3:这在运行python 2.7.6的ubuntu机器上工作,而我的kali发行版是2.7.3,所以我决定在我的kali盒上获得最新版本的python,恰好是2.7.9。仍然没有运气。

我将以下代码放置到结构中函数中,以查看缓冲区大小

print sizeof(self)

在我的Ubuntu和Windows机器上是20,但是在我的kali机器上是32

尼扎姆·穆罕默德(Nizam Mohamed):
#raw_buffer = sniffer.recvfrom(65565)[0]
raw_buffer = sniffer.recvfrom(65535)[0]

IP大小为(2 ^ 16)-1

问题出在32位和64位系统上。
ip_header = IP(raw_buffer[:20])在x86 Ubuntu上工作。
ip_header = IP(raw_buffer[:32])适用于amd64 CentOS 6.6 Python 2.6.6
ip_header = IP(raw_buffer)均可同时使用。

你必须改变这些,

("src",           c_ulong),
("dst",           c_ulong)  

self.src_address = socket.inet_ntoa(struct.pack("<L",self.src))
self.dst_address = socket.inet_ntoa(struct.pack("<L",self.dst))

进入

("src",           c_uint32),
("dst",           c_uint32)  

self.src_address = socket.inet_ntoa(struct.pack("@I",self.src))
self.dst_address = socket.inet_ntoa(struct.pack("@I",self.dst))

“ @I”是按本机顺序进行单符号化的int。因为c_ulong在i386中是4个字节,在amd64中是8个字节。检查以下内容,

struct.calcsize('@BBHHHBBHLL')  

在i386中为20,在amd64中为32,其大小为_fields_实际上,它是amd64中的28个字节,外加4个字节以进行字对齐。

ip_header = IP(raw_buffer[:20]) 现在可以独立于平台正常工作。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

来自分类Dev

没有根的Python Scapy嗅探

来自分类Dev

Python在特定条件下停止嗅探

来自分类Dev

在Python Elasticsearch Client中使用嗅探来解决无效的TCP连接问题

来自分类Dev

python中的BPF嗅探多个TCP端口的数据包

来自分类Dev

当scapy和pypcap严重丢失时,如何在python上嗅探所有数据包?

来自分类Dev

EF 6参数嗅探

来自分类Dev

Scapy可变嗅探停止

来自分类Dev

嗅探Facebook与Wireshark聊天

来自分类Dev

BeagleBone Black冻结

来自分类Dev

Beaglebone Black上的GPIO

来自分类Linux

修改Beaglebone Black的设备树

来自分类Linux

复制相同的BeagleBone Black设置

来自分类Linux

如何远程登录Beaglebone Black

来自分类Dev

在Android中嗅探蓝牙低功耗

来自分类Dev

phpCS排除不起作用的嗅探

来自分类Java

Java RMI:需要嗅探器

来自分类Dev

Golang的原始套接字嗅探

来自分类Dev

嗅探/记录自己的Android蓝牙流量

来自分类Dev

表值参数的参数嗅探

来自分类Dev

如何在Red Hat 7上安装python3-devel

来自分类Dev

修复Beagle Bone Black的启动顺序/ eMMC

来自分类Dev

Beaglebone Black上的Cloud9密码

来自分类Dev

在Beaglebone Black上搜索MLO文件

来自分类Dev

BeagleBone Black(v4.14)上的PWM

来自分类Dev

在OSX上嗅探USB串行通信的方法

来自分类Dev

Scapy中的HTTP GET数据包嗅探器

来自分类Linux

Scapy中的嗅探功能的过滤器选项

来自分类Dev

使用logger.exe嗅探系统调用

来自分类Dev

Scapy-嗅探3个接口中的2个

TOP 榜单

热门标签

归档