13{
14 readonly Socket socket = socket;
15
16
17
18
19
20 byte[] clientRandom = [];
21 ushort sessionID_size;
22 byte[] fakeSessionID = [];
23 readonly List<Ciphers> cipherSuites = [];
24
25 public void Parse(byte[] data)
26 {
27 Console.Clear();
28 PrintDatatable(data);
29 PrintDatatableASCII(data);
30
31
32 Console.WriteLine($"(offset : 0 )\tRequest Type: {data[0]:X2} (16 == Handshake record))");
33 Console.WriteLine($"(offset: 1)\tTLS Version (Major): {data[1]:X2} (Minor): {data[2]:X2})");
34
35 int handshakeLength = Utils.BytesToUShort([data[3], data[4]]);
36 Console.WriteLine(
37 $"(offset: 3)\tHandshake length (bytes): {data[3]:X2}{data[4]:X2} (int : {handshakeLength}) handshake ends at row {(handshakeLength + 4) / 16} col {(handshakeLength + 4) % 16})");
38
39 Console.WriteLine($"(offset 5)\tHandshake Type: {data[5]:X2} (1 == Client Hello))");
40 Console.WriteLine(
41 $"(offset 6)\tHandshake length (bytes): {data[6]:X2}{data[7]:X2}{data[8]:X2} (int : {Utils.UInt24ToUInt32([data[6], data[7], data[8]])})");
42
43 Console.WriteLine($"(offset 9)\tClient Version (Major): {data[9]:X2} (Minor): {data[10]:X2})");
44
45 if (data[9] == 0x03 && data[10] == 0x03)
46 {
48 Console.WriteLine(c);
49 return;
50
51 Console.WriteLine("Detected client TLS v1.3");
52 ParseTLS_1_3(data, handshakeLength);
53 ParseTLSv1_3(data);
54 }
55 else
56 {
57 Console.WriteLine("Detected client TLS up to v1.2");
58
59 }
60 }
61
62 static void PrintDatatable(byte[] data)
63 {
64 Console.WriteLine("Printing raw request preview\n============================================");
65
66 Console.WriteLine("\t 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15");
67 int i = 0;
68 int j = 0;
69 Console.Write($"{0}\t");
70 foreach (byte b in data)
71 {
72 Console.Write($"{b:X2} ");
73 i++;
74 if (i == 16)
75 {
76 j++;
77 Console.WriteLine("");
78 Console.Write($"{j}\t");
79 i = 0;
80 }
81 }
82
83 Console.WriteLine("\n====================================");
84 }
85
86 static void PrintDatatableASCII(byte[] data)
87 {
88 Console.WriteLine("Printing raw request preview\n============================================");
89
90 Console.WriteLine("\t 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15");
91 int i = 0;
92 int j = 0;
93 Console.Write($"{0}\t");
94 var str = Encoding.ASCII.GetString(data).ToCharArray();
95 for (int k = 0; k < data.Length; k++)
96 {
97 Console.Write($"{str[k]} ");
98 i++;
99 if (i == 16)
100 {
101 j++;
102 Console.WriteLine("");
103 Console.Write($"{j}\t");
104 i = 0;
105 }
106 }
107
108 Console.WriteLine("\n====================================");
109 }
110
111
112
113
114
115
116 private void ParseTLSv1_3(byte[] data)
117 {
118 Console.WriteLine("=============================\nNew parser result:");
120
121 byte requestType = d.ReadByte();
122 byte[] TLS_Version = d.ReadBytes(DataOffsets.TLS_VERSION.size);
123 byte[] msgLength = d.ReadBytes(DataOffsets.MESSAGE_LENGTH.size);
124 byte handshakeType = d.ReadByte();
125 byte[] handshakeLenght = d.ReadBytes(DataOffsets.HANDSHAKE_DATA_LENGHT.size);
126 uint handshakeLenghtInt = Utils.UInt24ToUInt32(handshakeLenght);
127
128
129 uint endPosition =
130 handshakeLenghtInt +
131 1 +
132 DataOffsets.TLS_VERSION.size +
133 DataOffsets.MESSAGE_LENGTH.size +
134 1 +
135 DataOffsets.HANDSHAKE_DATA_LENGHT.size;
136 d.SetEndPosition(Math.Min(endPosition, 512));
137
138 byte[] clientVersion = d.ReadBytes(DataOffsets.CLIENT_VERSION.size);
139 byte[] clientRandom = d.ReadBytes(32);
140 byte sessionIDSize = d.ReadByte();
141 byte[] fakeSessionID = d.ReadBytes(sessionIDSize);
142 byte[] cipherSuitesLength = d.ReadBytes(2);
143 ushort cipherSuitesLengthInt = Utils.BytesToUShort(cipherSuitesLength);
144 List<Ciphers> ciphers = [];
145 for (int i = 0; i < cipherSuitesLengthInt; i += 2)
146 {
147 ciphers.Add(GetCipher(d.ReadBytes(2)));
148 }
149
150 byte[] compressionData = d.ReadBytes(2);
151 byte[] extensionsLength = d.ReadBytes(2);
152 extensionsLength[0] = 0x0;
153 ushort extensionsLengthInt = Utils.BytesToUShort(extensionsLength);
154 List<IExtension> extensions = [];
155
156 while (d.DataAvailable() && extensionsLengthInt > 0 && extensionsLengthInt < 512)
157 {
158 IExtension e = ExtensionUtils.ReadExtension(d);
159 extensions.Add(e);
160
161 }
162
163
164 Console.Write(
165 $"Request Type: 0x{requestType:X2}" +
166 $"\nTLS Version: 0x{BitConverter.ToString(TLS_Version).Replace("-", " 0x")}" +
167 $"\nMessage Length: 0x{BitConverter.ToString(msgLength).Replace("-", " 0x")} ({Utils.BytesToUShort(msgLength)})" +
168 $"\nHandshake Type: 0x{handshakeType:X2}" +
169 $"\nHandshake Length: 0x{BitConverter.ToString(handshakeLenght).Replace("-", " 0x")} ({Utils.UInt24ToUInt32(handshakeLenght)})" +
170 $"\nClient Version: 0x{BitConverter.ToString(clientVersion).Replace("-", " 0x")}" +
171 $"\nClient Random: 0x{BitConverter.ToString(clientRandom).Replace("-", " 0x")}" +
172 $"\nSession ID: 0x{sessionIDSize:X2}" +
173 $"\nFake Session ID: 0x{BitConverter.ToString(fakeSessionID).Replace("-", " 0x")}0" +
174 $"\nCipher Suites Length: 0x{BitConverter.ToString(cipherSuitesLength).Replace("-", " 0x")} ({cipherSuitesLengthInt} bytes, {cipherSuitesLengthInt / 2} ciphers)" +
175 $"\nCipher Suites: \n\t{string.Join(",\n\t", ciphers)}" +
176 $"\nCompression Data: 0x{BitConverter.ToString(compressionData).Replace("-", " 0x")}" +
177 $"\nExtensions Length: 0x{BitConverter.ToString(extensionsLength).Replace("-", " 0x")} ({extensionsLengthInt} bytes)\n"
178 );
179
181 Console.WriteLine("\t" + e.ToString());
182
183
184 ClientHello clientHello =
new(clientRandom, fakeSessionID, ciphers, extensions);
185 ServerHello serverHello = new(clientHello);
186 serverHello.BuildResponse();
187
188
189
190
191
192
193
194
195
196 Console.WriteLine("Done");
197 }
198
199 private void ParseTLS_1_3(byte[] data, int handshake_length)
200 {
201
202
203 int offset = 11;
204 int col = offset % 16;
205 int row = offset / 16;
206
207
208
209 clientRandom = new byte[32];
210 Array.Copy(data, offset, clientRandom, 0, 32);
211 uint clientRandomInt = BitConverter.ToUInt32(clientRandom);
212 Console.WriteLine(
213 $"(offset {offset} (riga {row}, col {col}))\tRandom (32 bytes): 0x{BitConverter.ToString(clientRandom).Replace("-", " 0x")}");
214 Console.WriteLine($"The 32bit random number is : {clientRandomInt}");
215 offset += 32;
216 col = offset % 16;
217 row = offset / 16;
218
219 sessionID_size = data[offset];
220 Console.WriteLine(
221 $"(offset {offset} (riga {row}, col {col}))\tSession ID size: {data[offset]:X2} (int : {sessionID_size})");
222 fakeSessionID = new byte[sessionID_size];
223 Array.Copy(data, offset + 1, fakeSessionID, 0, sessionID_size);
224 Console.WriteLine(
225 $"(offset {offset} (riga {row}, col {col}))\tSession ID: {BitConverter.ToString(fakeSessionID).Replace("-", " ")}");
226 offset += 1 + sessionID_size;
227
228 col = offset % 16;
229 row = offset / 16;
230 ushort cipher_suites_length =
231 Utils.BytesToUShort([data[offset], data[offset + 1]]);
232 Console.WriteLine(
233 $"(offset {offset} (riga {row}, col {col}))\tCipher Suites Length: {data[offset]:X2} {data[offset + 1]:X2} (int : {cipher_suites_length / 2})");
234 offset += 2;
235 col = offset % 16;
236 row = offset / 16;
237 for (int i = 0; i < cipher_suites_length; i += 2)
238 {
239 Console.Write(
240 $"(offset {offset} (riga {row}, col {col}))\tCipher Suite: 0x{data[offset]:X2}, 0x{data[offset + 1]:X2} -> ");
241 var cS = GetCipher([data[offset], data[offset + 1]]);
242 cipherSuites.Add(cS);
243 Console.WriteLine(cS);
244 offset += 2;
245 col = offset % 16;
246 row = offset / 16;
247 }
248
249
250 Console.WriteLine(
251 $"(offset {offset} (riga {row}, col {col}))\tCompression Data: {data[offset]:X2} {data[offset + 1]:X2}");
252 offset += 2;
253
254 col = offset % 16;
255 row = offset / 16;
256 ushort extensions_length = Utils.BytesToUShort([data[offset], data[offset + 1]]);
257
258 Console.WriteLine(
259 $"(offset {offset} (riga {row}, col {col}))\tExtensions Length: {data[offset]:X2} {data[offset + 1]:X2} (int : {extensions_length}))");
260 offset += 2;
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275 Console.WriteLine("Client Hello (TLS version 1.3) parsed!");
276 }
277
278 private void ParseTLS_UP_TO_1_2(byte[] data)
279 {
280 int i;
281
282 Console.WriteLine($"(offset 11)\tRandom (32 bytes): {BitConverter.ToString(data, 11, 32).Replace("-", " ")}");
283
284 Console.WriteLine($"(offset 43 (riga {43 / 16}, col {43 % 16}))\tSession ID: 0x{data[43]:X2}");
285
286
287 ushort cipher_suites_length = Utils.BytesToUShort([data[44], data[45]]);
288 Console.WriteLine(
289 $"(offset 44 (riga {44 / 16}, col {44 % 16}))\tCipher Suites Length: {data[44]:X2} {data[45]:X2} (int : {cipher_suites_length / 2})");
290 int offset = 46;
291 int col = offset % 16;
292 int row = offset / 16;
293
294 for (i = 0; i < cipher_suites_length; i += 2)
295 {
296 offset += i;
297 Console.Write(
298 $"(offset {offset} (riga {row}, col {col}))\tCipher Suite: 0x{data[46 + i]:X2}, 0x{data[47 + i]:X2} -> ");
299 Console.WriteLine(CipherSuite.GetCipher([data[46 + i], data[47 + i]]));
300 }
301
302
303 offset = 46 + cipher_suites_length;
304 col = offset % 16;
305 row = offset / 16;
306 Console.WriteLine(
307 $"(offset {offset} (riga {row}, col {col}))\tCompression Methods Length: {data[offset]:X2} {data[offset + 1]:X2} (int : {Utils.BytesToUShort([data[offset], data[offset + 1]])})");
308 offset += 2;
309 col = offset % 16;
310 row = offset / 16;
311
312 int extensionsLength = Utils.BytesToUShort([data[offset], data[offset + 1]]);
313 Console.WriteLine(
314 $"(offset {offset} (riga {row}, col {col}))\tExtensions Length: {data[offset]:X2} {data[offset + 1]:X2} (int : {extensionsLength}))");
315 offset += 2;
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347 Console.WriteLine("Client Hello (TLS version max 1.2) parsed!");
348 }
349}
class DataReader(byte[] data)
A class to simplify reading data from a byte array.