作者:YuKong介绍:一次HTTPS流量分析和ntlmv2计算。
0x00 前言
你是一名安全防护人员,你发现有人成功入侵了公司的服务器,你查找有关的流量设备,发现了一个流量包文件,你认为它可能包含了一些重要的信息。但是当你打开它时,你发现它被加密了:你觉得这个文件可能被某种奇怪的系统加密过,你想要找出加密算法并解密出文件内容。
0x01 知识点介绍
1.1 HTTPS流量分析
工具:Wireshark
SSL (Secure Socket Layer)安全套接字层协议;TLS(Transport Layer Security)传输层安全协议。SSL/TLS是保护计算机网络通讯安全的一类加密协议,它们在传输层上给原先非安全的应用层协议提供加密保护,如非安全的HTTP协议即可被SSL/TLS保护形成安全的HTTPS协议。
使用Wireshark分析https流量通常分为两种。
(1)加载 pre-master-secret log文件
浏览器在访问https时会将与网站https建立连接后的会话私钥保存下来。在wireshark中,通过加载log文件可解密流量(流量包)中的HTTPS流量。
前提:通过某些信息提供一个SSL的私钥文件。
加载步骤:编辑 –> 首选项 –> 协议(protocols) –> TLS –>(Pre)-Master-Secret log filename –> log 文件
加载完成后,就可以看到解密后的SSL流量。
(2)加载服务端私钥
前提:通过某些信息提供一个SSL的私钥文件。
加载步骤:编辑 –> 首选项 –> 协议(protocols) –> TLS –> RSA keys list –> Editor
在这里导入私钥,为了防止私钥丢失被解开可以填入 password 为保存私钥时指定的加密密码。加载完成后,就可以看到解密后的SSL流量。
1.2 NTLM介绍
NTLM(New Technology LAN Manager)是一套Windows安全协议,被设计用于为用户提供包含完整性和机密性的身份验证技术。NTLM主要有NTLMv1、NTLMv2和NTLMv2 Session三个版本,最常见的是NTLMv2。
NTLM 协议是一种基于 挑战(Chalenge)/响应(Response) 认证机制,仅支持Windows的网络认证协议。它主要分为协商、质询和验证三个步骤:
协商:这个是为了解决历史遗留问题,也就是为了向下兼容,双方先确定一下传输协议的版本等各种信息。
质询:这一步便是Challenge/Response认证机制的关键之处,下面会介绍这里的步骤。
验证:对质询的最后结果进行一个验证,验证通过后,即允许访问资源。
认证流程:

(1)发送协商请求(Negotiate)
客户端在访问受限服务时,需要输入相应的用户名和密码,此时客户端将其进行预处理和转换,得到一份NTLM Hash进行缓存(并不是直接哈希得到的);然后发送协商请求包,包含(NTLM Hash以及申请认证的服务信息等),记为TYPE 1。
(2)发送质询请求(Challenge)
服务端根据收到的协商请求包TYPE 1后,如果判断其中的用户名存在,那么就会生成一个16字节的随机值Challenge(NTLMv1为8字节);并结合支持的服务信息,生成一个质询请求包,包含(Challenge随机值以及支持的服务信息等),记为TYPE 2。
(3)发送认证响应(Authenticate)
客户端使用HMAC-MD5算法来对TYPE 2中的Challenge值进行消息摘要并得到NTLMv2 Response,并结合用户名、Challenge等生成Authenticate响应包,记为TYPE 3;具体来说,客户端将(1)中得到的NTLM Hash和TYPE 2中的Challenge等作为HMAC-MD5的输入,得到一个摘要值,即NTLMv2 Response。
(4)服务端验证并应答(Reply)
服务端在收到TYPE 3后,根据用户名检索到缓存于本地的NTLM Hash,Challenge等传入HMAC-MD5,并将得到的数据和TYPE 3中的NTLMv2 Response进行比对,若相同则验证客户端身份成功,否则拒绝客户端的访问请求。
NTLMv2格式如下:
username::domain:challenge:HMAC‐MD5:blob
0x02 解题过程
2.1 分析流量,提取关键文件
(1)使用Wireshark打开流量包,发现流量中使用http请求传输了png图片。
(2)通过流量信息可以看到png图片中隐藏了压缩包,并且flag.txt 就在压缩包中。
(3)提取压缩包,解压需要密码。
2.2 加载log文件解密HTTPS流量
(1)同样在HTTP流量中还看到了关键密文。
(2)通过关键字可以搜索到这些密钥就是传输过程中留下的私钥。
(3)通过上文可知加载 pre-master-secret log文件可以解密SSL流量。

