studies/pwnable

libc-database 사용해보기

$1m0hYa 2019. 10. 23. 18:44

github에 들어가서 libc-database라고 검색해보자.

 

자세한 설명은 이곳에 나와있습니다.

 

https://github.com/niklasb/libc-database

 

niklasb/libc-database

Build a database of libc offsets to simplify exploitation - niklasb/libc-database

github.com

 # libc-database 설치 방법


위 링크에서 참고하시면 됩니다!

 # libc-database를 사용하는 이유


우리가 ctf문제를 풀다보면 이러한 어려움에 직면할때가 있습니다.

예를들어, ROP를 해야하는데 libc파일을 주지 않을때가 있어요.

 

보통 우리가 바이너리파일을 받으면, 주최측 서버에서 돌아가는 libc와 내 pc에서 돌아가는 libc가 다를수 있습니다.

 

그렇기 때문에 libc-database를 이용하는것입니다.

 

# libc-database를 사용하기 전에


보통 libc에는 항상 aslr이 걸려있습니다.

 

원리는 이렇습니다.

 

바이너리파일을 실행시켰을때, 거기에 링커되어있는 libc파일은 base주소를 정해둡니다.

마지막 1.5바이트는 000으로 맞추고 그 나머지는 랜덤값으로 맞추어 줍니다.

 

그때, 바이너리 내부에서 printf를 호출할때 plt를 이용해도 되지만, base+상대주소를 호출해도 상관없어요.

 

예시를 들어볼게요.

만약, printf의 상대주소는 0x12345이고 base주소가 0x999000이라고 해보겠습니다.

 

그때 바이너리 내부에서 printf함수 자체를 호출할때 0x999000 + 0x12345 인 0x9ab345 를 호출할수 있어요.

위에서 마지막 하위 1.5바이트를 보면 345로 되어있는것을 확인할 수 있습니다.

 

즉, 아무리 aslr이 걸려있다하더라도 하위 1.5바이트는 변하지 않는다는 것이죠!

 

libc-database는 이러한 원리를 이용하여 하위 1.5바이트와 일치하는 libc소스를 찾아주는 역할을 해줍니다.

 

 

 # libc-database 사용법


1. libc파일 모아주기

./get

 

이 명령어를 실행면 아래의 사진처럼 여러버전의 libc가 db라는 폴더 안에 모이게 됩니다.

 

 

2. 해당하는 libc를 찾아주기

아무 함수의 got를 printf나 puts의 인자로 넣어주고 실행해보면, 그 함수의 진짜 주소가 나오게 됩니다.

 

이번에는 puts주소를 이용해 볼게요.

gdb로 이용해서 예시를 들어 보겠습니다.

 

이렇게 끝자리 세자리수가 140인것을 확인하면 libc-database가 설치된 파일로 이동합니다.

 

기본적인 사용법은 이렇게 됩니다.

 

./find (함수의 이름) (끝 세자리수)

그래서 

./find puts 140

이라고 입력을 해볼게요.

 

2가지 libc가 나오게 되네요!

여기서 (id ~~~~)중에서 ~~~~를 복사해줍시다.

 

그 후에 dump를 실행시켜봅시다.

 

./dump (id) (함수이름)

이라고 입력하면, 그 id에 해당하는 libc의 함수의 주소의 offset을 구해줍니다.

 

잘 나오군요!

 

만약 함수이름을 제외하고

./dump (id)

이라고 입력을 해주면, 그 id에 해당하는 libc의 주로 쓰이는 offset들을 보여줍니다.

 

와우!! 성공!!


이렇게 libc-database사용법을 알아봤는데요, ctf에서 자주 쓰이는 툴이니 알아두면 좋겠죠?