본문 바로가기

High Level Technique/System Hacking

Return to Library Chain (RTL Chain)

Return to Library Chain (RTL Chain)



개념


Return to Library Chain(이하 RTL Chain)은 BOF가 일어나는 취약한 프로그램에서 사용하고자 하는 라이브러리 함수들을 계속해서 호출하여 사용할 수 있는 기법.

Rreturn Oriented Programming의 기본 바탕이 된다.




설명


RTL Chain은 RTL을 연속적으로 사용하여 원하는 함수를 사용하는 것을 말합니다.


간단한 예제를 통해서 알아보도록 하겠습니다.




위 C 코드는 main에서 buf의 16개의 공간에 argv[1]을 통해서 값을 저장시키는 함수입니다. 그러나 func1, func2, func3의 함수들은 실행을 할 수 없죠.

하지만 앞서 공부한 내용들을 바탕으로 buf + SFP + Ret 구조라는 것을 알고 있는데, ret에 원하는 주소를 넣으면 해당 위치로 이동한다는 것을 알고 있습니다.


그러면 일단 하나씩 살펴보면서 함수들을 실행시켜 보도록 하겠습니다.





지금까지 공부한 내용에서는 BUF + SFP + RET 구조 정도만 알고 있습니다.


먼저 ret의 값을 func1의 주소로 바꿔서 넘어가보도록 하겠습니다.





func1의 주소를 확인해 보니 0x804847d인 것을 확인 할 수 있었습니다.


r `python -c 'print "a"*16 + "BBBB" + "\x7d\x84\x04\x08"'`를 입력해 보겠습니다.




스택을 확인해 보니 값이 제대로 들어가 있는 것을 확인 할 수 있습니다.


이제 main에서 ret 명령어를 실행하게 되면 func1으로 넘어가게 될 것입니다.




func1으로 넘어온 것을 확인 할 수 있습니다.


그러면 func1의 ret까지 이동한 후에 어느 주소로 넘어가는지 확인해 보죠.




0xbffff130의 값인 0x00000000이 다음 주소로 넘어가도록 되어있습니다. 물론 해당 주소는 아무 것도 없겠죠.


그러면 왜 0x00000000이 되었을까요?


처음에 main함수에서 넣었던 값을 확인해 보면 ret를 func1의 주소로 했고 다음 값을 확인해 보면 0x00000000이였습니다. 바로 이 값이 func1에서 ret가 수행되는 것입니다.


그러면 다시 값을 넣어보도록 하죠. ret 다음값이 또 다시 ret가 수행되니 func2로 해보겠습니다.


r `python -c 'print "a"*16 + "BBBB" + "\x7d\x84\x04\x08" + "\x98\x84\x04\x08"'`




func1에서 ret 명령을 실행하기 전까지 상태입니다. 스택을 확인해보면 func2의 값이 실행될 것이라고 알 수 있습니다.




func2로 넘어온 것을 알 수있습니다. 마찬가지로 ret를 실행하기 전의 스택을 확인해 보도록 하겠습니다.




다음 실행될 주소는 0xbffff100인 것을 알 수있습니다. 이 값은 또 어디서 나타나게 된 걸까요?




main함수에서  r `python -c 'print "a"*16 + "BBBB" + "\x7d\x84\x04\x08" + "\x98\x84\x04\x08"'`과 같이 넣었을 때의 스택입니다.


Buffer + SFP + func1 + func2 + 0xbffff100 인 것을 알 수 있죠.


그래서 0xbffff100 대신에 func3를 넣으면 마찬가지로 func3로 넘어갈 것입니다.



r `python -c 'print "a"*16 + "BBBB" + "\x7d\x84\x04\x08" + "\x98\x84\x04\x08" + "\xb3\x84\x04\x08"'`




func3로 넘어온 것을 확인 할 수 있습니다.


실제로 한번 실행시켜 보죠.




func1, func2, func3가 모두 실행된 것을 확인 할 수 있습니다.



그러면 func1에서 val1의 값을 출력하고 있는데 해당 값은 어디에서 가져온 것 일까요?




값을 확인해 보니 func3의 주소가 val1의 값으로 출력이 되고 있습니다. 0x80484b3 인데 이 값이 십진수로 134513843 출력된 값을 확인해보니 같습니다.



