DASCTF2022年4月赛

Crackme #

MFC 程序

key 的长度为 8 比特,知道前 4 字节的 MD5 和后 4 字节的 SHA1

两边可以分开爆破

from hashlib import md5
from hashlib import sha1

key0_3md5 = bytes.fromhex('9f77c2a4ac5c0a671321bbe1e9972af6')
key4_7sha1 = bytes.fromhex('d59f8e94b0e1de6e329518a0c444aa94de7c8d44')

md5succ = 0
sha1succ = 0
key0_3 = b'not'
key4_7 = b'quite'
for i in range(65,123):
    for j in range(65,123):
        for k in range(65,123):
            for l in range(65,123):
                tmp = bytes([i,j,k,l])
                if md5succ == 0 and md5(tmp).digest() == key0_3md5:
                    key0_3 = tmp
                    md5succ = 1
                if sha1succ == 0 and sha1(tmp).digest() == key4_7sha1:
                    key4_7 = tmp
                    sha1succ = 1
                if md5succ == 1 and sha1succ == 1:
                    break

key = key0_3.decode('utf-8')+key4_7.decode('utf-8')
print(key)
# NocTuRne

使用 wincrypt 库解密得:

#include <iostream>
#include <windows.h>
#include <wincrypt.h>

char key_md5[] = "5c53a4a41d52437a9fa1e9c26ca59090";
char secret[] = "5b9ceeb23bb7d734f31b7514c6b21fe8de334474751b476ad4375188fc67e660da0d5807814353ea7b52856c8665afb4";

char tmp[3];
int sz_sec = 48;
void str2hex(char* ret, char* src, int sz)
{
    for (int i = 0; i < sz; i += 2)
    {
        tmp[0] = src[i];
        tmp[1] = src[i + 1];
        int c;
        sscanf_s(tmp, "%02x", &c);
        ret[i / 2] = c;
    }
    ret[sz / 2] = 0;
}

int main()
{
    BOOL v6; // [esp+4h] [ebp-18h]
    HCRYPTKEY phKey; // [esp+Ch] [ebp-10h] BYREF
    HCRYPTPROV phProv; // [esp+10h] [ebp-Ch] BYREF
    HCRYPTHASH phHash; // [esp+14h] [ebp-8h] BYREF

    char key_buf[64];
    str2hex(key_buf, key_md5, 32);
    char sec_buf[64];
    str2hex(sec_buf, secret, 96);

    phProv = 0;
    phHash = 0;
    phKey = 0;
    v6 = CryptAcquireContextA(&phProv, 0, 0, 0x18u, 0xF0000000);
    if (v6)
    {
        v6 = CryptCreateHash(phProv, 0x8003u, 0, 0, &phHash);
        if (v6)
        {
            v6 = CryptHashData(phHash, (BYTE*)key_buf, 16, 0);
            if (v6)
            {
                v6 = CryptDeriveKey(phProv, 0x660Eu, phHash, 1u, &phKey);// AES128
                if (v6)
                    v6 = CryptDecrypt(phKey, 0, 1, 0, (BYTE*)sec_buf, (DWORD*)&sz_sec);
            }
        }
    }
    if (phKey)
        CryptDestroyKey(phKey);
    if (phHash)
        CryptDestroyHash(phHash);
    if (phProv)
        CryptReleaseContext(phProv, 0);
    sec_buf[32] = 0;
    printf("%s\n", sec_buf);
    return v6;
}

DASCTF{H@sh_a^d_Aes_6y_W1nCrypt}

奇怪的交易 #

先 upx 脱壳

是 pyinstaller 打包的可执行文件,python 版本 3.10.0

使用 pyinstxtractor 解包,存在一个被加密的 pyc

密钥就在包中,加密方式是 tiny-aes,解密发现算法为 XXTEA

过了 XXTEA 还有一个 Wiener 攻击的板子

from gmpy2 import isqrt
# import libnum
from Crypto.Util.number import *
from pwn import *

