PLT : 외부 프로시저를 연결해주는 테이블 , PLT를 통해 다른 라이브러리에 있는 프로시저를 호출해 사용할 수 있다.
[어떤 프로시저(함수들)이 있는지 나열되어있는 테이블]

 

GOT : PLT가 참조하는 테이블 프로시저들의 주소가 들어있다.

[실제 함수들의 주소가 들어있는 테이블]

 

PLT 와 GOT의 대략적인 개념을 말씀드리겠습니다.

 

함수를 호출하면(PLT를 호출하면) GOT로 점프하는데 GOT에는 함수의 실제 주소가 쓰여있습니다

첫 번째 호출에는 GOT는 함수의 주소를 가지고 있지 않으나 "어떠한 과정"을 거쳐서 주소를 알아내게 되고 

두 번째 호출 부터는 첫 번째 호출 때 알아낸 주소로 바로 점프합니다 .

 

어떠한 과정이란? 대략 과정만 말씀드리자면 

 

 

Static Link 와 Dynamic Link

PLT와 GOT에 대해서 조금 더 깊게 들어가 보기 위해서는 링커에 관해서 알아야합니다 

 

소스파일을 실행파일로 만들어 주기 위해서는 컴파일이라는 과정이 필요합니다.

아래는 간단한 컴파일 과정입니다(*출처 http://blog.eairship.kr/2)

자 여기서 만약에 작성한 소스 안에 printf 함수를 호출하는 코드가 존재하고 

include<stdio.h>와 같은 헤더 파일에는 printf의 선언이 잇다고 가정합니다

이런식으로 컴파일을 통해 오브젝트 파일이 생성됩니다 . 

하지만 오브젝트 파일만으로는 실행이 가능하지 않습니다 그 이유는 printf의 구현 코드를 모르기 때문입니다 . printf를 호출 했을 때 어떠한 코드를 실행해야 하는지 우리가 작성한 코드만 가지고서는 아직 아무것도 알 수 없습니다

 

오브젝트 파일을 실행 가능하게 만들기 위해서는 printf의 실행 코드를 찾아서 오브젝트 파일과 연결 시켜야 합니다.

printf의 실행 코드는 printf의 구현 코드를 컴파일한 오브젝트 파일로 연결 해야합니다.

이런 오브젝트 파일들이 모여있는 곳을 라이브러리(Library)라고 합니다.

 

이렇게 라이브러리와 같이 필요한 오브젝트 파일들을 연결시키는 과정을 링킹이라고 합니다 

 

이렇게 링킹을 하는 방법은 Static과  Dynamic 방식이 존재합니다 

Static Link 방식을 통한 실행파일 생성입니다 . 

 

Static Link 방식은 파일 생성시 라이브러리 내용을 포함한 실행 파일을 만듭니다

 

Static Link로 파일을 만들던 도중에

 

/usr/bin/ld : cannot find -lc 라는 에러가 나왔습니다.

 

collect2 : ld returned 1 exit status 라는 오류 같은 경우에는 lob golem 편에서도 언급을 햇었는데요 라이브러리가 정의가 되어있지 않아서 발생한 오류였습니다.

 

그렇다면 이번에도 마찬가지로 라이브러리가 문제란것을 짐작할 수 있습니다.

 

--------------------------------틀린 방법입니다 참고만 하세요 --------------------------

 

-l 뒤에 있는 문자가 검색되지 않은 라이브러리입니다! 

그렇다면 해당되는 라이브러리를 검색해보겠습니다

 

 

yum list | grep *문제되는 라이브러리명*lib (여기서는 lc 이므로 clib) 을 검색해줬더니 두 친구들이 검색되네요!

 

 

이러한 식으로 설치를 진행하겠습니다!  

 

--------------------------------------------------------------------------------------------------

 

 

해당 명령어를 사용함으로써  

 

성공하였습니다 -static 컴파일이 됐군요! 

 

Static 옵션을 사용하면 Statick Link 방식으로 컴파일이 됩니다.

 

실행 파일 안에 모든 코드가 포함 되어서 라이브러리 연동 과정이 따로 필요 없으며 한 번 생성한 파일에 대해서는 필요한 라이브러리를 따로 관리하지 않아도 되기 때문에 간편합니다. 

 

하지만 단점으로써는 파일 크기가 커지고 동일한 라이브러리를 사용하더라도 해당 라이브러리를 사용하는 모든 프로그램들은 라이브러리의 내용을 메모리에 매핑 시켜야 된다는 것이 있습니다.(매핑 - 연결 시킨다는 느낌으로 아시면 될거같습니다 )



† Dynamic linking

Dynamic Link 방식은 공유라이브러리를 사용합니다.
라이브러리를 하나의 메모리 공간에 매핑한뒤에 여러 프로그램에서 공유하여 사용합니다.

실행파일 안에 라이브러리 코드를 포함하지 않아도 되므로 Static Link 방식을 사용해 컴파일 했을때보다 파일 크기가 훨씬 작아지고 적은 메모리를 차지하며 라이브러리를 따로 업데이트 할 수도 있는것이 장점입니다 .

하지만 단점으로썬 실행파일이 라이브러리에 의존해야 하기 때문에 라이브러리가 없으면 실행할 수 없다는 점 입니다.



아무런 옵션을 주지 않은채 gcc 컴파일을 한다면 자동으로 Dynamic Link방식으로 컴파일이 됩니다.


이제 여기서 공부하려고 했던 PLT 와 GOT를 Dynamic Link 컴파일에서 사용합니다.


그 이유는 Static Link 방식으로 컴파일 시 라이브러리가 프로그램 내부에 존재하기 때문에 함수의 주소를 알아오는 과정이 따로 필요하지 않지만 Dynamic Link 방식으로 컴파일을 하면 라이브러리가 프로그램 외부에 존재하기 때문에 함수의 주소를 알아오는 과정이 필요합니다 .


Dynamic Link 방식으로 프로그램이 컴파일 된다면 함수를 호출 할 때 PLT를 먼저 첫번째로 참조합니다. 

그 뒤에 PLT 에서 GOT로 점프를 하는데 GOT에 라이브러리에 존재 하는 실제 함수의 주소가 쓰여있어서 이 함수를 호출하게 됩니다 . 


이것은 첫 번째 호출이고 첫 번째 호출에는 GOT에 실제 함수의 주소가 쓰여있지 않으나 두 번째 호출부터는 GOT에 실제 함수의 주소가 쓰여있습니다.


그래서 첫 번째 호출에는 Linker가 dl_resolve라는 함수를 사용해서 필요한 함수의 주소를 알아오고 GOT에 그 주소를 써준 후 해당 함수를 호출하게됩니다.


Dynamic link 방식으로 컴파일 된 프로그램입니다 .


시작하기 전의 printf 의 주소를 봤더니 printf@plt 라는 이름과 함께 0x80482f4를 가르키고 있습니다 .

하지만 시작 한 후에 printf의 주소를 다시 보니 plt라는 이름이 사라진 후 다른 주소로 변한 것을 볼 수 있습니다. 


Static link 방식으로 컴파일 된 프로그램입니다 

프로그램 시작과 시작 전의 주소가 같은 것을 확인 할 수 있습니다 .


자 근데 Dynamic link 방식으로 만들어진 프로그램에서는 GOT에 실제주소가 존재하는것을 알게됬습니다. 

근데 이 GOT 주소를 해커가 원하는 흐름으로 갈 수 있는 함수의 주소로 바꿔버린다면? 쉘을 실행시키는거도 가능하겠지요 ? 

이러한 기법이 GOT_Overwrite 입니다 . 


간단한 예제를 보여드리겠습니다!



printf 라는 함수가 있지요 ? 이 printf를 system으로 바꿈으로써 쉘을 실행시켜볼겁니다! ( 쉘 대신 youngzzang을 넣었엇지만 결과를 보여드릴수가 없어서 바꿧습니다-_-)




먼저 컴파일을 할 때 혹시나 있을 보호기법을 생각해서

gcc -o young young.c -z execstack -fno-stack-protector -m32 로 컴파일을 해서 

nx bit 보호 기법을 해제해줬습니다 [ young 대신에 파일명을 넣어주세요 ] 


readelf 명령어로 간단히 plt가 어떠한 주소에 있나 파악한 후에 

printf 의 0x80482f4를 타고 들어간 후에 printf@plt 에서 jmp 하는 *0x08049650부분을 system 함수의 주소로 set 해주어서 실행시켰습니다.

set &printf@got=&system 

그랬더니 쉘이 실행된것을 볼 수 있엇습니다!


참고 bpsecblog.wordpress.com/2016/03/09/about_got_plt_2/

      shayete.tistory.com/

      항상 두 블로그에서 많은것을 배우며 작성중입니다! 


'시스템 기법 정리' 카테고리의 다른 글

ROP  (0) 2016.06.06
Fake EBP  (0) 2016.06.02
Format String Attack (FSB)  (0) 2016.05.30
ASLR를 해제하는 여러가지 방법  (0) 2016.05.29
plt , got , rtl chain , ASLR  (0) 2016.05.28

+ Recent posts