secdev / scapy

Scapy: the Python-based interactive packet manipulation program & library.
https://scapy.net
GNU General Public License v2.0
10.76k stars 2.03k forks source link

WARNING: DNS RR TXT prematured end of character-string #262

Closed Sn00z3r closed 8 years ago

Sn00z3r commented 8 years ago

For a CTF we are developing a DNS server/client RAT. We use scapy to send commands from the server to the client and to send the output from the client back to the server.

The problem here is that the rdata field can be maximum 255 chars long, so the way we fixed this is by nesting multile DNSRR -->DNS(rd=1,an=DNSRR(...)/DNSRR(..)/DNSRR(...)).

I open wireshark and can see the packet going out correctly with all the DNSRR fields in there, I can also see that same packet in wireshark on the server side coming in, no issues there.

However when scapy sniffs the packet on the server it has been transformed into a packet with RAW load data, this data is also truncated

Is this a known bug, or do I have to set some options to capture big packets (DNS packet length is around 900)?

Best regards!

p-l- commented 8 years ago

Could you be more specific and submit one exact example of packet that you can send, see correctly with wireshark, and how it is received by scapy on the other end?

Sn00z3r commented 8 years ago

I should have done this from the start, my apologies.

This is how scapy reads the packet:

###[ Ethernet ]###
  dst       = 00:0c:29:c7:71:7b
  src       = 00:0c:29:54:0d:15
  type      = 0x800
###[ IP ]###
     version   = 4L
     ihl       = 5L
     tos       = 0x0
     len       = 1500
     id        = 1
     flags     = MF
     frag      = 0L
     ttl       = 64
     proto     = udp
     chksum    = 0xd3bc
     src       = 192.168.0.1
     dst       = 192.168.0.2
     \options   \
###[ UDP ]###
        sport     = domain
        dport     = domain
        len       = 2253
        chksum    = 0x1339
###[ Raw ]###
           load      = '\x00\x00\x01\x00\x00\x00\x00\x0f\x00\x00\x00\x00\x07Snoogle\x03aln\x00\x00\x10\x00\x01\x00\x00\x00\x00\x00~}Q01EOmV0aDAgICAgICBMaW5rIGVuY2FwOkV0aGVybmV0ICBIV2FkZHIgMDA6MGM6Mjk6NTQ6MGQ6\nMGIgIAogICAgICAgICAgaW5ldCBhZGRyOjEwLjEwMC4xMy42\x07Snoogle\x03aln\x00\x00\x10\x00\x01\x00\x00\x00\x00\x00~}MiAgQmNhc3Q6MTAuMTAwLjEzLjI1\nNSAgTWFzazoyNTUuMjU1LjI1NS4wCiAgICAgICAgICBpbmV0NiBhZGRyOiBmZTgwOjoyMGM6Mjlm\nZjpmZTU0OmQwYi82NCB\x07Snoogle\x03aln\x00\x00\x10\x00\x01\x00\x00\x00\x00\x00~}TY29wZTpMaW5rCiAgICAgICAgICBVUCBCUk9BRENBU1QgUlVOTklORyBN\nVUxUSUNBU1QgIE1UVToxNTAwICBNZXRyaWM6MQogICAgICAgICAgUlggcGFja2V0czo\x07Snoogle\x03aln\x00\x00\x10\x00\x01\x00\x00\x00\x00\x00~}xMzUxODcg\nZXJyb3JzOjAgZHJvcHBlZDowIG92ZXJydW5zOjAgZnJhbWU6MAogICAgICAgICAgVFggcGFja2V0\nczoyOTggZXJyb3JzOjAgZHJvcHBlZDowIG92ZX\x07Snoogle\x03aln\x00\x00\x10\x00\x01\x00\x00\x00\x00\x00~}JydW5zOjAgY2FycmllcjowCiAgICAgICAgICBj\nb2xsaXNpb25zOjAgdHhxdWV1ZWxlbjoxMDAwIAogICAgICAgICAgUlggYnl0ZXM6MTcxMDYzMDQg\nKDE2LjMgT\x07Snoogle\x03aln\x00\x00\x10\x00\x01\x00\x00\x00\x00\x00~}WlCKSAgVFggYnl0ZXM6Mjk1NDIgKDI4LjggS2lCKQoKZXRoMSAgICAgIExpbmsgZW5j\nYXA6RXRoZXJuZXQgIEhXYWRkciAwMDowYzoyOTo1NDowZDoxNSAgCiAgI\x07Snoogle\x03aln\x00\x00\x10\x00\x01\x00\x00\x00\x00\x00~}CAgICAgICBpbmV0IGFk\nZHI6MTkyLjE2OC4wLjEgIEJjYXN0OjE5Mi4xNjguMC4yNTUgIE1hc2s6MjU1LjI1NS4yNTUuMAog\nICAgICAgICAgaW5ldDYgYWRkcjog\x07Snoogle\x03aln\x00\x00\x10\x00\x01\x00\x00\x00\x00\x00~}ZmU4MDo6MjBjOjI5ZmY6ZmU1NDpkMTUvNjQgU2NvcGU6TGlu\nawogICAgICAgICAgVVAgQlJPQURDQVNUIFJVTk5JTkcgTVVMVElDQVNUICBNVFU6MTUwMCAgTWV0\x07Snoogle\x03aln\x00\x00\x10\x00\x01\x00\x00\x00\x00\x00~}\ncmljOjEKICAgICAgICAgIFJYIHBhY2tldHM6Mjg3MiBlcnJvcnM6MCBkcm9wcGVkOjAgb3ZlcnJ1\nbnM6MCBmcmFtZTowCiAgICAgICAgICBUWCBwYWNrZXRzOjM\x07Snoogle\x03aln\x00\x00\x10\x00\x01\x00\x00\x00\x00\x00~}1MjggZXJyb3JzOjAgZHJvcHBlZDow\nIG92ZXJydW5zOjAgY2FycmllcjowCiAgICAgICAgICBjb2xsaXNpb25zOjAgdHhxd

I have included two wireshark captures, one for the sender, one for receiver. It's packet 30 for the sender and packet 17 for the receiver

wireshark.zip

Scapy code to create packet:

            #Divide rdata into multiple parts when larger than maximum length rdata field DNS
            if len(rdata_encoded)>125:
                rdata_encoded_array=[]
                parts=int(math.ceil(len(rdata_encoded)/125))
                chars_per_part=125

                for i in range (0,parts):
                    rdata_encoded_array.append(rdata_encoded[i*chars_per_part:(i+1)*chars_per_part])
                rdata_encoded_array.append(rdata_encoded[parts*chars_per_part:])

                payload=DNS(rd=1,an=DNSRR(rrname='Snoogle.aln',type="TXT", rdata=rdata_encoded_array[0]))
                for i in range (0,parts):
                    print i
                    payload.an.add_payload(DNSRR(rrname='Snoogle.aln',type="TXT", rdata=rdata_encoded_array[i+1]))

                send(header/payload,verbose=0,iface="eth1")

`

p-l- commented 8 years ago

Thanks. Can you also provide the scapy code you enter to create the packet?

Sn00z3r commented 8 years ago

I've added to code portion in the previous comment, if you need to see more let me know :)

Sn00z3r commented 8 years ago

Dear,

I found out why things go wrong, I have found the exact length where the server does not get the right response and this is due to fragmenting of the dns packet.

So I don`t believe that scapy is at fault here, noz I just need to find a easy and fast way to reconstruct fragmented packets

p-l- commented 8 years ago

OK, thanks for this update! Pierre