乐于分享
好东西不私藏

软件系统安全赛区域赛(果子面包赛区) —— pth_attcak

软件系统安全赛区域赛(果子面包赛区) —— pth_attcak

所有人都嘲笑我在机房啃果子面包,但他们不知道的是十天后丧尸病毒爆发,果子面包成了唯一解药

抛开赛方的抽象行为不谈,这题其实出的还不错,和24强网杯的谍影重重很类似

先来分析思路

附件只有两个流量包

其中

1-pth.pcapng中是一段winrm流量和一段SMB3加密(中间还传了一个猕猴桃),其中在SMB3相关流量中可以看到用户administrator和用户admin

2-rdp.pcapng则是经过tls加密过的RDP流量

那么一个整体的思路就是先从winrm流量中找到administrator或者admin的密码或NT HASH 然后解密SMB3流量找出TLS证书再还原RDP


解密winrm就需要拿到密码,而从流量中拿到密码的唯一方式就是爆破NTLMv2

筛选http协议定位到winrm登录成功的流量

image-20260421205227107

接着就可以看到哈希

唔….但只有者各还不够,还需要从前一条流量(就是info里有NTLMSSP_CHALLENGE的那个)把challenge摘出来

然后整理一下下($NETNTLMv2$USERNAME+domain$challenge$NTProofstr$blob )

$NETNTLMv2$ADMINISTRATORpc$cd0a6722277096c9$3fa965e4d9af9a92bde5cefcdd309acb$010100000000000022a2d32cbc72dc01ff545caf96411c670000000002000a0044004500310041005900010004005000430004001200640065003100610079002e0063006f006d0003001800500043002e00640065003100610079002e0063006f006d0005001200640065003100610079002e0063006f006d000700080022a2d32cbc72dc010600040002000000080030003000000000000000000000000030000026544cc05c735b21ae876ab6adeaf35030fb649315896d1d685326c99ddb5f6b0a001000000000000000000000000000000000000900220048005400540050002f00310030002e00310030002e00310030002e00320030003100000000000000000000000000

然后就可以丢给john爆破就好啦,字典就用kali自带的rockyou字典

好啦,就拿到了密码pass@word1

接下来就是解密winrm,这边呢我在github上找到一个脚本

https://github.com/h4sh5/decrypt-winrm/blob/main/winrm_decrypt.py

python .\winrm_decrypt.py -p pass@word1 .\1-pth.pcapng

下下来后用上述命令就可以解密啦,不过他遇到错误帧会直接崩溃,这个可以喊天才程序员稍微改一改,我就不放我改完的了,太长了

唔…由于脚本还原出来的是XML原文,所以还要写个脚本把命令提取出来

import reimport base64with open("winrm.txt""r", encoding="utf-16"as f:  #唔....这里主要是脚本提出来的是utf-16编码    text=f.read()pattern = r'(?<![A-Za-z0-9+/=])(?:[A-Za-z0-9+/]{4}){2,}(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?(?![A-Za-z0-9+/=])'#base64 正则筛选喵matches = re.findall(pattern, text)for i,s in enumerate(matches, 1):try:        payload = base64.b64decode(s).decode("utf-8")if payload and payload[0].isalnum():print(payload, end="\n-------------------\n")except UnicodeDecodeError:pass

保存结果到记事本上慢慢看

然后就找到了administratorNT HASH

好那么接下来就是解密SMB3了,这边我又在github找到一个小脚本

https://github.com/iamdonu/SMB3-Decryption/blob/main/randomSessionKeyNTLM.py

这个不用改奥,直接用就好啦

python .\randomSessionKeyNTLM.py -u administrator --domain= -n 3d83254b53697355ef7498b535e7ab29 -p 4103e8d84572fa74f220ecc20be704c1 -k 7433d4ac87cdff2d38b2e8a5840b919d

解释一下参数

  • -k session key
  • -p NTProofstr
  • -n NT HASH
  • --domain

这里留空是因为流量里他没有域(这里记一下sessionid,后面要用)

然后运行脚本,拿到key:3252507a61756f507132585748475953

接着回到wireshark里开始解密流量(注意一下协议树里的hex都是小端序,所以填的时候要倒一下)

然后,就能看到一部分解密后的SMB3

然后就是一样的流程,不过呢要先把这个密码哈希一下,用cyberchef就行,就不贴出来了

解密后就可以看到上传的证书

唔…不过有密码,就是猕猴桃的默认密码mimikatz

然后用openssl从证书中导出私钥就好啦

openssl pkcs12 -in ./%5cLOCAL_MACHINE_Remote\ Desktop_0_WIN-PJQQGRU9QOC.pfx -nocerts -nodes -out private-key.pem -passin pass:mimikatz

然后回到wireshark解密2-rdp.pcapng

接着导出PDU,也就是将解密后的解密后的上层流量单独导出来

然后就可以使用pyrdp库啦

pyrdp-convert -o pyrdpout ./rdp.pcap 

这里导出.pyrdp文件(用wsl啊,烧杯windows会报非法路径,抽象的很)

接着打开pyrdp-player就可以查看还原的rdp信息啦,包括键盘行为,鼠标行为,理论上来讲屏幕也可以还原来着但这没有,反正美美拿到flag

赛方说要大写,反正我没看出来哪里大写了,sync 里capslock都是False,抽象

下一篇文章会简单讲讲winrmSMB3的加密原理和怎么手动解密,但是不知道什么时候更新了说是,抽象排课早八排到晚九,诶哟


广告时间~ ~ ~

项目地址: https://github.com/lQ-A-Ql/Gshark

关于我的Gshark哈,也是托这个抽象比赛的福,给了我一点灵感,加上了winrm解密和SMB3 的Random SK 生成,不细说了,直接看结果叭

然后还顺便更新了一下图标嘻嘻