Skip to main content

trace-me

Solved by: grb

This is what the challenge looks like, as usual, there's a binary file attached to the challenge.

Challenge

And just like clockwork, lets open the binary under IDA.

_BOOL8 __fastcall main(int a1, char **a2, char **a3)
{
unsigned __int64 v3; // rdi
unsigned int v4; // ecx
unsigned int v5; // esi
unsigned int v6; // eax
unsigned __int32 v7; // r8d
unsigned __int64 v8; // rax
size_t v9; // rax
size_t v10; // rax
char v11; // dl
int v12; // r13d
char *v13; // rax
char *v14; // rdx
__m128i *p_si128; // rax
__m128i *v16; // rdx
const char *v17; // rdi
char *v19; // rax
char *v20; // rdx
__m128i *v21; // rax
__m128i *v22; // rdx
__m128i si128; // [rsp+0h] [rbp-138h] BYREF
_OWORD v24[3]; // [rsp+10h] [rbp-128h] BYREF
__int64 v25; // [rsp+40h] [rbp-F8h]
char s1[16]; // [rsp+50h] [rbp-E8h] BYREF
__int128 v27; // [rsp+60h] [rbp-D8h]
__int128 v28; // [rsp+70h] [rbp-C8h]
__int128 v29; // [rsp+80h] [rbp-B8h]
char s[168]; // [rsp+90h] [rbp-A8h] BYREF

v3 = 0;
v24[0] = _mm_load_si128((const __m128i *)&xmmword_2030);
v25 = 0x27B51D35DB37D400LL;
v24[1] = _mm_load_si128((const __m128i *)&xmmword_2040);
v24[2] = _mm_load_si128((const __m128i *)&xmmword_2050);
si128 = _mm_load_si128((const __m128i *)&xmmword_2060);
*(_OWORD *)s1 = 0;
v27 = 0;
v28 = 0;
v29 = 0;
do
{
v4 = *((_DWORD *)v24 + v3);
v5 = *((_DWORD *)v24 + v3 + 1);
v6 = -957401312;
do
{
v7 = v6 + si128.m128i_i32[(v6 >> 11) & 3];
v6 += 1640531527;
v5 -= v7 ^ (v4 + ((v4 >> 5) ^ (16 * v4)));
v4 -= (v6 + si128.m128i_i32[v6 & 3]) ^ (v5 + ((v5 >> 5) ^ (16 * v5)));
}
while ( v6 );
v8 = v3 >> 1;
v3 += 2LL;
*(_QWORD *)&s1[8 * v8] = ((unsigned __int64)_byteswap_ulong(v5) << 32) | _byteswap_ulong(v4);
}
while ( v3 != 14 );
BYTE4(v29) = 0;
printf("Enter flag: ");
if ( fgets(s, 128, stdin) )
{
v9 = strlen(s);
if ( v9 )
{
v10 = v9 - 1;
v11 = s[v10];
if ( v11 == 10 || v11 == 13 )
s[v10] = 0;
}
v12 = strcmp(s1, s);
v13 = s1;
do
{
v14 = v13++;
*v14 = 0;
}
while ( v13 != s );
p_si128 = &si128;
do
{
v16 = p_si128;
p_si128 = (__m128i *)((char *)p_si128 + 1);
v16->m128i_i8[0] = 0;
}
while ( p_si128 != (__m128i *)v24 );
v17 = "Nope.";
if ( !v12 )
v17 = "Correct!";
puts(v17);
return v12 != 0;
}
else
{
fwrite("Input error.\n", 1u, 0xDu, stderr);
v19 = s1;
do
{
v20 = v19++;
*v20 = 0;
}
while ( v19 != s );
v21 = &si128;
do
{
v22 = v21;
v21 = (__m128i *)((char *)v21 + 1);
v22->m128i_i8[0] = 0;
}
while ( v21 != (__m128i *)v24 );
return 1;
}
}

Yes yes I know, its not the prettiest decompilation you've ever seen. In the beginning of the code, we can see some data loading, it seems like its reading a dat thats stored from the binary and putting it to the stack. The next part of the code, we can see a loop, and inside the loop there's some XOR operation, so we can essentially deduce that this is the decryption process. Next part, it asks for our input and compares it with the output buffer from the previous decryption process. Now, my approach to my challenge is as simple as putting a breakpoint to strcmp and read the string parameter.

PWNED!

PO- PO- PO- PWNED!!!