Sh4n3e

Basic RTL 본문

System Hacking/BOF

Basic RTL

sh4n3e 2017. 6. 14. 15:54


RTL(Return to Library)?

RTL은 Return to Library의 약자로 Stack의 RET영역에 라이브러리 함수를 이용하여 쉘코드의 기능을 수행하는 공격기법이다.

RTL의 등장 배경은 기존 BOF공격방법인 Stack영역에서의 코드실행을 막는 보호기법으로 인하여 등장하게 되었다. Stack영역에 쉘코드를 넣고 실행할 수 없게 되니, 또다른 방법을 해커들은 연구하게 된 것이고 RTL은 그 연구의 산출물이라고 할 수 있겠다.


RTL은 기존의 BOF 공격과 절차는 비슷하나, 마지막 쉘코드 대신 라이브러리를 이용한다는 점이 다르다.

아래의 그림은 Stack을 나타낸 모습이며, Fuction Area의 최상단은 $esp이며, $sfp의 위의 4byte의 주소는 $ebp가 가리키고 있다.

현재 해당 스택은 DEP, NX의 보호기법이 걸려있기 때문에 Buf영역이나, RET아래 영역에 쉘코드를 넣고 실행시키는 것은 불가능한 상태이다.

여기서 우리는 RET에 SYSTEM()함수의 주소를 넣어주고, 그의 인자값을 4byte를 건너띄고 "/bin/sh"의 주소값을 넣어준다. 해당 이유는 함수 호출의 매커니즘이 이러하기에 4byte의 dummy(의미없는 값)을 넣어주고 해당 값의 주소를 넣어주는 것이다.



이렇게 하면 SYSTEM함수가 호출되면서, "/bin/sh" 문자열을 매개변수로하여 SYSTEM("/bin/sh"); 와 같은 코드가 실행되게 된다.

그렇다면 우선적으로 우리는 SYSTEM()함수의 주소와, "/bin/sh" 문자열의 주소를 찾아야 할 것이다.

system()함수의 주소값은 gdb상에서 print system을 통해 함수 값을 얻어낼 수 있으며

"/bin/sh" 문자열의 주소값은 아래 find.c 프로그램을 이용하여 주소 값을 얻어낼 수 있다.


find.c

 

#include <stdio.h>
#include <stdlib.h>

int main(){
        char *ptr = 0x40058ae0;
        while(1){
                if(strcmp(ptr, "/bin/sh") == 0){
                        printf("address : %p\n", ptr);
                        exit(1);
                }
                ptr++;
        }
        return 0;
}

 

이로써 준비는 끝이 났다.


우리는 다음과 같은 Payload로 쉘을 실행시킬 수 있다.

#./bofTest $(python -c "print "A"*bufsize+"system함수주소"+"dummy(4byte)"+"/bin/sh의 주소"')

 

다음은 실제 연습 코드와 수행과정이다. 예제를 통해 더 자세히 공부해보자.

 

 

위의 코드를 보면 다소 작은 사이즈의 buf가 존재하며, bof에 취약한 strcpy가 존재함을 확인할 수 있다. 이제는 gdb를 이용하여 어셈블 코드를 한번 살펴보자.

 

 

어셈블코드를 보게되면, strcpy함수를 call하기전에 $eax에 존재하는 값을 push하는 것을 볼 수 있는데, 이것은 strcpy를 수행하기위한 메모리상의 저장공간의 주소를 가리키고 있는 부분이다. 그럼 <main+31> break point로 잡아 그 당시의 $eax값이 어떤지 살펴보자.

 

 

살펴보게보면, 그 당시의 $eax값은 0xbffff020이며, $ebp의 값은 0xbffff048인 것을 확인할 수 있다. 그렇게되면 stack상에서 우리가 bof를 일으키기 위해서는 0xbffff048-0xbffff020 byte를 stack에 덮어 씌우고, $ebp의 공간인 0x04byte만 덮어 씌운다면 우리는 RET부분에 우리가 원하는 주소를 넣을 수 있게 되는 것이다.

 

 

위의 그림은 우리가 찾아낸 RET의 위치가 맞는지 확인하는 부분이다. 44개의 A를 넣어 Segmetation Fault가 나는 것을 확인할 수 있었다.

 

 

이제는 원하는 RET의 위치를 찾았으니, 우리는 실행시킬 라이브리 함수인 system()함수의 주소를 알아내야한다. 이것은 위의 그림과 같이 수행하면 된다.

 

 

위에서 알아낸 system()함수 대역의 주소값을 기준으로 우리는 "/bin/sh"라는 문자열의 주소를 찾아내기 위해서 위와같은 프로그램을 이용하여 해당 문자열을 찾아낸다.

 

결과적으로 위와 같은 payload를 이용하여 우리는 system("/bin/sh");의 코드를 RTL을 이용하여 실행시켰고 위의 그림은 해당 코드를 실행시킨 결과이다.



RTL참고 문서

http://www.hackerschool.org/HS_Boards/data/Lib_system/rtl_sc.txt


execv관련 함수들

http://bbolmin.tistory.com/35

 

execve & system 함수 차이

http://bbolmin.tistory.com/356

 

 

'System Hacking > BOF' 카테고리의 다른 글

VMware Tools 환경설정 문제  (0) 2017.06.25
Kali Linux APT Package Search  (0) 2017.06.21
Kali Linux Configuration  (0) 2017.06.21
GDB 사용방법  (0) 2017.06.14
Comments