0

I'm using python and scapy to send HTTP request to a specific URL address. After sending it, I want to read the response status code (200, 401, 404, etc.).

I used this method:

>>> syn = IP(dst='www.google.com') / TCP(dport=80, flags='S')
>>> syn_ack = sr1(syn)
>>> getStr = 'GET / HTTP/1.1\r\nHost: www.google.com\r\n\r\n'
>>> request = IP(dst='www.google.com') / TCP(dport=80, sport=syn_ack[TCP].dport, seq=syn_ack[TCP].ack, ack=syn_ack[TCP].seq + 1, flags='A') / getStr
>>> reply = sr1(request)

For some reason, I can't see it in "reply".

Thanks for helping!

Nick
  • 499
  • 4
  • 11
  • 25

2 Answers2

1

By using sr1(), you can only receive the first packet responded from server, in some cases an "empty" ACK to acknowledge the data you sent, so you cannot find the HTTP response and the response code. My suggestion is to use sr() instead of sr1(), as follows:

reply = sr(request, multi=1, timeout=2)

And this will receive all the packets including HTTP response arrived in 2 seconds, but you need to iterate over the reply packets to find the packet containing HTTP response code.

gkso
  • 513
  • 3
  • 12
  • You are confusing TCP and HTTP here, the ACK segment acknowledge a TCP segment which itself contains the HTTP request, it has no knowledge of application layer. The ACK could be sent in the same segment than the HTTP response so your statement is wrong, (i.e. "always" should be removed). – Jeff Bencteux May 27 '16 at 15:37
  • Thanks, Jeff. I revised my answer. – gkso May 27 '16 at 16:19
0

It's likely that your OS will send a RST packet automatically in response to the SYN+ACK received. By using sniff tool like wireshark, you can see that.

The issue can be resolved by adding an iptables rules to suppress the outgoing RST

sudo iptables -A OUTPUT -p tcp --dport 80 --tcp-flags RST RST -j DROP

And remove it later

sudo iptables -A OUTPUT -p tcp --dport 80 --tcp-flags RST RST -j DROP
gkso
  • 513
  • 3
  • 12
  • I tried it, the reply.show() command still has the same values. No response status code... – Nick May 26 '16 at 14:53
  • I got it. Seems the sr1 will only receive the first ACK packet from server, and it is an empty ACK, the second one is the HTTP response, so you need to use sr() instead of sr1() in order to capture the HTTP response – gkso May 26 '16 at 17:43