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)