#ldd 명령어 분석 ( for dynamic symbol 저장 위치 찾기) , ldd 동작 방식 ,shared library 호출 방식
- #ldd 명령어 소스코드의 원형 분석
- 파일 및 공유라이브러리들의 공유라이브러리 의존관계 출력 command 내부적으로LD_TRACE_LOADED_OBJECT=1을 사용 함
/* ld.so magic */
setenv("LD_TRACE_LOADED_OBJECTS", "yes", 1);
if (fmt1)
setenv("LD_TRACE_LOADED_OBJECTS_FMT1", fmt1, 1);
if (fmt2)
setenv("LD_TRACE_LOADED_OBJECTS_FMT2", fmt2, 1);
- 장점 : 실행 바이너리 외 실행되지 않은 공유 라이브러리 들간의 의존도도 볼 수 있다. ( 2번에서 이어서 설명 )
- LD_TRACE_LOADED_OBJECT
- root@k1rh4:~/libtest/1# LD_TRACE_LOADED_OBJECTS=1 ./main
linux-gate.so.1 => (0xb774b000)
libstrcpy2.so => /usr/lib/libstrcpy2.so (0xb7735000)
libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb758b000)
/lib/ld-linux.so.2 (0xb774c000)
- #ldd 커맨드와 LD_TRACE_LOADED_OBJECT 의 차이
- ( 실행 중이지 않은 라이브러리의 공유라이브러리 의존도 확인 가능 여부 )
root@k1rh4:~/libtest/1# ldd /usr/lib/libstrcpy2.so
linux-gate.so.1 => (0xb7788000)
libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb75c8000)
/lib/ld-linux.so.2 (0xb7789000)
root@k1rh4:~/libtest/1# LD_TRACE_LOADED_OBJECTS=1 /usr/lib/libstrcpy2.so
세그멘테이션 오류 (core dumped)
실행파일만 됨.
- ELF 헤더 정보에 dynamic 심볼 정보를 참조.
(테스트환경은 strcpy2 공유라이브러리를 링킹 후 테스트)
- ELF section header 정보 ( 우측 )
- [6].dynstr (STRTAB) 0x8048298 에 심볼 정보가 컴파일 시 저장됨.
(gdb) x/20s 0x08048298 //아래 섹션 헤더 부분을 참조
0x8048298: ""
0x8048299: "libstrcpy2.so" // 아래 섹션헤더 부분을 참조
0x80482a7: "__gmon_start__"
0x80482b6: "_Jv_RegisterClasses"
0x80482ca: "_init"
0x80482d0: "_fini"
0x80482d6: "strcpy2"
0x80482de: "libc.so.6"
0x80482e8: "_IO_stdin_used"
0x80482f7: "__libc_start_main"
0x8048309: "_edata"
0x8048310: "__bss_start"
0x804831c: "_end"
0x8048321: "GLIBC_2.0"
0x804832b: <Address 0x804832b out of bounds>
위 정보를 기준으로 libstrcpy2.so 를 탐색함.
- 바이너리 실행 시 library 이름으로 탐색함
root@k1rh4:~/libtest/1# strace -i ./main
[b77b1424] execve("./main", ["./main"], [/* 20 vars */]) = 0
[b773bf94] brk(0) = 0x8228000
[b773dcb1] access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
[b773dd63] mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7723000
[b773dcb1] access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
[b773db74] open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
[b773dafd] fstat64(3, {st_mode=S_IFREG|0644, st_size=67880, ...}) = 0
[b773dd63] mmap2(NULL, 67880, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7712000
[b773dbad] close(3) = 0
[b773dcb1] access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
[b773db74] open("/usr/lib/libstrcpy2.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[b773db74] open("/lib/i386-linux-gnu/tls/i686/sse2/cmov/libstrcpy2.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[b773dabd] stat64("/lib/i386-linux-gnu/tls/i686/sse2/cmov", 0xbff9d860) = -1 ENOENT (No such file or directory)
[b773db74] open("/lib/i386-linux-gnu/tls/i686/sse2/libstrcpy2.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[b773dabd] stat64("/lib/i386-linux-gnu/tls/i686/sse2", 0xbff9d860) = -1 ENOENT (No such file or directory)
[b773db74] open("/lib/i386-linux-gnu/tls/i686/cmov/libstrcpy2.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
.
.( 탐색 중… )
.
[b773db74] open("/lib/libstrcpy2.so", O_RDONLY|O_CLOEXEC) = 3
// [ /lib/ 에서 strcpy2 공유 라이브러리를 찾음 ]
[b773dbf4] read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\260\3\0\0004\0\0\0"..., 512) = 512
[b773dafd] fstat64(3, {st_mode=S_IFREG|0755, st_size=6760, ...}) = 0
[b773dd63] mmap2(NULL, 8216, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb770f000
// [ /lib/libstrcpy2.so ] 를 메모리에 적재 시킴
- 바이너리를 실행하면 .init 보다 먼저 공유라이브러리가 올라오게 된다.
(gdb) x/10xi 0xb7fc746c // 공유라이브러리의 strcpy2()
0xb7fc746c <strcpy2>: push %ebp
0xb7fc746d <strcpy2+1>: mov %esp,%ebp
0xb7fc746f <strcpy2+3>: push %ebx
0xb7fc7470 <strcpy2+4>: sub $0x14,%esp
0xb7fc7473 <strcpy2+7>: call 0xb7fc7467 <__i686.get_pc_thunk.bx>
0xb7fc7478 <strcpy2+12>: add $0x1b7c,%ebx
0xb7fc747e <strcpy2+18>: lea -0x1b02(%ebx),%eax
0xb7fc7484 <strcpy2+24>: mov %eax,(%esp)
0xb7fc7487 <strcpy2+27>: call 0xb7fc7380 <printf@plt>
0xb7fc748c <strcpy2+32>: add $0x14,%esp
- Strcpy2@PLT 은 -> strcpy2@GOT.PLT을 가리키고 있음.
(gdb) x/10xi 0x80483f0
0x80483f0 <strcpy2@plt>: jmp *0x804a008
0x80483f6 <strcpy2@plt+6>: push $0x10
0x80483fb <strcpy2@plt+11>: jmp 0x80483c0
(gdb) x/10xi 0x804a008
0x804a008 <strcpy2@got.plt>: testb $0x0,0x804(%ebx)
- Strcpy 한번 호출 뒤의 변화
(gdb) x/10xi 0x80483f0
0x80483f0 <strcpy2@plt>: jmp *0x804a008
0x80483f6 <strcpy2@plt+6>: push $0x10
0x80483fb <strcpy2@plt+11>: jmp 0x80483c0
(gdb) x/10xi *0x804a008
0xb7fc746c <strcpy2>: push %ebp // 공유라이브러리의 주소
0xb7fc746d <strcpy2+1>: mov %esp,%ebp
0xb7fc746f <strcpy2+3>: push %ebx
0xb7fc7470 <strcpy2+4>: sub $0x14,%esp
0xb7fc7473
<strcpy2+7>: call 0xb7fc7467 <__i686.get_pc_thunk.bx>
[ Section Headers: ]
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .interp PROGBITS 08048154 000154 000013 00 A 0 0 1
[ 2] .note.ABI-tag NOTE 08048168 000168 000020 00 A 0 0 4
[ 3] .note.gnu.build-i NOTE 08048188 000188 000024 00 A 0 0 4
[ 4] .gnu.hash GNU_HASH 080481ac 0001ac 00003c 04 A 5 0 4
[ 5] .dynsym DYNSYM 080481e8 0001e8 0000b0 10 A 6 1 4
[ 6] .dynstr STRTAB 08048298 000298 000093 00 A 0 0 1 // 참조된 섹션 헤더
[ 7] .gnu.version VERSYM 0804832c 00032c 000016 02 A 5 0 2
[ 8] .gnu.version_r VERNEED 08048344 000344 000020 00 A 6 1 4
[ 9] .rel.dyn REL 08048364 000364 000008 08 A 5 0 4
[10] .rel.plt REL 0804836c 00036c 000018 08 A 5 12 4
[11] .init PROGBITS 08048384 000384 00002e 00 AX 0 0 4
[12] .plt PROGBITS 080483c0 0003c0 000040 04 AX 0 0 16
[13] .text PROGBITS 08048400 000400 00017c 00 AX 0 0 16
[14] .fini PROGBITS 0804857c 00057c 00001a 00 AX 0 0 4
[15] .rodata PROGBITS 08048598 000598 000008 00 A 0 0 4
[16] .eh_frame_hdr PROGBITS 080485a0 0005a0 000034 00 A 0 0 4
[17] .eh_frame PROGBITS 080485d4 0005d4 0000c4 00 A 0 0 4
[18] .ctors PROGBITS 08049f0c 000f0c 000008 00 WA 0 0 4
[19] .dtors PROGBITS 08049f14 000f14 000008 00 WA 0 0 4
[20] .jcr PROGBITS 08049f1c 000f1c 000004 00 WA 0 0 4
[21] .dynamic DYNAMIC 08049f20 000f20 0000d0 08 WA 6 0 4
[22] .got PROGBITS 08049ff0 000ff0 000004 04 WA 0 0 4
[23] .got.plt PROGBITS 08049ff4 000ff4 000018 04 WA 0 0 4
[24] .data PROGBITS 0804a00c 00100c 000008 00 WA 0 0 4
[25] .bss NOBITS 0804a014 001014 000008 00 WA 0 0 4
[26] .comment PROGBITS 00000000 001014 00002a 01 MS 0 0 1
[27] .shstrtab STRTAB 00000000 00103e 0000fc 00 0 0 1
[28] .symtab SYMTAB 00000000 0015ec 000410 10 29 45 4
[29] .strtab STRTAB 00000000 0019fc 0001f2 00 0
0 1
'System_Hacking' 카테고리의 다른 글
Android Hooking Tool (0) | 2014.10.15 |
---|---|
리버스 쉘 치트 시트 (Reverse Shell Cheat Sheet) (0) | 2014.05.23 |
[ dumpcode ] C dumpcode (0) | 2014.04.23 |
[ ROP gadget finder ] ROP 가젯 찾아주는 소스코드 (ARM MIPS x64 등등 지원) (0) | 2014.04.21 |
Shellcode Database (0) | 2013.12.12 |