How to create HTTP GET request Scapy?

后端 未结 3 691
-上瘾入骨i
-上瘾入骨i 2020-12-11 21:14

I need to create HTTP GET request and save the data response. I tried to use this:

    syn = IP(dst=URL) / TCP(dport=80, flags=\'S\')
    syn_ack = sr1(syn)         


        
相关标签:
3条回答
  • 2020-12-11 21:43

    You are sending a SYN and correctly receiving a SYN_ACK. At this point, you should generate and send an ACK based on the SYN_ACK that you've received, and THEN finally transmit the HTTP GET request. It seems that you are somewhat confused about the TCP 3-way handshake mechanism. In short, you are not supposed to 'get' an ACK, you are supposed to generate and send this yourself.

    0 讨论(0)
  • 2020-12-11 21:43

    You are sending a RST segment in response to the SYN-ACK because your kernel has no knowledge of the SYN you sent via Scapy (see here). This could be solved with an iptable rule:

    iptables -A OUTPUT -p tcp --tcp-flags RST RST -s <your ip> -j DROP

    Because you are ending the connection with that RST segment, when you send your HTTP request, the endpoint answers with a RST too because connection is not established and so you are using show() on a RST segment with no data, that is why you do not see anything.

    0 讨论(0)
  • 2020-12-11 21:49

    After setting the rule in your iptables as has been suggested above, you could do the following :

    from scapy.all import *
    
    seq = 12345
    sport = 1040
    dport = 80
    
    ip_packet = IP(dst='192.168.56.107')
    syn_packet = TCP(sport=sport, dport=dport, flags='S', seq=seq)
    
    packet = ip_packet/syn_packet
    synack_response = sr1(packet)
    
    next_seq = seq + 1
    my_ack = synack_response.seq + 1
    
    ack_packet = TCP(sport=sport, dport=dport, flags='A', seq=next_seq, ack=my_ack)
    
    send(ip_packet/ack_packet)
    
    payload_packet = TCP(sport=sport, dport=dport, flags='A', seq=next_seq, ack=my_ack)
    payload = "GET / HTTP/1.0\r\nHOST: 192.168.56.107\r\n\r\n"
    
    reply, error = sr(ip_packet/payload_packet/payload, multi=1, timeout=1)
    for r in reply:
        r[0].show2()
        r[1].show2()
    

    Hope this helps. Basically, the first response you get back does not really hold the HTTP response data. I tested the script against an INETSIM simulated HTTP server and in that case (at least) the first packet (after the 3-way TCP handshake) that the server responded with was a series of NULL (0x00) bytes. Hence using multi somehow did the stuff in my case.

    0 讨论(0)
提交回复
热议问题