Notice
Recent Posts
Recent Comments
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Today
Total
관리 메뉴

9oat's LAB

Libc-Database를 이용한 함수 주소 구하기 본문

Study/System

Libc-Database를 이용한 함수 주소 구하기

90at 2017. 6. 28. 18:03

로컬 익스플로잇 시엔 gdb에서 제공하는 print 명령어로 손쉽게 원하는 함수의 주소를 찾을 수 있지만, CTF 등 원격 익스플로잇의 경우 라이브러리가 다르니 함수의 주소를 찾기가 어렵다. 

이 때 함수 주소를 찾기 쉽도록 해주는 도구가 바로 Libc-Database.


[사진 1] ASLR이 적용된 후 Library Base 변화


Libc-Database를 설명하기 전에 원리 겸 라이브러리에 대해 설명하자면 함수 주소Library Base + offset 이다. ASLR이 적용되어 있다 하더라도 Library Base랜덤으로 설정될 뿐 함수의 offset은 변하지 않는다. 이 offset Libc 버전 별로 달라지며, Libc 버전 별 offsetDB화 시킨 것이 Libc-Database다. 물론 모든 Libc의 정보를 갖고있는 것은 아니라는 점을 유의하고, 사용자가 Libc를 추가하여 사용할 수도 있다.


Libc-Databaseoffset들의 12bit를 저장하고 있는데, 이는 Library Base 12bit0으로 설정되기 때문인 걸로 보인다.(즉 ASLR이 동작한다 하더라도 함수 주소의 끝 12bit바뀌지 않고, 이 값은 offset이다)그래서 함수 주소끝 3자리(12bit)를 이용해 검색하면, 사용하고 있는 Libc의 버전을 알려주는 식이다. 그럼 offset을 알 수 있으니 이를 이용하여 Library Base를 구하고, 필요한 함수의 offset을 이용해 함수 주소를 계산하여 사용할 수 있게 되는 것.


https://github.com/niklasb/libc-database 에서 내려받을 수 있다.


[사진 2] libc-database


libc-database는 [사진 2] 같이 구성되어 있.

add, dump, find, get, identify는 명령어들이고, README.md는 명령어의 사용법이 적혀있다. 그리고 db libc 관련한 파일들이 저장되는 듯. 사용자가 libc를 추가할 때도 이 디렉토리를 이용하면 될 것 같다.


다음은 각 명령어들의 사용법이다.


[사진 3] get


get

현재 로컬에서 사용 중 libc를 자동으로 DB에 추가하는 명령어.. 라고 하는데 잘 안되는 거 같다. 

로컬에 있는 Libc를 추가할 일이 있다면 pedavmmap과 같은 명령어를 이용해 libc파일경로를 알아낸 뒤 libc-database의 add명령어로 해당 libc를 추가하여 쓰는게 정확한 듯 하다.


[사진 4] add


add [libc 파일]

사용자가 임의libc를 DB에 추가하는 명령어. 


[사진 5] find


find [함수명] [주소 끝 3글자(12bit)]

함수명과 12bit를 이용해 DB에서 libc 버전검색하는 명령어.

여러개의 함수들을 한 번에 입력하여 검색할 수도 있다.


[사진 6] dump


dump [id]

find 명령어로 얻은 id를 이용해 exploit에 쓰이는 주요 함수/문자열offset을 출력하는 명령어.

모든 함수의 offset을 출력하는 게 아니기 때문에 사실 [사진 6]에 보이는 함수들의 주소를 알아야만 제대로 Libc-database를 사용할 수 있다.

왜냐면 Library Base주소를 알아내야 하는데 Library Base주소는 함수 주소 - offset 으로 알아내야 하고, 알 수 있는 offset은 사진에 보이는 게 전부기 때문. 그렇기에 사용할 수 있는 함수 역시도 [사진 6]속의 함수가 전부다.


그래도 보통 [사진 6] 있는 함수 주소를 구할 수 있는 경우가 대부분이기 때문에 크게 무리는 없는 듯.


[사진 7] identify


identify [libc 파일]

해당 libc의 정보가 이미 DB에 존재하는 지 검사하는 명령어


명령어의 사용법을 알았으니 실제로 어떻게 쓰면 되는지 보자.

read 함수의 주소를 알고있다고 가정하고(0xf7edaaf0), system 함수와 문자열 "/bin/sh" 를 찾는 과정이다. 


[사진 8] libc를 알아내자


read 함수의 주소 끝 12bit(af0)를 이용해 libc 버전과 id를 알아낸다. 

만약 검색했을 때 libc두 개 이상 출력된다면 알고 있는 함수 주소를 하나 더 입력하여 검색하면 된다. 하지만 하나밖에 모른다면 음.. 찍어야겠지..


[사진 9] offset 알아내기


id를 이용해 offset을 구했으니 Library Base를 구해보자.

read 함수의 주소가 0xf7edaaf0이고, offset0xd5af0 이므로


Library Base = 0xf7edaaf0 - 0xd5af0 = 0xf7e05000


system 함수의 offset0x3ada0이고, 문자열 "/bin/sh"의 offset은 0x15b9ab다. 이를 Library Base와 더하여 주소를 알아낸다.


system() = 0xf7e05000 + 0x3ada0 = 0xf7e3fda0

&/bin/sh = 0xf7e05000 +  0x15b9ab = 0xf7f609ab


[사진 10] 짠


뭐 당연한 거지만 Libc-Database는 특정한 함수 중 하나라도 그 주소를 알고 있어야만 사용할 수 있다. 문제에서 대놓고 함수의 주소를 주는 경우는 드물기 때문에 함수의 주소를 알려면 Memory Leak이 필수다

그래서 다음 게시물Memory Leak인 걸로..



참고한 글 : http://kaspyx.tistory.com/86 [잘지내나요, 내청춘]

Ubuntu 16.04 / gcc 5.4.0

'Study > System' 카테고리의 다른 글

Pwnable.kr input 풀다가 궁금한 거  (0) 2017.07.16
Memory Leak 관련한 삽질(Feat. Buffering)  (0) 2017.07.02
Memory Leak 기법  (0) 2017.06.30
Dynamic Link 시 함수 호출 과정  (0) 2017.06.26
함수 주소에 대한 궁금증  (0) 2017.05.20
Comments