how to add http headers to a packet sniffed using scapy

10,244

If I understand correctly, the problem you're having is that you want to update an existing HTTP request with a new header. What you want is to update a string in place, which Python can't do directly (strings are immutable).

So what you should do is take the HTTP header:

old_hdr = pkt[Raw] or old_hdr = pkt[TCP].payload

and manipulate it like a string:

new_hdr = 'New Header: value'
hdr = old_hdr.split('\r\n') # This is a crappy hack. Parsing HTTP headers
hdr.insert(new_hdr, 2)      # is a [solved problem][1].
send_hdr = '\r\n'.join(hdr)
pkt[TCP].payload = send_hdr

If you find checksums are not updating, delete them before sending the packet:

del pkt[TCP].chksum

and Scapy will put them back for you, with the right values.

Edit: I just noticed that my link is fail. Here is how to parse HTTP headers.

Share:
10,244
fkl
Author by

fkl

Software developer with Embedded and TCP/IP protocol development experience of over 10 years. Worked on carrier grade equipment involving multicore network processors as well as a variety of embedded platforms such as ARM, MIPS, PPC etc. Also worked on Cloud based DPI solutions. Have been programming in c for more than a decade along with several languages such as C++/Python/C# etc. Prior experience includes value added services for cellular networks involving SMPP protocol as well as streaming software. Have also been a free lancer for many years writing high performance applications and a good deal of open source software such as VLC, dnrd to name a few. More recently worked on cross platform online services (C++ and some erlang) powering AAA games. Previously worked at one of the major software communication platforms in the world.

Updated on July 12, 2022

Comments

  • fkl
    fkl almost 2 years

    I am trying to sniff an out going http packet using scapy, add a few new http headers in it and send it ahead. The intention here is to only insert new headers while keeping the packet intact. At max any checksum recalculation should be done if needed.

    Have been through almost all questions on SO but didn't exactly get a solution.

    Following is what i have done.

    def parse(pkt):
    
        if pkt.haslayer(TCP) and pkt.getlayer(TCP).dport == 80 and pkt.haslayer(Raw):
            pkt = pkt / "New Header:value\r\n\r\n"
    
            # OR i tried this
            #pkt = pkt.getlayer(Raw).load / Raw.load(load="New Header:value\r\n\r\n")
    
            #pkt.getlayer(Raw).load("New Header:value\r\n\r\n")
            pkt.show()
            #del pkt[IP].chksum
            send(pkt)
    #end parse function
    
    # start sniffing
    a=sniff(filter="tcp and ( port 80 )", prn=parse)
    

    The problem is that above code inserts a new raw payload section instead of adding a plain header. There is already a double newline \r\n\r\n to indicate header termination according to HTTP standard.

    To overcome this i tried removing the last \r\n by doing as follows

       #pkt = pkt.getlayer(Raw).load[-2:] / Raw.load(load="New Header:value\r\n\r\n")
    

    But this strips all of the previously existing headers and only the "New Header" remains.

    I have tried this on Linux mint.

    UPDATE: I am trying to create a new http payload which would contain previous headers and i will add some. Can some one help with how to removing an existing layer