카테고리 없음

스택의 auxv leak을 통해서 libc 주소 쉽게 알아내거나 쉽게 브포하기

진모씨 2014. 8. 26. 21:54

사실 ld.so의 주소를 leak하는거구요.

하지만 간격은 거의 같으니까요, 아니면 0x1000 단위로 브포해도 되구요.


ELF의 엔트리포인트의 스택을 보면 이렇습니다.



argc 

argv + envp 포인터들 

auxv 키-값 배열 

argv, envp 문자열 값 



요렇습니다.

주목할 건 auxv입니다.


auxv는 Auxiliary Vectors의 줄임말이구요.

http://articles.manugarg.com/aboutelfauxiliaryvectors.html 보시면 됩니다.


나중에 보셔도 되여.


/proc/[PID]/auxv 파일을 xxd 파일로 보죠.

32비트 프로세스입니다.


bob_121@ubuntu:~$ xxd /proc/$$/auxv

0000000: 2000 0000 14d4 fdb7 2100 0000 00d0 fdb7   .......!.......

0000010: 1000 0000 fdfb 8b07 0600 0000 0010 0000  ................

0000020: 1100 0000 6400 0000 0300 0000 3480 0408  ....d.......4...

0000030: 0400 0000 2000 0000 0500 0000 0900 0000  .... ...........

0000040: 0700 0000 00e0 fdb7 0800 0000 0000 0000  ................

0000050: 0900 0000 9804 0608 0b00 0000 9a04 0000  ................

0000060: 0c00 0000 9a04 0000 0d00 0000 9a04 0000  ................

0000070: 0e00 0000 9a04 0000 1700 0000 0000 0000  ................

0000080: 1900 0000 5bfe ffbf 1f00 0000 f2ff ffbf  ....[...........

0000090: 0f00 0000 6bfe ffbf 0000 0000 0000 0000  ....k...........

bob_121@ubuntu:~$ 


네. 형식은 이렇습니다.

[키 4바이트(32비트)] [값 4바이트(32비트)]


64비트는 키가 8바이트, 값이 8바이트입니다.


이걸 다시 정리해보도록 하죠.

bob_121@ubuntu:~$ LD_SHOW_AUXV=1 /proc/$$/exe

AT_SYSINFO:      0xb7fdd414

AT_SYSINFO_EHDR: 0xb7fdd000

AT_HWCAP:    fpu de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2

AT_PAGESZ:       4096

AT_CLKTCK:       100

AT_PHDR:         0x8048034

AT_PHENT:        32

AT_PHNUM:        9

AT_BASE:         0xb7fde000

AT_FLAGS:        0x0

AT_ENTRY:        0x8060498

AT_UID:          1178

AT_EUID:         1178

AT_GID:          1178

AT_EGID:         1178

AT_SECURE:       0

AT_RANDOM:       0xbffff87b

AT_EXECFN:       /proc/20318/exe

AT_PLATFORM:     i686


건질게 많아보이죠? 저는 AT_BASE에 대해 포스팅을 할건데 사실 여기서 건질게 많아요.

일단 AT_RANDOM은 없는 환경도 있긴 한데 스택 카나리값이 있는 주소에요. 여기서 변형을 해서 첫바이트가 0이 된다던지 이런식으로 세팅을 많이 하죠. 이 값 자체가 아니라 이 값이 있는 주소에요.

AT_SYSINFO_EHDR은 vdso의 주소입니다. linux-gate.so.1 이라고 보통 부르죠.

여기 int 0x80 가젯들이 고정되어서 박혀있는 경우가 많아요.

그거 말고 PIE 환경에서 AT_PHDR과 AT_ENTRY값이 중요할 지 모르겠네요. 프로그램 정보가 담겨있으니까요.

네. LD_SHOW_AUXV 값이 1로 세팅되어있으면 이 값을 해석해서 보여줍니다. ld.so 기능이구요, 다른 유저의 suid, sgid 바이너리에서는 동작하지 않습니다.


이 부분을 보면 AT_BASE가 있습니다. 이건 ld.so의 베이스주소에요.


08048000-08125000 r-xp 00000000 fc:00 1572866    /bin/bash

...

b7fde000-b7ffe000 r-xp 00000000 fc:00 393219     /lib/i386-linux-gnu/ld-2.17.so

...

생략합니다.


ld.so랑 libc의 간격은 그렇게 많이 바뀌지 않고 (ld.so가 아주 크게 바뀌지 않으면 말이죠), 0x1000단위로 브포하면 되니 참 편합니다.

그래서 버전 상관없이 브포를 많이 안해도 되고, 간격이 많이 바뀌지도 않죠.


역시 exploit이죠.

한번 보겠습니다.


스택을 봅시다.



gdb를 켜고.


_start에 브포를 걸고(엔트리포인트) 실행합니다.



네, argc와 argv + envp 포인터들과 auxv 값들과 문자열값들이 보이는군요.


보시면 0xb7fde000이 있네요. ld.so 로딩된 주소가 어디였는지 보겠습니다.



ld.so의 로딩 주소는 0xb7fde000입니다. 같네요.


이상으로 마치겠습니다.


Thanks to 장석인님