Return To Library
이름 그대로 이해하시면 됩니다.
Library로 return 합니다.
ret 값을 덮어씌워 shell code로 떨어지게 하는게 고전적인 시스템 해킹 방법입니다.
해커들이 신명나게 해킹을 하고 다니는데
OS 개발자들이 가만히 보고만 있을리가 없겠지요.
고전적인 방법의 해킹을 할 때
프로그램을 실행하고 shell code를 집어넣습니다.
Parameter로 넘겨주든 환경변수를 쓰든
Shell code는 실행 영역이 아니라 stack에 들어가게 됩니다.
여기서 아이디어를 얻어 OS 개발자들은 DEP를 적용하게 됩니다.
DEP의 개념을 모르시면 다음 글을 읽고 오세요.
->
이제 stack상에 존재하는 shell code는 무의미하게 되었습니다.
그렇다고 해커들이 해킹을 포기할리는 없겠지요.
DEP에 대한 대책으로 나온 해킹 기술이 RTL입니다.
왼쪽의 그림이 shell code를 이용하는 방법이라면
오른쪽의 그림은 library를 이용하는 RTL입니다.
RTL은 shell code를 사용하지 않습니다.
프로그램을 실행할 때 같이 memory에 load 되어있는 library의 함수를 이용합니다.
Library에 있는 함수들은 library 내부의 code 영역에 존재합니다.
Code 영역은 stack과 달리 실행을 위한 code들이 저장되어 있습니다.
한마디로 DEP에 걸리지 않습니다.
그러므로 library의 함수를 이용해 공격을 하면 됩니다.
RTL 공격에 쓰이는 대표적인 함수로는 system()이 있습니다.
system() 함수를 이용해 RTL 공격을 시도해 보겠습니다.
공격대상이 되는 데몬의 코드는 다음과 같습니다.
입력받은 string을 출력하고 종료합니다.
BOF 취약점도 보이고 FSB 취약점도 보입니다.
해당 데몬은 bugbear라는 유저의 setuid가 걸려있습니다.
gdb로 attackme를 열어봅니다.
권한 문제로 debugging이 불가능하니 코드를 이용해 새로 컴파일한 후 debugging 합니다.
Stack을 0x80(128)만큼 확보합니다.
이제 return 할 system()의 주소를 찾습니다.
system()의 주소는 0x40058ae0입니다.
system()은 libc.so.6 library에 속해 있습니다.
libc.so.6에서 system()의 위치를 찾아보겠습니다.
gdb로 libc.so.6을 열어봅니다.
libc.so.6에서 system()의 위치는 0x00040ae0입니다.
.rodata section은 0x000e09e0부터 시작됩니다.
이제 attackme 프로그램에서의 "/bin/sh" string의 주소를 구해야 합니다.
attackme에서의 system() 주소에서
libc.so.6에서의 system() 주소를 빼줍니다.
그리고 libc.so.6에서의 .rodata section의 주소를 더하면
attackme process 상에서 mapping 되어있는 libc.so.6의 .rodata section 주소가 나옵니다.
0x40058ae0 - 0x40ae0 + e09e0 = 0x400f89e0
attackme에서 libc.so.6의 .rodata section 주소는 0x400f89e0입니다.
해당 주소부터 string을 검색해봅니다.
0x400fbff9에서 "/bin/sh"을 찾았습니다.
"/bin/sh"를 찾는 개념적인 방법을 설명하느라 위와같이 힘든 작업을 했지만
"/bin/sh"를 찾는 프로그램을 작성해서 돌려버리는게 훨씬 편합니다.
공격 코드는 BOF를 통해 ret를 system() 주소로 바꾸고
system에서 사용할 "/bin/sh"를 parameter로 쓰도록 넘겨주면 됩니다.
이제 공격해봅니다.
공격에 성공했습니다.
'Exploit > System' 카테고리의 다른 글
Format String Bug (0) | 2012.11.14 |
---|---|
Race condition (0) | 2012.09.14 |