zoukankan      html  css  js  c++  java
  • ByteCTF 2020 KOP Writeup

    一道非常有意思的流量分析题

    解题流程: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的通信协议

    1. 控制端向受控端发送 RSA 公钥
    2. 受控端随机生成 AES 密钥,并将 AES 密钥用 RSA 公钥加密后发送给控制端
    3. 控制端再用 RSA 私钥解密来得到 AES 密钥
    4. 双方使用 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)
    

    参考文章

    2020字节CTF KOP

  • 相关阅读:
    tomcat 无法clean 的bug
    Open Type vs Open resource
    Cannot change version of project facet Dynamic Web Module to 2.4.
    股权稀释
    Java的各种打包方式
    记忆
    【转】给女儿的信
    买房费用
    工作职场
    装修-水电改造
  • 原文地址:https://www.cnblogs.com/algonote/p/14162469.html
Copyright © 2011-2022 走看看