## crackme03 (RE, 150pts)
#### Challenge Description
tik-tok tik-tok can you defuse the bomb?
author: codacker
```nc 104.154.106.182 7777```
#### Overview
This challenge has a remote host unlike the first two, and the local binary doesn't contain the flag. After passing input that satisfies all the conditions, a flag file is read and printed out to you. The premise is fun - you must diffuse a bomb by passing 5 input checks, each progressively a little more difficult than the last. These checks are all stored in a table, and are as follows:
```#1: sub_1286#2: sub_12BD#3: sub_12E6#4: sub_1392#5: sub_1410```
We don't want to reach the "boom" function, which is `sub_1258`.
#### First check
The first check is `sub_1286` and just compares the first part of the string with a literal `"CRACKME02"`, so passing this check is easy.
```assemblylea     edx, (aCrackme02 - 4000h)[eax] ; "CRACKME02"push    edx             ; s2push    [ebp+s1]        ; s1mov     ebx, eaxcall    _strcmpadd     esp, 10htest    eax, eaxjz      short loc_12B7call    sub_1258```
Input so far:
```CRACKME02\n```
#### Second check
The second check is `sub_12BD` and is also fairly easy, we just need to pass an integer of `0xDEADBEEF`.
```assemblymov     [ebp+var_C], 0DEADBEEFhmov     eax, [ebp+arg_0]mov     eax, ds:(off_4000 - 4000h)[eax]cmp     [ebp+var_C], eaxjz      short loc_12E3call    sub_1258```
Input so far:
```CRACKME02\n\xEF\xBE\xAD\xDE\n```
#### Third check
If we decompile the third check, which is `sub_12E6`, we'll see the following:
```cint result; // eaxunsigned int v2; // et1size_t i; // [esp+10h] [ebp-28h]char s[4]; // [esp+17h] [ebp-21h]unsigned int v5; // [esp+2Ch] [ebp-Ch]
v5 = __readgsdword(0x14u);strcpy(s, "ZXytUb9fl78evgJy3KJN");for ( i = 0; strlen(s) > i; ++i ){  if ( s[i] != *(_BYTE *)(i + a1) )    sub_1258();}v2 = __readgsdword(0x14u);result = v2 ^ v5;if ( v2 != v5 )  sub_1670();return result;```
Essentially, we just need to make sure we pass `"ZXytUb9fl78evgJy3KJN"`. The XOR operation is for the stack cookie and is irrelevant to the challenge.
Input so far:
```CRACKME02\n\xEF\xBE\xAD\xDE\nZXytUb9fl78evgJy3KJN\n```
#### Fourth check
If we decompile `sub_1392`, which is the fourth check, we get:
```cint v1; // ST1C_4
if ( strlen(s) > 3 )    sub_1258();v1 = atoi(s);if ( v1 * v1 * v1 + 2 * (2 * v1 * v1 - v1) - 3 )    sub_1258();return puts("SUBSCRIBE TO PEWDIEPIE");```
This means we need a string that's both longer than 3 characters and doesn't make that mathematical statement true. Let's try something simple like `1`.
```= v1 * v1 * v1 + 2 * (2 * v1 * v1 - v1) - 3= 1 * 1 * 1 + 2 * (2 * 1 * 1 - 1) - 3= 3 + 2 * (1) - 3= 3 + 2 - 3 = 2```
This statement will be evaluated as false, so it'll pass.
Input so far:
```CRACKME02\n\xEF\xBE\xAD\xDE\nZXytUb9fl78evgJy3KJN\n1\n```
#### Fifth check
The fifth check is quite interesting, and is located in `sub_1410`. Here's the code:
```cstrncpy(&dest, a1, 0xAu);puts("Validating Input 4");if ( dest[0x0] + dest[0x8] != 0xD5 )  sub_1258();if ( dest[0x1] + dest[0x7] != 0xCE )  sub_1258();if ( dest[0x2] + dest[0x6] != 0xE7 )  sub_1258();if ( dest[0x3] + dest[0x5] != 0xC9 )  sub_1258();if ( dest[0x4] == 0x69 )  puts("you earned it");```
Although it allows 0xA bytes in the strncpy, we only need to care about 8 of them. Given this code, our string needs to pass the following conditions:
```dest[0] + dest[8] must add up to 0xD5dest[1] + dest[7] must add up to 0xCEdest[2] + dest[6] must add up to 0xE7dest[3] + dest[5] must add up to 0xC9dest[4] must be 0x69```
What makes this challenge interesting though will require us to look at a bit of the disassembly. Let's look at the disassembly for the check against `dest[2]` and `dest[6]`, the others are similar but with different local variable references and compare intermediates.
```assemblymovzx   eax, [ebp+var_15]movsx   edx, almovzx   eax, [ebp+var_F]movsx   eax, aladd     eax, edxcmp     eax, 0CEh```
Notice that it first moves with a zero extension, then moves with a sign extension. This means we must make sure every byte we use in this string to make these additions match up must be 0x7F or below. If they're 0x80 or higher in value, they'll move 0xFF's into the upper 3 bytes and the checks will fail. Below is the string I came up with:
```dest[0] = 0x56, dest[8] = 0x7F. 0x7F + 0x56 = 0xD5dest[1] = 0x67, dest[7] = 0x67. 0x67 + 0x67 = 0xCEdest[2] = 0x73, dest[6] = 0x74. 0x73 + 0x74 = 0xE7dest[3] = 0x64, dest[5] = 0x65. 0x64 + 0x65 = 0xC9dest[4] = 0x69
Which gives us: \x56\x67\x73\x64\x69\x65\x74\x67\x7F```
#### Flag
Finally, when we put this all together, we get:
```CRACKME02\n\xEF\xBE\xAD\xDE\nZXytUb9fl78evgJy3KJN\n1\n\x56\x67\x73\x64\x69\x65\x74\x67\x7F```
If we use python to send this to the given IP and port, we'll get the flag.
```$ python -c 'print "CRACKME02\n" + "\xef\xbe\xad\xde\n" + "ZXytUb9fl78evgJy3KJN\n" + "1\n" + "\x56\x67\x73\x64\x69\x65\x74\x67\x7F"' | nc 104.154.106.182 7777Hi!, i am a BOMB!I will go boom if you don't give me right inputsEnter input #0: Enter input #1: Enter input #2: Enter input #3: SUBSCRIBE TO PEWDIEPIEEnter input #4: Validating Input 4you earned itencryptCTF{B0mB_D!ffu53d}```
The flag:
```encryptCTF{B0mB_D!ffu53d}```
