I'm trying to parse UDP packets from a RADIUS server and I've tried different tools including Scapy, Pynids and pypcap.The problem is some of the Radius-Attributes are not decoded properly and some of them are. What could be the cause of this?
Here's my code:
from scapy.all import sniff, Radius
packets = sniff(iface='eth0', filter='udp', count=5)
packet = packets[0]
print packet.show()
And here's the summary of the output I get:
###[ Ethernet ]###
dst = 94:57:a5:53:ab:70
src = d4:ca:6d:ae:a0:66
type = 0x800
###[ UDP ]###
sport = 38667
dport = radius
len = 205
chksum = 0x2bbd
###[ Radius ]###
code = Access-Request
id = 80
len = 197
authenticator= "T\xfb\x9c\t\x00 '\x14\xeb\x99\x84t\x9b\xb4\x83\x95"
\attributes\
|###[ Radius Attribute ]###
| type = Framed-Protocol
| len = 6
| value = '\x00\x00\x00\x01'
|###[ Radius Attribute ]###
| type = NAS-Port
| len = 6
| value = '\x00\xf6\xa7\xf9'
|###[ Radius Attribute ]###
| type = Called-Station-Id
| len = 8
| value = 'Dslam1'
|###[ Radius Attribute ]###
| type = 87
| len = 16
| value = 'ether1-Dslam 1'
|###[ Radius Attribute ]###
| type = Vendor-Specific
| len = 24
| value = '\x00\x00\x017\x0b\x12\x19\xfc4\xd01\xaf\x03\xd6\x0e!j\xa7H]\xdd;'
|###[ Radius Attribute ]###
| type = NAS-Identifier
| len = 15
| value = 'TEH-P'
For future visitors this is how I managed to parse the packets.
You need create a dictionary file in your current directory or use an example from here so it can parse your data types correctly.
from pyrad.packet import Packet
from pyrad.dictionary import Dictionary
from scapy.all import sniff, Radius
def parse_packet(packet):
radius_packet = str(packet[Radius])
pkt = Packet(packet=radius_packet, dict=Dictionary("dictionary"))
for key, value in pkt.iteritems():
attr = pkt._DecodeKey(key)
value = pkt.__getitem__(attr)
print attr, value
sniff(iface='eth0', prn=parse_packet, filter="udp", store=0)
This is a response sample I got:
User-Name [u'12345678']
NAS-IP-Address ['192.168.*.*']
NAS-Port [15853417]
Service-Type ['Framed-User']
Framed-Protocol ['PPP']
Framed-IP-Address ['192.168.*.*']
Called-Station-Id [u'service4']
Calling-Station-Id [u'20:A7:5C:75:RA:TD']
NAS-Identifier [u'Test']
Acct-Status-Type ['Alive']
Acct-Delay-Time [0]
Acct-Input-Octets [1003335]
Acct-Output-Octets [15399190]
Acct-Session-Id [u'81c2332b']
Acct-Authentic ['RADIUS']
Acct-Session-Time [76321]
Acct-Input-Packets [15498]
Acct-Output-Packets [21247]
Related
I'm trying to write a Python code using Scapy that makes a DNS Request and receive a DNS response, but getting a problematic response.
This is what i wrote:
>>> req_packet = IP(dst="8.8.8.8")/UDP(sport=RandShort(),
dport=53)/DNS(rd=1,qd=DNSQR(qname="google.com",qtype="A"))
>>> res= sr1(req_packet)
Begin emission:
Finished sending 1 packets.
...*
Received 4 packets, got 1 answers, remaining 0 packets
In the response, the an field in the DNS layer is equal to None, this is
the response content:
>>> res.show()
###[ IP ]###
version = 4
ihl = 5
tos = 0xc0
len = 84
id = 63672
flags =
frag = 0
ttl = 64
proto = icmp
chksum = 0xfc42
src = ---------
dst = ---------
\options \
###[ ICMP ]###
type = redirect
code = host-redirect
chksum = 0xbf4
gw = ----------
unused = ''
###[ IP in ICMP ]###
version = 4
ihl = 5
tos = 0x0
len = 56
id = 1
flags =
frag = 0
ttl = 63
proto = udp
chksum = 0xa94b
src = -----------
dst = 8.8.8.8
\options \
###[ UDP in ICMP ]###
sport = 10957
dport = domain
len = 36
chksum = 0xee81
###[ DNS ]###
id = 0
qr = 0
opcode = QUERY
aa = 0
tc = 0
rd = 1
ra = 0
z = 0
ad = 0
cd = 0
rcode = ok
qdcount = 1
ancount = 0
nscount = 0
arcount = 0
\qd \
|###[ DNS Question Record ]###
| qname = 'google.com.'
| qtype = A
| qclass = IN
an = None
ns = None
ar = None
I use Python version 3.10.2 and Scapy version 2.5.0.dev15
I'm really stuck with this problem, any advice would be greatly appreciated!
I'm trying to create an app using python, to watch together movies, but I constantly getting errors with :
[Errno 10040] A message sent on a datagram socket was larger than the internal message buffer or some other network limit, or the buffer used to receive a datagram was smaller than the datagram itself
Server.py
BUFFOR_SIZE_DATA = 65536
# SERVER SETTINGS
server_socket_main = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server_socket_main.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, BUFFOR_SIZE_DATA)
print(Fore.RED + 'UDP Server')
host_name = socket.gethostname()
print('HOST NAME:',host_name)
host_ip_adress = ''
print('HOST IP:',host_ip_adress)
host_port = 1337
socket_adress_main = (host_ip_adress, host_port)
print('PORT:',host_port)
server_socket_main.bind(socket_adress_main)
print(Fore.GREEN + 'Server is listening > > >')
print(Fore.WHITE + ' ')
print(Fore.WHITE + 'Connected devices: ')
# VIDEO U WANT TO WATCH TOGETHER
server_video_main = cv2.VideoCapture('movies/exmpl.mp4')
# MAIN LOOP
while True:
msg, client_addres_obligatory = server_socket_main.recvfrom(BUFFOR_SIZE_DATA)
print('Connected from ', client_addres_obligatory)
WIDTH = 1024
while(server_video_main.isOpened()):
_,frame = server_video_main.read()
frame = imutils.resize(frame, width=WIDTH)
encoded, buffer = cv2.imencode('.jpg', frame, [cv2.IMWRITE_JPEG_QUALITY, 80])
message = base64.b64encode(buffer)
server_socket_main.sendto(message, client_addres_obligatory)
cv2.imshow('HOST | Currently hosting', frame)
key = cv2.waitKey(1) & 0xFF
if key == ord('c'):
server_socket_main.close()
break
Client.py
client_socket_main.sendto(welcomemessage.encode(), (client_ip_adress, client_port))
while True:
packet,_ = client_socket_main.recvfrom(BUFFOR_SIZE_DATA)
data = base64.b85decode(packet,' /')
npdata = np.fromstring(data, dtype=np.unit8)
frame = cv2.imdecode(npdata, 1)
cv2.imshow('Currently watching ', frame)
key = cv2.waitKey(1) & 0xFF
if key == ord('c'):
client_socket_main.close()
break
data = base64.b85decode(packet,' /')
TypeError: b85decode() takes 1 positional argument but 2 were given
Thanks in advance!
The 64KiB limit is determined not by UDP but by IP. Here's the IPv4 header from the original RFC:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Version| IHL |Type of Service| Total Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Identification |Flags| Fragment Offset |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Time to Live | Protocol | Header Checksum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Source Address |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Destination Address |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Options | Padding |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
See that "Total Length" field? It's 16 bits, so its maximum value is 0xffff, which is 64Ki. That even includes headers, so the actual maximum size is smaller.
Additionally, the typical MTU on the internet is 1500 bytes, sometimes less (again, including headers). Sending packets larger than the MTU is a recipe for trouble because it means that IP fragmentation will take place, which is not desirable.
You need to break up the data into smaller chunks or use TCP which takes care of that for you.
I need to sniff DNS packets with scapy in python.
I have created a script that works, but when I run the script with my c++ code I am getting these warnings:
WARNING: wrong value: DNS.qdcount=6334
WARNING: DNS RR prematured end (ofs=7080, len=1460)
WARNING: wrong value: DNS.arcount=32966
and as a result, the packet is missing data. A packet that was sniffed using running the script with C++ :
WARNING: wrong value: DNS.qdcount=6334
WARNING: DNS RR prematured end (ofs=7080, len=1460)
WARNING: wrong value: DNS.arcount=32966
[ Ethernet ]
dst = 48:2c:a0:5f:bb:50
src = b8:81:98:86:ee:f3
type = 0x800
[ IP ]
version = 4
ihl = 5
tos = 0x0
len = 1500
id = 1659
flags = MF
frag = 0
ttl = 128
proto = udp
chksum = 0x670d
src = 192.168.43.127
dst = 54.194.132.159
\options \
[ UDP ]
sport = 50066
dport = domain
len = 1530
chksum = 0x40a1
[ DNS ]
id = 2564
qr = 0
opcode = QUERY
aa = 1
tc = 0
rd = 1
ra = 1
z = 1
ad = 1
cd = 0
rcode = 8
qdcount = 6334
ancount = 1
nscount = 0
arcount = 32966
qd = ''
\an \
|###[ DNS Resource Record ]###
| rrname = '.'
| type = 41326
| rclass = 58674
| ttl = 582309185
| rdlen = 1448
| rdata = b'Q\xdd\xa9\x87?\xe3w\x9c\x00F\xd9\x9a2\xd6\xd5\x9f\xd1;r\xfb\xe7S\x13\xecm\x19wP\xd8\xfd\xd8\xec\x9bA\xb0\xe1\xb0\xea\x8fNw\xc4\xf2\x12\x8b\x89J1n\xb8\xacc\x07M1\xe2\x18\x08\x8e\x9f\xb1\x01\xfb\xbe">\x0etq::F\xbfek\x94\xdcN\xa5s\xfd4\xf36\x96\xd7\xd8a\x8c\x1e1\xa6\x97\xd9\x1f\xeaz\x91\x0b\x93ZLI\x15`$\x1b\x96(\xe5\x02\xb0\n\x08\x82\xb6\xa7+4\xca\xc3\xf8\xe7\x05}T\x1c_{\x884E\xcd,#\x0emx&+h\xa1\xd2\x95\x04\xa7x\xb8\xeaD\xecS\xd7s,\xeb\xff\xa0M\xd5\xcb\x00\xe6\x0e\x1dqa\xdeo\x9c\xdc\xb6#\x02pA;,2]\xa7\xe7\xc79l\x02\xf4\xd2\x197Ccd\x0c\x8eU9\xc6\x9e\x9d\xad\xffa\xc6\xe3be\xce\xee\x94,\x973(\xac\xdak\xd2.w\x89O~\xfc\x99YSB\xb1W\x99F\x15/r\x81p\x8a{\x1b_}\xbb\x9c\x19\xca\xa4\x1a}\xdd\x99\xc0\xe3\x9c\xdf|\x81M\x04\xd1\t\xcb\xf4\x95\x17[\x9ej"M\x07\xec\x93\xb8DO.\x94W\xc3eg|\x9a\\\x8b\xa2\xf36\x82d\x80\xcd!\xb2\xcd\xe9:#\x103%\xfd\xfa\xd1\xe5\xe4\xd2\xbe\xb5\x7fF(`\x85\xedW\xd9\x98\xff\xe7A3\x92\x93\xd3\x19\x9f\xe7\x1b\x17\xaa\x81\x1cS\xee\xed\x94Q\xf1\x98\x02\x1fH\xba\xc5\x87\x03\x94\xa0\xee9\xb8\xc5_q\xe6P\xf7G\x0e\x12\x8b"C\xa7j\xf9\x19<\xd6\x8d+\xaf\x0c\x8c\xce\xbf\xfcN\xc8\xb4\xe8\xed\x18\xddShe\xb2T\x80\xfbAu\xb3kj\xc9\x1b\xcd\xa1\xde4>\xb3,\xb4\x8b\xa7\x1c7\ra\x19\x86\x94\x8f\xa7\xa3\xae-&\xac\xa1v\xd5Q\x94\x884\x1d&\xbf\xd4\xc9\xe6\x88\xd88\xca+\x9e\xd3\xe4\xdf\x83F\xf0\x16\x12\xf0\xb6\xdet\x1eCE\x9e\x1eQje\xa7\xc2\x13\xa79e\xbcUr\x8d#\x85c\xd0\x8f\t\x95\xa3\xf6\x84f\xfa\x9e\xc5\x1f\xd2\xdet\xc3\x17\xdb=\x92\xab\xfe\xa1\xf4sN\xbeH#\xe5\xc1\xd8\x04\xca\xca\xc8\xf9\xe3p-q.\x10\x1e|5^\xea8slX?\x86\xee,b\x9f\xe3L\xeaxTr\x86\x8c\xa1\xce\x9a\xc1\xcf\x82\x16p\xde\xe5\xc6\xb9\xf6\x03\x15\xfc\xea\x1f\x14az\r\xd9\xbd\x80`\x15\x12[\xfbW\xda\xab6\xd8\xfbZ\x00\xe5)\xae\xd0\x18\x97\x11\xd8\xfa\xe0\xec\x9a\xa7\x8f<\xb3\x98\xd7C\x08\x9cp1kj\x9f\x9a\xe08\xa0SR>\x95\x82\xcd\x12\xacD<\xdd\x1e\xec\x95q\x87}LE\xc6G\xf1\x12.\xe1\xbe\xdfG\x0cV\x1c\xfcr\xdfnW\x94\xfbVR\x16_\n\x83Qv\x04\x1e4\xc4\xfeHBi)\x1a\n\x06\xa5l#\x818\x11\x14!\xa0>\xcfv\\\nT\xb2\xe1\x89R\'\x90\xa5\x90\xb3\xd2\xc5)\xc0R\xf6\x99^\xe1\xf0\x0f(\xf4\\\xbex\x8aq\xbf\x8d\xdel#\x15<v4\xef]\xfdr\xe2\x11\x82\xe1\x03\x0e\x1f\xd1\xa5\xdf\xd1~\xe9\xdd\xfdAG\x7f\x7f\xbd\xac\xbb\x9c\x08\xe6LjsN\xf1\xf5G\xe8*6\x86\x8b\x1b\r\x9ck\xabOU\x91\xf1\xba\r[\xf7\x970\xc4\xdd\x84>\x859u\xe7\xa6[\xf5m\x9f\x1a\x8f\xc0\xc7y\xd2\x8b\x89Q\xa8\xfau\x12\xa3#\x84N\x0c/\x9akHp\x0c\x07\xd1j\x86\xf6\x04\x8f\x85\x00\xaa2\xfap\xb9\xd1\x00\xdb\x91R\xb2\xf3\xcc\xfc\xfdB\x1em\xb0\xd0\x88\x05\x0f\x0f\xae41\xbd\xffqA\x01\x8a\xd8D\xa0\xb7D\xcei\x91$p\r\xc4B\xe5\x98\xee\x9aX\x1c1\xcdc\xa0\\Ycy1\xbb`\x8f\x07\x1f\xef\xc6\x9c+3,\r\xd4cHnBDLw9\x8e,\xff=\x1d\x92\xbfw\xfbd\xbe\xc2~\x8dH\xc8Ht\xc1Om\xe1N\x00\xd4&\xb4\x07E\xf16\xaa\x00\xea(?%\xb8?\xf9/\xc5\x94\x84\xac\xcc`\xdd+\x02\xe1MOi\xd6e\xbc\x1c\x94o`\x8f\xcax#\x94\xc3\xf1b\xea\x8d\x1f\xc0Cg\x93\xe3\xd6\xf3<\xed$D\xf7\x82\x05\xe9\xa7\xcc\x19?\xb4b\xe3\xc4\x83\xb7}\xcf\x89O\xe4\xce\x1a\xfd`a\xbeGs\xb2\xc2\xa2\x8d\xfdFTXR\xf2\xab\xffF\x12v\n\x98\xe9\x90\xc1d\x01\x83W\xd7}[D\xee\x1fc\xefG\xa2\xbf\xdff\xa0.\xc7\xbf\x13/_\x1c\xc5L\xc5\x17b\xc5\xd3P\xad\xc4S\x07\x02\xfd\x85\x90g\x04u\x9fW\xda\x1fq\xb4\x06\xf4\xb9\x1b\x9e\xe2a/K\xd7b\xf2d\x03\xfba\x0e\xb4\x89\x16;0~V\xab\x95\xc3\x90\xd1\xee\xb7b\xfcp\x86As\xa3h\xf2$\x12\x9f\xa3\xa6i\xefl\xc6p~Ww\x95\xdcr\x17\xe0S\xd0\x8d\xee\xe1\x00\xe5A\xa1~\xceh\xf3(\x1cB\xba\x8e\xa8E7\rr>=:u\xecpz\xa2\x01L\x88\xb9\t\xe7\xec;\xef\xa1\xff\xdf%.9\xf4\x13\xcau\xa0\xb8H\x07`\xda\xe8T\xf3c\xb0\xf0\x17\xbc\xa5:\x8b\xb3\x9dFRM\xdd\ty:\xcd\xaa\x80~K:iy\xac=\xe5\xa2\xaca\xd6\xc7\xc87\xc4\x08\xad\x87\xe8h\xa3i\x89\xaa\xea\xb9\xf5\x10\xabsw\xf0\xae\xa0Q7\xb6\x11\x1b\xe9\x89\x94fU\x96i+^\xba\xa2\x9e\xf1\xe2R\xe5y_\xb0;\xa7\xe8B\x0ef\xb9\xaf\xa8\xba\xfa\xd6\xf1\xb6ta{\xd3\xe4QtC\x8b\x92\xe9\xc6\xe0)\x90\xdfP\xb5K\xf2n|\xf9\xba\xa5-o\xban\xddN\x96\xc4\xcaC\x93\x96\xf3\xf9\xe9N\x16\xdf\x80\t\x05\xee\xf7\xa2\x94\xe0\x02\xd3k\x102\xbe\xb7W/G\xc5\x96\x9d\x8a\xe3\xa2^\xc7,\xd4\xf3|\xafH\n\x15ftV\xb0\xef\xc5\xaf\xef`\x00_S\x89d\x0cbSa\xb4\x9cN\xde\xaeIM#:F\xcc\x00\x01\x1e\xd7P,\n\x07\xcd\xed\x9f\xd1\x92\xc2\xae\xec\x9a\xe5\xd2v\xff\xb2\xe5\xe4-JN\x02\xae\xfa\xd4m\x82\x9eL0V\xd8C\xd1GL\xdc'
ns = None
ar = ''
[ Raw ]
load = b'\xdb\xb4\xa1n\xe52"\xb5UA*\x9bQ\xdd\xa9\x87?\xe3w\x9c\x00F\xd9\x9a2\xd6\xd5\x9f\xd1;r\xfb\xe7S\x13\xecm\x19wP\xd8\xfd\xd8\xec\x9bA\xb0\xe1\xb0\xea\x8fNw\xc4\xf2\x12\x8b\x89J1n\xb8\xacc\x07M1\xe2\x18\x08\x8e\x9f\xb1\x01\xfb\xbe">\x0etq::F\xbfek\x94\xdcN\xa5s\xfd4\xf36\x96\xd7\xd8a\x8c\x1e1\xa6\x97\xd9\x1f\xeaz\x91\x0b\x93ZLI\x15`$\x1b\x96(\xe5\x02\xb0\n\x08\x82\xb6\xa7+4\xca\xc3\xf8\xe7\x05}T\x1c_{\x884E\xcd,#\x0emx&+h\xa1\xd2\x95\x04\xa7x\xb8\xeaD\xecS\xd7s,\xeb\xff\xa0M\xd5\xcb\x00\xe6\x0e\x1dqa\xdeo\x9c\xdc\xb6#\x02pA;,2]\xa7-\xe7\xc79l\x02\xf4\xd2\x197Ccd\x0c\x8eU9\xc6\x9e\x9d\xad\xffa\xc6\xe3be\xce\xee\x94,\x973(\xac\xdak\xd2.w\x89O~\xfc\x99YSB\xb1W\x99F\x15/r\x81p\x8a{\x1b_}\xbb\x9c\x19\xca\xa4\x1a}\xdd\x99\xc0\xe3\x9c\xdf|\x81M\x04\xd1\t\xcb\xf4\x95\x17[\x9ej"M\x07\xec\x93\xb8DO.\x94W\xc3eg|\x9a\\\x8b\xa2\xf36\x82d\x80\xcd!\xb2\xcd\xe9:#\x103%\xfd\xfa\xd1\xe5\xe4\xd2\xbe\xb5\x7fF(`\x85\xedW\xd9\x98\xff\xe7A3\x92\x93\xd3\x19\x9f\xe7\x1b\x17\xaa\x81\x1cS\xee\xed\x94Q\xf1\x98\x02\x1fH\xba\xc5\x87\x03\x94\xa0\xee9\xb8\xc5_q\xe6P\xf7G\x0e\x12\x8b"C\xa7j\xf9\x19<\xd6\x8d+\xaf\x0c\x8c\xce\xbf\xfcN\xc8\xb4\xe8\xed\x18\xddShe\xb2T\x80\xfbAu\xb3kj\xc9\x1b\xcd\xa1\xde4>\xb3,\xb4\x8b\xa7\x1c7\ra\x19\x86\x94\x8f\xa7\xa3\xae-&\xac\xa1v\xd5Q\x94\x884\x1d&\xbf\xd4\xc9\xe6\x88\xd88\xca+\x9e\xd3\xe4\xdf\x83F\xf0\x16\x12\xf0\xb6\xdet\x1eCE\x9e\x1eQje\xa7\xc2\x13\xa79e\xbcUr\x8d#\x85c\xd0\x8f\t\x95\xa3\xf6\x84f\xfa\x9e\xc5\x1f\xd2\xdet\xc3\x17\xdb=\x92\xab\xfe\xa1\xf4sN\xbeH#\xe5\xc1\xd8\x04\xca\xca\xc8\xf9\xe3p-q.\x10\x1e|5^\xea8slX?\x86\xee,b\x9f\xe3L\xeaxTr\x86\x8c\xa1\xce\x9a\xc1\xcf\x82\x16p\xde\xe5\xc6\xb9\xf6\x03\x15\xfc\xea\x1f\x14az\r\xd9\xbd\x80`\x15\x12[\xfbW\xda\xab6\xd8\xfbZ\x00\xe5)\xae\xd0\x18\x97\x11\xd8\xfa\xe0\xec\x9a\xa7\x8f<\xb3\x98\xd7C\x08\x9cp1kj\x9f\x9a\xe08\xa0SR>\x95\x82\xcd\x12\xacD<\xdd\x1e\xec\x95q\x87}LE\xc6G\xf1\x12.\xe1\xbe\xdfG\x0cV\x1c\xfcr\xdfnW\x94\xfbVR\x16_\n\x83Qv\x04\x1e4\xc4\xfeHBi)\x1a\n\x06\xa5l#\x818\x11\x14!\xa0>\xcfv\\\nT\xb2\xe1\x89R\'\x90\xa5\x90\xb3\xd2\xc5) \xc0R\xf6\x99^\xe1\xf0\x0f(\xf4\\\xbex\x8aq\xbf\x8d\xdel#\x15<v4\xef]\xfdr\xe2\x11\x82\xe1\x03\x0e\x1f\xd1\xa5\xdf\xd1~\xe9\xdd\xfdAG\x7f\x7f\xbd\xac\xbb\x9c\x08\xe6LjsN\xf1\xf5G\xe8*6\x86\x8b\x1b\r\x9ck\xabOU\x91\xf1\xba\r[\xf7\x970\xc4\xdd\x84>\x859u\xe7\xa6[\xf5m\x9f\x1a\x8f\xc0\xc7y\xd2\x8b\x89Q\xa8\xfau\x12\xa3#\x84N\x0c/\x9akHp\x0c\x07\xd1j\x86\xf6\x04\x8f\x85\x00\xaa2\xfap\xb9\xd1\x00\xdb\x91 R\xb2\xf3\xcc\xfc\xfdB\x1e-m\xb0\xd0\x88\x05\x0f\x0f\xae41\xbd\xffqA\x01\x8a\xd8D\xa0\xb7D\xcei\x91$p\r\xc4B\xe5\x98\xee\x9aX\x1c1\xcdc\xa0\\Ycy1\xbb`\x8f\x07\x1f\xef\xc6\x9c+3,\r\xd4cHnBDLw9\x8e,\xff=\x1d\x92\xbfw\xfbd\xbe\xc2~\x8dH\xc8Ht\xc1Om\xe1N\x00\xd4&\xb4\x07E\xf16\xaa\x00\xea(?%\xb8?\xf9/\xc5\x94\x84\xac\xcc`\xdd+\x02\xe1MOi\xd6e\xbc\x1c\x94o`\x8f\xcax#\x94\xc3\xf1b\xea\x8d\x1f\xc0Cg\x93\xe3\xd6\xf3<\xed$D\xf7\x82\x05\xe9\xa7\xcc\x19?\xb4b\xe3\xc4\x83\xb7}\xcf\x89O\xe4\xce\x1a\xfd`a\xbeGs\xb2\xc2\xa2\x8d\xfdFTXR\xf2\xab\xffF\x12v\n\x98\xe9\x90\xc1d\x01\x83W\xd7}[D\xee\x1fc\xefG\xa2\xbf\xdff\xa0.\xc7\xbf\x13/_\x1c\xc5L\xc5\x17b\xc5\xd3P\xad\xc4S\x07\x02\xfd\x85\x90g\x04u\x9fW\xda\x1fq\xb4\x06\xf4\xb9\x1b\x9e\xe2a/K\xd7b\xf2d\x03\xfba\x0e\xb4\x89\x16;0~V\xab\x95\xc3\x90\xd1\xee\xb7b\xfcp\x86As\xa3h\xf2$\x12\x9f\xa3\xa6i\xefl\xc6p~Ww\x95\xdcr\x17\xe0S\xd0\x8d\xee\xe1\x00\xe5A\xa1~\xceh\xf3(\x1cB\xba\x8e\xa8E7\rr>=:u\xecpz\xa2\x01L\x88\xb9\t\xe7\xec;\xef\xa1\xff\xdf%.9\xf4\x13\xcau\xa0\xb8H\x07`\xda\xe8T\xf3c\xb0\xf0\x17\xbc\xa5:\x8b\xb3\x9dFRM\xdd\ty:\xcd\xaa\x80~K:iy\xac=\xe5\xa2\xaca\xd6\xc7\xc87\xc4\x08\xad\x87\xe8h\xa3i\x89\xaa\xea\xb9\xf5\x10\xabsw\xf0\xae\xa0Q7\xb6\x11\x1b\xe9\x89\x94fU-\x96i+^\xba\xa2\x9e\xf1\xe2R\xe5y_\xb0;\xa7\xe8B\x0ef\xb9\xaf\xa8\xba\xfa\xd6\xf1\xb6ta{\xd3\xe4QtC\x8b\x92\xe9\xc6\xe0)\x90\xdfP\xb5K\xf2n|\xf9\xba\xa5-o\xban\xddN\x96\xc4\xcaC\x93\x96\xf3\xf9\xe9N\x16\xdf\x80\t\x05\xee\xf7\xa2\x94\xe0\x02\xd3k\x102\xbe\xb7W/G\xc5\x96\x9d\x8a\xe3\xa2^\xc7,\xd4\xf3|\xafH\n\x15ftV\xb0\xef\xc5\xaf\xef`\x00_S\x89d\x0cbSa\xb4\x9cN\xde\xaeIM#:F\xcc\x00\x01\x1e\xd7P,\n\x07\xcd\xed\x9f\xd1\x92\xc2\xae\xec\x9a\xe5\xd2v\xff\xb2\xe5\xe4-JN\x02\xae\xfa\xd4m\x82\x9eL0V\xd8C\xd1GL\xdc'
A packet that was sniffed with Python compiler:
[ Ethernet ]###
dst = 48:2c:a0:5f:bb:50
src = b8:81:98:86:ee:f3
type = 0x800
[ IP ]
version = 4
ihl = 5
tos = 0x0
len = 61
id = 30144
flags =
frag = 0
ttl = 128
proto = udp
chksum = 0xec5d
src = 192.168.43.127
dst = 192.168.43.194
\options \
[ UDP ]
sport = 63691
dport = domain
len = 41
chksum = 0xf1c7
[ DNS ]
id = 34891
qr = 0
opcode = QUERY
aa = 0
tc = 0
rd = 1
ra = 0
z = 0
ad = 0
cd = 0
rcode = ok
qdcount = 1
ancount = 0
nscount = 0
arcount = 0
\qd \
|###[ DNS Question Record ]###
| qname = 'docs.python.org.'
| qtype = A
| qclass = IN
an = None
ns = None
ar = None
I have initialized the script using Python.h class in c++, and I need the 'qname' field in the packet.
any solution will be appreciated.
Consider this simple python dns spoofer:
#!/usr/bin/python3
import socket
from scapy.all import *
port = 53
def handle(payload):
data = payload[0]
src_ip = payload[1][0]
src_port = payload[1][1]
print("-" * 10 + " Incoming " + "-" * 10)
a = DNS(data)
a.show2()
output = IP(dst=src_ip, chksum = 0)/ UDP(sport=53, dport=src_port) / DNS(id=a.id, qr=1, opcode=a.opcode, aa=1, tc=0, rd=1, ra=1, z=0, ad=0, cd=0, rcode=0, qdcount=1, ancount=1, nscount=0, arcount=0,qd=DNSQR(qname=a[DNS].qd.qname, qtype=a[DNS].qd.qtype, qclass=a[DNS].qd.qclass), an=DNSRR(rrname='cnn.com', rdata='192.168.1.100'), )
print("-" * 10 + " Output " + "-" * 10)
output.show2()
send(output)
if __name__ == "__main__":
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # create a socket object
s.bind(("", port))
while True:
payload = s.recvfrom(1024)
handle(payload)
I would run it from sudo (so I can bind to udp port 53):
$ sudo python3 -i ./dns_python.py
However my requests to it are timing out:
$ host cnn.com 127.0.0.1
;; connection timed out; no servers could be reached
I need help to figure out how to spoof successfully:
Some more details:
$ sudo python3 -i ./dns_python.py
---------- Incoming ----------
###[ DNS ]###
id = 59652
qr = 0
opcode = QUERY
aa = 0
tc = 0
rd = 1
ra = 0
z = 0
ad = 0
cd = 0
rcode = ok
qdcount = 1
ancount = 0
nscount = 0
arcount = 0
\qd \
|###[ DNS Question Record ]###
| qname = 'cnn.com.'
| qtype = A
| qclass = IN
an = None
ns = None
ar = None
---------- Output ----------
###[ IP ]###
version = 4
ihl = 5
tos = 0x0
len = 76
id = 1
flags =
frag = 0
ttl = 64
proto = udp
chksum = 0x0
src = 127.0.0.1
dst = 127.0.0.1
\options \
###[ UDP ]###
sport = domain
dport = 36774
len = 56
chksum = 0xb87f
###[ DNS ]###
id = 59652
qr = 1
opcode = QUERY
aa = 1
tc = 0
rd = 1
ra = 1
z = 0
ad = 0
cd = 0
rcode = ok
qdcount = 1
ancount = 1
nscount = 0
arcount = 0
\qd \
|###[ DNS Question Record ]###
| qname = 'cnn.com.'
| qtype = A
| qclass = IN
\an \
|###[ DNS Resource Record ]###
| rrname = 'cnn.com.'
| type = A
| rclass = IN
| ttl = 0
| rdlen = 4
| rdata = '192.168.1.100'
ns = None
ar = None
.
Sent 1 packets.
I see packets when I watch from a ngrep -d lo '' src or dst port 53 window. Any help would much appreciated!
Scapy does not work with 127.0.0.1 or on the loopback interface
http://scapy.readthedocs.io/en/latest/troubleshooting.html
The loopback interface is a very special interface. Packets going through it are not really assembled and disassembled. The kernel routes the packet to its destination while it is still stored an internal structure. What you see with tcpdump -i lo is only a fake to make you think everything is normal. The kernel is not aware of what Scapy is doing behind his back, so what you see on the loopback interface is also a fake. Except this one did not come from a local structure. Thus the kernel will never receive it.
In order to speak to local applications, you need to build your packets one layer upper, using a PF_INET/SOCK_RAW socket instead of a PF_PACKET/SOCK_RAW (or its equivalent on other systems than Linux):
I'm trying to build an own layer in Scapy which contains a "LengthField". This field should contain the total size of this layer + everything that follows.
I know that the "post_build" method is what I need to achieve this and I have tried to understand how it is used in the Scapy Documentation, but I do not understand it.
Let's say I have a layer
class MyLayer(Packet):
name = "MyLayer"
fields_desc = [
ByteField("SomeField", 1),
IntField("LengthField", 0)
]
How do I need to modify this class so it can automatically update the LengthField upon buildung?
def post_build(self, p, pay):
p += pay
if self.LengthField is None:
p = p[:1] + struct.pack("I", len(p)) + p[5:]
hexdump(p)
return p
You can refer to some examples in the source code:
class HCI_Command_Hdr(Packet):
name = "HCI Command header"
fields_desc = [XLEShortField("opcode", 0),
ByteField("len", None), ]
def post_build(self, p, pay):
p += pay
if self.len is None:
p = p[:2] + struct.pack("B", len(pay)) + p[3:]
return p
The result is:
>>> (HCI_Command_Hdr()/"1234567").show2()
###[ HCI Command header ]###
opcode= 0x0
len= 7
###[ Raw ]###
load= '1234567'
You can print p and pay to understand the code:
p[:2] + struct.pack("B", len(pay)) + p[3:]
Then, modify it to achieve your needs.
fix the fields size with the length of a new MyLayer in post_dissect. Note that you cannot use len(str(self)) for length calculation as you'll end up in an endless recursion due to str() calling do_dissect.
class MyLayer(Packet):
name = "MyLayer"
fields_desc = [
ByteField("SomeField", 1),
LenField("LengthField", None), # calcs len(pkt.payload)
]
def post_dissect(self, s):
self.LengthField += len(str(self.__class__())) # add this layer size by creating a new temporary layer and calculating its size.
return Packet.post_dissect(self, s)
the value will be calculated upon show2()
(MyLayer()/Raw().show2()
results in
###[ MyLayer ]###
SomeField = 1
LengthField= 9
###[ Raw ]###
load = 'hihiii'
where 9 = 6 bytes payload (Raw) + 1 byte (SomeField) + 2 Bytes (LenField with fmt="H" == shortInt == 2bytes)