Fun pwn challenges!
full repo:
https://github.com/qwerty-po/hacklu_2022
Before analysis, vuln occurs at Human::requestName()
. It just get name by scanf("%s", ...)
so we can make stack overflow when Human
instance exist on stack.
void Human::requestName()
{
printf("What's your name?\\n");
scanf("%s", this->name);
util::readUntilNewline();
}
First, let’s start with main.cpp. The curious thing is, it has two different modes, single player and multiplayer.
int main()
{
[...]
if (selection == '1')
{
printf("Do you want to play against a (b)ot or against a (h)uman? ");
fflush(stdout);
result = scanf("%c", &selection);
if (result == EOF)
return 1;
util::readUntilNewline();
selection |= 0x20; // Make lowercase
if (selection == 'b')
Game::startSingleplayer();
else if (selection == 'h')
Game::startMultiplayer();
}
[...]
}
In Game::startSingleplayer
,
human.requestName() -> bot.requestName()
and game.play()
called. So we can overwrite bot
’s info.
void Game::startSingleplayer()
{
Human human;
Bot bot;
human.requestName();
bot.requestName();
Game game(&human, &bot);
game.play();
}
In Game::startMultiplayer
, both variable info are given by user. By using this function, I leak some stack info first(address of player1 and player2). Game::startSingleplayer
's Human
and Bot
use same address.
So, Now we know stack address