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