Python-Scapy or the like-How can I create an HTTP GET request at the packet level
Question:
I am a moderate programmer, just getting into network programming.
As an attempt to improve my understanding of networks in general, I am trying to perform several basic HTTP actions from the packet level. My question is this: How might I use a library such as SCAPY to build an HTTP GET request and assosciated items at the packet level? I realise this may sound odd, but I can’t seem to find any information detailing it, and my own attempts with PAROS and Ethereal have been… Less than satisfactory.
Thanks for any offered help!
Trimiert
Answers:
Have you had a look at the tutorial? Just copying and pasting, this looks like it’s going to assemble an HTTP request:
>>> a=Ether()/IP(dst="www.slashdot.org")/TCP()/"GET /index.html HTTP/1.0 nn"
If you want to do a full three-way handshake, you’ll have to do it manually.
Start with your SYN packet:
>>> syn = IP(dst='www.google.com') / TCP(dport=80, flags='S')
>>> syn
<IP frag=0 proto=tcp dst=Net('www.google.com') |<TCP dport=www flags=S |>>
Then receive the SYN-ACK packet from the server, sr1 works. Then send your HTTP GET request:
>>> syn_ack = sr1(syn)
Begin emission:
Finished to send 1 packets.
*
Received 1 packets, got 1 answers, remaining 0 packets
>>> syn_ack
<IP version=4L ihl=5L tos=0x0 len=44 id=424 flags= frag=0L ttl=55 proto=tcp chksum=0x2caa src=74.125.226.148 dst=10.20.30.40 options=[] |<TCP sport=www dport=ftp_data seq=3833491143 ack=1 dataofs=6L reserved=0L flags=SA window=5720 chksum=0xd8b6 urgptr=0 options=[('MSS', 1430)] |<Padding load='x00x00' |>>>
Then set your TCP sequence and ack numbers and send the GET:
getStr = 'GET / HTTP/1.1rnHost: www.google.comrnrn'
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)
FTR, as of Scapy 2.4.3, dissection of HTTP packets was implemented, among a util called “TCP_client” to do the 3 handshake automatically.
While it’s not as teaching as the above answer, it doesn’t hurt to have a look: https://scapy.readthedocs.io/en/latest/layers/http.html#use-scapy-to-send-receive-http-1-x
load_layer("http")
req = HTTP()/HTTPRequest(
Accept_Encoding=b'gzip, deflate',
Cache_Control=b'no-cache',
Connection=b'keep-alive',
Host=b'www.secdev.org',
Pragma=b'no-cache'
)
a = TCP_client.tcplink(HTTP, "www.secdev.org", 80)
answser = a.sr1(req)
a.close()
I am a moderate programmer, just getting into network programming.
As an attempt to improve my understanding of networks in general, I am trying to perform several basic HTTP actions from the packet level. My question is this: How might I use a library such as SCAPY to build an HTTP GET request and assosciated items at the packet level? I realise this may sound odd, but I can’t seem to find any information detailing it, and my own attempts with PAROS and Ethereal have been… Less than satisfactory.
Thanks for any offered help!
Trimiert
Have you had a look at the tutorial? Just copying and pasting, this looks like it’s going to assemble an HTTP request:
>>> a=Ether()/IP(dst="www.slashdot.org")/TCP()/"GET /index.html HTTP/1.0 nn"
If you want to do a full three-way handshake, you’ll have to do it manually.
Start with your SYN packet:
>>> syn = IP(dst='www.google.com') / TCP(dport=80, flags='S')
>>> syn
<IP frag=0 proto=tcp dst=Net('www.google.com') |<TCP dport=www flags=S |>>
Then receive the SYN-ACK packet from the server, sr1 works. Then send your HTTP GET request:
>>> syn_ack = sr1(syn)
Begin emission:
Finished to send 1 packets.
*
Received 1 packets, got 1 answers, remaining 0 packets
>>> syn_ack
<IP version=4L ihl=5L tos=0x0 len=44 id=424 flags= frag=0L ttl=55 proto=tcp chksum=0x2caa src=74.125.226.148 dst=10.20.30.40 options=[] |<TCP sport=www dport=ftp_data seq=3833491143 ack=1 dataofs=6L reserved=0L flags=SA window=5720 chksum=0xd8b6 urgptr=0 options=[('MSS', 1430)] |<Padding load='x00x00' |>>>
Then set your TCP sequence and ack numbers and send the GET:
getStr = 'GET / HTTP/1.1rnHost: www.google.comrnrn'
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)
FTR, as of Scapy 2.4.3, dissection of HTTP packets was implemented, among a util called “TCP_client” to do the 3 handshake automatically.
While it’s not as teaching as the above answer, it doesn’t hurt to have a look: https://scapy.readthedocs.io/en/latest/layers/http.html#use-scapy-to-send-receive-http-1-x
load_layer("http")
req = HTTP()/HTTPRequest(
Accept_Encoding=b'gzip, deflate',
Cache_Control=b'no-cache',
Connection=b'keep-alive',
Host=b'www.secdev.org',
Pragma=b'no-cache'
)
a = TCP_client.tcplink(HTTP, "www.secdev.org", 80)
answser = a.sr1(req)
a.close()