본문 바로가기

BOF(Basic)

Return Into Libc(RTL)

1997년 8월, Solar Designer는 Bugtrack에서 논의되던 'Return Into Libc'(이하 RTL) 기술을 이용한 공격 코드를 공개하면서 자신의 Non-executable Stack 패치를 수정한다. RTL은 함수의 Return Address(이하 RET)를 덮어써서 공유 라이브러리에 존재하는 system()과 같은 함수를 가리키게 하고 함수 실행에 필요한 매개 변수를 전달하여 실행하는 공격법이다. 메모리에 적재된 공유 라이브러리는 스택에 존재하는 것이 아니므로 Non-executable Stack을 우회하는 것이 가능하다.


여기에서 잠깐 Non-executable Stack 이란?
1997년에 Solar Designer는 스택에서 어떤 코드도 실행되지 못하도록 하는 기능을 가진 Non-executable Stack을 리눅스 커널 패치의 형태로 개발하여 배포하는데, 이를 적용할 경우  'Phrack 49호에 Aleph1이 발표한 방법(버퍼 오버플로우 취약점을 가지는 프로그램을 공격하는 자세한 방법을 설명한 기사)' 에서 제시한 스택 안에 공격 코드를 주입하여 실행시키는 공격은 실패하게 된다. 이 기술은 Solar Designer에 의해 이후 OpenWall Project로 발전하게 된다. [참조 : Smashing The Stack For Fun And Profit (Phrack 49-14) 번역 문서 by 박상운]


다시 RTL로 돌아와서 

그림


Solar Designer는 위 그림처럼 RET를 메모리에 적재된 system() 함수를 가리키게 하고, 환경변수에 저장한 "/bin/sh"의 주소를 ebp + X (레드햇 리눅스 8.0 기준으로 ebp + 8 에서 인자 값을 읽는다)에 위치시켜 system() 함수에 전달함으로써 shell을 획득할 수 있음을 증명하였다. 만약 공격자가 setuid() 함수를 이용할 경우 root 권한의 shell도 획득 가능함을 증명하였다.


이 취약점을 막기위해 Solar Designer는 공유 라이브러리들의 기본 주소를 mmap() 함수를 사용하여 '0'을 포함하는 주소로 변경하였다. 예를 들어, system()의 주소는 0x00401037인 식이다. 일반적으로 공격 코드는 아스키 문자열의 형태로 전달되므로 '0'을 문장의 끝으로 인식하기 때문에 그림 4의 공격 방법으로는 RET를 덮어쓸 수 없게 된다.


[출처] : History of Buffer Overflow.pdf written by Jerald Lee