→ PlaidCTF 2012 - Override [300]

| No TrackBacks
Obfuscated x64 binary. Very small amount of code is split into chunks that are linked together via jmp | push + jmp and "high-level" constructions like this:
mov rdx, offset InputData
push offset trim_password
mov rcx, offset _strlen
jmp @jmp_via_ecx
...
@jmp_via_ecx:
mov rdi, rdx
push ecx
jmp do_ret

@do_ret:
ret
Bring things together:
mov rdx, offset InputData
push offset trim_password ; retaddr
mov rcx, offset _strlen   ; destination
mov rdi, rdx
jmp ecx
Or, more clear
mov rdi, offset InputData
push offset trim_password ; retaddr
jmp qword ptr [_strlen]   ; destination
After de-obfuscation, code becomes more readable.

First, seed value is calculated: seed = 940903 * 659 * -3;

Then srand(seed) is called, and console is read using fgets(InputData, 80, STDIN). Each symbol from user input (InputData array) is compared with an one symbol of the Key sequence:
Rh|hx6VPJXwt7b%YUh3|ku9!Nnl#p-B*fjKUrA:r83Alg3KMjoiWA%P-8Xo5R%^:
Position is determined by rand() calling. In other words,
InputData[i] == Key[rand() % 64] ? continue : exit()
After full comparison, length of InputData is considered, and successful result is only possible if length of InputData is 64.

The following code snapshot allow to encode the flag:
char input[] = "Rh|hx6VPJXwt7b%YUh3|ku9!Nnl#p-B*fjKUrA:r83Alg3KMjoiWA%P-8Xo5R%^:";
char result[sizeof(input)];

int seed = 940903 * 659 * -3;
srand(seed);

for (int i = 0; i < sizeof(input) - 1; i++)
{
    result[i] = input[rand() % 64];
}
result[sizeof(input) - 1] = '\0';
printf("%s\n", result);
Output: Bg8Ph#xnr||l*YjV|9K#RRfh6XhnhK8*%f:h5AAUgg%t5K3%xRnR%Xh|iU#W6h3k

No TrackBacks

TrackBack URL: http://smokedchicken.org/m/mt-tb.cgi/78

About this Entry

This page contains a single entry by Павел Збицкий published on May 2, 2012 9:27 PM.

PlaidCTF 2012 - Debit or Credit [200] was the previous entry in this blog.

PlaidCTF 2012 - Mess [300] is the next entry in this blog.

Find recent content on the main index or look in the archives to find all content.