Bootstrap

python渗透工具编写学习笔记:2、数据包监听/解析结构/劫持

前言

    我们在信息网络中,常通过发送与接受数据包来完成通信,今天我们来学习这些数据包是如何构造的、各类数据包有什么功能与差异?我们能利用数据包做什么?初出茅庐,如有错误望各位不吝赐教。

2.1 概念

    数据包是网络通信中的基本单位,它是一段二进制数据,包含了从源到目标的传输信息。数据包通常由几个部分组成,包括头部、数据和尾部,其中头部包含了一些关键信息,如源地址、目标地址、协议类型、校验和等等。

在互联网中,数据包是通过协议栈的层次化结构传输的。在每一层次中,数据包被添加上该层次的头部信息以标识该层次的功能和需求,然后再发送到下一层。在接收端,数据包按照相同的顺序从下往上逐层解包,并按照相应的协议处理和分发。

数据包的大小通常受限于网络的带宽和MTU(最大传输单元),如果数据包太大超过了MTU,则需要进行分片,将其分解为多个较小的数据包,以便传输和重新组装。

2.2 Scapy基本用法

    Scapy,目前许多优秀的网络扫描和攻击工具都使用到了这个模块。它可以实现对网络数据包的发送、监听和解析。我们先来学习一下构造所有数据包都要使用的方法:

1、创建一个数据包

在Scapy中创建一个数据包非常简单。只需要使用Packet()函数或者自定义一个继承自Packet的类:

from scapy.all import *

packet = IP(dst="8.8.8.8")/ICMP()

创建一个目的地址为“8.8.8.8”的IP数据包,并将其与ICMP数据包合并。

2、发送一个数据包

发送一个数据包可以使用send()函数:

send(packet)

发送创建的IP/ICMP数据包。

3、接收一个数据包

接收一个数据包可以使用sr()或sr1()函数。sr()函数将返回接收到的数据包列表,而sr1()函数将返回第一个接收到的数据包:

response = sr1(packet)

发送创建的IP/ICMP数据包,并返回响应数据包。

4、解析一个数据包:

解析一个数据包可以使用Python的切片操作或Scapy提供的函数来访问数据包的每个字段。例如:

print(packet[IP].dst)

这将打印IP数据包的目的地址。

修改一个数据包:

可以使用Python的切片操作或Scapy提供的函数来修改数据包的每个字段:

packet[IP].dst = "1.1.1.1"

将IP数据包的目的地址更改为“1.1.1.1”。

2.3 IP数据包

    IP数据包是在互联网协议(IP)中传输数据的基本单位。它是一种在网络上进行通信的数据包,其中包含了源IP地址、目标IP地址和数据负载等信息。注意:IP数据包是通过传输控制协(TCP)或用户数据报协议(UDP)等协议在网络上进行传输的。正因如此我们就需要用到scapy中一个非常重要的概念——多层协议组合。

scapy中的分层通过符号“/”实现,如下我们构建一个设置了IP与TCP确定参数的数据包:

from scapy.all import *

# 构建IP和TCP协议层
ip_pkt = IP(src="192.168.0.1", dst="192.168.0.2")
tcp_pkt = TCP(sport=1234, dport=80)

# 组合多个协议层
pkt = ip_pkt/tcp_pkt/Raw(b"Hello, World")

# 发送数据包
send(pkt)
 

但要是如果不需要确定的TCP参数,还能发送IP数据包吗?当然也是可以的:

from scapy.all import *

# 创建IP数据包
ip_packet = IP(src='192.168.1.1', dst='192.168.1.2')

# 显示IP数据包头信息
print(ip_packet.show())

# 发送IP数据包
send(ip_packet)
 

2.4 HTTP数据包

    HTTP(Hyper Text Transfer Protocol)数据包是一种用于在Web服务器和Web浏览器之间传输数据的协议。HTTP数据包由两部分组成:请求和响应。

请求由以下组成:

  • 请求行:包含请求方法(GET、POST、PUT、DELETE等)、请求URI(Uniform Resource Identifier)和HTTP协议版本号。
  • 请求头部:包含一些元数据,如请求的主机、语言、缓存等。
  • 请求正文:包含具体的数据(如表单提交的数据、上传的文件等)。

响应由以下组成:

  • 状态行:包含HTTP协议版本号、状态码和状态短语。
  • 响应头部:包含一些元数据,如服务器版本、响应的类型、长度等。
  • 响应正文:包含具体的数据,如HTML文档、图片等。

HTTP数据包是通过TCP/IP协议进行传输的,可以用一些抓包工具(如Wireshark)进行捕获和分析。接下来我们来学习使用scapy来构造HTTP数据包:

使用Scapy构造HTTP数据包需要以下步骤:

1、导入Scapy库

from scapy.all import *

2、构造IP和TCP数据包

ip = IP(dst="www.example.com")
tcp = TCP(dport=80, sport=RandShort())

3、构造HTTP请求数据包

http_request = "GET / HTTP/1.1\r\nHost: www.example.com\r\n\r\n"

