Take the 2-minute tour ×

I'm trying to build a simple Scapy script which manually manages 3-way-handshake, makes an HTTP GET request (by sending a single packet) to a web server and manually manages response packets (I need to manually send ACK packets for the response).

Here is the beginning of the script:


import logging

# Import scapy
from scapy.all import *

# beginning of 3-way-handshake

TCP_SYN=TCP(sport=1500, dport=80, flags="S", seq=100, options=[('NOP', None), ('MSS', 1448)])

my_ack = TCP_SYNACK.seq + 1
TCP_ACK=TCP(sport=1500, dport=80, flags="A", seq=101, ack=my_ack)

TCP_PUSH=TCP(sport=1500, dport=80, flags="PA", seq=102, ack=my_ack)

# end of 3-way-handshake

# beginning of GET request

getString = 'GET / HTTP/1.1\r\n\r\n'
request = ip / TCP(dport=80, sport=1500, seq=103, ack=my_ack + 1, flags='A') / getString

# help needed from here...

The script above completes the 3-way-handshake and prepares the HTTP GET request.
Then, I've to send the request through:


Now, after the sending, I should obtain/manually read the response.
My purpose is indeed to read the response by manually sending the ACK packets of the response (this is the main focus of the script).

How can I do that?

Is the send(_) function appropriate, or it's better to use something like response = sr1(request) (but in this case, I suppose ACK are automatically sent)?

share|improve this question
add comment

2 Answers

Use sr(), read the data in from every ans that is received (you'll need to parse, as you go, the Content-Length or the chunk lengths depending on whether you're using transfer chunking) then send ACKs in response to the last element in the ans list, then repeat until the end criteria is satisfied (don't forget to include a global timeout, I use eight passes without getting any replies which is 2 seconds).

Make sure sr is sr(req, multi=True, timeout=0.25) or thereabouts. Occasionally as you loop around there will be periods where no packets turn up, that's why HTTP has all those length specs. If the timeout is too high then you might find the server gets impatient waiting for the ACKs and starts re-sending.

Note that when you're using transfer chunking you can also attempt to cheat and just read the 0\r\n\r\n but then if that's genuinely in the data stream... yeah. Don't rely on the TCP PSH, however tempting that may look after a few Wireshark sessions with trivial use-cases.

Obviously the end result isn't a completely viable user-agent, but it's close enough for most purposes. Don't forget to send Keep-Alive headers, RST on exceptions and politely close down the TCP session if everything works.

Remember that RFC 2616 isn't 176 pages long just for giggles.

share|improve this answer
add comment

Did you try:

responce = sr1(request)
print responce.show2

Also try using a different sniffer like wireshark or tcpdump as netcat has a few bugs.

share|improve this answer
add comment

Your Answer


