Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to add http headers to a packet sniffed using scapy

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

like image 877
fkl Avatar asked Oct 22 '12 18:10

fkl


1 Answers

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.

like image 80
nmichaels Avatar answered Sep 17 '22 05:09

nmichaels