4、将HTTP请求数据包添加到TCP负载中

pkt = ip/tcp/http_request

5、发送数据包

send(pkt)

完整代码示例:

from scapy.all import *

ip = IP(dst="www.example.com")
tcp = TCP(dport=80, sport=RandShort())
http_request = "GET / HTTP/1.1\r\nHost: www.example.com\r\n\r\n"
pkt = ip/tcp/http_request

send(pkt)

2.5 ICMP数据包

    ICMP (Internet Control Message Protocol) 数据包是用于在互联网上发送错误消息和操作控制消息的协议。 ICMP 数据包通常用于网络故障排除和网络管理。它包含以下字段:

  • 类型 (Type):用于标识 ICMP 数据包的类型,例如差错报告或操作控制消息。
  • 代码 (Code):用于提供与类型字段相关的详细信息。
  • 校验和 (Checksum):用于检测 ICMP 数据包是否损坏。
  • 其他 (其他):包含与 ICMP 数据包类型和代码相关的其他信息,例如差错报告中的 IP 报头。

 构造ICMP数据包的示例代码:

from scapy.all import *

icmp_packet = IP(dst="192.168.1.1")/ICMP()/"Hello World!"
send(icmp_packet)

创建一个ICMP数据包,并将其发送到目标IP地址为“192.168.1.1”的主机上。ICMP数据包中包含了一个字符串消息“Hello World!”。构造ICMP数据包的过程包括创建一个IP层和一个ICMP层,使用“/”运算符将它们连接起来,并使用send()函数将数据包发送出去。

也可以通过添加其他数据包头来构造不同类型的ICMP数据包:

icmp_packet = IP(dst="192.168.1.1")/ICMP(type=8,code=0)/Raw(load="Ping!")

这个代码片段创建了一个类型为8、代码为0的ICMP数据包,并将一个原始数据载荷添加到其中。原始数据载荷使用Raw类来表示,并使用load属性设置其内容。

在构造ICMP数据包时,还可以添加其他选项和参数:

icmp_packet = IP(dst="192.168.1.1")/ICMP(type=8,code=0)/Raw(load="Ping!")
icmp_packet.show()

这个代码片段使用show()函数来显示ICMP数据包的详细信息,包括各个字段的值和选项。可以使用这些信息来检查和调试生成的数据包。

2.6 Ether

Ether类是Scapy中的一个重要类,用于处理以太网帧(Ethernet Frame)。

下面是Ether类的一些常用属性和方法:

属性:

  • dst:目的MAC地址
  • src:源MAC地址
  • type:以太网类型,常用类型有0x0800(IPv4)、0x0806(ARP)、0x86dd(IPv6)

方法:

  • show():显示以太网帧的信息
  • summary():显示以太网帧的摘要信息
  • str():以字符串形式打印以太网帧的详细信息

下面是一个使用Ether类创建以太网帧的示例:

from scapy.all import *

ether = Ether(dst='00:11:22:33:44:55', src='aa:bb:cc:dd:ee:ff', type=0x0800)
packet = ether/IP(dst='192.168.1.1')/TCP(dport=80)
send(packet)

我们首先创建了一个以太网帧对象,指定目的MAC地址、源MAC地址和以太网类型,然后创建了一个IP数据包对象,指定目的IP地址和TCP端口号,最后将IP数据包封装在以太网帧中并发送。

 实战训练   

    学了这么多,我们来综合练习一下吧,解决开头我们问到的最后一个问题:我们能利用数据包做什么?

1、监控网络流量并打印出所有数据包的源地址和目标地址:

from scapy.all import *

def print_packet(packet):
    print("Source: {}, Destination: {}".format(packet[IP].src, packet[IP].dst))

sniff(prn=print_packet)

2、仅监控指定源地址或目标地址的数据包:

from scapy.all import *

def print_packet(packet):
    if packet[IP].src == '192.168.1.1' or packet[IP].dst == '192.168.1.1':
        print("Source: {}, Destination: {}".format(packet[IP].src, packet[IP].dst))

sniff(prn=print_packet)

3、监控所有数据包并劫持HTTP请求:

from scapy.all import *

def process_packet(packet):
    if packet.haslayer(HTTPRequest):
        url = packet[HTTPRequest].Host + packet[HTTPRequest].Path
        print("[+] HTTP Request => " + url)

sniff(filter="port 80", prn=process_packet, store=False)

4、监控所有数据包并劫持DNS请求:

from scapy.all import *

def process_packet(packet):
    if packet.haslayer(DNSQR):
        query = packet[DNSQR].qname
        print("[+] DNS Request => " + query)

sniff(filter="udp port 53", prn=process_packet, store=False)
 

就是这样!将它们综合,这里的sniff()函数进行数据包嗅探,可以指定嗅探的网卡、嗅探的数据包数量、过滤条件等参数。

以后我们将一起来制作第一款渗透工具(在将要用到的技术学习完后)让我们拭目以待吧!

;