block

THB room 链接: https://tryhackme.com/room/blockroom

前言

之前打2024强网杯, 做谍影重重5.0时由于对smb流量不太熟悉, 在网上搜了一堆文章, 收益良多

最后虽然拿了这题的一血, 队伍还是没打进半决赛, 深感自己是个彩笔

顺着大佬的文章, 到THM复现了一下提到的room

题目

第一个登录服务器的用户名是?

wireshark打开, 发现smb登录流量:

image-20250410152446581

直接发现登录用户名 mrealman:

image-20250410152512725

问题1中的用户密码是?

找到上面登录的包, 根据解析信息构造hash:

image-20250410152826339

1
username::domain:ntlmserverchallenge:ntproofstr:删掉ntproofstr之后的ntresponse

使用tshark导出信息:

1
2
3
4
# 除了challenge的信息
tshark -n -r traffic.pcapng -Y 'ntlmssp.messagetype == 0x00000003' -T fields -e ntlmssp.auth.username -e ntlmssp.auth.domain -e ntlmssp.ntlmv2_response.ntproofstr -e ntlmssp.auth.ntresponse
# challenge信息
tshark -n -r traffic.pcapng -Y 'ntlmssp.messagetype == 0x00000002' -T fields -e ntlmssp.ntlmserverchallenge

得到mrealman登录的除了challenage的信息:

image-20250410153139309

chanllenage信息:

image-20250410153244576

最终构造hash:

1
mrealman::WORKGROUP:2a9c5234abca01e7:16e816dead16d4ca7d5d6dee4a015c14:0101000000000000abce46bf0905da01da0395279d6ab0260000000002000a0042004c004f0043004b0001001e00570049004e002d00320032003500380048004800430042004e00510052000400120062006c006f0063006b002e00740068006d0003003200570049004e002d00320032003500380048004800430042004e00510052002e0062006c006f0063006b002e00740068006d000500120062006c006f0063006b002e00740068006d0007000800abce46bf0905da01060004000200000008003000300000000000000000000000000000002a514197857a27e5d174fa71e991a6853a1360abfc915b014a33b215c721873f0a0010000000000000000000000000000000000009001c0063006900660073002f00310030002e0030002e0032002e003700300000000000

或者使用脚本加快速度(需要tshark):

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
import subprocess

# 提取出challenge外的信息
cmd1 = [
'tshark',
'-n',
'-r', 'traffic.pcapng',
'-Y', 'ntlmssp.messagetype == 0x00000003',
'-T', 'fields',
'-e', 'ntlmssp.auth.username',
'-e', 'ntlmssp.auth.domain',
'-e', 'ntlmssp.ntlmv2_response.ntproofstr',
'-e', 'ntlmssp.auth.ntresponse'
]

# 提取challenge信息
cmd2 = [
'tshark',
'-n',
'-r', 'traffic.pcapng',
'-Y', 'ntlmssp.messagetype == 0x00000002',
'-T', 'fields',
'-e', 'ntlmssp.ntlmserverchallenge'
]

result1 = subprocess.run(cmd1, capture_output=True, text=True)

result2 = subprocess.run(cmd2, capture_output=True, text=True)


output1 = result1.stdout.strip().split('\n')

output2 = result2.stdout.strip().split('\n')

for line1, line2 in zip(output1, output2):
fields1 = line1.split('\t')
fields2 = line2.split('\t')

username = fields1[0]
domain = fields1[1]
challenge = fields2[0]
ntproofstr = fields1[2]
ntresponse = fields1[3][32:]

print(username + "::" +
domain + ":" +
challenge + ":" +
ntproofstr + ":" +
ntresponse
)

image-20250410161100024

得到hash后可以使用john或hashcat进行解密(这里使用rockyou字典):

image-20250410161040527

得到密码Blockbuster1

第一个用户得到的flag是?

在wireshark中使用密码解密smb流量:

image-20250410161343377

导出smb对象:

image-20250410161720921

发现csv, 查看对应流:

image-20250410161805212

导出data字段内容并解码:

image-20250410162044151

得到flag:THM{SmB_DeCrypTing_who_Could_Have_Th0ughT}

第二个登录服务器的用户名是?

根据上面的内容知道第二个用户为eshellstrop

问题4中的用户hash是?

