Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 11 days ago.
Improve this question
How can I read TLS information (record length, record type...) from a packet using scapy. I have used load_layer('tls') and I'm able to read some information when there is a single TLS record in a packet but when there is multiple TLS record in a packet I'm only able to read the first TLS record.
For exemple this packet contain 3 TLS record and when I want to read the records length with scapy I only get the first record length
Total TLS decoding
As you've found, scapy doesn't decode the entire packet. But this is fine, because we can manually decode the TLS sections that scapy currently considers as a "Raw load" of bytes.
>>> pkts = rdpcap("facebook.com.pcap")
>>> extra_tls_layers = TLS(pkts[5]["TLS"].load)
>>> # We can see that TLS is now decoded, with two new layers:
>>> extra_tls_layers.show()
###[ TLS ]###
type= application_data
version= TLS 1.2
len= 1017 [deciphered_len= 1017]
iv= b''
\msg\
|###[ TLS Application Data ]###
| data= '\x1f\x11\xc4\xab\x920l\xae]=\x10\xd4\x13\x81k\x14\x98e\x8b\xcd\xa0...
mac= b''
pad= b''
padlen= None
###[ TLS ]###
type= application_data
version= TLS 1.2
len= 1517 [deciphered_len= 240]
iv= b''
\msg\
|###[ TLS Application Data ]###
| data= '\xac\x0b\xda\xba\xe8z\x99\xad\x0b_\x82\x96c\xb3\xff\x9f\xcc...
mac= b''
pad= b''
padlen= None```
To access a value of each of these layers (the newly decoded layers start at 0, 2), use the deciphered_len attribute.
>>> pkts[5][TLS][0].deciphered_len
122
>>> pkts[5][TLS][5].deciphered_len
1
>>> extra_tls_layers[0].deciphered_len
1017
>>> extra_tls_layers[2].deciphered_len
240
Verifying completeness
The length of the entire TLS section is 1400 here, which we get with len(pkts[5][TLS]). Note that the TLS record header is 5 bytes (content type = 1 byte, version = 2 bytes, length = 2 bytes).
So with a budget of 1400 bytes, let's check the record lengths:
record 1: 5 + 122 => 127
record 2: 5 + 1 => 6
record 3: 5 + 1017 => 1022
record 4: 5 + 240 => 245
Checking that the 4 TLS records add up,
127 + 6 + 1022 + 245 = 1400 for the TLS section.
Raw packet #6
For future readers, if the pcap is not available, and you're in the scapy interpreter, this is the relevant packet bytes for packet 6:
>>> pkt = b'\x00\r:\x8a\x18P\x124Vx\x9a\xbc\x08\x00E\x00\x05\xa0E\xfc#\x00R\x06)E\x9d\xf0\x08#\n\x00\x04\x04\x01\xbb\xca`0l;1\xfa\x93\n\xc2P\x10\x00r<\xd3\x00\x00\x16\x03\x03\x00z\x02\x00\x00v\x03\x03\x94\x01\xb5\xcc1b\x86Jh\x85\xf0vG\xb7#\xe7\xd2\n\x1d\xd0\'\x01\x8d\xb6\xab\xa9\x8af\x92=h= \x98\x0fJKbJ\xff(sw\xcbdW\xae\x16\x17\xec\xec\xb7\xba\x139\x92/9\xed\xc2\xeb\xa3\x07\x88\xaa\x13\x01\x00\x00.\x00+\x00\x02\x03\x04\x003\x00$\x00\x1d\x00 \xed\xfd\x0f*\x87\x9a;Q\xbb\x88\n\xad*\x9d,C\x96\xdd\x14\xab\xd8\xd8}\xf9(\x8f\xcb\xb3\x10+\xa63\x14\x03\x03\x00\x01\x01\x17\x03\x03\x03\xf9\x1f\x11\xc4\xab\x920l\xae]=\x10\xd4\x13\x81k\x14\x98e\x8b\xcd\xa0\x9f\xca\xfd\xcf\xd5\xc2\xa3\xc9S\xd0\x86G\xf3\xdc\x08\x8a,\x15\xbe+\x84\xfd\x87\x8bk\x956zO\xb3;\x875\xf4\xbd\x01\xe7`\x0f=\x08\xc5\xd8\xe6\x9e\xa4\xd9\xa3\x89C^\x07y"\x85\xb9|\xfc:{\x19\x99r\x9av\x15{\xf6\xf4\x91\x97\xfd\xe6\x7f\xbf\x1c\x81\xb9\x81\xc7W\xbao\x98X>n\'\x91\x11X\x9660\x92\\ub\xb896\xce\r\x84\xe0\x82:r{\xff\xbet\xea*\x03\x97Iw\xc8\x8b\x1d\xe3m\xe2%\x054\xc7\x0e\x9e\xe2LQ")a\x11M\x92eY=\xcc\x89\x9cj\xae\xa73\xf0\x90\xf9.&\xf5\x14\xbc\\\x8f\xa5\xfc\x0e"bD\xce\x92\xb0\x9d\xc3\xddm\xc2\x94\x90\x93T\no\xc7\x10k\x1a\xdfP\xecF\xa9\xeb\xe3=\xe4\xe5\xf5\x8b\x1a]l\x82\xdb\x93\x0c\xb7Q\x15bS\x97\xd6xu\xec\x0fd5$\xb03A\xa8\x14 \x00\xd7h\x82\xb0\xb7\xb3QY\x82%s\xf8H\x1a\xf3\xa1\xac\xcd\x07\xb0=\xdcdv\x16y\x91D\xb1\xbfzq\x92\xcf\x07\xef\x84\x8c\'\xefD\x05\xcb\xe1\xd1\x01\'\xcf\xbedG\rg\x94\x073\x9c\xe7e-\xd3\xd2|\x0e\xa2\xeb$\xc2\xe3\xa4&`\x9c\xd6\xe9\xf3\xd4fP\xf5\xdb\x10\x85\xbf\xc8\xa1\x86d;\x9e\xe3\xa2\xce\xe2Tx\xba~g\t\x8e\xbd5\xce8T\x00\xa4*\xc7\x15\xf1\xa3\xae\x90\xearT\x03\xcaK\xb9\xf8\x04-\xd7\xeb\xfb\xc1<}\x95\x85\xd97\'\xfbIH\xcf\x07\x85G\xd7\xe6~\xaeb\x14*\xcf\xe2#\xbc\xa5\xc79+\x1e\xff\x90 Df[\xc3\xb9;\x9c\x8a\x0b\x02\xb4*\xb7s/\x9c\xaa{\xb7\xbd4\xfb\x00\xa7\xa6u\xdf0\x84\x060\xbf#\x17\xba\x0e\xbe\x86\x83\xc8h\xba!\x86j\x04\x98\x0c/\xfa\xe2wp\x16:z\x04\xc5\xc0yo\x06\xfd\xcd\x9fCxJ\xb0fS\x989\x1c\xe5\xfe\x18Kl\x8b\'\xcday%\xe5\xa7\xa6T_`\x07{\xdc\xe7OI\x80\x03\xc9\x92(\x9f\xa5\xee\x0e\xac\xc4\x01`g*|\x88\x13\x8d\xe3I\x8dZ;\xfdcV\xc0\xdb,*#\xd4Y\xd7\x9b\xe0\xd0J6u\xedn\xe3VR\xab\xb5x(\xe7\x9cF\xfd\xc0\xea\xf2\xb5\xc2\xce\r\xd1\xec\xb6 {\xce;<\x8f\n\x80\xa0\xf7W\xf0R"\x80N\xdc\x82\x92\x19wa\xb3/\xab\xf6\xec\x99\xfa\xca\xeb\x08\xaf\x97\xc8\x89g\xdd\xf3\xf2\xb1|Yo\xca\x0b\xd3_\n/\x8e!\xf7\x11b&\xae\xed\xa3\xcc\\\xeb\xbf\x19\xd6\xacE\x02\n[\xa4i(\xaa\x0cQ\xcf\xf0\xf6"`\x04M\xe9%\x8e\xfdRo\xae]eA6}l\x1e\xe2\x04[\xf0\x93\xa2)\x02\xf1\xd0&\x00_J\xd3y\x99\x90(\x85VrN\t\xf3z\xfel\xd7.\x80\x07\x8e\x1f=\x9c\xebrK\x06 6-O\xb1\x8f\xfa\xc6"f\x02\t%\xf8q\xb5\x14\xcbp*\xb4!({r\x00S\xf1\x19\t\xb2\xafs`\xd1\x0b\xc8\x14V]{B\x15\xc4\xc3\x06\x08\n\xa02&\xe1`b\xf0\xd8PZL\xb5\x8b\x93\xb8<a[\xcc\x07\xadtr\xa3hbNv\xa9t)\xb4hB\xe5\xf5\xe1\xbb\xde\x03\xe3\x14\xac\xe2\xb6i\xfe\x9a/"\x95\x9332 \xabu\xbb\x1a\xf2x\x85C\xad;\x8d\x87\x95;\x14O%\xa9f\xe1\x10x\xce">-\xb3.\xc9w\xf0fB\xfe;\xdd\xea\xf5\x85\xa2\'\x8b\x08\xe8\x1c\xb8\xeb\x7fb\xd4\xf0\xba\x7f\xfd\x9a{\x92]\x0bp5\x91.Q\'\x03Q\xf9#\xbc{\x93\xa9\xc9\x96W&\xb8\x15\x8d\xa9_k\xd2\x8bz\x90\xde\xc0\xa1`\xe4r8\xd2W\xfb\x1f\xd2]S?\xe4\x0cK^\xde\xfds\xd3\xf0\xc6\xb9\x04\x05\xd1\xf6\xb3\xd8\x0fz6\xdf\x86\xa8Z\x1cj\xadO\xa0\x89;\x94%\xa4K"`\x8b:\xdc\xb6\xa0=g\xc7\x04k/f\x04\xf5E\x00\xdd\r\xbd]\xe8\x869+\xd7\x85\xb3{yG\x1bH\x8fn\xad\xd5\xd7\xea\xf6u\x13\x85\xcd\xa3$\xbaF~\x1e\xc1M#>\n!\x97\xcd\x1aF\x86\x84\xb2\x9b\xf9u}\x96\xc68\x89\x97\x17\x03\x03\x05\xed\xac\x0b\xda\xba\xe8z\x99\xad\x0b_\x82\x96c\xb3\xff\x9f\xcc\t\xbd \x9cM\x0bP\xe2\xb0\xa5#\xfb)\xda:K\x9b-\xb0\x0b\xb36p\xe2<oOj\x96\x10\xe2jEq o\xc8\x99\xf2\x0es\x9fj\xc5\x0c\xc5\xc0\x83\x92>\x9d\x05\x17\xed\x85\xc8,Q\xf1W\xa9\xac\x9ez\x19\x14\x90i\x1ef\xe8E\xd6\xf1\x9f\xe0\xc1#\xed\'\x88\xb13\xf5;pg\x18\xc19,\xe2u\xefTJ\xd2\x08\xb5\x8e\xf2\xcf\xd2\xce\xf0L\xfa]\x95\x05wk\x8f\x85\xa2\x8aQ\x00\x12\r\x0f\xa6\xa9\x88:4\xb3\xa3z\xa8\xf6\xeaV\x1c\x86w\xce\xe7\x97\xf4\xc3\x19.\n\xe7>\xb2\x8dj\xcf\\\xaf5{$\xa0L\x1e\x15\xb6\xd4\xc7\xdb\xbc\x99l"D\x890K\xa8\x03\x0fz\xfd\x88\xabH\xcb\xbe\xbc0\xa3\xbetp\x90\xd3_BGe\x93[\x98\x9c\xf86\xc8\xdd\xb3]\x1c\xf0\x83\xbf\xbfs\xccj\xbd\x8fR\x8d\x9e\t\xe8\xce\xd33R/'
>>> # To reconstitute, create an Ethernet packet
>>> new_pkt = Ether(pkt)
Related
following a tutorial I coded a wifi sniffer in python using sockets (on linux) and the "struct" package. The code is splitted in two parts: the first one decodes the Ipv4 header packets getting the Ips and other information and then sends the remaining data to the second part which decodes ICMP, UDP and TCP packets. When I decode the TCP and UDP packets I can easily get source ports and destinations ports, flags etc... but I'm now looking for the host name. In other words Im trying to see which website is visited by the packet sender/receiver.
How can I get the host name? Is it in the "data" part of the tcp/udp packet, if so how to decode it? Do I have to look at the source and destination ports?
Here is the code: 2 functions for UDP/TCP packets, the data argument is the "data" part from a Ipv4 packet.
def tcp_segment(data):
(src_port, dest_port, sequence, acknowledgement, offset_reserved_flags) = struct.unpack('! H H L L H', data[:14])
offset = (offset_reserved_flags >> 12) * 4
flag_urg = (offset_reserved_flags & 32) >> 5
flag_ack = (offset_reserved_flags & 16) >> 4
flag_psh = (offset_reserved_flags & 8) >> 3
flag_rst = (offset_reserved_flags & 4) >> 2
flag_syn = (offset_reserved_flags & 2) >> 1
flag_fin = offset_reserved_flags & 1
return src_port, dest_port, sequence, acknowledgement, flag_urg, flag_ack, flag_psh, flag_rst, flag_syn, flag_fin, data[offset:]
def udp_segment(data):
src_port, dest_port, size = struct.unpack('! H H 2x H', data[:8])
return src_port, dest_port, size, data[8:]
TCP packet
I receive some packets from serial port. Packet example:
last 2 bytes
/\
[ data length ] [ data ] [packet crc]
I get crc, for example, b'w\x06'. Value is 125 (sum(b'w\x06') = 125). I calculate crc of packet: sum(data). And I get 1655. I know that 1655 is the same as b'w\06', but I do not know, how to translate it simply to 125 and compare with right checksum. What I need to convert 1655 to the same value as received packet bytes (125 or b'w\x06')? binascii/struct/something else?
Thanks
You can use int.from_bytes:
int.from_bytes(b'w\x06', 'little')
or with struct:
struct.unpack("<H", b'w\x06')[0]
I would like to send fragmented packets size of 8 bytes and a random starting offset. Also want to leave out the last fragmented packet.
So far I got everything except the fragment of
from scapy.all import *
from random import randint
dip="MY.IP.ADD.RESS"
payload="A"*250+"B"*500
packet=IP(dst=dip,id=12345,off=123)/UDP(sport=1500,dport=1501)/payload
frags=fragment(packet,fragsize=8)
print(packet.show())
for f in frags:
send(f)
What does the above code do?
It sends IP Fragment Packets size of 8 byte to a destination IP address.
I would like to send IP Fragment Packets with a random Frag Offset.
I can't find anything about fragment() and the only field, I was able to edit was in IP packet instead of each fragmented IP packet.
Does someone have an idea to accomplish this?
Infos: Python2.7, latest version of scapy (pip)
If you want to generate "broken" fragment offset fields, you have to do that yourself. The scapy fragment() function is simple enough:
def fragment(pkt, fragsize=1480):
"""Fragment a big IP datagram"""
fragsize = (fragsize + 7) // 8 * 8
lst = []
for p in pkt:
s = raw(p[IP].payload)
nb = (len(s) + fragsize - 1) // fragsize
for i in range(nb):
q = p.copy()
del(q[IP].payload)
del(q[IP].chksum)
del(q[IP].len)
if i != nb - 1:
q[IP].flags |= 1
q[IP].frag += i * fragsize // 8 # <---- CHANGE THIS
r = conf.raw_layer(load=s[i * fragsize:(i + 1) * fragsize])
r.overload_fields = p[IP].payload.overload_fields.copy()
q.add_payload(r)
lst.append(q)
return lst
Source: https://github.com/secdev/scapy/blob/652b77bf12499451b47609b89abc663aa0f69c55/scapy/layers/inet.py#L891
If you change the marked code line above, you can set the fragment offset to whatever you want.
Upon the receive of a TCP ACK (with option experiment) like this
I want to generate a TCP SYN+ACK (with option experiment and Fast Open Cookie) as indicated below
I want to generate the TCP SYN+ACK with scapy so I added
So I added 254 : ("RFC3692-style Experiment","!HHH") in the /usr/share/pyshared/scapy/layers/inet.py like this
TCPOptions = (
{ 0 : ("EOL",None),
1 : ("NOP",None),
2 : ("MSS","!H"),
3 : ("WScale","!B"),
4 : ("SAckOK",None),
5 : ("SAck","!"),
8 : ("Timestamp","!II"),
14 : ("AltChkSum","!BH"),
15 : ("AltChkSumOpt",None),
25 : ("Mood","!p"),
254 : ("Experiment","!HHHH")
},
{ "EOL":0,
"NOP":1,
"MSS":2,
"WScale":3,
"SAckOK":4,
"SAck":5,
"Timestamp":8,
"AltChkSum":14,
"AltChkSumOpt":15,
"Mood":25,
"Experiment":254
} )
And upon the receive of the TCP ACK (with experiment option), I executhe the following scapy function:
TCP_SYNACK=TCP(sport=Ddport, dport=Ssport, flags="SA", seq=SeqNr, ack=AckNr, options=[('Experiment',0xf989,0xcafe,0x0102,0x0002),('NOP',0),('NOP',0)])
ANSWER=sr1(ip/TCP_SYNACK)
But I got a python error. It looks like I made error in the definition of the option field in the TCP packet with scapy. What I m doing wron?
I think you need to specify the optional field's value in a tuple format, as follows:
TCP_SYNACK = TCP(sport=Ddport, dport=Ssport, flags="SA", seq=SeqNr, ack=AckNr, options=[('Experiment', (0xf989, 0xcafe, 0x0102, 0x0002)), ('NOP', 0), ('NOP', 0)])
but I had the same problem. You can actually put an integer as the first element of your options tuple. I wanted to put in a hash, so I used the following code in scapy:
pkt = TCP(options=[("NOP", None), (19, "\xff\xff\xff\xff\xff\xff")])
I am interested in being able to detect specific parameters using the loading time it took a request from when I send it to when it got to the server.
The request I am talking about is the SYN packet in a three way hand shake.
How can I do this?
Looking forward to your answer!
Of course also what language should I use...I am testing with Python + Scapy right now.
If you want to use Scapy (which seems a reasonable choice for what you want to do), you need to use the Packet.time attribute. Here is a simple example:
>>> def measure_delay(packet):
... ans, _ = sr(packet, verbose=False)
... if ans:
... return reduce(lambda x, y: y.time - x.time, ans[0])
...
>>> measure_delay(IP(dst='192.168.1.254')/TCP(dport=80))
0.07259798049926758
From a Unix command line, you can also use hping3, and look for the rtt= value:
# sudo hping3 --syn 192.168.1.254 -p 80 -c 1
HPING 192.168.1.254 (wlan0 192.168.1.254): S set, 40 headers + 0 data bytes
len=44 ip=192.168.1.254 ttl=64 DF id=0 sport=80 flags=SA seq=0 win=14600 rtt=3.1 ms
--- 192.168.1.254 hping statistic ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 3.1/3.1/3.1 ms