(4)可以看到解密后的流量。
(5)分析流量拿到关键数据。
username::domain:challenge:HMAC‐MD5:blobadmin::SecretServer:d158262017948de9:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx:010100000000000058b2da67cbe0d001c575cfa48d38bec50000000002001600450047004900540049004d002d00500043003100340001001600450047004900540049004d002d00500043003100340004001600650067006900740069006d002d00500043003100340003001600650067006900740069006d002d0050004300310034000700080058b2da67cbe0d0010600040002000000080030003000000000000000000000000030000065d85a4000a167cdbbf6eff657941f52bc9ee2745e11f10c61bb24db541165800a001000000000000000000000000000000000000900240063006900660073002f003100390032002e003100360038002e0031002e00310030003700000000000000000000000000

和上文NTLMv2格式一致,但是可以看到存在xxx的隐藏数据,对应值为HMAC‐MD5,猜测隐藏的HMAC‐MD5就是压缩包的密码。
2.3 计算HMAC‐MD5
参考文档:https://stackoverflow.com/questions/32272615/is-it-possible-to-convert-netmtlmv2-hash-to-ntlm-hash
(1)提取文中提到的代码
import hashlib, binascii, hmac _ntlm = hashlib.new("md4", "123".encode("utf-16-le")).digest()ntlm = binascii.hexlify(_ntlm)server="tryPC".upper().encode("utf-16-le").encode("hex") firstHMAC = hmac.new(bytes.fromhex(ntlm), bytes.fromhex(server),hashlib.md5).hexdigest()type2Challange = "d158262017948de9010100000000000058b2da67cbe0d001c575cfa48d38bec50000000002001600450047004900540049004d002d00500043003100340001001600450047004900540049004d002d00500043003100340004001600650067006900740069006d002d00500043003100340003001600650067006900740069006d002d0050004300310034000700080058b2da67cbe0d0010600040002000000080030003000000000000000000000000030000065d85a4000a167cdbbf6eff657941f52bc9ee2745e11f10c61bb24db541165800a001000000000000000000000000000000000000900240063006900660073002f003100390032002e003100360038002e0031002e00310030003700000000000000000000000000"ntlmv2 = hmac.new(firstHMAC.decode("hex"),type2Challange.decode("hex"),hashlib.md5).hexdigest()print(ntlmv2)
(2)根据流量中提供的数据修改代码
"123" 改为 "QUICAUTH-CCC123!@#""tryPC" 改为 "adminSecretServer"type2Challange 为 challenge+blob"d158262017948de9010100000000000058b2da67cbe0d001c575cfa48d38bec50000000002001600450047004900540049004d002d00500043003100340001001600450047004900540049004d002d00500043003100340004001600650067006900740069006d002d00500043003100340003001600650067006900740069006d002d0050004300310034000700080058b2da67cbe0d0010600040002000000080030003000000000000000000000000030000065d85a4000a167cdbbf6eff657941f52bc9ee2745e11f10c61bb24db541165800a001000000000000000000000000000000000000900240063006900660073002f003100390032002e003100360038002e0031002e00310030003700000000000000000000000000"
import hashlibimport binasciiimport hmacfrom Crypto.Hash import MD4 # 生成 NTLM 哈希md4_hasher = MD4.new()md4_hasher.update("QUICAUTH-CCC123!@#".encode("utf-16-le"))_ntlm = md4_hasher.digest()ntlm = binascii.hexlify(_ntlm).decode('utf-8') # 将服务器名称编码为十六进制server = "adminSecretServer".upper().encode("utf-16-le")server_hex = binascii.hexlify(server).decode('utf-8') # 生成第一个 HMACfirstHMAC = hmac.new(binascii.unhexlify(ntlm), binascii.unhexlify(server_hex), hashlib.md5).hexdigest() # type2Challangetype2Challange = "d158262017948de9010100000000000058b2da67cbe0d001c575cfa48d38bec50000000002001600450047004900540049004d002d00500043003100340001001600450047004900540049004d002d00500043003100340004001600650067006900740069006d002d00500043003100340003001600650067006900740069006d002d0050004300310034000700080058b2da67cbe0d0010600040002000000080030003000000000000000000000000030000065d85a4000a167cdbbf6eff657941f52bc9ee2745e11f10c61bb24db541165800a001000000000000000000000000000000000000900240063006900660073002f003100390032002e003100360038002e0031002e00310030003700000000000000000000000000" # 生成 NTLMv2 响应ntlmv2 = hmac.new(binascii.unhexlify(firstHMAC), binascii.unhexlify(type2Challange), hashlib.md5).hexdigest()print(ntlmv2)

efa243f442b9d683eb1b00a2b1a0c9fc
0x03 总结
在做这个题的过程中,因为之前没有遇到过类似的题花费了很长时间去计算HMAC-MD5的值,记录一下继续积累,希望下次不要这么菜了。
文章来源:宸极实验室
黑白之道发布、转载的文章中所涉及的技术、思路和工具仅供以安全为目的的学习交流使用,任何人不得将其用于非法用途及盈利等目的,否则后果自行承担!
如侵权请私聊我们删文
END















暂无评论内容