Python 3.x Python3从字符串中跳过自定义负载 简介

Python 3.x Python3从字符串中跳过自定义负载 简介,python-3.x,network-programming,scapy,Python 3.x,Network Programming,Scapy,我正在使用python3和scapy修改并重新发送捕获的数据包 问题 当我在原始部分发送修改后的有效负载时,\r和\n消息部分不会被解释为特殊字符。相反,它们作为字符串包含,如下面的cmd和wireshark屏幕截图所示 当前有效载荷 预期有效载荷 这是网络上捕获的正确数据包格式。 wireshark中显示的数据包如下所示: SIP/2.0 486此处忙 Via:SIP/2.0/UDP 192.168.1.5:5060;分支=z9hG4bK226016822;接收=192.168.1.5;

我正在使用python3和scapy修改并重新发送捕获的数据包

问题 当我在原始部分发送修改后的有效负载时,\r和\n消息部分不会被解释为特殊字符。相反,它们作为字符串包含,如下面的cmd和wireshark屏幕截图所示

当前有效载荷

预期有效载荷 这是网络上捕获的正确数据包格式。

wireshark中显示的数据包如下所示:

SIP/2.0 486此处忙 Via:SIP/2.0/UDP 192.168.1.5:5060;分支=z9hG4bK226016822;接收=192.168.1.5;rport=5060 发件人:sip:301@192.168.1.2;标签=2032604445 致:sip:300@192.168.1.2;标签=as1b0290be 电话号码:338695025 CSeq:21邀请 服务器:星号PBX 16.10.0 允许:邀请、确认、取消、选项、再见、参考、订阅、通知、信息、发布、消息 支持:替换、定时器 X-星号-挂断原因:呼叫被拒绝 X-星号-挂起原因代码:21 内容长度:0

代码 这是迄今为止的代码:

from scapy.all import sniff, Ether, IP, UDP, sendp, ICMP, rdpcap,Raw
import scapy.fields
import re
import codecs
import argparse

def traffic_parser(packet):
    BUSY_1 = 'SIP/2.0 486 Busy Here'
    BUSY_2 = 'X-Asterisk-HangupCause: Call Rejected\\\\r\\\\nX-Asterisk-HangupCauseCode: 21'

    payload = packet[3].command()
    print(bytes(payload))

    header=re.findall("Ringing", payload)
    if header:
        
        eth_attributes={}
        eth_attributes['dst']=packet[0].dst
        eth_attributes['src']=packet[0].src
        eth_attributes['type']=packet[0].type
        
        eth = Ether_layer(eth_attributes)


        udp_attributes={}
        udp_attributes['sport']=packet[2].sport
        udp_attributes['dport']=packet[2].dport
        udp_attributes['len']=444
    
        udp = UDP_layer(udp_attributes)

        # Implement packet modification
        payload = payload.replace("SIP/2.0 180 Ringing", BUSY_1, 1)
        payload = re.sub("Contact\:.*>", BUSY_2, payload,1)
        payload = payload.replace("Raw(load=b\'", '', 1)
        payload = re.sub("\'\)$", '', payload, 1)

        for incr in range(1,5):
            ip_attributes={}
            ip_attributes['version']=packet[1].version
            ip_attributes['tos']=packet[1].tos
            ip_attributes['len']=464 
            ip_attributes['id']=0 #Zero is handled by scapy on send by default
            ip_attributes['flags']=packet[1].flags
            ip_attributes['frag']=packet[1].frag
            ip_attributes['ttl']=packet[1].ttl
            ip_attributes['proto']=packet[1].proto
            ip_attributes['src']=packet[1].src
            ip_attributes['dst']=packet[1].dst

            ip = IP_layer(ip_attributes)

            sendp(eth/ip/udp/Raw(load=payload))

            print(payload)
            print(Raw(load=payload))
            print("\n")

def Ether_layer(attributes):
    layer2=Ether()
    layer2.dst=attributes['dst']
    layer2.src=attributes['src']
    layer2.type=attributes['type']

    return layer2


def IP_layer(attributes):
    layer3=IP()
    layer3.version=attributes['version']
    layer3.tos=attributes['tos']
    layer3.len=attributes['len']
    layer3.id=attributes['id']
    layer3.flags=attributes['flags']
    layer3.frag=attributes['frag']
    layer3.ttl=attributes['ttl']
    layer3.proto=attributes['proto']
    layer3.src=attributes['src']
    layer3.dst=attributes['dst']

    return layer3


def UDP_layer(attributes):
    layer4=UDP()
    layer4.sport=attributes['sport']
    layer4.dport=attributes['dport']
    layer4.len=attributes['len']

    return layer4


parser = argparse.ArgumentParser(description="rtp replay script. Arguments: -i <interface> -f <sniff filter> -o <sniff outputfile> Interface defaults to 'eth0' and filter defaults to 'udp and port 5060'")
parser.add_argument('-i', "--interface", default="eth0", help="interface to use for sniffing")
parser.add_argument('-f', '--filter', default="udp and port 5060", help="filter to be used in scapy")
parser.add_argument('-o', "--outfile", help="output file (optional)")
parser.add_argument('-t', "--testfile", help="parse test file (optional)")
args=parser.parse_args()

if __name__ == '__main__':

    if args.testfile:
        packets = rdpcap(args.testfile)
        for packet in packets:
            traffic_parser(packet)
    else:
        sniff(iface=args.interface, prn=traffic_parser, filter="udp and port 5060", store=0)
