先讲点废话,这个比赛本来半决打进后,由于时间跟其他比赛冲突,本来都要放弃了,但刚好美亚柏科本部就在厦门,跟主办方商量了一下,安排在第一场比,可以错开时间,没想到,误打误撞还拿了个一等,属实有点意外。有道Misc,也是唯一,一道misc,线下没有存WinRM解密脚本,没搓出来,赛后复现了一下,就有了这篇。

image-20250126221702995

题目问题:

plaintext
1
2
3
1.系统管理员密码是多少
2.加密脚本的IV是多少
3.flag值是多少

在流量包导出的文件中,删除无关的文件,即扫描器扫描出404网页

plaintext
1
find . -type f -size 2659c -exec rm -f {} +

说明:

  1. find .:表示在当前目录及其子目录中查找。
  2. -type f:表示仅查找普通文件。
  3. -size 2659c:匹配文件大小为 2659 字节(c 表示字节)。
  4. -exec rm -f {} +:删除找到的文件。
    • rm -f:强制删除文件,不会提示。
    • {}:占位符,表示找到的文件名。
    • +:优化执行,将多个文件传递给 rm 一次删除。

找到mz.log文件。

plaintext
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
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
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
Using 'mz.log' for logfile : OK
ERROR kuhl_m_sekurlsa_acquireLSA ; Handle on memory (0x00000005)

Rdp TS Passwords
ERROR kuhl_m_ts_logonpasswords ; OpenProcess (0x00000005)
ERROR kuhl_m_lsadump_lsa_getHandle ; OpenProcess (0x00000005)

Domain
ERROR kuhl_m_sekurlsa_acquireLSA ; Handle on memory (0x00000005)

SCCM Network accounts
Token Id : 0
User name :
SID name : NT AUTHORITY\SYSTEM

ERROR kuhl_m_dpapi_sccm_networkaccessaccount ; IWbemLocator_ConnectServer: 0x8004100e
Bye!
Using 'mz.log' for logfile : OK

Authentication Id : 0 ; 279517 (00000000:000443dd)
Session : Interactive from 1
User Name : admin
Domain : DESKTOP-TDJI4JC
Logon Server : DESKTOP-TDJI4JC
Logon Time : 2024/12/20 17:34:48
SID : S-1-5-21-2926860605-1856709270-2663500017-1001
msv :
[00000003] Primary
* Username : admin
* Domain : DESKTOP-TDJI4JC
* NTLM : 209c6174da490caeb422f3fa5a7ae634
* SHA1 : 7c87541fd3f3ef5016e12d411900c87a6046a8e8
* DPAPI : 7c87541fd3f3ef5016e12d411900c87a
tspkg :
wdigest :
* Username : admin
* Domain : DESKTOP-TDJI4JC
* Password : (null)
kerberos :
* Username : admin
* Domain : DESKTOP-TDJI4JC
* Password : (null)
ssp :
credman :

Authentication Id : 0 ; 279461 (00000000:000443a5)
Session : Interactive from 1
User Name : admin
Domain : DESKTOP-TDJI4JC
Logon Server : DESKTOP-TDJI4JC
Logon Time : 2024/12/20 17:34:48
SID : S-1-5-21-2926860605-1856709270-2663500017-1001
msv :
[00000003] Primary
* Username : admin
* Domain : .
* NTLM : 209c6174da490caeb422f3fa5a7ae634
* SHA1 : 7c87541fd3f3ef5016e12d411900c87a6046a8e8
* DPAPI : 7c87541fd3f3ef5016e12d411900c87a
tspkg :
wdigest :
* Username : admin
* Domain : DESKTOP-TDJI4JC
* Password : (null)
kerberos :
* Username : admin
* Domain : DESKTOP-TDJI4JC
* Password : (null)
ssp :
credman :

Authentication Id : 0 ; 995 (00000000:000003e3)
Session : Service from 0
User Name : IUSR
Domain : NT AUTHORITY
Logon Server : (null)
Logon Time : 2024/12/20 17:34:42
SID : S-1-5-17
msv :
tspkg :
wdigest :
* Username : (null)
* Domain : (null)
* Password : (null)
kerberos :
ssp :
credman :

