<menu id="guoca"></menu>
<nav id="guoca"></nav><xmp id="guoca">
  • <xmp id="guoca">
  • <nav id="guoca"><code id="guoca"></code></nav>
  • <nav id="guoca"><code id="guoca"></code></nav>

    DASCTF 2023六月挑戰賽 二進制專項 RE writeup

    VSole2023-06-08 09:05:42

    一、careful

    動態調試,題目里有個inline hook,在這里打個斷點。

     

    那么網址就是Just_An_APIH00k11.com

    二、babyre

    die查一下殼。

    有sleep反調試,把sleep nop掉。

    這里讀取了名稱為cod的資源,用resource hacker把資源復制下來。

    然后向下執行,這里是一個對cod資源進行解密的地方。

    這里要注意的是如果檢測到調試器,那么byte_7FF6DA64F000[3]將會被賦值為36。

    所以要把這個if語句通過修改ZF標志位的方式來繞過反調試。

    cod資源解密腳本如下:

    arr = [0x18, 0x57, 0x68, 0x64]
    with open('COD101.bin', 'rb') as f:
        b = f.read()
    b = bytearray(b)
    for i in range(len(b)):
        b[i] = b[i] ^ arr[i % 4]
    with open('COD_de.bin', 'wb') as f:
        f.write(b)
    

    用ida打開,看到有花指令。

    nop一下,主要的改動有這幾處:

    于是得到如下的偽代碼:

    看算法是魔改的RC4,exp如下:

    class RC4:
        def __init__(self, key) -> None:
            self.key = key
            self.S = 0
            self.__rc4_init__()
        def __rc4_init__(self):
            S = [i for i in range(256)]
            j = 0
            for i in range(256):
                j = (2 * j + S[i] + key[i % len(key)]) % 256
                S[i], S[j] = S[j], S[i]
            self.S = S
        def rc4_encrypt(self, plain) -> list:
            i = 0
            j = 0
            cipher = []
            cnt = 0
            for p in plain:
                p = (p + 256 - cnt % 0xd) % 256
                cnt += 1
                i = (i + j) % 256
                j = (j + self.S[i]) % 256
                self.S[i], self.S[j] = self.S[j], self.S[i]
                tmp = self.S[(self.S[i] + self.S[j] + j) % 256]
                k = p ^ tmp
                cipher.append(k)
            return cipher
    key = [0x5D , 0x42 , 0x62 , 0x29 , 0x3, 0x36 , 0x47 , 0x41 , 0x15, 0x36]
    data = [0xF7, 0x2E, 0x34, 0xF0, 0x72, 0xCF, 0x5E, 0x0A, 0xBB, 0xEC, 0xB1, 0x2B, 0x70, 0x88, 0x88, 0xED,
    0x46, 0x38, 0xDB, 0xDA, 0x6C, 0xBD, 0xD4, 0x06, 0x77, 0xF2, 0xCF, 0x56, 0x88, 0xC6, 0x31, 0xD2,
    0xB7, 0x5A, 0xC1, 0x42, 0xB0, 0xF4, 0x48, 0x37, 0xF5, 0x2C, 0xF5, 0x58]
    rc4 = RC4(key)
    plain = rc4.rc4_encrypt(data)
    print(''.join(map(chr,plain)))
    三
    ez_exe
    

    查個殼,是python逆向、

    pyinstxtractor脫一下。

    用在線網站看一下ez_py.pyc的源代碼。

    #!/usr/bin/env python
    # visit https://tool.lu/pyc/ for more information
    # Version: Python 3.11
    import ctypes
    from time import *
    from ctypes import *
    from ctypes import wintypes
    from hashlib import md5
    class _STARTUPINFO(Structure):
        _fields_ = [
            ('cb', c_ulong),
            ('lpReserved', c_char_p),
            ('lpDesktop', c_char_p),
            ('lpTitle', c_char_p),
            ('dwX', c_ulong),
            ('dwY', c_ulong),
            ('dwXSize', c_ulong),
            ('dwYSize', c_ulong),
            ('dwXCountChars', c_ulong),
            ('dwYCountChars', c_ulong),
            ('dwFillAttribute', c_ulong),
            ('dwFlags', c_ulong),
            ('wShowWindow', c_ushort),
            ('cbReserved2', c_ushort),
            ('lpReserved2', c_char_p),
            ('hStdInput', c_ulong),
            ('hStdOutput', c_ulong),
            ('hStdError', c_ulong)]
    class _PROCESS_INFORMATION(Structure):
        _fields_ = [
            ('hProcess', c_void_p),
            ('hThread', c_void_p),
            ('dwProcessId', c_ulong),
            ('dwThreadId', c_ulong)]
    StartupInfo = _STARTUPINFO()
    ProcessInfo = _PROCESS_INFORMATION()
    key1 = bytes(md5(b'bin1bin1bin1').hexdigest().encode())
    file = open('bin1', 'rb').read()
    arr = range(len(file))()
    open('bin1', 'wb').write(bytes(arr))
    sleep(0)
    bet = ctypes.windll.kernel32.CreateProcessA(b'bin1', ctypes.c_int(0), ctypes.c_int(0), ctypes.c_int(0), ctypes.c_int(0), ctypes.c_int(0), ctypes.c_int(0), ctypes.c_int(0), byref(StartupInfo), byref(ProcessInfo))
    ctypes.windll.kernel32.WaitForSingleObject(ctypes.c_int(ProcessInfo.hProcess), ctypes.c_int(-1))
    open('bin1', 'wb').write(file)
    

    用ida反編譯bin1失敗,看來是被加密了。

    用這個代碼看一下字節碼。

    import marshal, dis
    f = open("ez_py.pyc", "rb").read()
    code = marshal.loads(f[16:])            #這邊從16位開始取因為是python3 python2從8位開始取
    dis.dis(code)
    

    在最后面得到了這個:

    Disassembly of  at 0x00000297CC7F8E70, file "ez_py.py", line 59>:
     59           0 RESUME                   0
                  2 BUILD_LIST               0
                  4 LOAD_FAST                0 (.0)
            >>    6 FOR_ITER                50 (to 108)
                  8 STORE_FAST               1 (i)
                 10 LOAD_GLOBAL              0 (key1)
                 22 LOAD_FAST                1 (i)
                 24 LOAD_GLOBAL              3 (NULL + len)
                 36 LOAD_GLOBAL              0 (key1)
                 48 PRECALL                  1
                 52 CALL                     1
                 62 BINARY_OP                6 (%)
                 66 BINARY_SUBSCR
                 76 LOAD_GLOBAL              4 (file)
                 88 LOAD_FAST                1 (i)
                 90 BINARY_SUBSCR
                100 BINARY_OP               12 (^)
                104 LIST_APPEND              2
                106 JUMP_BACKWARD           51 (to 6)
            >>  108 RETURN_VALUE
    

    那么解密代碼如下:

    from hashlib import md5
    key1 = bytes(md5(b'bin1bin1bin1').hexdigest().encode())
    # print(key1)
    file = open('bin1', 'rb').read()
    arr = [key1[i % len(key1)] ^ file[i] for i in range(len(file))]
    # open('bin1', 'wb').write(bytes(arr))
    with open('bin1__','wb') as f:
        f.write(bytes(arr))
    

    反編譯出來是這個:

    那根據提示我們把上面的解密腳本稍作修改:

    from hashlib import md5
    key1 = bytes(md5(b'bin2bin2bin2').hexdigest().encode())
    # print(key1)
    file = open('bin2', 'rb').read()
    arr = [key1[i % len(key1)] ^ file[i] for i in range(len(file))]
    # open('bin1', 'wb').write(bytes(arr))
    with open('bin2__','wb') as f:
        f.write(bytes(arr))
    

    然后用ida反編譯bin2__

    那么這就是正常的逆向題了。

    btea函數里面是這個,這是一個xxtea算法。

    寫一下exp。

    #include 
    #include 
    using namespace std;
    #include 
    #define DELTA 0x7937B99E
    #define MX (((z>>5^y<<2) + (y>>3^z<<4)) ^ ((sum^y) + (key[(p&3)^e] ^ z)))
    void btea(uint32_t* v, int n, uint32_t const key[4]) {
        uint32_t y, z, sum;
        unsigned p, rounds, e;
        if (n > 1) {          /* Coding Part */
            rounds = /*6 + */52 / n;
            sum = 0;
            z = v[n - 1];
            do {
                sum += DELTA;
                e = (sum >> 2) & 3;
                for (p = 0; p < n - 1; p++) {
                    y = v[p + 1];
                    z = v[p] += MX;
                }
                y = v[0];
                z = v[n - 1] += MX;
            } while (--rounds);
        }
        else if (n < -1) {  /* Decoding Part */
            n = -n;
            rounds = /*6 + */52 / n;
            sum = rounds * DELTA;
            y = v[0];
            do {
                e = (sum >> 2) & 3;
                for (p = n - 1; p > 0; p--) {
                    z = v[p - 1];
                    y = v[p] -= MX;
                }
                z = v[n - 1];
                y = v[0] -= MX;
            } while ((sum -= DELTA) != 0);
        }
    }
    int main()
    {
        uint32_t const key[4] = { 0x4B5F, 0xDEAD, 0x11ED, 0xB3CC };
        uint32_t data[11] = { 0xCC45699D, 0x683D5352,0xB8BB71A0,0xD3817AD,0x7547E79E,0x4BDD8C7C,0x95E25A81,0xC4525103,0x7049B46F,0x5417F77C,0x65567138 };
        uint32_t* sent = data;
        //btea(sent, 11, key);
        //printf("coded:%x  %x", sent[0], sent[1]);
        btea(sent, -11, key);
        //printf("decoded:%x  %x", sent[0], sent[1]);
        for (int i = 0; i < 11; i++) {
            for (int j = 0; j < 4; j++)
            {
                printf("%c", sent[i] & 0xff);
                sent[i] >>= 8;
            }
        }
        return 0;
    }
    //DASCTF{7eb20cb2-deac-11ed-ae42-94085339ce84}
    

    四、cap

    在這個地方動調。

    可以發現數組的下標在0~12之間循環。

    我們隨便打開一個BMP類型的文件,用010看看。

    對于BMP類型的文件前兩個字節必定是43 4D。

    既然這個加密的bmp的每一個字節進行的都是異或,那我們可以將前兩個字節異或看看。

    n和c是密鑰enc_by_dasctf的第2個和第3個字符,按照這個序列,我們向后將密鑰向后延申看看后面的情況如何。

    所以我們寫個腳本,從密鑰的第二位開始,循環異或。

    key = "enc_by_dasctf"
    with open('cap.bin', 'rb') as f:
        s = bytearray(f.read())
    for i in range(len(s)):
        s[i] ^= ord(key[(i+1) % len(key)])
    with open('flag.bmp', 'wb') as f:
        f.write(s)
    

    得到flag。

    五、unsym

    查一下殼,是go逆向。

    用這個腳本恢復一下go符號https://github.com/renshareck/IDAGolangHelper_SupportGo1.20

    依次點擊如下按鈕:

    首先判斷key正確與否,看來這是個rsa。

    用yafu解一下p和q。

    然后解出密鑰。

    import gmpy2
    from Crypto.Util.number import long_to_bytes
    n = 0x1d884d54d21694ccd120f145c8344b729b301e782c69a8f3073325b9c5
    p = 37636318457745167234140808130156739
    q = 21154904887215748949280410616478423
    c = 0xfad53ce897d2c26f8cad910417fbdd1f0f9a18f6c1748faca10299dc8
    e = 0x10001
    phi = (p - 1) * (q - 1)
    d = gmpy2.invert(e, phi)
    m = pow(c, d, n)
    print(long_to_bytes(m))
    # E@sy_RSA_enc7ypt
    

    再往后看:

    動調了一下看到iv和key都是一樣的。

    所以直接寫個exp把加密的文件解密。

    from Crypto.Cipher import AES
    password = b'E@sy_RSA_enc7ypt'  # 秘鑰必須為 16 字節或者 16 字節的倍數的字節型數據
    iv = b'E@sy_RSA_enc7ypt'  # iv 偏移量,bytes 類型
    with open('encrypted.bin','rb') as f:
        en_text = f.read()
    aes = AES.new(password, AES.MODE_CBC, iv)  # CBC 模式下解密需要重新創建一個 aes 對象
    de_text = aes.decrypt(en_text)
    with open('decrypt.exe','wb') as f:
        f.write(de_text)
    

    運行一下解密出的exe,就得到flag了。

    本作品采用《CC 協議》,轉載必須注明作者和本文鏈接
    有sleep反調試,把sleep nop掉。這里讀取了名稱為cod的資源,用resource hacker把資源復制下來。然后向下執行,這里是一個對cod資源進行解密的地方。這里要注意的是如果檢測到調試器,那么byte_7FF6DA64F000[3]將會被賦值為36。所以要把這個if語句通過修改ZF標志位的方式來繞過反調試。cod資源解密腳本如下:arr = [0x18, 0x57, 0x68, 0x64]. 用ida打開,看到有花指令。
    舉辦首屆基地“楚慧杯”網絡空間安全實踐能力競賽
    看程序圖標是個mfc的程序,先打開看看,隨便輸入一點東西,看到彈窗彈出:直接拖進ida搜索Wrong!!!字符串,借此通過查看引用跳轉到主函數。
    前景剛剛結束的浙江省網絡安全大賽,其中Web類的第二題考察了POP鏈以及原生類的利用,在比賽期間只構造了POP鏈、得到flag的文件名,但是并沒有利用原生類將flag文件完整讀出來。這篇文章將會把這個題涉及到的知識點復現一遍,并且給出這個題詳細的WP。
    8月1日,首屆數字空間安全攻防大賽決賽圓滿落下帷幕。引領數字時代CTF新范式2022 DSCTF由中國信息協會信息安全專業委員會指導,由ISC組委會主辦,360數字安全集團承辦,北京航空航天大學網絡空間安全學院、北京郵電大學網絡空間安全學院、天津理工大學計算機科學與工程學院共同協辦。作為行業首個聚焦數字安全領域的CTF賽事,大賽吸引了上千人百余支戰隊熱情參賽。
    VSole
    網絡安全專家
      亚洲 欧美 自拍 唯美 另类