SCTF2024 Reverse
ez_cython
from regadgets import *
ans = [4108944556, 3404732701, 1466956825, 788072761, 1482427973, 782926647,
1635740553, 4115935911, 2820454423, 3206473923, 1700989382, 2460803532,
2399057278, 968884411, 1298467094, 1786305447, 3953508515, 2466099443,
4105559714, 779131097, 288224004, 3322844775, 4122289132, 2089726849,
656452727, 3096682206, 2217255962, 680183044, 3394288893, 697481839,
1109578150, 2272036063]
def xxtea_sctf2024_shift(z, y, sum, k, p, debug = False):
e = (sum.value >> 3) & 3
PE = (p & 2) ^ e
Ly = y.value << 3
Ry = y.value >> 4
Lz = z.value << 2
Rz = z.value >> 3
LzRy = Rz ^ Ly
LyRz = Ry ^ Lz
SY = sum.value ^ y.value
K = k[PE].value
KZ = K ^ z.value
result = (LzRy + LyRz) ^ (KZ + SY)
return result
key = [0x53, 0x79, 0x43, 0x31] # Syc1
dec = xxtea_decrypt(ans, key, delta=0x9e3779b9, round_base=4, round_addi=60, shift_func=xxtea_sctf2024_shift)
print(bytes(dec))
# b'SCTF{w0w_y0U_wE1_kNOw_of_cYtH0N}'
BBox
Android
超绝一键apk混淆捏
const char *__fastcall Java_com_example_bbandroid_MainActivity_checkFlag(_JNIEnv *a1, __int64 a2, __int64 a3)
{
time_t v5; // w22
const char *result; // x0
const char *v7; // x21
unsigned int v8; // w23
signed int v9; // w22
__int64 v10; // x19
__int64 v11; // x20
char *v12; // x22
char v13; // w0
int v14; // w9
signed int v15; // w8
unsigned __int64 v16; // x10
unsigned __int64 v17; // x11
int v18; // w12
int v19; // w13
char flag[256]; // [xsp+8h] [xbp-108h] BYREF
__int64 v21; // [xsp+108h] [xbp-8h]
v21 = *(_QWORD *)(_ReadStatusReg(ARM64_SYSREG(3, 3, 13, 0, 2)) + 40);
v5 = time(0LL);
result = (const char *)((__int64 (__fastcall *)(_JNIEnv *, __int64, _QWORD))a1->functions->GetStringUTFChars)(
a1,
a3,
0LL);
if ( result )
{
v7 = result;
v8 = v5 / 1000000 / 100;
strncpy(flag, result, 0xFFu);
flag[255] = 0;
v9 = __strlen_chk(flag, 0x100u);
((void (__fastcall *)(_JNIEnv *, __int64, const char *))a1->functions->ReleaseStringUTFChars)(a1, a3, v7);
srand(v8);
if ( v9 >= 4 )
{
v10 = 0LL;
v11 = (unsigned int)v9 >> 2;
do
{
v12 = &flag[4 * v10];
*v12 ^= rand();
v12[1] ^= rand();
v12[2] ^= rand();
v13 = rand();
v14 = 32;
v12[3] ^= v13;
v15 = *(_DWORD *)v12;
do
{
if ( v15 >= 0 )
v15 *= 2;
else
v15 = (2 * v15) ^ 0x85B6874F;
--v14;
}
while ( v14 );
*(_DWORD *)&flag[4 * v10++] = v15;
}
while ( v10 != v11 );
}
if ( flag[0] == '3' )
{
v16 = 0LL;
do
{
v17 = v16;
if ( v16 == 0x27 )
break;
v18 = (unsigned __int8)flag[v16 + 1];
v19 = dword_B14[++v16];
}
while ( v18 == v19 );
return (const char *)(v17 > 0x26);
}
else
{
return 0LL;
}
}
return result;
}
Exp
from regadgets import *
from z3 import *
from copy import deepcopy
enc = [0x33, 0xC0, 0xC8, 0xA3, 0xF3, 0xBF, 0x1D, 0x1A, 0x3B, 0x41,
0xB7, 0xC6, 0xF1, 0x5E, 0x86, 0x52, 0x52, 0xCF, 0x6B, 0x1E,
0xC5, 0xF9, 0xCB, 0xBF, 0xED, 0x7B, 0x62, 0xF1, 0xF7, 0x43,
0x48, 0x54, 0xFB, 0x85, 0x4C, 0xD9, 0x35, 0x30, 0xF2, 0x6E]
print(bytes(enc))
dw = byte2dword(enc)
print(dw)
s = Solver()
x = [BitVec(f"x{i}", 32) for i in range(len(dw))]
y = deepcopy(x)
for i in range(len(dw)):
for j in range(32):
x[i] = If(LShR(x[i], 31) == 1, 2*x[i] ^ 0x85b6874f, 2*x[i])
s.add(x[i] == dw[i])
print(s.check())
m = s.model()
r = []
for i in y:
r.append(m[i].as_long())
print(r)
randv = [0x49308bb9,0x3cb3ad,0xfb4e87f,0x75655103,0x6d505b9f,0x1d20580f,
0xdcf4af1,0x3e381967,0x54bcf579,0x73c09db7,0x501b2039,0x1b8950dd,
0x23e73393,0x2b480a88,0x6818cdae,0x61d009ea,0x44c0c5b0,0x385aff3d,
0x5cfb2a7a,0x587f9c07,0x158172f2,0x4d334c89,0x302b76e5,0x5e17f434,
0x692de923,0x806d155,0x3d2c61d8,0x1d09ef4e,0x7c3d83b7,0x1d7621da,
0x2dc0a3ec,0x456e0f71,0x1db2d588,0x3d758c6c,0x3ad36074,0xb033127,0x5a95e47b,0x48a2ab65,0x493b4a8e,0x2f52d9f5 ]
randv = [i & 0xff for i in randv]
v1 = bxor(dword2byte(r)[:len(enc)], bytes(randv)[:len(enc)])
v2 = bxor_cycle(v1, b'\x1e').decode()
print(decode_b64(v2, "nopqrstDEFGHIJKLhijklUVQRST/WXYZabABCcdefgmuv6789+wxyz012345MNOP"))
# b'Y0u_@re_r1ght_r3ver53_is_easy!'
其中 randv 是通过hook得到的rand()的结果。中间是一个不安全的CRC。
easyMCU
我自认为这是一个逆向题目,所以把它放到了Reverse下。
首先,使用010Editor,打开mcu.s19,发现它直接自动给我转hex了,我们Ctrl+S保存到文件即可。
隔壁队伍使用的是bincopy convert mcu.s19 -o binary out.bin
进行的转换,也是一种方法。
通过图片中的TriCore
,我们可以知道固件是Tri
经过翻找,我们找到关键代码
/* WARNING: Globals starting with '_' overlap smaller symbols at the same address */
undefined4 FUN_80000690(void)
{
byte bVar1;
bool bVar2;
uint uVar3;
undefined4 uVar4;
int i;
bVar2 = FUN_8000125a(0x6000009c,(undefined *)0x60000004,(short *)0x60000000,_DAT_80003990,
iRam80003994);
if (bVar2) {
AES_ENCRYPT(0x60000004,-0x7fffc65d,0x6000007c,0x20);
for (i = 0; i < 0x20; i += 1) {
uVar3 = rol((uint)*(byte *)(i + 0x6000007c),3);
*(char *)(i + 0x6000007c) = (char)uVar3;
bVar1 = bRam6000007c;
if (i < 0x1f) {
bVar1 = *(byte *)(i + 0x6000007d);
}
*(byte *)(i + 0x6000007c) = bVar1 ^ *(byte *)(i + 0x6000007c);
*(byte *)(i + 0x6000007c) = *(byte *)(i + 0x6000007c) ^ 0xff;
}
FUN_80001278((int *)0x6000009c,(undefined *)0x6000007c,(short *)0x60000000,_DAT_80003990,
iRam80003994);
uVar4 = 0;
}
else {
uVar4 = 0xffffffff;
}
return uVar4;
}
void AES_ENCRYPT(int param_1,int param_2,int param_3,uint param_4)
{
uint uVar1;
undefined8 auStack_c0 [2];
undefined key [176];
FUN_800002b0(param_2,(int)key);
for (uVar1 = 0; uVar1 < param_4; uVar1 += 0x10) {
FUN_80003782(auStack_c0,(undefined8 *)(param_1 + uVar1),0x10);
aes((int)auStack_c0,(int)key);
FUN_80003782((undefined8 *)(param_3 + uVar1),auStack_c0,0x10);
}
return;
}
void AES_ENCRYPT(int param_1,int param_2,int param_3,uint param_4)
{
uint uVar1;
undefined8 auStack_c0 [2];
undefined key [176];
FUN_800002b0(param_2,(int)key);
for (uVar1 = 0; uVar1 < param_4; uVar1 += 0x10) {
FUN_80003782(auStack_c0,(undefined8 *)(param_1 + uVar1),0x10);
aes((int)auStack_c0,(int)key);
FUN_80003782((undefined8 *)(param_3 + uVar1),auStack_c0,0x10);
}
return;
}
写出EXP。
from regadgets import *
enc = bytes.fromhex('63 D4 DD 72 B0 8C AE 31 8C 33 03 22 03 1C E4 D3 C3 E3 54 B2 1D EB EB 9D 45 B1 BE 86 CD E9 93 D8')
print(len(enc))
key = [ 0x2e, 0x35, 0x7d, 0x6a, 0xed, 0x44, 0xf3, 0x4d, 0xad, 0xb9, 0x11, 0x34, 0x13, 0xea, 0x32, 0x4e ]
enc = list(enc)
for i in range(len(enc)):
enc[31-i] ^= 0xff
enc[31-i] ^= enc[(32-i) % 32]
enc[31-i] = ror8(enc[31-i], 3)
aes = AES(key)
dec = aes.decrypt_ecb_block(enc[:16]) + aes.decrypt_ecb_block(enc[16:])
print(dec) # b'SCTF{Wlc_t0_the_wd_oF_IOT_s3cur}'
评论已关闭