Authentication Id : 0 ; 154011 (00000000:0002599b)
Session : Service from 0
User Name : SQLTELEMETRY
Domain : NT Service
Logon Server : (null)
Logon Time : 2024/12/20 17:34:42
SID : S-1-5-80-2652535364-2169709536-2857650723-2622804123-1107741775
msv :
tspkg :
wdigest :
* Username : DESKTOP-TDJI4JC$
* Domain : WORKGROUP
* Password : (null)
kerberos :
* Username : SQLTELEMETRY
* Domain : NT Service
* Password : (null)
ssp :
credman :

Authentication Id : 0 ; 151969 (00000000:000251a1)
Session : Service from 0
User Name : MSSQLSERVER
Domain : NT Service
Logon Server : (null)
Logon Time : 2024/12/20 17:34:42
SID : S-1-5-80-3880718306-3832830129-1677859214-2598158968-1052248003
msv :
tspkg :
wdigest :
* Username : DESKTOP-TDJI4JC$
* Domain : WORKGROUP
* Password : (null)
kerberos :
* Username : MSSQLSERVER
* Domain : NT Service
* Password : (null)
ssp :
credman :

Authentication Id : 0 ; 80381 (00000000:000139fd)
Session : Interactive from 1
User Name : DWM-1
Domain : Window Manager
Logon Server : (null)
Logon Time : 2024/12/20 17:34:40
SID : S-1-5-90-0-1
msv :
tspkg :
wdigest :
* Username : DESKTOP-TDJI4JC$
* Domain : WORKGROUP
* Password : (null)
kerberos :
ssp :
credman :

Authentication Id : 0 ; 80340 (00000000:000139d4)
Session : Interactive from 1
User Name : DWM-1
Domain : Window Manager
Logon Server : (null)
Logon Time : 2024/12/20 17:34:40
SID : S-1-5-90-0-1
msv :
tspkg :
wdigest :
* Username : DESKTOP-TDJI4JC$
* Domain : WORKGROUP
* Password : (null)
kerberos :
ssp :
credman :

Authentication Id : 0 ; 997 (00000000:000003e5)
Session : Service from 0
User Name : LOCAL SERVICE
Domain : NT AUTHORITY
Logon Server : (null)
Logon Time : 2024/12/20 17:34:40
SID : S-1-5-19
msv :
tspkg :
wdigest :
* Username : (null)
* Domain : (null)
* Password : (null)
kerberos :
* Username : (null)
* Domain : (null)
* Password : (null)
ssp :
credman :

Authentication Id : 0 ; 996 (00000000:000003e4)
Session : Service from 0
User Name : DESKTOP-TDJI4JC$
Domain : WORKGROUP
Logon Server : (null)
Logon Time : 2024/12/20 17:34:40
SID : S-1-5-20
msv :
tspkg :
wdigest :
* Username : DESKTOP-TDJI4JC$
* Domain : WORKGROUP
* Password : (null)
kerberos :
* Username : desktop-tdji4jc$
* Domain : WORKGROUP
* Password : (null)
ssp :
credman :

Authentication Id : 0 ; 52076 (00000000:0000cb6c)
Session : Interactive from 1
User Name : UMFD-1
Domain : Font Driver Host
Logon Server : (null)
Logon Time : 2024/12/20 17:34:40
SID : S-1-5-96-0-1
msv :
tspkg :
wdigest :
* Username : DESKTOP-TDJI4JC$
* Domain : WORKGROUP
* Password : (null)
kerberos :
ssp :
credman :

Authentication Id : 0 ; 52054 (00000000:0000cb56)
Session : Interactive from 0
User Name : UMFD-0
Domain : Font Driver Host
Logon Server : (null)
Logon Time : 2024/12/20 17:34:40
SID : S-1-5-96-0-0
msv :
tspkg :
wdigest :
* Username : DESKTOP-TDJI4JC$
* Domain : WORKGROUP
* Password : (null)
kerberos :
ssp :
credman :

