4n6x4t

RTL(Return to LibC) 공격의 3단계 수행 절차 및 대응 방안 3가지 본문

Study/System Security

RTL(Return to LibC) 공격의 3단계 수행 절차 및 대응 방안 3가지

HCHC 2023. 4. 27. 13:14
728x90

안녕하세요 오늘은 RTL 공격에 대해서 알아보겠습니다. RTL은 일반적인 Buffer overflow의 대응방안인 NX-bit을 우회하기 위해서 개발되었습니다. NX-Bit는 스택영역에서 코드 실행을 막는 대응방안인데요, RTL은 스택영역에서 실행하지 않고 TEXT영역에 있는 코드의 주소로 Return Address를 덮어써서 우회 실행하는 방법입니다.

ex) system()함수로 RET를 덮어씀

추상화한 실행원리

이 방법을 수행하기 위해서는 먼저 함수의 기본 동작인 프롤로그와 에필로그에 대해서 알아야 하는데요 한번 알아보겠습니다.

함수 프롤로그, 에필로그

사실 함수의 동작에는 필수적으로 프롤로그와 에필로그라는 동작이 동반됩니다. 이러한 동작을 이해한 다음 RTL을 더 쉽게 이해할 수 있습니다. 먼저 프롤로그부터 살펴보면 다음과 같습니다.

함수 프롤로그 동작방식

축약한 과정은 다음과 같습니다. 함수가 만들어지기 전 ebp를 만들고 esp(stack pointer)을 ebp까지 만든다음 esp에 N 만큼 빼서 함수의 여유공간 프레임을 만들어 주는 것입니다.

함수 에필로그 동작방식

에필로그는 만들어진 esp를 ebp까지 올리고 ebp를 제거한뒤 호출 함수 위치로 돌아가는 것입니다...!

 

자 이제 함수 프롤로그, 에필로그에 대한 설명을 했으니 RTL을 하기 위한 3가지 절차에 대해서 알아보도록 하겠습니다.

TASK A : system() 의 주소 찾기

system()의 주소를 찾을 텐데, gdb p system()을 통해서 디버깅하여 주소를 찾을 수 있게됩니다.

TASK B : "/bin/sh" string 주소찾기

system()을 찾았으니 이 함수의 인자로 쓸 인자값의 주소도 마찬가지로 필요하게 됩니다. 이를 위해서 우리는 환경변수를 이용할 수 있습니다. OS는 프로그램 실행 시 환경변수를 stack에 적재하게 되는데요, "/bin/sh" 값을 갖는 환경변수를 EXPORT로 등록하고 이후 getenv() 함수를 통해서 주소를 확인하는 프로그램을 짜서 인자값의 주소를 찾을 수 있습니다,

※ getenv()를 사용하는 프로그램 이름 길이에 따라 주소가 영향을 받으므로, 공격을 할 취약 프로그램과 같은 길이의 이름을 사용해야 합니다.

TASK C : 함수와 인자 조합하기

스택 어디에 인자를 넣을지 찾는 부분입니다. Return Address가 위치하는 주소(=%ebp+4)에 system() 함수의 주소를,
Return Address + 4에 exit()의 주소를(흔적 제거를 위해), Return Address+8에 "/bin/sh"의 주소를 입력하면 system("/bin/sh") 실행 후 이 프로그램 종료가지 되게 됩니다.

RTL의 대응 방안

앞서 설명드렸듯 RTL은 NX-bit에 대응하는 기법입니다. 그러나 RTL에 대응하는 방법은 다음과 같습니다.

  1. Stack Gaurd : 여전히 덮어쓰므로 스택 가드로 대응할 수 있습니다.
  2. ASLR : 주소를 랜덤화하여 완전히는 아니지만 해당 함수의 주소를 넣기 어렵게 만들어 공격 난이도를 올릴 수 있습니다.
  3. 애초에 안전한 함수 사용: 코드와 데이터가 분리된 안전한 함수를 사용하는 것이 훌륭한 대응 방법이 될 수 있습니다.

 

이상으로 간단하게 RTL 공격에 대해서 알아보았습니다.

감사합니다.

728x90
Comments