profile image

L o a d i n g . . .

article thumbnail image
Published 2021. 3. 7. 18:29

Return To Libc(RTL)리턴 주소를 라이브러리 내에 존재하는 함수의 주소로 바꿔 NX bit를 우회하는 공격 기법이다.

 

리눅스 익스플로잇의 최종 목표는 셸 바이너리를 실행하는 것이다. libc.so.6 라이브러리에는 execve , execlp , execl , execvp , system , popen 등 프로그램을 실행할 수 있는 다양한 함수들이 존재한다. 

이 중 system 함수를 이용해 "/bin/sh" 문자열의 주소를 system 함수의 인자로 넘겨준 후 호출하면 /bin/sh 바이너리가 실행된다.

 

example1 예제에 NX bit가 추가된 example1_nx를 이용해 RTL을 실습해 보도록 하겠다.

취약점은 이전과 동일하지만 example1_nx에는 NX bit가 적용되어 스택의 셸코드를 실행시킬 수 없다.

이전 익스플로잇에서는 스택 내의 셸코드를 실행시켜 execve 시스템 콜을 호출하는 것이 목표였다면, RTL의 목표는 라이브러리 내에 존재하는 system 함수를 호출하여 system("/bin/sh")를 실행하는 것이다.

 


 

//gcc -o example1_nx example1.c -fno-stack-protector -mpreferred-stack-boundary=2 -m32
#include <stdio.h>
int vuln(char * src){
  
  char buf[32] = {};
  
  strcpy(buf, src);
  return 0;
}

int main(int argc, char * argv[], char * environ[]){
  if (argc < 2){
    exit(-1);
  }
  vuln(argv[1]);
  return 0;
  
}

앞에서도 썼던 example.c에 nx-bit 보호기법을 추가해 컴파일 해준다.

 

buf 배열부터 vuln 함수의 리턴 주소 위치까지는 이전과 동일하게 36바이트이다.

 

실행 결과 eip 레지스터가 0x42424242로 바뀌었고, ret을 하기 전의 스택 포인터인 esp-4 메모리에 0x42424242가 저장되어있는 것을 볼 수 있다.

 

RTL에서, 리턴 주소에 호출할 함수의 주소를 덮어쓴 후 ret을 하면 eip 레지스터가 덮은 값이 되고, esp 레지스터는 리턴 주소의 위치+4가 된다.

 

system("/bin/sh")를 호출하는 익스플로잇 코드는 다음의 익스플로잇 코드 구조와 같이 구성된다.

"A" * 36 + (system 함수 주소) + "BBBB" + ("/bin/sh" 주소)

 

return address 전까지를 더미값("A"*36)으로 채운 뒤, return address에 system 함수 주소를 넣어 system 함수를 호출한다. 함수 호출 시에는 함수가 종료되고 난 후 리턴할 주소와 함수의 인자를 같이 전달해줘야 하기 때문에 "BBBB"(리턴할 주소), 그리고 "/bin/sh"(함수의 인자)를 뒤에 적어준다.

 

이때, BBBB 문자열은 system 함수가 종료되고 난 후 리턴할 주소인데, 단지 system("/bin/sh")를 실행하는 것이 목표이기 때문에 임의의 값을 적어도 무방하다.

 

그러면 system 함수가 호출되어 우리의 최종 목표인 /bin/sh을 실행할 수 있을 것이다!

 

 


 

system("/bin/sh")를 호출하기 위해 알아야 하는 값 system 함수의 주소와 /bin/sh 문자열의 주소이다.

 

main 함수에 브레이크포인트를 설정한 후, gdb의 print 명령어를 통해 system 주소를 찾고

 

find 명령어를 통해 libc.so.6 라이브러리에 존재하는 /bin/sh 문자열의 주소를 찾았다.

 


 

이제 앞에서 알아낸 system 함수와 "/bin/sh" 문자열의 주소를 이용해 실제 익스플로잇을 만들어 보면 다음과 같은 익스플로잇 코드가 완성된다.

"A"*36 + "xbo/xdd/xe3/xf7" + "BBBB" + "x0b/xeb/xf5/xf7"

 

실제로 익스프로잇해서 쉘을 획득한 모습이다!!

단, 익스플로잇 했을 때 잘 되지 않는 경우 ASLR을 끄고 익스플로잇하길 바란다!

 

 

참고
dreamhack - Linux Exploitation & Mitigation Part 1

'Hacking > Pwnable' 카테고리의 다른 글

[Pwnable] ASLR  (0) 2021.03.11
[Pwnable ] NOP Sled 실습  (0) 2021.03.11
[Pwnable] NX bit  (0) 2021.03.07
[Pwnable ] Return Address Overwrite 실습  (0) 2021.03.01
[Pwnable] ELF 동적 분석  (0) 2021.03.01
복사했습니다!