来自scapy.all导入嗅探、以太、IP、UDP、sendp、ICMP、rdpcap、原始
导入scapy.fields
进口稀土
导入编解码器
导入argparse
def流量分析器(数据包):
忙_1='SIP/2.0 486此处忙'
忙\u 2='X星号挂起原因:呼叫被拒绝\\\\r\\\nX星号挂起原因代码:21'
有效负载=数据包[3]。命令()
打印(字节(有效负载))
标题=关于findall(“振铃”,有效载荷)
如果标题为:
eth_属性={}
eth_属性['dst']=数据包[0]。dst
eth_属性['src']=数据包[0]。src
eth_属性['type']=数据包[0]。类型
eth=乙醚层(乙醚层属性)
udp_属性={}
udp_属性['sport']=数据包[2]。运动
udp_属性['dport']=数据包[2]。dport
udp_属性['len']=444
udp=udp\U层(udp\U属性)
#实现包修改
有效载荷=有效载荷。更换(“SIP/2.0 180振铃”,忙_1,1)
有效载荷=re.sub(“联系人\:.*>”,忙2,有效载荷,1)
有效载荷=有效载荷。替换(“原始(载荷=b\”,“”,1)
有效载荷=re.sub(“\”\)$”,“”,有效载荷,1)
对于范围(1,5)内的增量:
ip_属性={}
ip_属性['version']=数据包[1]。版本
ip_属性['tos']=数据包[1]。tos
ip_属性['len']=464
ip_属性['id']=0#默认情况下,在发送时由scapy处理零
ip_属性['flags']=数据包[1]。标志
ip_属性['frag']=数据包[1]。frag
ip_属性['ttl']=数据包[1]。ttl
ip_属性['proto']=数据包[1]。proto
ip_属性['src']=数据包[1]。src
ip_属性['dst']=数据包[1]。dst
ip=ip_层(ip_属性)
sendp(eth/ip/udp/Raw(负载=有效负载))
打印(有效载荷)
打印(原始(负载=有效负载))
打印(“\n”)
def乙醚_层(属性):
第2层=乙醚()
layer2.dst=属性['dst']
layer2.src=属性['src']
layer2.type=属性['type']
返回层2
def IP_层(属性):
第3层=IP()
layer3.version=属性['version']
layer3.tos=属性['tos']
layer3.len=属性['len']
layer3.id=属性['id']
layer3.flags=属性['flags']
layer3.frag=属性['frag']
layer3.ttl=属性['ttl']
layer3.proto=属性['proto']
layer3.src=属性['src']
layer3.dst=属性['dst']
返回层3
def UDP_层(属性):
layer4=UDP()
layer4.sport=属性['sport']
layer4.dport=属性['dport']
layer4.len=属性['len']
返回层4
parser=argparse.ArgumentParser(description=“rtp replay script.Arguments:-i-f-o接口默认为'eth0',过滤器默认为'udp和端口5060')
parser.add_参数('-i',“--interface”,default=“eth0”,help=“用于嗅探的接口”)
parser.add_参数('-f','-filter',default=“udp和端口5060”,help=“要在scapy中使用的过滤器”)
add_参数('-o',“--outfile”,help=“输出文件(可选)”)
parser.add_参数('-t',“--testfile”,help=“parse test file(可选)”)
args=parser.parse_args()
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
如果args.testfile:
packets=rdpcap(args.testfile)
对于分组中的分组:
流量分析器(数据包)
其他:
嗅探(iface=args.interface,prn=traffic\u解析器,filter=“udp和端口5060”,store=0)
Q 如何以所需的形式连接有效负载

编辑: 此pcap文件可用于测试

i指示脚本执行:
sudo python byespam.py-t

\r
\n
被解释为文本字符串,因为您已经对它们进行了转义

这是您的字符串:

>>> BUSY_2 = 'X-Asterisk-HangupCause: Call Rejected\\\\r\\\\nX-Asterisk-HangupCauseCode: 21'
>>> print(BUSY_2)
X-Asterisk-HangupCause: Call Rejected\\r\\nX-Asterisk-HangupCauseCode: 21
这是相同的字符串,但没有转义:

>>> BUSY_2 = 'X-Asterisk-HangupCause: Call Rejected\r\nX-Asterisk-HangupCauseCode: 21'
>>> print(BUSY_2)
X-Asterisk-HangupCause: Call Rejected
X-Asterisk-HangupCauseCode: 21

为了能够将负载用作字符串,您需要将其转换为字符串,并确保编码正确

在您的情况下,您应该:

  • 您应该只从scapy.packet.packet获取原始数据的加载部分
  • 将加载部分编码为UTF-8,以便Python正确解释特殊字符
  • 以下是一些适用于您的案例的工作代码:

    payload = packet[UDP].payload.load *
    payload = payload.decode("utf-8")
    
    然后,您可以打印有效负载,它将得到“正确”的解释


    *我使用UDP是因为在脚本和pcapng文件中只有UDP数据包。如果存在TCP数据包,您应该使用
    payload=packet[TCP].payload.load

    ,这对于我要交换的字符串部分是正确的。但正如您在Wireshark屏幕截图上看到的,从原始数据包中提取的剩余有效负载包括原始形式的
    \r
    \n
    字符。