그렇다면 지금까지 한 결과를 바탕으로 정리를 해보겠습니다.





이와 같은 구조로 값을 넣었었죠. 하지만 func1에서 val1이라는 파라미터를 가지고 출력했었습니다. 그 값이 바로 func3의 주소였죠.




결과적으로는 위와 같은 구조가 되는 것이죠.


그러면 func1에 val1을 출력하고 있으므로 parameter를 AAAA (0x41414141)로 주고 한번 실행해 보도록 하겠습니다.


 `python -c 'print "a"*16 + "BBBB" + "\x7d\x84\x04\x08" + "\x98\x84\x04\x08" + "AAAA"'`




위 값은 10진수 값으로 0x41414141의 값입니다. 정확하게 들어가는 것이 확인되었습니다.



자 그러면 func1에 파라미터를 넣는 것은 알겠는데 func2에는 파라미터를 어떻게 넣어야 할까요?


func1 func2 func3를 넣어서 값을 계속 호출을 할 수 있지만 func3가 func1의 파라미터가 되버립니다.



그.래.서!! Gadget을 이용합니다.


Gadget은 필요한 명령어들을 찾아서 사용하는 것을 말하는데요. 계속 설명하면서 알아가겠습니다.



현재 func1 + func2 + func1 Parameter 인 구조를 가지고 실행을 해 보았습니다. func1이 끝나면 func2가 실행된다는 것도 아시겠죠.


그런데 func2에도 Parameter를 넣고 싶은데 넣을 수가 없습니다. 그래서 func2의 주소에 pop pop ret 명령어를 넣어서 pop pop ret를 실행시켜 func2가 실행되도록 하고 Parameter 또한 넣습니다.


구조를 나타내면 아래와 같습니다.








1: main()에서 ret 주소를 func1으로 합니다. 이때 func1의 parameter 또한 넘어갑니다.

2: func1()에서 모든 과정이 끝난 후 ret 명령어가  2를 가리키고 있습니다. 이 부분에 pop ret를 넣어줍니다.

3. 2에서 넣은 pop이 한번 실행 됩니다. 

4: 2에서 넣은 ret가 실행이 됩니다. 해당 부분에 func2를 넣어줍니다. 마찬가지로 func2의 parameter또한 넘어갑니다.


이와 같은 과정으로 연결하는 것을 바로 Chain이라고 합니다.


func2 Address 다음에 dummy가 있는데 이것 또한 마찬가지로 pop ret 명령어를 넣어준다면 func3에도 원하는 파라미터를 넣고 실행할 수 있게 되는 것이죠.




그러면 먼저 어떻게 pop pop ret를 넣어야 하는지 알아봅시다.


objdump -d 파일명 -M intel 명령어를 입력하면 아래와 같이 출력이 나타납니다.




현재 필요한 것은 pop ret이므로 해당 명령어가 있는 곳을 찾습니다.



pop ret의 주소를 찾아본 결과 0x804856e에 있는 것을 알 수 있습니다. 그러면 값을 넣을 때 아래와 같이 넣을 수 있습니다.


r `python -c 'print "a"*16 + "DDDD" + "\x7d\x84\x04\x08" + "\x6f\x85\x04\x08" + "AAAA" + "\x98\x84\x04\x08" + "CCCC" + "BBBB"'`




정확히 func2에도 값이 1111638594(0x42424242)가 들어간 것을 알 수 있습니다.



이와 같은 방법으로 연결을 계속해 나가면서 함수를 호출 할 수 있습니다. 설명한 것은 일반 적인 함수이지만 RTL Chain은 라이브러리 함수 주소를 사용하면 되겠죠.





정리


1. ret에 원하는 라이브러리 함수를 넣는다.

2. 기본 구조는 ret + dummy + parameter 이며, dummy에 원하는 명령어를 넣는다.

2. 해당 라이브러리가 참조하는 파라미터는 +8의 위치에 넣어준다.

3. 다음에 실행하고 싶은 라이브러리 함수는 Gaget(pop ret)를 이용하여 호출한다.



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

Return Oriented Programming (ROP) - step 2  (1) 2016.05.04
Return Oriented Programming (ROP) - step 1  (0) 2016.04.28
Format String Bug (FSB)  (0) 2016.04.25
Return To Library (RTL)  (2) 2016.04.20
Plt 와 Got  (0) 2016.04.20