2022DASCTF Apr X FATE 防疫挑战赛 Re wp

CrackMe

MFC程序

  if ( Size != 8 && lenFlag != 32 )
    return wrong((CWnd *)this);
  encrypt((BYTE *)key, Size >> 1, 0x8003u, (int)&Buf1, (int)&dwDataLen);// key0-3 md5
  encrypt((BYTE *)&key[4], Size >> 1, 0x8004u, (int)&Buf2, (int)&v11);// key 4-7 sha1
  encrypt((BYTE *)key, Size, 0x8003u, (int)&keyMD5, (int)&v12);// key0-7 md5
  memcmp(Buf1, (const void *)(this + 220), dwDataLen);
  if ( memcmp(Buf2, (const void *)(this + 480), v11) )// key 前4位 后4位 分2组校验
    return wrong((CWnd *)this);
  encflag(keyMD5, v12, input, &lenFlag, 0x104u);
  if ( !memcmp(input, (const void *)(this + 740), lenFlag) )// this+740 -> encodeFlag
    return success((CWnd *)this);
  else
    return wrong((CWnd *)this);

找到md5 的k[0:4],及sha1的 key[5:8]。使用在线网站解码。得到

md5的hash明文为 NocT

提取sha1的hash D59F8E94B0E1DE6E329518A0C444AA94DE7C8D44

import hashlib
from Crypto.Util.number import long_to_bytes
import string

s = 'D59F8E94B0E1DE6E329518A0C444AA94DE7C8D44'


for a in string.ascii_letters:
    for b in string.ascii_letters:
        for c in string.ascii_letters:
            for d in string.ascii_letters:
                m = (a+b+c+d).encode()
                # r1 = hashlib.md5(a).digest()
                r2 = hashlib.sha1(m).hexdigest()
                if r2.upper() == s:
                    print(m)

爆破解出 sha1 key为 b'uRne' , key=NocTuRne

在线网站解的 uRnE 的sha1为F72C7BCCEA714AF5FA65102C8B1C1E7C7E0852CE不一样 自己爆破

!memcmp(v13, (const void *)(this + 740), lenFlag)
提取密文 5B9CEEB23BB7D734F31B7514C6B21FE8DE334474751B476AD4375188FC67E660DA0D5807814353EA7B52856C8665AFB4

用wincrypto带的API来处理。用python解码不太成功。

//https://gift1a.github.io/2022/04/23/DASCTF-FATE-Reverse/#more
#include <stdbool.h>
#include <windows.h>
#include <windef.h>
#include <wincrypt.h>
#include <stdio.h>

bool __stdcall encflag(BYTE *key, DWORD dwDataLen, BYTE *input, DWORD *pdwDataLen, DWORD dwBufLen) {
    BOOL v6;
    HCRYPTKEY phKey;
    HCRYPTPROV phProv;
    HCRYPTHASH phHash;

    phProv = 0;
    phHash = 0;
    phKey = 0;
    v6 = CryptAcquireContextA(&phProv, 0, 0, 0x18u, 0xF0000000);
    if (v6) {
        // CryptGetHashParam(phHash, 2u, key, (DWORD *)v8, 0); 在加密函数中会将hash值写入key->addr的值
        v6 = CryptCreateHash(phProv, 0x8003u, 0, 0, &phHash);
        if (v6) {
            v6 = CryptHashData(phHash, key, dwDataLen, 0); // 将key 按hashalg生成 写入key->addr
            if (v6) {
                v6 = CryptDeriveKey(phProv, 0x660Eu, phHash, 1u, &phKey);
                CryptDecrypt(phKey, 0, 1, 0, input, pdwDataLen);
                for (int i = 0; i < 32; ++i) {
                    putchar(input[i]);
                }
            }
        }
    }
    if (phKey)
        CryptDestroyKey(phKey);
    if (phHash)
        CryptDestroyHash(phHash);
    if (phProv)
        CryptReleaseContext(phProv, 0);
    return v6;
}

void main() {
    BYTE flag_data[] = {0x5B, 0x9C, 0xEE, 0xB2, 0x3B, 0xB7, 0xD7, 0x34, 0xF3, 0x1B, 0x75, 0x14, 0xC6, 0xB2, 0x1F, 0xE8,
                        0xDE, 0x33, 0x44, 0x74, 0x75, 0x1B, 0x47, 0x6A, 0xD4, 0x37, 0x51, 0x88, 0xFC, 0x67, 0xE6, 0x60,
                        0xDA, 0x0D, 0x58, 0x07, 0x81, 0x43, 0x53, 0xEA, 0x7B, 0x52, 0x85, 0x6C, 0x86, 0x65, 0xAF, 0xB4};
    BYTE keyBuf[] = {0x5c, 0x53, 0xa4, 0xa4, 0x1d, 0x52, 0x43, 0x7a, 0x9f, 0xa1, 0xe9, 0xc2, 0x6c, 0xa5, 0x90, 0x90}; // 就是key的md5
    DWORD dwDataLen_2;
    DWORD *pdwDataLen = &dwDataLen_2;
    *pdwDataLen = 0x20;
    encflag(keyBuf, 0x10, flag_data, pdwDataLen, 0x104);
}

奇怪的交易

uncompyle6 和 pycdc 反编译一下。有问题。直接逆向 bytecode 恢复脚本。。。
逆向字节码用python自带的模块。不要用pycdas,会多一堆垃圾代码。。

from cup import * 这里是一个普通的xxtea。

然后用脚本直接解密就行了。。。

fakepica

1.PKID查壳、BlackDex脱壳、jadx打开
2.查看到加密data, key, iv

from Crypto.Cipher import AES

password = [-40, 26, 95, -49, -40, -123, 72, -90, -100, -41, 122, -4, 25, -101, -58, 116]
email = [-114, 95, -37, 127, -110, 113, 41, 74, 40, 73, 19, 124, -57, -88, 39, -116, -16, -75, -3, -45, -73, -6, -104, -6, -78, 121, 110, 74, -90, -47, -28, -28]


def decrypt(text):
    iv = b"0102030405060708"
    key = b"picapicapicapica"
    mode = AES.MODE_CBC

    cryptor = AES.new(key, mode, iv)
    plain_text = cryptor.decrypt(text)
    print(bytes.decode(plain_text))


if __name__ == '__main__':
    text = bytes([x & 0xff for x in password])
    decrypt(text)
    text = bytes([x & 0xff for x in email])
    decrypt(text)
posted @ 2022-04-27 09:01  wgf4242  阅读(238)  评论(0编辑  收藏  举报