Authentication Id : 0 ; 51086 (00000000:0000c78e)
Session : UndefinedLogonType from 0
User Name : (null)
Domain : (null)
Logon Server : (null)
Logon Time : 2024/12/20 17:34:40
SID :
msv :
tspkg :
wdigest :
kerberos :
ssp :
credman :

Authentication Id : 0 ; 999 (00000000:000003e7)
Session : UndefinedLogonType from 0
User Name : DESKTOP-TDJI4JC$
Domain : WORKGROUP
Logon Server : (null)
Logon Time : 2024/12/20 17:34:40
SID : S-1-5-18
msv :
tspkg :
wdigest :
* Username : DESKTOP-TDJI4JC$
* Domain : WORKGROUP
* Password : (null)
kerberos :
* Username : desktop-tdji4jc$
* Domain : WORKGROUP
* Password : (null)
ssp :
credman :

Rdp TS Passwords
!!! Warning, false positive can be listed !!!
Domain : DESKTOP-TDJI4JC / S-1-5-21-2926860605-1856709270-2663500017

RID : 000003e9 (1001)
User : admin
LM :
NTLM : 209c6174da490caeb422f3fa5a7ae634

RID : 000001f4 (500)
User : Administrator
LM :
NTLM :

RID : 000001f7 (503)
User : DefaultAccount
LM :
NTLM :

RID : 000001f5 (501)
User : Guest
LM :
NTLM :

RID : 000001f8 (504)
User : WDAGUtilityAccount
LM :
NTLM : b17a4c76fed130a0b7d5e22f5c09e2a6

Domain

Authentication Id : 0 ; 279517 (00000000:000443dd)
Session : Interactive from 1
User Name : admin
Domain : DESKTOP-TDJI4JC
Logon Server : DESKTOP-TDJI4JC
Logon Time : 2024/12/20 17:34:48
SID : S-1-5-21-2926860605-1856709270-2663500017-1001
kerberos :
* Username : admin
* Domain : DESKTOP-TDJI4JC
* Password : (null)

Authentication Id : 0 ; 279461 (00000000:000443a5)
Session : Interactive from 1
User Name : admin
Domain : DESKTOP-TDJI4JC
Logon Server : DESKTOP-TDJI4JC
Logon Time : 2024/12/20 17:34:48
SID : S-1-5-21-2926860605-1856709270-2663500017-1001
kerberos :
* Username : admin
* Domain : DESKTOP-TDJI4JC
* Password : (null)

Authentication Id : 0 ; 995 (00000000:000003e3)
Session : Service from 0
User Name : IUSR
Domain : NT AUTHORITY
Logon Server : (null)
Logon Time : 2024/12/20 17:34:42
SID : S-1-5-17
kerberos :

Authentication Id : 0 ; 154011 (00000000:0002599b)
Session : Service from 0
User Name : SQLTELEMETRY
Domain : NT Service
Logon Server : (null)
Logon Time : 2024/12/20 17:34:42
SID : S-1-5-80-2652535364-2169709536-2857650723-2622804123-1107741775
kerberos :
* Username : SQLTELEMETRY
* Domain : NT Service
* Password : (null)

Authentication Id : 0 ; 151969 (00000000:000251a1)
Session : Service from 0
User Name : MSSQLSERVER
Domain : NT Service
Logon Server : (null)
Logon Time : 2024/12/20 17:34:42
SID : S-1-5-80-3880718306-3832830129-1677859214-2598158968-1052248003
kerberos :
* Username : MSSQLSERVER
* Domain : NT Service
* Password : (null)

Authentication Id : 0 ; 80381 (00000000:000139fd)
Session : Interactive from 1
User Name : DWM-1
Domain : Window Manager
Logon Server : (null)
Logon Time : 2024/12/20 17:34:40
SID : S-1-5-90-0-1
kerberos :

