block
THB room 链接: https://tryhackme.com/room/blockroom
前言
之前打2024强网杯, 做谍影重重5.0
时由于对smb流量不太熟悉, 在网上搜了一堆文章, 收益良多
最后虽然拿了这题的一血, 队伍还是没打进半决赛, 深感自己是个彩笔
顺着大佬的文章, 到THM复现了一下提到的room
题目
第一个登录服务器的用户名是?
wireshark打开, 发现smb登录流量:

直接发现登录用户名 mrealman
:

问题1中的用户密码是?
找到上面登录的包, 根据解析信息构造hash:

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的信息:

chanllenage信息:

最终构造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
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' ]
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 )
|

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

得到密码Blockbuster1
第一个用户得到的flag是?
在wireshark中使用密码解密smb流量:

导出smb对象:

发现csv, 查看对应流:

导出data字段内容并解码:

得到flag:THM{SmB_DeCrypTing_who_Could_Have_Th0ughT}
第二个登录服务器的用户名是?
根据上面的内容知道第二个用户为eshellstrop
问题4中的用户hash是?
除了流量附件, 还给出了一个lsass
进程的内存dmplsass.DMP
, 在windows上可以使用mimikatz
来获取内存中的密码, 这里使用它的python实现pypykatz
, 安装只需要一行命令:
使用pypykatz
获取内存中的密码hash:

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


因此用户2的hash: 3f29138a04aadc19214e9c04028bf381
同样可以使用NTLM解密用户1的密码:

用户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
|

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

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

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

导出对应流的data发现flag:

最后的最后, 只使用流量来解密smb的方法
方法来源于Khris Tolbert,感谢Ladislav Baco的精彩文章
想要只通过流量来解密smb, 需要一个随机会话密钥, 而计算出这个随机密钥需要以下条件:
条件 |
是否可获得 |
用户的密码或者NTLMhash |
需要获得 |
用户名(username) |
流量中给出 |
用户域(domain) |
流量中给出 |
NTProofStr |
可以通过计算得出 |
Key Exchange Key |
可以通过计算得出 |
加密的会话密钥(Encrypted Session Key) |
流量中给出 |
加密的会话密钥Encrypted Session Key
位置:

会话idsession id
位置:

需要注意的是这里可能有端序问题, 这里显示为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流量:

写到这里其实有点疑问, 说是只用流量来解密smb, 这里实际上还是需要用户的密码或者NTLMhash, 但有了其中任何一样之后都可以直接解密smb(参照前面的方法), 这第三种方法只是提供了wireshark中的另外一种解密思路
参考文章
wireshark wiki
Insomni’Hack Teaser 2023 - Autopsy
SMB Decryption - TryHackMe
Decrypting SMB3 Traffic with just a PCAP? Absolutely (maybe.)