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에서 자주 쓰이는 툴이니 알아두면 좋겠죠?
'studies > pwnable' 카테고리의 다른 글
[Format String Bug] 포맷스트링 버그 (fsb) - 2 (2) | 2020.04.23 |
---|---|
[Format String Bug] 포맷스트링 버그 (fsb) - 1 (1) | 2019.10.02 |