basic_exploitation_003

oogu ㅣ 2023. 1. 24. 19:55

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
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);
}

void get_shell() {
    system("/bin/sh");
}

int main(int argc, char *argv[]) {
 
    char *heap_buf = (char *)malloc(0x80);
    char stack_buf[0x90] = {};
    
    initialize();
    
    read(0, heap_buf, 0x80);
    sprintf(stack_buf, heap_buf);
    printf("ECHO : %s\n", stack_buf);
    
    return 0;
}

[그림 1-1]

코드와 [그림 1-1]을 보고 두 가지 방법이 떠올랐다.

1. printf got 주소에 get_shell 주소를 넣는다.

2. ret 값을 get_shell 주소로 바꾼다.

 

2번이 간단해 보여서 바로 스택을 그려봤다.

[그림 1-2]

156개를 넣은 다음에는 ret 값이 덮인다.

[그림 1-3]

2번째 방법은 익스코드가 너무 간단하다.

[그림 1-4]

성공!

 

첫 번째 방법으로 구해보자

[그림 2-1]

printf got 주소와 get_shell 주소는 앞 2byte는 같다. -> 0x0804

따라서 뒤에 2byte만 바꾸면 된다.

[그림 2-2]

[그림 2-2] 하면 8669가 써질 거 같지만 문제가 발생한다. sprintf(stack_buf,printf(heap_buf)) 이다. -> sprintf를 쉽게 쓰면

payload를 printf로 출력해서 stack_buf 변수에 써지는데 payload의 크기가 stack_buf 변수보다 커서 다른 메모리까지 침범해서 문제가 발생이 된다.

따라서 1byte씩 나눠서 써야 한다. -> 86 69

[그림 2-3]

hhn을 이용해서 1byte씩 쓰자

[그림 2-4]

성공!

'Dreamhack - pwnable' 카테고리의 다른 글

uaf_overwrite  (0) 2023.01.28
ptmalloc2  (0) 2023.01.28
basic_exploitation_002  (0) 2023.01.24
Format String Bug  (0) 2023.01.24
out_of_bound  (0) 2023.01.20