黑客与解密python_《python黑帽子:黑客与渗透测试编程之道》学习笔记(第三章)...

这篇文章记录《python黑帽子:黑客与渗透测试编程之道》第三章的学习笔记。这张讲了原始套接字和流量嗅探。

Windows和Linux上的包嗅探

这一部分是写了一个很简单的嗅探工具,用于发现目标网络中存活的主机。

# -*- coding:utf-8 -*-

import socket

import os

# 监听的主机

host = "192.168.1.105"

# 创建原始套接字,然后绑定在公开接口上

if os.name == "nt": # 判断现在正在使用的平台,Windows 返回 ‘nt'; Linux 返回’posix'

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))

# 设置在捕获的的数据包中包含IP头

sniffer.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)

# 在Windows平台上,我们需要设置IOCTL以启动混杂模式

if os.name == "nt":

sniffer.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON)

# 读取单个数据包

print(sniffer.recvfrom(65565))

# 在Windows平台上关闭混杂模式

if os.name == "nt":

sniffer.ioctl(socket.SIO_RCVALL, socket.RCVALL_OFF)

运行脚本

解码IP层

sniffer_ip_header_decode.py

# -*- coding:utf-8 -*-

import socket

import os

import struct

from ctypes import *

# 监听的主机

host = "192.168.1.105"

# 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_ulong),

("dst", c_ulong)

]

def __new__(self, socket_buffer=None):

return self.from_buffer_copy(socket_buffer) #https://docs.python.org/3.8/library/ctypes.html

def __init__(self, socket_buffer=None):

# 协议字段与协议名称对应

self.protocol_map = {1: "ICMP", 6: "TCP", 17: "UDP"}

# 可读性更强的IP地址

self.src_address = socket.inet_ntoa(struct.pack("

self.dst_address = socket.inet_ntoa(struct.pack("

# 协议类型

try:

self.protocol = self.protocol_map[self.protocol_num]

except:

self.protocol = str(self.protocol_num)

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))

sniffer.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)

if os.name == "nt":

sniffer.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON)

try:

while True:

# 读取数据包

raw_buffer = sniffer.recvfrom(65565)[0]

print(raw_buffer)

# 将缓冲区的前20个字节按IP头进行解析

ip_header = IP(raw_buffer[0:20])

# 输出协议和通信双方IP地址

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

# 处理CTRL-C

except KeyboardInterrupt:

# 如果运行在Windows上,关闭混杂模式

if os.name == "nt":

sniffer.ioctl(socket.SIO_RCVALL, socket.RCVALL_OFF)

有udp的包

有tcp的包

解码ICMP

这部分代码是在上段代码的基础上添加上对ICMP的处理。

# -*- coding:utf-8 -*-

import socket

import os

import struct

from ctypes import *

import threading

import time

from netaddr import IPNetwork,IPAddress

# 监听的主机

host = "192.168.1.105"

#host = "10.11.144.106"

#扫描的目标子网

subnet = "192.168.1.0/24"

# 自定义的字符串,我们将在ICMP响应中进行核对

magic_message = b"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_ulong),

("dst", c_ulong)

]

def __new__(self, socket_buffer=None):

return self.from_buffer_copy(socket_buffer) # https://docs.python.org/3.8/library/ctypes.html

def __init__(self, socket_buffer=None):

# 协议字段与协议名称对应

self.protocol_map = {1: "ICMP", 6: "TCP", 17: "UDP"}

# 可读性更强的IP地址

self.src_address = socket.inet_ntoa(struct.pack("

self.dst_address = socket.inet_ntoa(struct.pack("

# 协议类型

try:

self.protocol = self.protocol_map[self.protocol_num]

except:

self.protocol = str(self.protocol_num)

class ICMP(Structure):

_fields_ = [

("type", c_ubyte),

("code", c_ubyte),

("checksum", c_ushort),

("unused", c_ushort),

("next_hop_mtu", c_ushort)

]

def __new__(cls, socket_buffer):

return cls.from_buffer_copy(socket_buffer)

def __init__(cls, socket_buffer):

pass

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))

sniffer.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)

if os.name == "nt":

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])

# 输出协议和通信双方IP地址

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

# 如果为ICMP,进行处理

if ip_header.protocol == "ICMP":

# 计算ICMP包的起始位置

offset = ip_header.ihl * 4

buf = raw_buffer[offset:offset + sizeof(ICMP)]

# 解析ICMP数据

icmp_header = ICMP(buf)

#print("ICMP -> Type: %d Code: %d" % (icmp_header.type, icmp_header.code))

# 检查类型和代码是否为3

if icmp_header.code == 3 and icmp_header.type == 3:

# 确认响应的主机在我们的目标子网之内

if IPAddress(ip_header.src_address) in IPNetwork(subnet):

# 确认icmp数据中包含我们发送的自定义的字符串

if raw_buffer[len(raw_buffer) - len(magic_message):] == magic_message:

print("Host Up: %s" % ip_header.src_address)

# 处理CTRL-C

except KeyboardInterrupt:

# 如果运行在Windows上,关闭混杂模式

if os.name == "nt":

sniffer.ioctl(socket.SIO_RCVALL, socket.RCVALL_OFF)

扫了半天只扫到本机

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值