Authentication Id : 0 ; 80340 (00000000:000139d4)
Session : Interactive from 1
User Name : DWM-1
Domain : Window Manager
Logon Server : (null)
Logon Time : 2024/12/20 17:34:40
SID : S-1-5-90-0-1
kerberos :

Authentication Id : 0 ; 997 (00000000:000003e5)
Session : Service from 0
User Name : LOCAL SERVICE
Domain : NT AUTHORITY
Logon Server : (null)
Logon Time : 2024/12/20 17:34:40
SID : S-1-5-19
kerberos :
* Username : (null)
* Domain : (null)
* Password : (null)

Authentication Id : 0 ; 996 (00000000:000003e4)
Session : Service from 0
User Name : DESKTOP-TDJI4JC$
Domain : WORKGROUP
Logon Server : (null)
Logon Time : 2024/12/20 17:34:40
SID : S-1-5-20
kerberos :
* Username : desktop-tdji4jc$
* Domain : WORKGROUP
* Password : (null)

Authentication Id : 0 ; 52076 (00000000:0000cb6c)
Session : Interactive from 1
User Name : UMFD-1
Domain : Font Driver Host
Logon Server : (null)
Logon Time : 2024/12/20 17:34:40
SID : S-1-5-96-0-1
kerberos :

Authentication Id : 0 ; 52054 (00000000:0000cb56)
Session : Interactive from 0
User Name : UMFD-0
Domain : Font Driver Host
Logon Server : (null)
Logon Time : 2024/12/20 17:34:40
SID : S-1-5-96-0-0
kerberos :

Authentication Id : 0 ; 51086 (00000000:0000c78e)
Session : UndefinedLogonType from 0
User Name : (null)
Domain : (null)
Logon Server : (null)
Logon Time : 2024/12/20 17:34:40
SID :
kerberos :

Authentication Id : 0 ; 999 (00000000:000003e7)
Session : UndefinedLogonType from 0
User Name : DESKTOP-TDJI4JC$
Domain : WORKGROUP
Logon Server : (null)
Logon Time : 2024/12/20 17:34:40
SID : S-1-5-18
kerberos :
* Username : desktop-tdji4jc$
* Domain : WORKGROUP
* Password : (null)

SCCM Network accounts
Token Id : 0
User name :
SID name : NT AUTHORITY\SYSTEM

664 {0;000003e7} 1 D 46029 NT AUTHORITY\SYSTEM S-1-5-18 (04g,21p) Primary
-> Impersonated !
* Process Token : {0;000443a5} 1 F 6193198 DESKTOP-TDJI4JC\admin S-1-5-21-2926860605-1856709270-2663500017-1001 (14g,24p) Primary
* Thread Token : {0;000003e7} 1 D 6269894 NT AUTHORITY\SYSTEM S-1-5-18 (04g,21p) Impersonation (Delegation)
ERROR kuhl_m_dpapi_sccm_networkaccessaccount ; IWbemLocator_ConnectServer: 0x8004100e
Bye!

发现admin的NTLM为209c6174da490caeb422f3fa5a7ae634,用hashcat进行爆破。

plaintext
1
hashcat -m 1000 -a 0 hash /usr/share/wordlists/rockyou.txt

img

得到系统管理员密码admin。

在数据包中发现基于WinRM协议的流量,这里使用网上一个解密脚本进行解密。

参考文章解密 https://fdlucifer.github.io/2022/01/05/decrypt-winrm-traffic/

脚本 https://gist.github.com/jborean93/d6ff5e87f8a9f5cb215cd49826523045/

img

plaintext
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# PYTHON_ARGCOMPLETE_OK

# Copyright: (c) 2020 Jordan Borean (@jborean93) <jborean93@gmail.com>
# MIT License (see LICENSE or https://opensource.org/licenses/MIT)

# Fork / modifications by Haoxi Tan (haoxi.tan@gmail.com)
# MIT License (see LICENSE or https://opensource.org/licenses/MIT)

"""
Script that can read a Wireshark capture .pcapng for a WinRM exchange and decrypt the messages. Currently only supports
exchanges that were authenticated with NTLM. This is really a POC, a lot of things are missing like NTLMv1 support,
shorter signing keys, better error handling, etc.
"""

