Hacking useless things :3
Information
Difficulty: Medium
Tags: pwn, crypto
Author: aaaa

Just a test as always :3
Solution
We’re provided with a launcher and 3 games.
Here is some pseudocode for the launcher:
let's just start
_QWORD *__fastcall read_parse_and_check_file(const char *file, _QWORD *start_ptr, _QWORD *sig_ptr, _QWORD *sig_idx)
{
char *ptr; // [rsp+28h] [rbp-18h]
__int64 size; // [rsp+30h] [rbp-10h]
FILE *stream; // [rsp+38h] [rbp-8h]
stream = fopen(file, "rb");
if ( !stream )
{
perror("[ERROR] Failed to open signed file");
exit(-1);
}
if ( fseek(stream, 0, 2) )
{
perror("[ERROR] fseek end");
fclose(stream);
exit(-1);
}
size = ftell(stream);
if ( size < 0 )
{
perror("[ERROR] ftell");
fclose(stream);
exit(-1);
}
rewind(stream);
if ( size <= 256 || size > 0x100000 )
{
fwrite("[ERROR] Invalid file size.\n", 1u, 0x1Bu, stderr);
fclose(stream);
exit(-1);
}
ptr = malloc(size);
if ( !ptr )
{
fwrite("[ERROR] malloc failed\n", 1u, 0x16u, stderr);
fclose(stream);
exit(-1);
}
if ( fread(ptr, 1u, size, stream) != size )
{
perror("[ERROR] fread");
free(ptr);
fclose(stream);
exit(-1);
}
fclose(stream);
*sig_idx = size - 256;
*start_ptr = ptr;
*sig_ptr = &ptr[*sig_idx];
return sig_ptr;
}
After some research, it becomes clear that this challenge is based upon an actual vulnerability that used to be present in IOS: The Trucha bug.
The core of the vulnerability exploits a flaw in the behaviour of the strncmp() function: the function returns prematurely whenever it encouters a null byte on either of the two strings its comparing (normally at the end). However, because we’re not passing ASCII strings but binary hashes to the function, we can this behavior if either of two hashes compared (the signature hash and the game_hash) contains a null byte (00) at any position.
However, strncmp returns whenever it encounters a null byte (00) on either of the strings it compares, but it doesn’t return 0 (strings are equal) unless the bytes it compared actually are the same, even if it returned prematurely.
To summarize:
$ ./demo/exploit.py
[i] running our exploit....
[i] DECRYPTED HASH:
00 59 DF 5E D5 96 49 B0
F3 88 65 68 F4 0A 8F AF
50 FF 4B 37 C9 D1 9C BB
2D 84 24 03 5B 27 70 66
...
$ python3 solve.py
[*] Payload size: 16016 bytes
[*] Signature size: 256 bytes (Expected: 256)
[+] Nonce found in 46 iterations.
[+] Nonce (hex): 2e
[+] Associated hash: 00cbf278e41a69596c814a573acfb7ba5fcfe228357f2c0f25d3ce6e7feb4fad
We send the locally compiled payload to the remote server: