BUUCTF RE [ACTF新生賽2020]usualCrypt
阿新 • • 發佈:2021-12-15
1.查殼 無殼
2.拖進IDA
int __cdecl main(int argc, const char **argv, const char **envp) { int v3; // esi int v5[3]; // [esp+8h] [ebp-74h] BYREF __int16 v6; // [esp+14h] [ebp-68h] char v7; // [esp+16h] [ebp-66h] char v8[100]; // [esp+18h] [ebp-64h] BYREF sub_403CF8(&unk_40E140); scanf("%s", v8); memset(v5, 0, sizeof(v5)); v6 = 0; v7 = 0; sub_401080(v8, strlen(v8), v5); v3 = 0; while ( *((_BYTE *)v5 + v3) == byte_40E0E4[v3] ) { if ( ++v3 > strlen((const char *)v5) ) goto LABEL_6; } sub_403CF8(aError); LABEL_6: if ( v3 - 1 == strlen(byte_40E0E4) ) return sub_403CF8(aAreYouHappyYes); else return sub_403CF8(aAreYouHappyNo); }
3.進入函式 sub_401080
int __cdecl sub_401080(int a1, int a2, int a3) { int v3; // edi int v4; // esi int v5; // edx int v6; // eax int v7; // ecx int v8; // esi int v9; // esi int v10; // esi int v11; // esi _BYTE *v12; // ecx int v13; // esi int v15; // [esp+18h] [ebp+8h] v3 = 0; v4 = 0; sub_401000(); v5 = a2 % 3; v6 = a1; v7 = a2 - a2 % 3; v15 = a2 % 3; if ( v7 > 0 ) { do { LOBYTE(v5) = *(_BYTE *)(a1 + v3); v3 += 3; v8 = v4 + 1; *(_BYTE *)(v8 + a3 - 1) = byte_40E0A0[(v5 >> 2) & 0x3F]; *(_BYTE *)(++v8 + a3 - 1) = byte_40E0A0[16 * (*(_BYTE *)(a1 + v3 - 3) & 3) + (((int)*(unsigned __int8 *)(a1 + v3 - 2) >> 4) & 0xF)]; *(_BYTE *)(++v8 + a3 - 1) = byte_40E0A0[4 * (*(_BYTE *)(a1 + v3 - 2) & 0xF) + (((int)*(unsigned __int8 *)(a1 + v3 - 1) >> 6) & 3)]; v5 = *(_BYTE *)(a1 + v3 - 1) & 0x3F; v4 = v8 + 1; *(_BYTE *)(v4 + a3 - 1) = byte_40E0A0[v5]; } while ( v3 < v7 ); v5 = v15; } if ( v5 == 1 ) { LOBYTE(v7) = *(_BYTE *)(v3 + a1); v9 = v4 + 1; *(_BYTE *)(v9 + a3 - 1) = byte_40E0A0[(v7 >> 2) & 0x3F]; v10 = v9 + 1; *(_BYTE *)(v10 + a3 - 1) = byte_40E0A0[16 * (*(_BYTE *)(v3 + a1) & 3)]; *(_BYTE *)(v10 + a3) = 61; LABEL_8: v13 = v10 + 1; *(_BYTE *)(v13 + a3) = 61; v4 = v13 + 1; goto LABEL_9; } if ( v5 == 2 ) { v11 = v4 + 1; *(_BYTE *)(v11 + a3 - 1) = byte_40E0A0[((int)*(unsigned __int8 *)(v3 + a1) >> 2) & 0x3F]; v12 = (_BYTE *)(v3 + a1 + 1); LOBYTE(v6) = *v12; v10 = v11 + 1; *(_BYTE *)(v10 + a3 - 1) = byte_40E0A0[16 * (*(_BYTE *)(v3 + a1) & 3) + ((v6 >> 4) & 0xF)]; *(_BYTE *)(v10 + a3) = byte_40E0A0[4 * (*v12 & 0xF)]; goto LABEL_8; } LABEL_9: *(_BYTE *)(v4 + a3) = 0; return sub_401030(a3);
通過檢視各位大佬部落格得知 此處是BASE64的特徵碼 我沒有看出來
4.這個函式就可以分為三個部分
1.開頭sub_401000函式
2.中間base64加密
3.結尾sub_401030函式
sub_401000函式
int sub_401000() { int result; // eax char v1; // cl for ( result = 6; result < 15; ++result ) { v1 = byte_40E0AA[result]; byte_40E0AA[result] = byte_40E0A0[result]; byte_40E0A0[result] = v1; } return result; }
看出來是在進行換位操作
這裡就是一個對base64的變表處理
sub_401030函式
int __cdecl sub_401030(const char *a1)
{
__int64 v1; // rax
char v2; // al
v1 = 0i64;
if ( strlen(a1) )
{
do
{
v2 = a1[HIDWORD(v1)];
if ( v2 < 97 || v2 > 122 )
{
if ( v2 < 65 || v2 > 90 )
goto LABEL_9;
LOBYTE(v1) = v2 + 32;
}
else
{
LOBYTE(v1) = v2 - 32;
}
a1[HIDWORD(v1)] = v1;
LABEL_9:
LODWORD(v1) = 0;
++HIDWORD(v1);
}
while ( HIDWORD(v1) < strlen(a1) );
}
return v1;
}
將經過base64變表加密的結果,大小寫互換。
因此,我們只需要反過來,先將byte_40E0E4大小寫互換,構造base64變表,再利用變表將byte_40E0E4轉換為正常的base64解密就行。
import base64
Str = list("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/")
model = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
for i in range(6,15):
Str[i],Str[i+10] = Str[i+10],Str[i]
Str = ''.join(Str)
enc = "zMXHz3TIgnxLxJhFAdtZn2fFk3lYCrtPC2l9".swapcase()
dec = ""
for i in range(len(enc)):
dec += model[Str.find(enc[i])]
print (dec)
print (Str)
print (base64.b64decode(dec))
flag{bAse64_h2s_a_Surprise}