除了流量附件, 还给出了一个lsass进程的内存dmplsass.DMP, 在windows上可以使用mimikatz来获取内存中的密码, 这里使用它的python实现pypykatz, 安装只需要一行命令:

1
pip install pypykatz

使用pypykatz获取内存中的密码hash:

image-20250410163719013

分别找到了两个用户的NTLMhash:

image-20250410163910599

image-20250410164012654

因此用户2的hash: 3f29138a04aadc19214e9c04028bf381

同样可以使用NTLM解密用户1的密码:

image-20250410163840622

用户2的密码通过NTLM无法解出(使用上面用户1的方法也不行,密码复杂度过高或者别的原因)

第二个用户得到的flag是?

这里需要想办法解密用户2eshellstrop的smb流量, 除了使用上面的两种方法外, 还有第三种方法

根据wireshark wiki的说明以及其中提到的[Insomni’Hack Teaser 2023 - Autopsy]

使用ktutil将hash写入密钥表文件, 然后再将密钥表文件提供给wireshark实现解密

1
2
3
4
5
6
7
8
9
10
# 进入交互shell
ktutil
# 添加一条记录, 主体为eshellstrop@WORKGROUP, -k 1代表版本为1, -key代表手动输入hash, -e代表加密算法
ktutil: add_entry -p eshellstrop@WORKGROUP -k 1 -key -e rc4-hmac
# 这里手动输入NTLMhash
Key for eshellstrop@WORKGROUP (hex): 3f29138a04aadc19214e9c04028bf381
# 将数据写入文件
ktutil: write_kt block.keytab
# 退出
ktutil: q

image-20250410165050940

将密钥表文件提供给wireshark, 同时勾选让wireshark尝试解密Kerberos簇:

image-20250410170053297

此时用户2的smb流量被解密:

image-20250410170211250

同样导出smb对象可以发现传输的文件:

image-20250410170259680

导出对应流的data发现flag:

image-20250410170413335

最后的最后, 只使用流量来解密smb的方法

方法来源于Khris Tolbert,感谢Ladislav Baco的精彩文章

想要只通过流量来解密smb, 需要一个随机会话密钥, 而计算出这个随机密钥需要以下条件:

条件 是否可获得
用户的密码或者NTLMhash 需要获得
用户名(username) 流量中给出
用户域(domain) 流量中给出
NTProofStr 可以通过计算得出
Key Exchange Key 可以通过计算得出
加密的会话密钥(Encrypted Session Key) 流量中给出

加密的会话密钥Encrypted Session Key位置:

image-20250410191035131

会话idsession id位置:

image-20250410191123659

需要注意的是这里可能有端序问题, 这里显示为0x0000100000000041, 最后需要输入的是4100000000100000

通过下面的代码进行计算:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from Crypto.Cipher import ARC4 
from Crypto.Hash import MD4, MD5, HMAC

password = 'Blockbuster1'
passwordHash = MD4.new(password.encode('utf-16-le')).hexdigest()
username = 'mrealman'
domain = 'workgroup'
ntProofStr = '16e816dead16d4ca7d5d6dee4a015c14'
serverChallenge = '2a9c5234abca01e7'
sessionKey = 'fde53b54cb676b9bbf0fb1fbef384698'

responseKey = HMAC.new(bytes.fromhex(passwordHash), (username.upper()+domain.upper()).encode('utf-16-le'), MD5).digest()

keyExchangeKey = HMAC.new(responseKey, bytes.fromhex(ntProofStr), MD5).digest()

decryptedSessionKey = ARC4.new(keyExchangeKey).decrypt(bytes.fromhex(sessionKey))

print('Decrypted SMB Session Key is: {}'.format(decryptedSessionKey.hex()))

使用session id和未加密的sessionkey来解密smb流量:

image-20250410191634010

写到这里其实有点疑问, 说是只用流量来解密smb, 这里实际上还是需要用户的密码或者NTLMhash, 但有了其中任何一样之后都可以直接解密smb(参照前面的方法), 这第三种方法只是提供了wireshark中的另外一种解密思路

参考文章

wireshark wiki

Insomni’Hack Teaser 2023 - Autopsy

SMB Decryption - TryHackMe

Decrypting SMB3 Traffic with just a PCAP? Absolutely (maybe.)