from __future__ import (absolute_import, division, print_function)
__metaclass__ = type

import argparse
import base64
import hashlib
import hmac
import os
import pyshark
import binascii
import sys
import struct
import xml.dom.minidom

from cryptography.hazmat.primitives.ciphers import (
algorithms,
Cipher,
)

from cryptography.hazmat.backends import (
default_backend,
)

try:
import argcomplete
except ImportError:
argcomplete = None


class SecurityContext:

def __init__(self, port, nt_hash):
self.port = port
self.tokens = []
self.nt_hash = nt_hash
self.complete = False

self.key_exch = False
self.session_key = None
self.sign_key_initiate = None
self.sign_key_accept = None
self.seal_handle_initiate = None
self.seal_handle_accept = None

self.__initiate_seq_no = 0
self.__accept_seq_no = 0

@property
def _initiate_seq_no(self):
val = self.__initiate_seq_no
self.__initiate_seq_no += 1
return val

@property
def _accept_seq_no(self):
val = self.__accept_seq_no
self.__accept_seq_no += 1
return val

def add_token(self, token):
self.tokens.append(token)

if token.startswith(b"NTLMSSP\x00\x03"):
# Extract the info required to build the session key
nt_challenge = self._get_auth_field(20, token)
b_domain = self._get_auth_field(28, token) or b""
b_username = self._get_auth_field(36, token) or b""
encrypted_random_session_key = self._get_auth_field(52, token)
flags = struct.unpack("<I", token[60:64])[0]

encoding = 'utf-16-le' if flags & 0x00000001 else 'windows-1252'
domain = b_domain.decode(encoding)
username = b_username.decode(encoding)

# Derive the session key
nt_proof_str = nt_challenge[:16]
response_key_nt = hmac_md5(self.nt_hash, (username.upper() + domain).encode('utf-16-le'))
key_exchange_key = hmac_md5(response_key_nt, nt_proof_str)
self.key_exch = bool(flags & 0x40000000)

if self.key_exch and (flags & (0x00000020 | 0x00000010)):
self.session_key = rc4k(key_exchange_key, encrypted_random_session_key)

else:
self.session_key = key_exchange_key

# Derive the signing and sealing keys
self.sign_key_initiate = signkey(self.session_key, 'initiate')
self.sign_key_accept = signkey(self.session_key, 'accept')
self.seal_handle_initiate = rc4init(sealkey(self.session_key, 'initiate'))
self.seal_handle_accept = rc4init(sealkey(self.session_key, 'accept'))
self.complete = True

def unwrap_initiate(self, data):
print('unwrap_initiate',file=sys.stderr)
return self._unwrap(self.seal_handle_initiate, self.sign_key_initiate, self._initiate_seq_no, data)

def unwrap_accept(self, data):
print('unwrap_accept',file=sys.stderr)
return self._unwrap(self.seal_handle_accept, self.sign_key_accept, self._accept_seq_no, data)

def _unwrap(self, handle, sign_key, seq_no, data):
header = data[4:20]
enc_data = data[20:]
dec_data = handle.update(enc_data)

b_seq_num = struct.pack("<I", seq_no)

checksum = hmac_md5(sign_key, b_seq_num + dec_data)[:8]
if self.key_exch:
checksum = handle.update(checksum)
actual_header = b"\x01\x00\x00\x00" + checksum + b_seq_num

if header != actual_header:
# raise Exception("Signature verification failed")
print("Signature verification failed")
# meh, continue

return dec_data

def _get_auth_field(self, offset, token):
field_len = struct.unpack("<H", token[offset:offset + 2])[0]
if field_len:
field_offset = struct.unpack("<I", token[offset + 4:offset + 8])[0]
return token[field_offset:field_offset + field_len]


def hmac_md5(key, data):
return hmac.new(key, data, digestmod=hashlib.md5).digest()


def md4(m):
return hashlib.new('md4', m).digest()


def md5(m):
return hashlib.md5(m).digest()


