There is encrypted file “reverse2.7z.enc”. So if you look careful you see repeated pattern:
If you look at normal 7z file there are nulls there, so it means that XOR or ADD with DWORD could be there like a crypt algorithm.
When we tried XOR with 0x9012347a and we got 7z archive:
After unpack there are 2 file there: “a” and “b”. At first glance “a” is a code part and “b” is a data. So let’s look at a in IDA. There are two functions:
int __cdecl sub_0(unsigned __int8 *a1) { int result; // eax@1 int v2; // [sp+0h] [bp-50h]@0 int v3; // [sp+0h] [bp-50h]@1 unsigned int i; // [sp+4Ch] [bp-4h]@1 result = v6001A238(0x60011268u, v2); for ( i = 0; i < 0x18; ++i ) { v6001A238(0x60011264u, a1[i] % 10 + 48); if ( i == 12 ) v6001A238(0x60011260u, v3); result = i + 1; } return result; } |
And
int __cdecl sub_A0(char *a1) { int result; // eax@3 unsigned int i; // [sp+4Ch] [bp-4h]@1 unsigned int j; // [sp+4Ch] [bp-4h]@4 for ( i = 0; i < 0x18; ++i ) { a1[i] = i; result = i + 1; } for ( j = 0; j < 0x18; ++j ) { a1[j] ^= *(_BYTE *)(2 * j + 0x60011288); result = j + 1; } return result; } |
There are several interesting constant:
0x6001A238, 0x60011268, 0x60011264, 0x60011260, 0x60011288
Here I recall you about file “b” which should be data. 0x60011260 is a lowest address which used and if we confront it with 0 offset in file “b” then function sub_0 became more understandable:
- 0x6001A238 – is a “printf” function.
- 0x60011260 – pointer to “-”
- 0x60011264 – pointer to “%c”
- 0x60011268 – pointer to “Bank account:”
So I rewrite this function:
void print(unsigned char* a1) { printf("Bank account: "); for (int i = 0; i < 0x18; ++i ) { if (a1[i] % 10 + 48 >= 48) printf("%c", a1[i] % 10 + 48); else printf("%c", a1[i] % 10 + 48); if ( i == 12 ) printf("-"); } } |
Now we know that 0x60011288 is offset 0x28 in file “b” and can rewrite second function:
unsigned char key2[] = "\x1F\x82\x9D\x23\x3F\x5F\x5C\x59\x17\xF7\x95\xAF \xEC\x2B\xC6\x5E\x11\xEB\x33\xFE\x35\xF6\xF7\x87 \x28\xAA\xA0\x32\xCE\xA9\x2B\x40\x5E\x42\xCD\x53 \xE7\x07\xD2\x8D\x98\x01\xA1\xE2\x12\x37\x54\xEA"; int decrypt(unsigned char *a1) { for (int i = 0; i < 0x18; ++i ) { a1[i] = i; } for (int j = 0; j < 0x18; ++j ) { a1[j] ^= *(char *)(2 * j + key2); } return 0; } |
Let’s call them together
int main(int argc, char* argv[]) { unsigned char key1[0x18*2]; memset(key1,0,0x18*2); decrypt(key1); print(key1); } |
C:\ctf\~writeups\ictf2011\challenge30\keygen\debug>keygen.exe
Bank account: 1615944358326-32680530047
1 ping
[…] More (Challenges 29, 30, 31, 32, […]