본문 바로가기

High Level Technique/System Hacking

Return To Library (RTL)

Return To Libray (RTL)



개념


NX Bit(Never Execute Bit)가 적용된 스택을 우회하기 위해서 사용되는 기법.


* NX Bit

NX Bit는 프로세스 명령어나 코드 또는 데이터 저장을 위한 메모리 영역을 따로 분리하는 CPU의 기술. 지정된 모든 메모리 구혁은 데이터 저장을 위해서만 사용되며, 프로세서 명령어가 그 곳에 상주하지 않음으로써 실행되지 않도록 만들어준다.





설명


메모리 보호기법(DEP)의 NX Bit를 우회하여 사용하는 방법이 RTL입니다.


먼저 RTL에 대해서 설명하기 전에 알아야 할 개념이 Plt와 Got 입니다. http://kblab.tistory.com/217



RTL은 Plt와 Got를 이용하여 쉘을 실행시키는 방법입니다.





위 C 코드를 보면 argv로 받은 값을 buf에 복사하고 해당 buf를 출력 하는 아주 간단한 코드입니다.


어셈블리어 코드를 살펴보면 아래와 같습니다.





현재 사용되는 함수는 strcpy@plt와 printf@plt가 사용되고 있는 것을 알 수 있습니다.


RTL은 plt와 got를 이용한 것이라고 앞에서 설명했으므로 strcpy@plt나 printf@plt를 이용한다고 생각할 수 있겠죠.


일단 strcpy를 실행해야 하므로 다음 주소에 브레이크 포인트를 걸고 buf가 16개의 공간을 가지고 있으니 16개의 값을 넣어 보도록 하겠습니다.




일단 구조를 살펴보면 아래와 같습니다.




bof에 대한 포스팅 내용을 공부하셨다면  ret에 원하는 주소를 넣으면 해당 위치로 넘어간다는 것을 알고 계실겁니다.


이때, 넘어갈 함수의 주소를 이용하는 것입니다.



여기서 사용할 방법은 system("/bin/sh")를 이용하여 쉘을 실행시켜 보도록 하겠습니다.



그런데 문득 궁금한 것이 생각이 나네요 해당 소스코드에서 사용하는 것은 strcpy와 printf인데 system은 어디서 가져와서 사용을 할까요?



답은 libc.so.6에 있습니다.


libc.so.6는 프로그램 내에서 printf() 하나만 사용하고 있어서 printf()에 대한 정보만 메모리에 올라가는 것이 아니라 libc.so.6 파일이 통채로 메모리에 올라가게 됩니다.

그래서 system을 사용할 수 있게 됩니다.


그러면 해당 프로그램 내에서 system의 주소가 어디인지 한번 확인해 보도록 하겠습니다.




0xb7e56190에 위치하고 있다고 나타나네요.



여기서 중요한 것이 하나 있습니다. 바로 저 주소가 고정적이지 않다는 것이죠.




이렇게 libc.so6 의 주소가 실행 시 계속 바뀌는 것을 알 수 있습니다.


그래서 실제 프로그램에 gdb로 분석한 주소를 넣어도 실행되지 않습니다.


그래서 해당 주소를 고정하는 방법이 stack 제한을 해제합니다.


ulimit -s unlimited 명령을 이용해서 주소를 고정시켜 버립니다.





다시 gdb를 이용해서 strcpy 다음 주소에 브레이크 포인트를 걸고 16개의 값을 넣고 실행 시켰습니다.

그리고 system의 주소를 확인합니다.


위 사진을 보면 libc.so.6의 주소가 고정된 것을 알 수 있습니다. system의 주소도 고정이 되겠죠.



자 이제 그러면 system의 주소가 0x4007b190인 것을 알게 되었습니다. 그러면 이제  system에 넣을 인자인 "/bin/sh"도 찾아야 하죠.


"/bin/sh"를 만들어야 하는데, 환경변수를 이용합니다.



"/bin/sh"를 대체할 만한 값을 찾아야 합니다. code영역은 0x8048000 인데, 해당 영역은 주소가 바뀌지 않아 고정되어있습니다.

해당 영역에서 "/bin/sh"를 대체할 만한 값을 찾아보도록 하겠습니다.





100개의 값을 가져왔는데 여기서 대체할 만한 값을 찾아보면...




0x34라는 값이 존재하는 걸 알 수 있는데, 해당 값은 ascii table을 참고하면 "4"인 것을 알 수 있습니다.


이제 "/bin/sh"를 "4"로 대체해 보도록 하겠습니다.




위와 같이 /bin/sh를 "4"로 복사를 하고 환경변수를 이용해서 현재 위치를 등록하면 4만 눌러도 쉘이 실행되는 것을 알 수 있습니다.


자 이제 지금까지 알아낸 정보를 이용하여 페이로드를 작성해보도록 하겠습니다.




r `python -c 'print "a"*16 + "AAAA" + "\x90\xb1\x07\x40" + "\x1c\x80\x04\x08"'`


위와 같이 페이로드를 작성하고 실행했더니? 실행이 되지 않았습니다.





위와 같이 나오게 된 이유는 system과 execl 함수는 ebp+8의 위치의 인자를 인식합니다. 그래서 system주소와 파라미터 사이에 임의의 값 4바이트를 넣어줘야 합니다.





r `python -c 'print "a"*16 + "AAAA" + "\x90\xb1\x07\x40" + "BBBB" + "\x1c\x80\x04\x08"'`





쉘이 실행된 것을 확인 할 수 있습니다.



'High Level Technique > System Hacking' 카테고리의 다른 글

Return to Library Chain (RTL Chain)  (0) 2016.04.28
Format String Bug (FSB)  (0) 2016.04.25
Plt 와 Got  (0) 2016.04.20
Fake EBP  (0) 2016.04.19
main의 SFP는 왜 0이 되는가?  (1) 2016.04.19