def ntowfv1(password):
return md4(password.encode('utf-16-le'))


def rc4init(k):
arc4 = algorithms.ARC4(k)
return Cipher(arc4, mode=None, backend=default_backend()).encryptor()


def rc4k(k, d):
return rc4init(k).update(d)


def sealkey(session_key, usage):
direction = b"client-to-server" if usage == 'initiate' else b"server-to-client"
return md5(session_key + b"session key to %s sealing key magic constant\x00" % direction)


def signkey(session_key, usage):
direction = b"client-to-server" if usage == 'initiate' else b"server-to-client"
return md5(session_key + b"session key to %s signing key magic constant\x00" % direction)


def unpack_message(data):
# parts = data.split(b'--Encrypted Boundary\r\n')
parts = list(filter(None, parts))

messages = []
for i in range(0, len(parts), 2):
header = parts[i].strip()
payload = parts[i + 1]

length = int(header.split(b"Length=")[1])

# remove the end MIME block if it exists
if payload.endswith(b"--Encrypted Boundary--\r\n"):
payload = payload[:len(payload) - 24]

wrapped_data = payload.replace(b"Content-Type: application/octet-stream\r\n", b"")

messages.append((length, wrapped_data))

return messages


def pretty_xml(xml_str):
dom = xml.dom.minidom.parseString(xml_str)
return dom.toprettyxml()


def main():
"""Main program entry point."""
args = parse_args()

if args.password:
nt_hash = ntowfv1(args.password)

else:
nt_hash = base64.b16decode(args.hash.upper())

captures = pyshark.FileCapture(os.path.expanduser(os.path.expandvars(args.path)),
display_filter='http and tcp.port == %d' % args.port)

contexts = []
for cap in captures:
try:
source_port = int(cap.tcp.srcport)
unique_port = source_port if source_port != args.port else int(cap.tcp.dstport)

auth_token = None
if hasattr(cap.http, 'authorization'):
b64_token = cap.http.authorization.split(' ')[1]
auth_token = base64.b64decode(b64_token)

elif hasattr(cap.http, 'www_authenticate'):
b64_token = cap.http.www_authenticate.split(' ')[1]
auth_token = base64.b64decode(b64_token)

context = None
if auth_token:
if not auth_token.startswith(b"NTLMSSP\x00"):
continue

if auth_token.startswith(b"NTLMSSP\x00\x01"):
context = SecurityContext(unique_port, nt_hash)
contexts.append(context)

else:
context = [c for c in contexts if c.port == unique_port][-1]
if not context:
raise ValueError("Missing exisitng NTLM security context")

context.add_token(auth_token)

if hasattr(cap.http, 'file_data'):
if not context:
context = next(c for c in contexts if c.port == unique_port)

if not context.complete:
raise ValueError("Cannot decode message without completed context")

# file_data = cap.http.file_data #.binary_value
# messages = unpack_message(file_data)
length = int(cap.mime_multipart.data_len)
msgdata = binascii.unhexlify(cap.mime_multipart.data)
messages = [(length, msgdata)]

unwrap_func = context.unwrap_accept if source_port == args.port else context.unwrap_initiate

dec_msgs = []
for length, enc_data in messages:
msg = unwrap_func(enc_data)
# if len(msg) != length:
# raise ValueError("Message decryption failed")
# print(f'decrypted msg ({len(msg)}):',msg)
try:
dec_msgs.append(pretty_xml(msg.decode('utf-8')))
except Exception as e:
print("Exception: ", e)
dec_msgs.append("[bad message]")


dec_msgs = "\n".join(dec_msgs)
print("No: %s | Time: %s | Source: %s | Destination: %s\n%s\n"
% (cap.number, cap.sniff_time.isoformat(), cap.ip.src_host, cap.ip.dst_host, dec_msgs))

except Exception as e:
raise Exception("Failed to process frame: %s" % cap.number) from e


def parse_args():
"""Parse and return args."""
parser = argparse.ArgumentParser(description='Parse network captures from WireShark and decrypts the WinRM '
'messages that were exchanged.')

