Brief description
scapy writes key logs to temporary files as bytes
|
with open(filename, "wb") as fd: |
|
fd.write(secrets_data) |
|
fd.close() |
|
|
|
keys = load_nss_keys(filename) |
and then
load_nss_keys opens them using the default UTF-8 encoding:
|
with open(filename) as fd: |
and it leads to UnicodeDecodeError when the decoder fails.
Scapy version
81b51d0
Python version
3.11.2
Operating system
Linux version 6.1.14-200.fc37
Additional environment information
No response
How to reproduce
diff --git a/test/tls.uts b/test/tls.uts
index 474db2b3..42879d3e 100644
--- a/test/tls.uts
+++ b/test/tls.uts
@@ -1590,3 +1590,36 @@ if shutil.which("editcap"):
assert b"GET /secret.txt HTTP/1.0\n" in packets[11].msg[0].data
assert b"z2|gxarIKOxt,G1d>.Q2MzGY[k@" in packets[13].msg[0].data
conf = bck_conf
+
+= pcapng file with a non-UTF-8 Decryption Secrets Block
+
+hdump = """
+00000000 0a 0d 0d 0a c4 00 00 00 4d 3c 2b 1a 01 00 00 00 |........M<+.....|
+00000010 ff ff ff ff ff ff ff ff 02 00 37 00 49 6e 74 65 |..........7.Inte|
+00000020 6c 28 52 29 20 43 6f 72 65 28 54 4d 29 20 69 37 |l(R) Core(TM) i7|
+00000030 2d 36 37 30 30 48 51 20 43 50 55 20 40 20 32 2e |-6700HQ CPU @ 2.|
+00000040 36 30 47 48 7a 20 28 77 69 74 68 20 53 53 45 34 |60GHz (with SSE4|
+00000050 2e 32 29 00 03 00 2a 00 4c 69 6e 75 78 20 34 2e |.2)...*.Linux 4.|
+00000060 32 30 2e 31 32 2d 67 65 6e 74 6f 6f 2d 61 6e 64 |20.12-gentoo-and|
+00000070 72 6f 6d 65 64 61 2d 32 30 31 39 30 33 30 35 2d |romeda-20190305-|
+00000080 76 31 00 00 04 00 33 00 44 75 6d 70 63 61 70 20 |v1....3.Dumpcap |
+00000090 28 57 69 72 65 73 68 61 72 6b 29 20 33 2e 31 2e |(Wireshark) 3.1.|
+000000a0 30 20 28 76 33 2e 31 2e 30 72 63 30 2d 34 36 38 |0 (v3.1.0rc0-468|
+000000b0 2d 67 65 33 65 34 32 32 32 62 29 00 00 00 00 00 |-ge3e4222b).....|
+000000c0 c4 00 00 00 0a 00 00 00 c4 00 00 00 4b 53 4c 54 |............KSLT|
+000000d0 b0 00 00 00 43 4c 49 45 4e 54 5f 52 41 4e 44 4f |....CLIENT_RANDO|
+000000e0 4d 20 41 36 39 39 35 43 37 44 35 41 35 31 35 42 |M A6995C7D5A515B|
+000000f0 30 44 34 39 41 31 42 38 31 33 33 39 33 34 32 37 |0D49A1B813393427|
+00000100 43 43 35 43 39 44 42 37 36 36 37 38 45 34 38 44 |CC5C9DB76678E48D|
+00000110 31 41 43 35 39 31 44 37 44 37 44 35 42 38 30 31 |1AC591D7D7D5B801|
+00000120 44 43 20 34 30 33 37 35 37 34 30 31 42 30 30 37 |DC 403757401B007|
+00000130 34 35 33 38 33 41 46 36 41 36 30 38 31 39 42 43 |45383AF6A60819BC|
+00000140 37 46 38 42 36 33 39 33 42 37 32 45 44 45 39 46 |7F8B6393B72EDE9F|
+00000150 45 42 32 30 44 33 31 33 46 38 31 42 39 c0 bd bb |EB20D313F81B9...|
+00000160 c6 36 46 36 41 43 37 34 32 46 46 46 35 45 43 31 |.6F6AC742FFF5EC1|
+00000170 44 31 41 32 44 39 39 41 46 34 39 35 33 45 31 33 |D1A2D99AF4953E13|
+00000180 33 34 41 0a c4 00 00 00 |34A.....|
+00000188
+""".strip()
+
+rdpcap(io.BytesIO(import_hexcap(hdump)))
Actual result
>>> rdpcap(io.BytesIO(import_hexcap(hdump)))
Traceback (most recent call last):
File "<input>", line 2, in <module>
File "/home/vagrant/scapy-2/scapy/utils.py", line 1142, in rdpcap
return fdesc.read_all(count=count)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/vagrant/scapy-2/scapy/utils.py", line 1414, in read_all
res = self._read_all(count)
^^^^^^^^^^^^^^^^^^^^^
File "/home/vagrant/scapy-2/scapy/utils.py", line 1324, in _read_all
p = self.read_packet() # type: Packet
^^^^^^^^^^^^^^^^^^
File "/home/vagrant/scapy-2/scapy/utils.py", line 1729, in read_packet
rp = super(PcapNgReader, self)._read_packet(size=size)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/vagrant/scapy-2/scapy/utils.py", line 1527, in _read_packet
res = self._read_block()
^^^^^^^^^^^^^^^^^^
File "/home/vagrant/scapy-2/scapy/utils.py", line 1481, in _read_block
return self.blocktypes.get(
^^^^^^^^^^^^^^^^^^^^
File "/home/vagrant/scapy-2/scapy/utils.py", line 1703, in _read_block_dsb
keys = load_nss_keys(filename)
^^^^^^^^^^^^^^^^^^^^^^^
File "/home/vagrant/scapy-2/scapy/layers/tls/session.py", line 47, in load_nss_keys
for line in fd:
File "<frozen codecs>", line 322, in decode
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xc0 in position 137: invalid start byte
Expected result
I think decryption secrets blocks like that should probably be just ignored.
On a somewhat related note I'm not sure scapy should fully log those secrets when the parser fails because it's relatively easy to screw something up with, say, editcap --inject-secrets and inject actual secrets that can be rejected by the parser anyway. For example wireshark doesn't even complain about that by default. When the debug log level is on it just prints something like pcapng_read_block(): wtap_read_bytes_or_eof() failed without being specific.
Related resources
No response
Brief description
scapywrites key logs to temporary files as bytesscapy/scapy/utils.py
Lines 1699 to 1703 in 378be02
and then
load_nss_keysopens them using the default UTF-8 encoding:scapy/scapy/layers/tls/session.py
Line 46 in 378be02
and it leads to UnicodeDecodeError when the decoder fails.
Scapy version
81b51d0
Python version
3.11.2
Operating system
Linux version 6.1.14-200.fc37
Additional environment information
No response
How to reproduce
Actual result
Expected result
I think decryption secrets blocks like that should probably be just ignored.
On a somewhat related note I'm not sure scapy should fully log those secrets when the parser fails because it's relatively easy to screw something up with, say,
editcap --inject-secretsand inject actual secrets that can be rejected by the parser anyway. For example wireshark doesn't even complain about that by default. When the debug log level is on it just prints something likepcapng_read_block(): wtap_read_bytes_or_eof() failedwithout being specific.Related resources
No response