# wiener attack on RSA
def continued_fraction(e, n):
    cf = []
    x, y = e, n
    while y != 0:
        cf.append(x // y)
        x, y = y, x % y
    return cf

def gradual_fraction(cf):
    num, denom = 1, 0
    for x in cf[::-1]:
        denom, num = num, x * num + denom
    return denom, num

def get_gradual_fraction(cf):
    return list(map(gradual_fraction, (cf[0:i] for i in range(1, len(cf)))))

def solve_pq(a, b, c):
    delta = isqrt(b * b - 4 * a * c)
    return (-b + delta) // (2 * a), (-b - delta) // (2 * a)

def wiener_attack(e, n):
    cf = continued_fraction(e, n)
    gf = get_gradual_fraction(cf)
    for (d, k) in gf:
        if k == 0:
            continue
        if (e * d - 1) % k != 0:
            continue
        phi = (e * d - 1) // k
        p, q = solve_pq(1, phi - n - 1, n)
        if p * q == n:
            return d

# xxtea decrypt
def mix1(y, z):
    return (((z >> 5) ^ (y << 2)) + ((y >> 3) ^ (z << 4))) & 0xffff_ffff

def mix2(y, z, s, p, e, k):
    return ((s ^ y) + (k[(p & 3) ^ e] ^ z)) & 0xffff_ffff

def mix(y, z, s, p, e, k):
    return mix1(y, z) ^ mix2(y, z, s, p, e, k)

def decrypt(v, n, k):
    y, z = v[0], 0
    rounds = 6 + 52 // n
    s = (rounds * 0x9e3779b9) & 0xffff_ffff
    for i in range(rounds):
        p, e = n - 1, (s >> 2) & 3
        while p > 0:
            z = v[p - 1]
            v[p] = (v[p] - mix(y, z, s, p, e, k)) & 0xffff_ffff
            y = v[p]
            p -= 1
        z = v[n - 1]
        v[0] = (v[0] - mix(y, z, s, p, e, k)) & 0xffff_ffff
        y = v[0]
        s = (s - 0x9e3779b9) & 0xffff_ffff

ciphertext = [
    0xD28ED952,
    1472742623,
    0xD91BA938,
    0xF9F3BD2D,
    0x8EF8E43D,
    617653972,
    1474514999,
    1471783658,
    1012864704,
    0xD7821910,
    993855884,
    438456717,
    0xC83555B7,
    0xE8DFF468,
    198959101,
    0xC5B84FEB,
    0xD9F837C6,
    613157871,
    0x8EFA4EDD,
    97286225,
    0x8B4B608C,
    1471645170,
    0xC0B62792,
    583597118,
    0xAAB1C22D,
    0xBDB9C266,
    1384330715,
    0xAE9F9816,
    0xD1F40B3C,
    0x8206DDC3,
    0xC4E0BADC,
    0xE407BD26,
    145643141,
    0x8016C6A5,
    0xAF4AB9D3,
    506798154,
    994590281,
    0x85082A0B,
    0xCA0BC95A,
    0xA7BE567C,
    1105937096,
    1789727804,
    0xDFEFB591,
    0x93346B38,
    1162286478,
    680814033,
    0xAEE1A7A2,
    0x80E574AE,
    0xF154F55F,
    2121620700,
    0xFCBDA653,
    0x8E902444,
    0xCA742E12,
    0xB8424071,
    0xB4B15EC2,
    0x943BFA09,
    0xBC97CD93,
    1285603712,
    798920280,
    0x8B58328F,
    0xF9822360,
    0xD1FD15EE,
    1077514121,
    1436444106,
    0xA2D6C17E,
    1507202797,
    500756149,
    198754565,
    0x8E014807,
    880454148,
    1970517398,
    0xBFC6EE25,
    1161840191,
    560498076,
    1782600856,
    0x9D93FEBE,
    1285196205,
    788797746,
    1195724574,
    0xF2174A07,
    103427523,
    0x952BFE83,
    0xF730AC4C,
    617564657,
    978211984,
    1781482121,
    0x8379D23A,
    0xEAD737EE,
    0xE41555FB,
    659557668,
    0x99F3B244,
    1561884856,
    0x842C31A4,
    1189296962,
    169145316,
    0xA5CE044C,
    1323893433,
    824667876,
    408202876,
    0xE0178482,
    0xF412BBBC,
    1508996065,
    162419237,
    0xDE740B00,
    0xB7CB64FD,
    0xEBCADB1F,
    0x8EAE2326,
    0x933C216C,
    0xD7D1F649,
    481927014,
    0xA448AC16,
    0xBC082807,
    1261069441,
    2063238535,
    0x8474A61D,
    101459755,
    0xBC5654D1,
    1721190841,
    1078395785,
    176506553,
    0xD3C5280F,
    1566142515,
    1938949000,
    1499289517,
    0xC59872F8,
    829714860,
    0xE51502A2,
    952932374,
    1283577465,
    2045007203,
    0xEBE6A798,
    0xE09575CD,
    0xADDF4157,
    0xC4770191,
    482297421,
    1734231412,
    0xDAC71054,
    0x99807E43,
    0xA88D74B1,
    0xCB77E028,
    1533519803,
    0xEEEBC3B6,
    0xE7E680E5,
    272960248,
    317508587,
    0xC4B10CDC,
    0x91776399,
    27470488,
    1666674386,
    1737927609,
    750987808,
    0x8E364D8F,
    0xA0985A77,
    562925334,
    0x837D6DC3
]

key = [54, 54, 54, 54]
decrypt(ciphertext, len(ciphertext), key)
print(f'ciphertext = {ciphertext}')

c = ''.join(bytes.fromhex(hex(ct)[2:]).decode() for ct in ciphertext)
print(f'c = {c}')

n = 0x649EE967E7916A825CC9FD3320BEABF263BEAC68C080F52824A0F521EDB6B78577EC52BF1C9E78F4BB71192F9A23F1A17AA76E5979E4D953329D3CA65FB4A71DA57412B59DFD6AEDF0191C5555D3E5F582B81B5E6B23163E9889204A81AFFDF119FE25C92F4ED59BD3285BCD7AAE14824240D2E33C5A97848F4EB7AAC203DE6330D2B4D8FF61691544FBECD120F99A157B3D2F58FA51B2887A9D06CA383C44D071314A12B17928B96F03A06E959A5AFEFA0183664F52CD32B9FC72A04B45913FCB2D5D2D3A415A14F611CF1EAC2D6C785142A8E9CC41B67A6CD85001B06EDB8CA767D367E56E0AE651491BF8A8C17A38A1835DB9E4A9292B1D86D5776C98CC25
e = 0x647327833ACFEF1F9C83E74E171FC300FA347D4A6769476C33DA82C95120ACB38B62B33D429206FE6E9BB0BB7AB748A1036971BEA36EC47130B749C1C9FF6FE03D0F7D9FC5346EB0E575BDFA6C530AA57CD676894FC080D2DD049AB59625F4B9C78BCFD95CDCD2793E440E26E189D251121CB6EB177FEDB596409034E8B0C5BBD9BD9342235DBB226C9170EFE347FF0FD2CFF9A1F7B647CC83E4D8F005FD7125A89251C768AFE70BDD54B88116814D5030F499BCAC4673CCCC342FB4B6AC58EA5A64546DC25912B6C430529F6A7F449FD96536DE269D1A1B015A4AC6B6E46EE19DCE8143726A6503E290E4BAE6BD78319B5878981F6CFFDB3B818209341FD68B
d = wiener_attack(e, n)
m = pow(int(c), d, n)
print(long_to_bytes(m))
# flag{You_Need_Some_Tea}

FakePica #

WIP

LetsGo2 #

WIP