how to add http headers to a packet sniffed using scapy
Asked Answered
P

1

7

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

Peephole answered 22/10, 2012 at 18:50 Comment(6)
This is a really high level thing to be trying to do with packet analysis tools. What if the HTTP headers are split between two (or more) packets?Cundiff
Agreed. But i can ignore it for the time being. A high performance real app would probably needed to be written in c. A POC with a basic test case would be fine.Peephole
@GregHewgill By the way do you have another tool in mind which does above while sniffing along live? I don't mean to modify a pcap.Peephole
Sure, if you want to add specific headers to an HTTP transaction, you should be using an HTTP proxy application instead of trying to fiddle with IP packets directly.Cundiff
A proxy application will craft a packet of it's own and forward it. It will contain source ip of the proxy, not the original sender. Then the proxy has to receive the response back too, and forward to the original sender. This incurs additional processing overhead on the proxy which i am trying to avoid.Peephole
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? So i can use the rest of the packet as it is.Peephole
S
6

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.

Selfhypnosis answered 25/10, 2012 at 13:53 Comment(1)
Thank you very much. I will try this out and get back to you if i have issues.Peephole

© 2022 - 2024 — McMap. All rights reserved.