how to get glibc debugging sysmbols

문제를 풀다보면 주어진 glibc 파일이 디버깅 심볼이 없는 경우가 많다.

일단 첫번째로 glibc의 버전을 알 수 있는 방법은 크게 두가지가 있다.

예를 들어 내가 glibc의 파일을 가지고 있지 않은 상태이며, 특정 함수의 offset을 알 수 있는 경우

https://libc.rip

해당 사이트에 가서 심볼이름 ( 함수명 ) 과 해당 주소의 하위 3개를 입력하면 된다. 예를 들어

C
Dump of assembler code for function printf:
   0x0000000000064e80 <+0>:	sub    $0xd8,%rsp
   0x0000000000064e87 <+7>:	test   %al,%al
   0x0000000000064e89 <+9>:	mov    %rsi,0x28(%rsp)
   0x0000000000064e8e <+14>:	mov    %rdx,0x30(%rsp)
   0x0000000000064e93 <+19>:	mov    %rcx,0x38(%rsp)
   0x0000000000064e98 <+24>:	mov    %r8,0x40(%rsp)
   0x0000000000064e9d <+29>:	mov    %r9,0x48(%rsp)

이런식으로 printf , e80 을 입력하면 된다.

그럼 이런식으로 결과가 나온다. 결과가 1개가 될때까지 찾던가

결과들에 build id를 잘 찾아보고 맞는 것을 고르면 된다.

두번째는

이제 버전을 알았으면,

이후에 libc 뒤에 “-dbg” 를 붙인다음에 구글에 검색하면 다운로드를 받을 수 있다.

혹은 ( 중요 ) 바로 다운로드 받고 싶다?

우분투 일경우에

https://launchpad.net/ubuntu/+source/glibc

여기에 들어가서 특정 버전을 누르면 아래에 다운로드 링크들이 있는데

Libc-gdb을 다운로드 받으면 된다. 물론 다운로드 링크를 복사해서 wget을 사용할 수 도 있다.

근데 위에는 메이저한 거 밖에 없음 https://launchpad.net/ubuntu/bionic/amd64/libc6-dbg/2.27-3ubuntu1.2

이런식에 링크에 뒤에 2.27-3ubuntu1.2 이부분만 바꿔서 이용하삼

wget 으로 다운로드 받으면 이제 바로 deb 파일의 아카이브가 다운로드 된다.

C
root@bc21bd9b5bb7:/home/ow_rtld# ls
exploit.py  exploit2.py  flag  ld-2.27.so  libc-2.27.so  libc6-dbg_2.27-3ubuntu1_amd64.deb  ow_rtld  ow_rtld2
root@bc21bd9b5bb7:/home/ow_rtld# ar x libc6-dbg_2.27-3ubuntu1_amd64.deb 
root@bc21bd9b5bb7:/home/ow_rtld# ls
control.tar.xz  data.tar.xz  debian-binary  exploit.py  exploit2.py  flag  ld-2.27.so  libc-2.27.so  libc6-dbg_2.27-3ubuntu1_amd64.deb  ow_rtld  ow_rtld2
root@bc21bd9b5bb7:/home/ow_rtld# 

ar x 명령어로 해제를 해주면 control.tar.xz data.tar.xz debian-binary 이렇게 3개가 생기는데

우리는 data.tar.xz 이거를 압축해제 해주면 된다.

C
./usr/lib/debug/usr/lib/x86_64-linux-gnu/gconv/libCNS.so
./usr/lib/debug/usr/lib/x86_64-linux-gnu/gconv/libGB.so
./usr/lib/debug/usr/lib/x86_64-linux-gnu/gconv/libISOIR165.so
./usr/lib/debug/usr/lib/x86_64-linux-gnu/gconv/libJIS.so
./usr/lib/debug/usr/lib/x86_64-linux-gnu/gconv/libJISX0213.so
./usr/lib/debug/usr/lib/x86_64-linux-gnu/gconv/libKSC.so
./usr/share/
./usr/share/doc/
./usr/share/doc/libc6-dbg/
./usr/share/doc/libc6-dbg/copyright
./usr/share/doc/libc6-dbg/changelog.Debian.gz
root@bc21bd9b5bb7:/home/ow_rtld# ls
control.tar.xz  data.tar.xz  debian-binary  exploit.py  exploit2.py  flag  ld-2.27.so  libc-2.27.so  libc6-dbg_2.27-3ubuntu1_amd64.deb  ow_rtld  ow_rtld2  usr
root@bc21bd9b5bb7:/home/ow_rtld# 

압축 해제 하면 우리가 아는 디버깅 심볼의 위치인

“/usr/lib/debug/lib/x86_64-linux-gnu” 디렉토리가 생긴다. 보면 usr 디렉토리가 생긴 것을 알 수 있다.

C
root@bc21bd9b5bb7:/home/ow_rtld/usr/lib/debug/lib/x86_64-linux-gnu# ls
ld-2.27.so               libanl-2.27.so   libcrypt-2.27.so  libmemusage.so   libnss_compat-2.27.so  libnss_hesiod-2.27.so   libpcprofile.so    libthread_db-1.0.so
libBrokenLocale-2.27.so  libc-2.27.so     libdl-2.27.so     libmvec-2.27.so  libnss_dns-2.27.so     libnss_nis-2.27.so      libresolv-2.27.so  libutil-2.27.so
libSegFault.so           libcidn-2.27.so  libm-2.27.so      libnsl-2.27.so   libnss_files-2.27.so   libnss_nisplus-2.27.so  librt-2.27.so
root@bc21bd9b5bb7:/home/ow_rtld/usr/lib/debug/lib/x86_64-linux-gnu# pwd
/home/ow_rtld/usr/lib/debug/lib/x86_64-linux-gnu
root@bc21bd9b5bb7:/home/ow_rtld/usr/lib/debug/lib/x86_64-linux-gnu# 

이제 저 디버깅 심볼이 있는 libc-2.27.so 을 야무지게 사용하면 된다.

근데 중요한건 제는 디버깅 심볼이지 실제 so가 아니다

그럼 어떻게 쟤를 debugging 심볼로 쓸 수 있을까?

( docker 환경을 가정하고 말합니다 )

docker 환경에서 gdbinit 파일을 수정해서 gdb가 디버깅을 읽어오는 경로를 수정해주면 된다.

이러면 익스짤때 gdb를 붙일때도 , 일반 gdb 상태일때도 동작한다.

C
root@5ce1728591f8:/home/ow_rtld# cat ~/.gdbinit 
source /opt/pwndbg/gdbinit.py
set disassembly-flavor att
set debug-file-directory ./usr/lib/debug/lib/x86_64-linux-gnu/

다음과 같이

C
set debug-file-directory < 경로 >

를 해주면 된다. 나는 홈 디렉토리 아래에 실행파일과 파이썬 익스 코드가 있으니깐 홈 디렉토리 아래에 저렇게 경로를 해놓았다.

참고로 debugging symbol 이 적용 되었는지 확인할려면

C
│pwndbg> info sharedlibrary
│From                To                  Syms Read   Shared Object Library
│0x00007c357c9322d0  0x00007c357caaac3c  Yes         ./libc-2.27.so
│0x00007c357cd02f10  0x00007c357cd21b20  Yes         ./ld-2.27.so

info sharedlibrary 명령어로 확인하면 된다. yes로만 되어 있으면 적용 된것이고 yes 옆에 (*) 가 있으면 적용이 되지 않은 것이다.

훨씬 쉬운 방법이 최근 생성되었다.