티스토리 뷰




RTL 공격

(DEP 우회, 공유 라이브러리를 이용하여 공격)




[환경 요약]

OS

Kali 1.0

파일

/tmp/test3.c

ASLR

X (echo 0 > /proc/sys/kernel/randomize_va_space)

DEP(N/X)

O (gcc -o test3 test3.c -mpreferred-stack-boundary=2)

취약점

strcpy 함수 이용

 

실행파일에 DEP가 걸려 있는 파일은 내부 STACK에서 shellcode가 실행되지 않는다.

DEP를 우회하기 위해서는 실행 가능한 공유라이브러리 주소를 이용하여 공격할 수 있다



 

[그림 - test3.c 소스]


#include<stdio.h>
int main(int argc, char* argv[]){
	char buf[50];
	strcpy(buf.,argv[1]);
	printf("%s\n",buf);
	return 0;
}  






STACK 실행 여부는 /tmp/test3.c 프로그램을 gdb에서 /proc/PID/maps으로 확인할 수 있다.


 

[그림 - GDB에서 PID 확인]


Test3 실행파일을 GDB에서 breakpoint를 걸어 실행중인 상태로 만든다음 ps명령어를 통해 PID를 확인 할 수 있다.

확인한 22064 PID를 이용하여 /proc/22064/maps 를 확인하면 STACK 실행여부를 확인 할 수 있다.


 

[그림 - 프로세스 maps 확인]

해당 프로그램은 STACK에 실행 권한이 없음을 확인 할 수 있다.


[공격 시나리오]

1. buf에서 RET 이전까지 거리

2. execl() 주소 찾기 (공유라이브러리)

3. execl() 인자 주소 (환경변수 shcode=”/tmp/sh”)

 

Payload :

“a”(50byte) + “bbbb”(SFP 4byte) + RET(execl() 주소)+”aaaa”+”환경변수의 주소

이전 공격에서는 RET위치에 환경변수 shellcode의 시작주소를 바로 변조하여 shellcode가 실행되었다. 하지만 DEP가 걸려있기 때문에 실행되지 않는다. 따라서 공유라이브러리 안에 있는 execl()를 실행시키고 인자 값을 shellcode 시작주소를 넣어준다.

 

/tmp/sh 프로그램 작성



 

[그림 - /tmp/sh.c 소스]


#include<stdio.h>
int main(){
    setuid(0);
    system("/bin/sh");
}  


Execl()는 자신의 프로세스가 바뀌기 때문에 /tmp/sh 프로그램이 실행되면 권한 그대로 “/bin/sh”를 실행 할 수 있어 uid=0을 획득할 수 있다.

GDB를 이용하여 execl()의 주소를 구할 수 있다


 

[그림 - execl() 주소 확인]


공유 라이브러리에 있는 execl() 주소를 GDB에서 확인 할 수 있으며 해당 주소는 실행 가능한 영역 임도 확인 할 수 있다.

환경변수로 인자 값을 넣고 주소를 구한다.


 

[그림 - 환경변수 인자 값 주소]


Execl() 주소 : 0xb7eb6960

환경변수 주소 : 0xbfffffa5

Payload : “a”(50byte) + “bbbb”(SFP 4byte) + RET(execl() 주소)+”aaaa”+”shellcode의 주소


 /tmp/test3 `python -c 'print “a"*50+"bbbb"+"\x60\x69\xeb\xb7"+"aaaa"+"\xa5\xff\xff\xbf";'`


 

[그림 - RTL 공격 성공]


*ASLR 우회 (ASLR = Adress Space Layout Randomization)

- 프로세스가 메모리에 올라갈 때 heap,stack, libc 위치주소를 랜덤하게 정한다.

설정 :  echo 1 > /proc/sys/kernel/randomize_va_space


 

[그 - ASLR 적용 주소 확인]


 

[그림 - 환경변수 랜덤 주소 확인]


그림 31,32와 같이 랜덤하게 주소가 바뀌는 것을 확인 할 수 있다.  ASLR을 우회하기 위해서는 변하지 않는 영역을 활용할 수 있다.


 

[그림 - ASLR 미적용 부분 확인]


 

[그림 - ‘\x44’ 주소 확인]


/tmp/test3파일의  0x8048000 -0x805400 사이의 값 중에 ‘\x44’ 값이 포함된 주소를 찾는다.

해당 주소 : 0x080480e4

앞서 본 ‘\x44’문자의 주소를 찾았기 때문에 44 D 와 같으므로 /bin/sh 파일을 /tmp/D로 복사한다.

그리고 어디서든지 바로 실행할 수 있도록 환경변수에 현재 위치인 . 을 추가한다.


 

[그림 - D파일 생성]


D를 입력하면 바로 shell을 확인 할 수 있다.

추가로 공유라이브러리의 execl() 함수의 주소를 찾아야 한다. 하지만 라이브러리 주소도 ASLR이 걸려있기 때문에 주소가 랜덤 하게 바뀌는 것을 확인 할 수 있다.

 

 

[그림 - 공유 라이브러리  ASLR 적용 확인]


공유 라이브러리도 ASLR이 적용되여 주소값이 램덤하게 바뀌어 원하는 함수의 주소를 찾기가 힘들다.

공유 라이브러리 ASLR 해제는 ulinit –s unlimited 명령어로 해제할 수 있다.

STACK을 더 이상 증가하지 못할 정도로 증가시켜 랜덤으로 매핑 되는 ASLR 기능을 막는다


 

[그림 - 공유라이브러리 ASLR 해제]


 

[그림 - execl() 주소 확인]

 

Ulimit가 적용된 후로는 라이브러리 주소가 변동되지 않으므로 execl()의 주소는 일정하게 나온다.

 

이제 변하지 않는 주소인 /tmp/D 의 주소 0x080480e4의 주소, execl()의 주소 0x400f6960 를 활용하여 공격하면 된다.

 

Payload : /tmp/test3 `python -c 'print ”a"*50+"bbbb"+"\x60\x69\x0f\x40"+"aaaa"+"\xe4\x80\x04\x08";'`



 

[그림 - RTL 공격 성공 확인]


Comments
최근에 올라온 글
최근에 달린 댓글
TAG
more
Total
Today
Yesterday