一道非常有意思的流量分析题
解题流程:WPA 2 密钥破解 + Meterpreter 流量分析 + RSA 模数分解
WPA 2 密钥破解
首先用 Wireshark 打开题目所给的流量文件,通过广播信息可以判断认证方式是 WPA 2
用工具提取出其中的握手包之后,可以在 colab 上跑 hashcat 来爆破密钥
hashcat -a 3 -m 2500 ./bytectf.hccapx ByteCTF?d?d?d?d?d?d?d?d
得到 WPA 2 密钥为 ByteCTF20201212
Meterpreter 流量分析
通过跟踪 TCP 流可以发现这里通过远程方式安装了一个 APK
但是因为抓取的流量不完整,所以只能用 binwalk 提取出来不完整的 dex
通过 strings 可以发现存在和 Meterpreter 相关的方法名
可以在 rapid7/metasploit-framework 下找到 Python 实现的 Meterpreter
参考 从Reverse_HTTP浅析Metasploit的通信协议
- 控制端向受控端发送 RSA 公钥
- 受控端随机生成 AES 密钥,并将 AES 密钥用 RSA 公钥加密后发送给控制端
- 控制端再用 RSA 私钥解密来得到 AES 密钥
- 双方使用 AES 密钥加密通信内容
RSA 模数分解
简单介绍下 RSA 原理
首先选择两个大质数(p,q),计算二者的乘积(n=p*q)
再计算(n)的欧拉函数值(phi(n)=(p-1)*(q-1))
选择一个与(phi(n))互质的数(e),通常取(65537)
计算(d)满足(edequiv 1pmod{phi(n)}),即(e)在模(phi(n))意义下的逆元(d)
((n,d))作为私钥,((n,e))作为公钥,(m)为明文,(c)为密文
用公钥中的(e)加密(m)得到(c):(m^eequiv cpmod{n})
用私钥中的(d)解密(c)得到(m):(c^dequiv mpmod{n})
如果能通过分解公钥中的(n)得到(p,q),就能根据上述过程计算出(d)得到私钥
本题中(n=18871291564770640664148800347584822680868182671984145797895532086883503360318700336495365612391409300072891881695207132365560715090292373627752017518973939673190928757510324236372389820855712170126905584127742104734451993179263410168242734908932738706692951170322096247098631087884988914459555236103979084499418787307984156821762918242074700255056333052043772599009922971042360003130449287658485508371082774995474587954191898774267366467484050606038502149717184445264754841832881405998441052692163667189562855971894479990818644527870185211990290040676461768277037843554385709513561157385466983474986006532925227067791)
可以在 factordb 上分解得到
(p=39157)
(q = 481939156849877178132870249191327800415460394616138769514915138720624750627440823773408729279347480656661436823434050932542347858372509988705774638480321262435603564050114264023607268709444343798730893176896649506715325310398227907353544319251544773774623979628727845521838524092371451195432623441631868746314038034271883873171155048703289328984762189443618576474447045765568353120270942300443994901833204152398666597394894878930136794634013091044730243627376572394840126716369522843896137413289160742384831727964207676553838254408411911331059326319086287720638400376800717866883600821959470426104809013277963763)
从而计算出 RSA 私钥,解密出 AES 密钥
再用 AES 密钥解密出之后的通信内容
解题代码:
from meterpreter import *
from Crypto import Random
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5
from Crypto.Cipher import AES
import binascii
# 提取 RSA 公钥
enc1 = 'a6a71feda6a71feda6a71feda6a71feda6a71feda6a71feda6a71e86a6a71feda6a71fe1a6a51feca6a71ffda6a71fc4a6a61fef96952fdf909226d49e962adb9e9429d8919427dc9f952ddf9e932fdd94912bdaa6a71fec88a71bef80979dec849712ebaf8d99a5205012eca7a61aeda5251ee2a6979decaca59deca7a78a90ec4a563dda8a0db2935af065bc0a3c726446788db0153b770eb45c8c5c4353ff2f6cb5df035d95622f5f98f96637080f00a879b382ddf23e1e2b30655b8644fbc6d3dc49eeebf1bd78a65826aac7d07b5b8f97292db874cd1b9f120fa9798f090d3bd50b1d465eb801da9869de2032504e025c370704b2a9746c885684c01b91b84398329261d28cee21625936ffa6c7d77d5d745e3348bf6ffe31a188d49eca9e7805c23163f9362a17a5dc6c0abeacb720ff587ce86319ec1492b516c92ee6e00048b1b2cadd6c741bc0bb40b9f57b8e376c046c67ec3b08d477479ed1bdd09f199d85aadd263d6ed7849c5d697ee1b9315476d74948af3eeefe054f281deea7a71e'
enc1 = binascii.unhexlify(enc1)
req1 = Transport().decrypt_packet(enc1)
der = packet_get_tlv(req1, TLV_TYPE_RSA_PUB_KEY)['value'].strip()
pub = RSA.import_key(der)
print('[*] RSA key: ' + str(binascii.b2a_hex(der)))
# 分解得到 p 和 q
e=65537
p=39157
q=481939156849877178132870249191327800415460394616138769514915138720624750627440823773408729279347480656661436823434050932542347858372509988705774638480321262435603564050114264023607268709444343798730893176896649506715325310398227907353544319251544773774623979628727845521838524092371451195432623441631868746314038034271883873171155048703289328984762189443618576474447045765568353120270942300443994901833204152398666597394894878930136794634013091044730243627376572394840126716369522843896137413289160742384831727964207676553838254408411911331059326319086287720638400376800717866883600821959470426104809013277963763
# 计算 d 并构造 RSA 私钥
n = p * q
Qn = long((p-1) * (q-1))
i = 1
while (True):
x = (Qn * i ) + 1
if (x % e == 0):
d = x // e
break
i += 1
pri = RSA.construct((n,e,d))
# 用 RSA 私钥解密得到 AES 密钥
enc2 = '3a7be6af3a7be6af3a7be6af3a7be6af3a7be6af3a7be6af3a7be7f23a7be6ae3a7be6a33a79e6ae3a7be6bf3a7be6863a7ae6ad0a49d69d0c4edf96024ad3990248d09a0d48de9e0349d49d024fd69f084dd2983a7be6ae327be2ad13f84c14f9f7a0fa3b7351369b7312a3ef2fe3dba4efc933fc822b9ed895cc41cdaae88abb46f256c34e39478fe13e2b67899c74234839f2431d62afa4b490feda3eeab7836632efe83320b3c2f80f9ddec9ef5622fb226aef35223bbe38fa8f297829d57da42d1fd279083363d4fa43d257941065ecbf9fc4a241e96306982e4b7342d0bf2151a4f78e9bf291efd553e6210404d7f19f71b6591ed0c966b9b424bd45739ca2655787b3101fc0f2a0c9df2c6e187e9dc582b6f3b138d96896401524a7502bad619b411c36d8232a9912bdf8ee2cbff9165aa886e64af7d2b547e4e574494354dafeaf1e1894c4f2a433dc24ffd1341d7ec1973b57df15ec5384ca7be6af367be4ad1d7be6af3b7be6af367be4af3e7be6af3a'
enc2 = binascii.unhexlify(enc2)
req2 = Transport().decrypt_packet(enc2)
enc_aes_key = packet_get_tlv(req2, TLV_TYPE_ENC_SYM_KEY)['value'].strip()
chiper = PKCS1_v1_5.new(pri)
random_generator = Random.new().read
aes_key = chiper.decrypt(enc_aes_key, random_generator)
print('[*] AES key: ' + str(binascii.b2a_hex(aes_key)))
# 用 AES 密钥解密后续流量
msg = [
'8410d281b5d8aa7be75d91da1eb7989fbbf84c198410d2808410d2598410d2808e1eac4324745edfecade0fddd1430fcaa54821bf20284ade9175d340b76fe312c7bc95d1b235dc90f101127c6dfada2918fb2e319bc1bd74e968bb5777c93fc0dfae287408ff115f25f8f32b7c177a1ea0c3c531ad0770fbce775877db155dd8a9437d259ab3250417177031e0a92795e31aacf36d0e53044012c2ef7881b912324c474d5c38364d540306ceb5af7eef67a6fb910e997246bf735a4209694c5856799238f1129d79c92a04727647b08393bb156b314ff053bf733967ec32944d4266c5b9d4498bc07ec14c2e8ca612f',
]
T=Transport()
T.aes_key=aes_key
for enc3 in msg:
enc3 = binascii.unhexlify(enc3)
req3 = T.decrypt_packet(enc3)
print(req3)