本帖最后由 m1n9yu3 于 2022-1-10 09:20 编辑
这题很有意思,给了一个client端,server端,以及一个tls流量,我们要分析进程拿到流量的加密方式, 破解流量中的对话
因为是一道零解题,这里只给出思路,不提供详细的调试过程. 感兴趣的师傅可以玩一下.
差不多这样(不好意思画成tcp
注意每次发送出去的数据都是加密的,保证了数据安全(画的很丑,请见谅
在client中,通过调试,我们发现 一个可疑字符串 Dem0_wants_girls
此处 初始化密钥,然后 传递密钥,我们就可以猜测是 加解密算法了,这里sm4是后来命名的
分析特征
[C] 纯文本查看 复制代码 v11 = 0; v7 = _byteswap_ulong(*a2);
v8 = _byteswap_ulong(a2[1]);
v9 = _byteswap_ulong(a2[2]);
v10 = _byteswap_ulong(a2[3]);
v3 = v7 ^ 0xA3B1BAC6;
v4 = dword_4A9664[1] ^ v8;
v5 = dword_4A9664[2] ^ v9;
result = dword_4A9664[3] ^ v10;
v6[0] = result;
while ( v11 < 0x20 )
{
v6[v11 + 1] = *(&v3 + v11) ^ sub_451700(dword_4ABF78[v11] ^ v6[v11] ^ *(&v5 + v11) ^ *(&v4 + v11));
*(_DWORD *)(a1 + 4 * v11) = v6[v11 + 1];
result = ++v11;
}
return result;
得到,这是 sm4 的初始化key函数 ,主要是 0xA3B1BAC6 百度一搜就有了
一开始想着无脑去套sm4算法,却发现怎么也解的不对,去搜了一波源码才发现,emm 人家用的cbc模式,我一直用的ecb 模式,怎么能解出来呢
调试 wireshark + IDA
客户端发送消息之后,会接收到 服务端发送的消息,我们在这个时候可以使用wireshark截获数据,拿到发送的消息,tls数据,一般来说需要进行解密,这里我们发现server 端泄露了 key , 那么我们可以直接使用 key 来解密,步骤为: wireshark --> 编辑 -> 首选项 -> rsa 密钥 -> add new keyfile 选中 server\cert\server.key 文件即可, 最后 ctrl + r 重新加载下wireshark
会出现 Decrypted TLS
后面经过调试,发现 wireshark抓到的 iv 并不是 真正的 iv ,真正的iv 还要经过一层xor 加密
37 0c 52 00 6e 18 a4 00 a5 24 f6 00 dc 30 48 01
与该数据 xor 后拿到的 iv 才是真正的 iv
我们知道了详细的加密过程了,我们就可以去解密聊天流量了
[Python] 纯文本查看 复制代码 #!/usr/bin/python3
# coding = utf-8
from gmssl.sm4 import CryptSM4, SM4_ENCRYPT, SM4_DECRYPT
import binascii
from heapq import heappush, heappop
from collections import OrderedDict
import time
import requests
def decrypt(iv, value):
s = "Dem0_wants_girls"
keys = [ord(i) for i in s]
key = bytes(b % 256 for b in keys)
crypt_sm4 = CryptSM4()
crypt_sm4.set_key(key, SM4_DECRYPT)
d_value = crypt_sm4.crypt_cbc(iv, bytes.fromhex(value))
return d_value
if __name__ == "__main__":
with open(r"F:\SafeIm\1.txt", mode="r") as f:
content = f.read()
iv_xor = b"\x37\x0c\x52\x00\x6e\x18\xa4\x00\xa5\x24\xf6\x00\xdc\x30\x48\x01"
count = 0
for i in content.split("\n"):
desc = i[:64]
encontent = i[64:]
enciv = encontent[:32]
encocontent = encontent[32:]
encivb = bytes.fromhex(enciv)
iv = bytes([encivb[i] ^ iv_xor[i] for i in range(16)])
content = decrypt(iv, encocontent)
print(bytes.fromhex(desc[24:]).replace(b"\x00", b"").replace(b'\x0fFZ\xe7', b''), end=":")
if b'PNG' in content:
filename = r"F:\SafeIm\other\%d.png" % count
print("是png")
elif b'\xff\xd8\xff\xe1' in content:
filename = r"F:\SafeIm\other\%d.jpg" % count
print("是 jpg")
else:
filename = r"F:\SafeIm\other\%d.txt" % count
print(content.replace(b"\x00", b"").decode())
with open(filename, mode="wb") as f:
f.write(content)
count += 1
这里 1.txt 来自 流量包文件 capture.pcap
依照上面讲的步骤解密 tls 流量后,导出 tls 原始数据,而且只需要 服务端发送给客户端的流量,去掉握手流量
最后拿到 flag
说实话挺好玩的,就是有点废人(bushi
链接:https://pan.baidu.com/s/1-Eupw5Va2-705m_JDLvlcw 提取码:8jx0 --来自百度网盘超级会员V2的分享
|