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