/* * http://sosal.tistory.com/ * made by so_Sal */ 1. Shared Library Hijacking? 2. 예제와 Shared library(공유라이브러리) 의존성을 확인법 3. 라이브러리를 만들기 위한 gcc 컴파일러의 옵션 4. 완성된 공격 라이브러리를 이용하여 공격하기 1. Shared Library Hijacking? 공유라이브러리는 심볼(함수,변수)들을 프로그램이 시작하기 전에 로드하여, 필요로 할때마다 연동되는 동적인 라이브러리이다. 메모리, 용량 절약과 라이브러리를 언제든지 업데이트 할 수 있는 융통성을 가지고 있지만 사용자로부터 접근하기 쉽도록 짜여 있어, 보안에 문제가 발생한다. 일반적으로 gcc 컴파일을 대부분 아래와 같이 하게된다. gcc source.c -o source gcc -o source source.c 이렇게 만들어진 프로그램들은 기본적으로 공유 라이브러리를 참조하는 방식으로 symbol (function, variable) 를 가져온다. 아래 그림은 공유 라이브러리가 프로그램에 적재되는 모습을 보여준다. 사용자가 만든 프로그램 소스는 컴파일 되면서 라이브러리를 프로그램에 포함시키지 않고, 프로그램이 동작중에 필요한 symbol이 있을때 공유 라이브러리를 찾아가서 심볼(함수,변수) 정보를 가져온다. shared library hijacking 취약점은 라이브러리를 프로그램이 실행될 때, 공유 라이브러리에서 심볼을 적재하는 과정에서 나타나게 된다. 공유 라이브러리를 프로그램에 적재하는 과정에서의 취약점?. 아래 그림은 공유 라이브러리 취약점을 이용한 하이재킹을 보여준다.
#include<stdio.h> int main(void){ uid_t uid = getuid(); // 공유 라이브러리 참조 함수들 uid_t euid = geteuid(); int i,j; for(i=0;i<10;i++) } Dynamic Section: NEEDED libc.so.6 위 결과로 libc.so.6 하나의 공유 라이브러리를 필요함을 알 수 있다. 이 정보들은 동적 공유 섹션의 NEEDED에 기록되어 있다. 하지만, 위 프로그램이 libc.so.6 하나만 필요한것은 아니다. 공유라이브러리는 내부적으로 또 다른 공유 라이브를 필요로 하기 때문이다. 2) ldd 공유 라이브러리 의존 관계 확인 ldd - print shared library dependencies 공유라이브러리 의존성을 확인하는데 특화된 프로그램 ELF 파일이 실행 하려 할 때 필요한 공유 라이브러리에 대해서 검사하는 프로그램이다. 이 정보들은 동적 섹션의 NEEDED에 기록되어 있다. (objdump 출력문에서도 보았다.) objdump나 readelf를 사용하여 공유 라이브러리 의존관계를 확인할 수 있지만, 개별적으로 각각의 공유 라이브러리에 대한 의존 관계를 확인해야 하므로 번거롭고, 또한 공유라이브러리의 디렉토리 경로를 정확히 얻기도 어렵다. LD_TRACE_LOADED_OBJECTS에 1을 설정하여 프로그램을 실행시키면 프로그램 실행 시점에 ELF 런타임 로더가 필요한 공유라이브러리를 찾아 메모리에 로딩해서 그 정보를 표시한 후, 실제 프로그램이 실행되기 전에 종료하게 된다. 따라서 ldd를 사용하지 않더라도, 위 환경변수를 이용하면 동일한 결과를 얻을 수 있다. (-v 옵션을 뺀것과 같은 결과) 3) readelf - ELF 파일 정보 보기 Binary File Descriptor Library(이하 BFD Library) 를 이용하지 않고, 직접 ELF에 접근하여 읽기위한 툴이다. readelf는 BFD Library를 경유하지 않기 때문에, objdump보다 상세한 정보를 얻을 수 있다. -d (--dynamic) 옵션을 사용하여 볼 수 있다. Displays the contents of the file’s dynamic section, if it has one. - readelf :: 정리 동적 공유 라이브러리 의존성을 확인하면서 Attackme는 libc.so.6 이 필요한 실행 파일이라는 것을 알 수 있었다. 공유 라이브러리는 /usr/lib나 환경변수 LD_LIBRARY_PATH에 설정되어 있는 경로를 참조한다. 2. ldd 에도 설명되었지만, 환경변수를 이용하여 의존 동적 라이브러리를 확인하기도 하였다. (사실 ldd 명령은 내부적으로 환경변수 LD_TRACE_LOADED_OBJECTS를 이용해 구현되어 있다.) 3. 라이브러리를 만들기 위한 gcc 컴파일러의 옵션 -shared 옵션 공유 라이브러리를 우선하여 링크하도록 하는 옵션 정적라이브러리와 같이 있을 경우에 우선적으로 공유 라이브러리를 링크하도록 하는데, 사실 아무 옵션을 주지 않아도 공유 라이브러리를 우선적으로 링크한다. -fpic -fPIC 옵션 gcc 컴파일러가 object file을 만들때, 그 안의 symbol (function, variable)들이 어떤 위치에 있더라도 동작을 하는 구조로 compile 하라는 것입니다 그렇게 된 것만이 리눅스에서 사용 가능한 모듈파일(*.so)이 될 수 있습니다. 모듈파일(*.so)은 안에는 공유 라이브러리가 포함되어있습니다. -fpic와 -fPIC - 둘의 차이점.
uid_t getuid( void ){ 참고 자료 및 문서, 홈페이지 hkpco 박찬암 님의 문서 http://packetstormsecurity.org/papers/attack/shl_hijacking.txt http://hkpco.kr/paper/udcsc2006_report.txt yundream 윤상배 님의 블로그 http://www.joinc.co.kr/modules/moniwiki/wiki.php/Site/C/Documents/Make_Library 해커가 전수하는 테크닉 100선 Binary Hacks / O'REILLY 유닉스, 리눅스 프로그래밍 필수 유틸리티 / 한빛 미디어 |
출처: http://sosal.tistory.com/125