|
12 | 12 | ] |
13 | 13 | }, |
14 | 14 | { |
15 | | - "cell_type": "code", |
16 | | - "execution_count": null, |
17 | 15 | "metadata": {}, |
18 | | - "outputs": [], |
| 16 | + "cell_type": "code", |
19 | 17 | "source": [ |
20 | 18 | "from scapy.all import *\n", |
21 | 19 | "load_layer('tls')" |
22 | | - ] |
| 20 | + ], |
| 21 | + "outputs": [], |
| 22 | + "execution_count": null |
23 | 23 | }, |
24 | 24 | { |
25 | | - "cell_type": "code", |
26 | | - "execution_count": null, |
27 | 25 | "metadata": {}, |
28 | | - "outputs": [], |
| 26 | + "cell_type": "code", |
29 | 27 | "source": [ |
30 | 28 | "record1_str = open('raw_data/tls_session_compromised/01_cli.raw', 'rb').read()\n", |
31 | 29 | "record1 = TLS(record1_str)\n", |
32 | 30 | "record1.msg[0].show()" |
33 | | - ] |
| 31 | + ], |
| 32 | + "outputs": [], |
| 33 | + "execution_count": null |
34 | 34 | }, |
35 | 35 | { |
36 | 36 | "cell_type": "code", |
37 | | - "execution_count": null, |
38 | 37 | "metadata": { |
39 | 38 | "scrolled": true |
40 | 39 | }, |
41 | | - "outputs": [], |
42 | 40 | "source": [ |
43 | 41 | "record2_str = open('raw_data/tls_session_compromised/02_srv.raw', 'rb').read()\n", |
44 | 42 | "record2 = TLS(record2_str, tls_session=record1.tls_session.mirror())\n", |
45 | 43 | "record2.msg[0].show()" |
46 | | - ] |
| 44 | + ], |
| 45 | + "outputs": [], |
| 46 | + "execution_count": null |
47 | 47 | }, |
48 | 48 | { |
49 | 49 | "cell_type": "code", |
50 | | - "execution_count": null, |
51 | 50 | "metadata": {}, |
52 | | - "outputs": [], |
53 | 51 | "source": [ |
54 | 52 | "# Supposing that the private key of the server was stolen,\n", |
55 | 53 | "# the traffic can be decoded by registering it to the Scapy TLS session\n", |
56 | 54 | "key = PrivKey('raw_data/pki/srv_key.pem')\n", |
57 | 55 | "record2.tls_session.server_rsa_key = key" |
58 | | - ] |
| 56 | + ], |
| 57 | + "outputs": [], |
| 58 | + "execution_count": null |
59 | 59 | }, |
60 | 60 | { |
61 | 61 | "cell_type": "code", |
62 | | - "execution_count": null, |
63 | 62 | "metadata": {}, |
64 | | - "outputs": [], |
65 | 63 | "source": [ |
66 | 64 | "record3_str = open('raw_data/tls_session_compromised/03_cli.raw', 'rb').read()\n", |
67 | 65 | "record3 = TLS(record3_str, tls_session=record2.tls_session.mirror())\n", |
68 | 66 | "record3.show()" |
69 | | - ] |
| 67 | + ], |
| 68 | + "outputs": [], |
| 69 | + "execution_count": null |
70 | 70 | }, |
71 | 71 | { |
72 | 72 | "cell_type": "code", |
73 | | - "execution_count": null, |
74 | 73 | "metadata": {}, |
75 | | - "outputs": [], |
76 | 74 | "source": [ |
77 | 75 | "record4_str = open('raw_data/tls_session_compromised/04_srv.raw', 'rb').read()\n", |
78 | 76 | "record4 = TLS(record4_str, tls_session=record3.tls_session.mirror())\n", |
79 | 77 | "record4.show()" |
80 | | - ] |
| 78 | + ], |
| 79 | + "outputs": [], |
| 80 | + "execution_count": null |
81 | 81 | }, |
82 | 82 | { |
83 | 83 | "cell_type": "code", |
84 | | - "execution_count": null, |
85 | 84 | "metadata": {}, |
86 | | - "outputs": [], |
87 | 85 | "source": [ |
88 | 86 | "# This is the first TLS Record containing user data. If decryption works,\n", |
89 | 87 | "# you should see the string \"To boldly go where no man has gone before...\" in plaintext.\n", |
90 | 88 | "record5_str = open('raw_data/tls_session_compromised/05_cli.raw', 'rb').read()\n", |
91 | 89 | "record5 = TLS(record5_str, tls_session=record4.tls_session.mirror())\n", |
92 | 90 | "record5.show()" |
93 | | - ] |
| 91 | + ], |
| 92 | + "outputs": [], |
| 93 | + "execution_count": null |
94 | 94 | }, |
95 | 95 | { |
96 | | - "cell_type": "markdown", |
97 | 96 | "metadata": {}, |
| 97 | + "cell_type": "markdown", |
98 | 98 | "source": [ |
99 | 99 | "# Decrypting TLS Traffic Protected with PFS\n", |
100 | 100 | "\n", |
|
104 | 104 | "```\n", |
105 | 105 | "cd doc/notebooks/tls/raw_data/\n", |
106 | 106 | "\n", |
107 | | - "# Start a TLS 1.12 Server using the s_server\n", |
108 | | - "sudo openssl s_server -accept localhost:443 -cert pki/srv_cert.pem -key pki/srv_key.pem -WWW -tls1_2\n", |
| 107 | + "# Start a TLS Server using the s_server\n", |
| 108 | + "sudo openssl s_server -accept localhost:443 -cert pki/srv_cert.pem -key pki/srv_key.pem -WWW\n", |
109 | 109 | "\n", |
110 | 110 | "# Sniff the network and write packets to a file\n", |
111 | 111 | "sudo tcpdump -i lo -w tls_nss_example.pcap port 443\n", |
112 | 112 | "\n", |
113 | | - "# Connect to the server using s_client and retrieve the secrets.txt file\n", |
114 | | - "openssl s_client -connect localhost:443 -keylogfile tls_nss_example.keys.txt\n", |
| 113 | + "# Connect to the server using TLS 1.2 and TLS 1.3, and write the keys to a file\n", |
| 114 | + "echo -e \"GET /pki/srv_key.pem HTTP/1.0\\r\\n\" | openssl s_client -connect localhost:443 -keylogfile tls_nss_example.keys.txt -tls1_2 -ign_eof\n", |
| 115 | + "echo -e \"GET /pki/srv_key.pem HTTP/1.0\\r\\n\" | openssl s_client -connect localhost:443 -keylogfile tls_nss_example.keys.txt -tls1_3 -ign_eof\n", |
115 | 116 | "```\n", |
116 | 117 | "\n", |
117 | 118 | "## Decrypt a PCAP files\n", |
|
120 | 121 | ] |
121 | 122 | }, |
122 | 123 | { |
123 | | - "cell_type": "code", |
124 | | - "execution_count": null, |
125 | 124 | "metadata": {}, |
126 | | - "outputs": [], |
| 125 | + "cell_type": "code", |
127 | 126 | "source": [ |
128 | 127 | "load_layer(\"tls\")\n", |
129 | 128 | "\n", |
130 | 129 | "conf.tls_session_enable = True\n", |
131 | 130 | "conf.tls_nss_filename = \"raw_data/tls_nss_example.keys.txt\"\n", |
132 | 131 | "\n", |
133 | | - "packets = rdpcap(\"raw_data/tls_nss_example.pcap\")" |
134 | | - ] |
| 132 | + "packets = sniff(offline=\"raw_data/tls_nss_example.pcap\", session=TCPSession)" |
| 133 | + ], |
| 134 | + "outputs": [], |
| 135 | + "execution_count": null |
135 | 136 | }, |
136 | 137 | { |
137 | | - "cell_type": "code", |
138 | | - "execution_count": null, |
139 | 138 | "metadata": {}, |
140 | | - "outputs": [], |
| 139 | + "cell_type": "code", |
141 | 140 | "source": [ |
142 | | - "# Display the HTTP GET query\n", |
143 | | - "packets[11][TLS].show()" |
144 | | - ] |
| 141 | + "# Display the TLS1.2 HTTP GET query\n", |
| 142 | + "packets[9][TLS].show()" |
| 143 | + ], |
| 144 | + "outputs": [], |
| 145 | + "execution_count": null |
145 | 146 | }, |
146 | 147 | { |
| 148 | + "metadata": {}, |
147 | 149 | "cell_type": "code", |
148 | | - "execution_count": null, |
| 150 | + "source": [ |
| 151 | + "# Display the answer containing the secret\n", |
| 152 | + "packets[10][TLS].show()" |
| 153 | + ], |
| 154 | + "outputs": [], |
| 155 | + "execution_count": null |
| 156 | + }, |
| 157 | + { |
149 | 158 | "metadata": {}, |
| 159 | + "cell_type": "code", |
| 160 | + "source": [ |
| 161 | + "# Display the TLS1.3 HTTP GET query\n", |
| 162 | + "packets[27][TLS13].show()" |
| 163 | + ], |
150 | 164 | "outputs": [], |
| 165 | + "execution_count": null |
| 166 | + }, |
| 167 | + { |
| 168 | + "metadata": {}, |
| 169 | + "cell_type": "code", |
151 | 170 | "source": [ |
152 | 171 | "# Display the answer containing the secret\n", |
153 | | - "packets[13][TLS].show()" |
154 | | - ] |
| 172 | + "packets[28][TLS13].show()" |
| 173 | + ], |
| 174 | + "outputs": [], |
| 175 | + "execution_count": null |
155 | 176 | }, |
156 | 177 | { |
157 | 178 | "cell_type": "markdown", |
|
166 | 187 | }, |
167 | 188 | { |
168 | 189 | "cell_type": "code", |
169 | | - "execution_count": null, |
170 | 190 | "metadata": {}, |
171 | | - "outputs": [], |
172 | 191 | "source": [ |
173 | 192 | "# Read packets from a pcap\n", |
174 | 193 | "load_layer(\"tls\")\n", |
175 | 194 | "\n", |
| 195 | + "conf.tls_session_enable = False\n", |
176 | 196 | "packets = rdpcap(\"raw_data/tls_nss_example.pcap\")\n", |
177 | 197 | "\n", |
178 | 198 | "# Load the keys from a NSS Key Log\n", |
179 | 199 | "nss_keys = load_nss_keys(\"raw_data/tls_nss_example.keys.txt\")" |
180 | | - ] |
| 200 | + ], |
| 201 | + "outputs": [], |
| 202 | + "execution_count": null |
181 | 203 | }, |
182 | 204 | { |
183 | 205 | "cell_type": "code", |
184 | | - "execution_count": null, |
185 | 206 | "metadata": {}, |
186 | | - "outputs": [], |
187 | 207 | "source": [ |
188 | 208 | "# Parse the Client Hello message from its raw bytes. This configures a new tlsSession object\n", |
189 | 209 | "client_hello = TLS(raw(packets[3][TLS]))\n", |
|
192 | 212 | "server_hello = TLS(raw(packets[5][TLS]), tls_session=client_hello.tls_session.mirror())\n", |
193 | 213 | "\n", |
194 | 214 | "# Configure the TLS master secret retrieved from the NSS Key Log\n", |
195 | | - "server_hello.tls_session.master_secret = nss_keys[\"CLIENT_RANDOM\"][\"Secret\"]\n", |
| 215 | + "server_hello.tls_session.master_secret = nss_keys[\"CLIENT_RANDOM\"][client_hello.tls_session.client_random]\n", |
| 216 | + "server_hello.tls_session.compute_ms_and_derive_keys()\n", |
196 | 217 | "\n", |
197 | 218 | "# Parse remaining TLS messages\n", |
198 | 219 | "client_finished = TLS(raw(packets[7][TLS]), tls_session=server_hello.tls_session.mirror())\n", |
199 | | - "server_finished = TLS(raw(packets[9][TLS]), tls_session=client_finished.tls_session.mirror())" |
200 | | - ] |
| 220 | + "server_finished = TLS(raw(packets[8][TLS]), tls_session=client_finished.tls_session.mirror())" |
| 221 | + ], |
| 222 | + "outputs": [], |
| 223 | + "execution_count": null |
201 | 224 | }, |
202 | 225 | { |
203 | 226 | "cell_type": "code", |
204 | | - "execution_count": null, |
205 | 227 | "metadata": {}, |
206 | | - "outputs": [], |
207 | 228 | "source": [ |
208 | 229 | "# Display the HTTP GET query\n", |
209 | | - "http_query = TLS(raw(packets[11][TLS]), tls_session=server_finished.tls_session.mirror())\n", |
| 230 | + "http_query = TLS(raw(packets[9][TLS]), tls_session=server_finished.tls_session.mirror())\n", |
210 | 231 | "http_query.show()" |
211 | | - ] |
| 232 | + ], |
| 233 | + "outputs": [], |
| 234 | + "execution_count": null |
212 | 235 | }, |
213 | 236 | { |
214 | 237 | "cell_type": "code", |
215 | | - "execution_count": null, |
216 | 238 | "metadata": {}, |
217 | | - "outputs": [], |
218 | 239 | "source": [ |
219 | 240 | "# Display the answer containing the secret\n", |
220 | | - "http_response = TLS(raw(packets[13][TLS]), tls_session=http_query.tls_session.mirror())\n", |
| 241 | + "http_response = TLS(raw(packets[10][TLS]), tls_session=http_query.tls_session.mirror())\n", |
221 | 242 | "http_response.show()" |
222 | | - ] |
| 243 | + ], |
| 244 | + "outputs": [], |
| 245 | + "execution_count": null |
223 | 246 | } |
224 | 247 | ], |
225 | 248 | "metadata": { |
|
0 commit comments