【问题标题】:Python Scapy RTP header manipulation - how can I decode RTP in scapy?Python Scapy RTP 标头操作 - 如何在 scapy 中解码 RTP?
【发布时间】:2018-08-31 08:43:13
【问题描述】:

我需要在 PACP 文件中编辑 2 个 RTP 标头字段。

我想编辑RTP timestamp 字段和SSRC 字段。这样我就可以使用tcpreplay 操作一些捕获以进行回放,以测试终端设备,原因有两个。

使用 Python REPL 我可以加载文件:

from scapy.all import rdpcap
pkts_list = rdpcap("foo.pcap")

我得到文件的长度

len(pkts_list)

然后我可以检查一个数据包

pkts_list[xxx].show()

如何/我可以解码/查看 RTP 标头信息?抱歉,scapy docs 对我来说有点想这个。

提前致谢

尼尔

【问题讨论】:

  • 我认为 RTP(pkts_list[xxx]).timestamp 可能是一个开始......但我得到的结果对于在wireshark中它们正在递增的每个数据包都是相同的......
  • 好的一些进展RTP(pkts_list[xxx]['UDP'].payload).timestamp 让我到了那里......现在唯一的问题是努力将索引中的列表设置为新值。 RTP(pkts_list[xxx]['UDP'].payload).timestamp = 0 不这样做..

标签: python scapy rtp


【解决方案1】:

RTP(pkts_list[xxx]['UDP'].payload).timestamp 做了一些尝试和错误

我的另一个问题与 python 相关,我会在其他地方问。

更新:

发布我用于操作 RTP 标头的完整代码,因为它需要大量的试验和错误以及非常小的信息来对其进行排序......这是一个 hack,但它有效,可能对其他人有所帮助。

### Python 2.7 Script by Neil Bernard neil@themoog.org
## This script is for editing RTP header information in PCAP files to manipulate RTP timestamp and SSRC
## for testing hardware transport stream devices and testing SMPTE 2022-2 handling

## There is some error checking for scapy network layers but try to keep capture as clean as possible
## also try to keep captures under 260Mb for performance, can take a good 20mins on an intel i7 / 16GB ram

#### Basic Scapy Tutorial

# *https://www.youtube.com/watch?v=ADDYo6CgeQY

#### Scapy cheat sheet

# https://blogs.sans.org/pen-testing/files/2016/04/ScapyCheatSheet_v0.2.pdf

#### Scapy RTP Library https://fossies.org/linux/scapy/scapy/layers/rtp.py

# import scapy
from scapy.all import rdpcap
from scapy.all import wrpcap
from scapy.all import RTP
from scapy.all import *

infile = "test_rtp.pcap"
outfile = "modified_" + infile
dest_port = 2000 # usefull to make sure you only action packets that are RTP

# load packet capture
print "Loading Packet Capture Keep <200Mb - Might take a few mins....."
pl = rdpcap(infile)
print "Loading complete!"

# print number of packets
print(len(pl))
# # print rtp timestamp
# print(RTP(pl[0][UDP].payload).timestamp)
numberofpckts = len(pl)

print numberofpckts

for pkt in range(numberofpckts):

    # You cant use the [RTP] layer on a list index so you have to put it in a
    # variable first. Also need to make sure its a UDP packet with .haslayer(UDP):
    # https://stackoverflow.com/questions/48763072/scapy-getting-trailer-field-in-the-dissector

    if pl[pkt].haslayer(UDP):
        packet = pl[pkt][UDP]

    else:
        print "Probably Not a UDP / RTP Packet# {0}".format(pkt)


    # You need to do the line below to force RTP detection and manipulation
    # https://stackoverflow.com/questions/44724186/decode-rtp-over-udp-with-scapy

    if pl[pkt].haslayer(UDP):
        if packet["UDP"].dport==2000: # Make sure its actually RTP
            packet["UDP"].payload = RTP(packet["Raw"].load)

        #### un-commment and change lines below to manipulate headers

            # packet[RTP].version = 0
            # packet[RTP].padding = 0
            # packet[RTP].extension = 0
            # packet[RTP].numsync = 0
            # packet[RTP].marker = 0
            # packet[RTP].payload_type = 0
            # packet[RTP].sequence = 0

            # packet[RTP].timestamp = 0

            packet[RTP].sourcesync = 0
            # packet[RTP].sync = 0

            ### Calculate UDP Checksum or they will now be wrong!

            #https://scapy.readthedocs.io/en/latest/functions.html

            checksum_scapy_original = packet[UDP].chksum

            # set up and calculate some stuff

            packet[UDP].chksum = None ## Need to set chksum to None before starting recalc
            packetchk = IP(raw(packet))  # Build packet (automatically done when sending)
            checksum_scapy = packet[UDP].chksum
            packet_raw = raw(packetchk)
            udp_raw = packet_raw[20:]
            # in4_chksum is used to automatically build a pseudo-header
            chksum = in4_chksum(socket.IPPROTO_UDP, packetchk[IP], udp_raw)  # For more infos, call "help(in4_chksum)"

            # Set the new checksum in the packet

            packet[UDP].chksum = checksum_scapy # <<<< Make sure you use the variable in checksum_scapy

            # needed below to test layers before printing newts/newsourcesync etc to console

            if pl[pkt].haslayer(UDP):
                newts = RTP(pl[pkt][UDP].payload).timestamp
                newsourcesync = RTP(pl[pkt][UDP].payload).sourcesync

            else:
                newts = 999
                newsourcesync = 999

            print("Changing packet {0} of {3} to new timestamp {1} SSRC {2} Old UDP chksum {4} >> New UDP chksum ???").format(pkt+1,newts,newsourcesync,numberofpckts,hex(checksum_scapy_original))

        else:
            print "Probably Not a UDP / RTP Packet# {0}".format(pkt)

# Write out new capture file
wrpcap(outfile, pl)

【讨论】:

    【解决方案2】:

    你可以使用这个命令来写一个 rtp 头包。但是你试图在 pcap 中写入这个数据包。你会看到这个错误:

    TypeError: clone_with() 为关键字参数获取了多个值 “有效载荷”

    因此你在写数据包之前必须改变 scapy/packet.py 库。这个链接解释得更好:

    https://github.com/CJTozer/scapy/commit/d0367f2efa86e65fa2b0a82a864b7fe89222f153

    【讨论】:

    猜你喜欢
    • 2017-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-10
    • 1970-01-01
    • 2014-10-11
    相关资源
    最近更新 更多