parser.add_argument('path',
type=str,
help='The path to the .pcapng file to decrypt.')

parser.add_argument('--port',
dest='port',
default=5985,
type=int,
help='The port to scan for the WinRM HTTP packets (default: 5985).')

secret = parser.add_mutually_exclusive_group()

secret.add_argument('-p', '--password',
dest='password',
help='The password for the account that was used in the authentication.')

secret.add_argument('-n', '--hash',
dest='hash',
help='The NT hash for the account that was used in the authentication.')

if argcomplete:
argcomplete.autocomplete(parser)

return parser.parse_args()


if __name__ == '__main__':
main()

解出来找到base64编码的脚本以及加解密明文和密文,可以知道是AES CBC加密

这里给出了两组一组明文和密文,以及flag密文,我们可以利用第一组明文求解出aes iv。

img

img

plaintext
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#coding:utf-8
import base64
from Crypto.Cipher import AES

def pkcs7padding(text):
bs = AES.block_size # 16
length = len(text)
bytes_length = len(bytes(text, encoding='utf-8'))
padding_size = length if(bytes_length == length) else bytes_length
padding = bs - padding_size % bs
padding_text = chr(padding) * padding
return text + padding_text


def pkcs7unpadding(text):
try:
length = len(text)
unpadding = ord(text[length-1])
return text[0:length-unpadding]
except Exception as e:
pass


def aes_encode(key, content):
import iv
key_bytes = bytes(key, encoding='utf-8')
iv = iv.iv
cipher = AES.new(key_bytes, AES.MODE_CBC, iv)
content_padding = pkcs7padding(content)
aes_encode_bytes = cipher.encrypt(bytes(content_padding, encoding='utf-8'))
result = str(base64.b64encode(aes_encode_bytes), encoding='utf-8')
return result




key = '99754106633f94d3'
data = ''
mi = aes_encode(key, data)
print(mi)
# c1:cExAFo22QSzk/IGDRZ06zEB3QInt/1vCOB+Hv/iwpa4=
# m1:HelloworldTestRemoteLoginwin
# rm
# c2:Yq8RtQ7mGXDTMWCxCKwJUlAmvLQFIxBh0RiOprrIa0/Wo8/4uOtjOwVrwCSyFUBb
from Crypto.Cipher import AES
import base64


'''
在已知明文和密钥key的情况下,使用p7填充,这里是CBC模式
'''

def pkcs7unpadding(text):
"""去填充"""
try:
length = len(text)
unpadding = ord(text[length-1])
return text[0:length-unpadding]
except Exception as e:
print(f"Error during unpadding: {e}")
return text

def find_iv(ciphertext_b64, plaintext, key):
"""反推 IV"""
# 解码密文
ciphertext_bytes = base64.b64decode(ciphertext_b64)

# 提取第一个 16 字节密文块 C1
C1 = ciphertext_bytes[:16]

# 获取明文的前16字节 M1
M1 = bytes(plaintext[:16], encoding='utf-8')

# 使用密钥解密密文块 C1,得到解密结果
key_bytes = bytes(key, encoding='utf-8')
cipher = AES.new(key_bytes, AES.MODE_CBC, iv=b'\x00' * 16) # 使用假 IV(全零)进行解密
decrypted_C1 = cipher.decrypt(C1)

# 异或解密结果与明文的前16字节得到 IV
iv = bytes(a ^ b for a, b in zip(decrypted_C1, M1))
return iv

# 已知数据
c1 = "cExAFo22QSzk/IGDRZ06zEB3QInt/1vCOB+Hv/iwpa4=" # Base64 编码的密文
m1 = "HelloworldTestRemoteLoginwinrm" # 明文,已提供
key = '99754106633f94d3' # 假设密钥

# 反推 IV
iv = find_iv(c1, m1, key)

# 打印 IV 字节结果
print("Recovered IV (bytes):", iv)

反推出IV为3be1a0e448f0c838,最后解flag

img

flag{54f49661-6171-269b-e545-453f687cef0a}