Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change TCP Payload with nfqueue/scapy

Hello I am using nfqueue and scapy and I my goal is to recieve packets at my NFQUEUE, change the payload and resend them.

I can change fields like the TTL without any kind of problem, but when it comes to change the payload, I am encoutering problems.

When I change the payload, I sniff the packet with wireshark and apparently I send the packet with the payload modified, but the server doesn't answer.

This is my code:

#!/usr/bin/env python

import nfqueue
from scapy.all import *
def callback(payload):
    data = payload.get_data()
    pkt = IP(data)

    pkt[TCP].payload = str(pkt[TCP].payload).replace("ABC","GET")

    pkt[IP].ttl = 40

    print 'Data: '+ str(pkt[TCP].payload)
    print 'TTL: ' + str(pkt[IP].ttl)

    del pkt[IP].chksum
    payload.set_verdict_modified(nfqueue.NF_ACCEPT, str(pkt), len(pkt))
def main():
    q = nfqueue.queue()
    q.open()
    q.bind(socket.AF_INET)
    q.set_callback(callback)
    q.create_queue(0)
    try:
        q.try_run() # Main loop
    except KeyboardInterrupt:
        q.unbind(socket.AF_INET)
        q.close()

main()

I have set this rule for outgoing traffic to port 80: iptables -I OUTPUT -s 192.168.1.10 -p tcp --dport 80 -j NFQUEUE

And, to test it, for example I open telnet to google port 80, do a GET / HTTP/1.1 and this is what I see:

TTL: 40
DATA: GET / HTTP/1.1

Now, if I do ABC / HTTP/1.1 I receive no answer! My telnet just get stuck.

I have also tried on HTTP websites browers to browse something, check on wireshark how my TTL is really changing to 40, then, browse the string "ABC" and my browser again get stuck. I sniff the request changed to GET but I receive no answer.

Thank is kind of giving me a headache and I would really appreciate if someone with more experience could lead me to the right way. Thank you in advance.

like image 755
aDoN Avatar asked Dec 04 '14 12:12

aDoN


People also ask

Does scapy use Libpcap?

Scapy runs natively on Linux, Windows, OSX and on most Unixes with libpcap (see scapy's installation page). The same code base now runs natively on both Python 2 and Python 3.

How do I create a TCP packet in scapy?

Creating a packet In scapy, packets are constructed by defining packet headers for each protocol at different layers of TCP/IP and then stacking these layers in order. To create a DNS query, you need to build Ether(sometimes optional), IP,UDP headers and stack them using / operator.

What is the difference between send and Sendp in scapy?

The send() function will send packets at layer 3. That is to say, it will handle routing and layer 2 for you. The sendp() function will work at layer 2. It's up to you to choose the right interface and the right link layer protocol.

What is TTL in scapy?

The technique is to send series of packets to the target with Time to Live (TTL) set in such a way that each router on the path will have to notify you of the death of the packet. The traceroute technique is based on the way the IP protocol is designed.


1 Answers

I added the line for recalculate the TCP checksum, that was usefull.

That only works if I change payload I don't alter the lenght of it, otherwise, I would need to change the field length of the IP Header, and answering myself, and maybe other people that is looking for this answer, I achieve that just by doing:

payload_before = len(pkt[TCP].payload)

pkt[TCP].payload = str(pkt[TCP].payload).replace("Heading","Other string")

payload_after = len(pkt[TCP].payload)

payload_dif = payload_after - payload_before

pkt[IP].len = pkt[IP].len + payload_dif

I know that I have to change more fields, because sometimes, if you add enough payload for needing to fragment into a new packet, you have to change more fields.

Currently I don't know how to achieve this efficiently but little by little. Hope someone find my solution for altering the payload useful.

like image 187
aDoN Avatar answered Oct 17 '22 05:10

aDoN