Hacking/System Hacking

Stack Buffer Overflow(BOF) - DEP+ASLR 우회 (RTL 공격)

나노콛 2019. 9. 27. 00:41

ASLR(Address Space Layout Randomization)
메모리 영역의 주소 공간 배치를 랜덤화하여 공격을 방해

RTL 공격 시 환경 변수에 함수를 담고 그 주소를 사용했는데요
환경 변수가 ASLR 보호 기법으로 랜덤이 되어 주소가 바뀐다면 이용하기 어려워집니다.

그래서 DATA 영역에 있는 기계어 값에 실행에 필요한 내용을 넣고 그 주소를 이용하는 방법을 이용해서
DEP+ASLR 보호 기법을 우회해보겠습니다.

이 data 영역에는 실행 권한이 있습니다.
그리고 이 영역 안의 항상 있을법한 기계어 (ex \x01)를 파일명으로 사용하여 이전에 만들었던 /tmp/sh 파일에 대한 실행 명령어(/tmp/sh)를 넣어 우회합니다.

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

다시 한번 얘기하자면
이전의 RTL 공격에서는 공유 라이브러리의 execl 함수를 이용하고
위의 sh 파일을 만들어 (/tmp 경로에 만들었음) 
execl 함수의 인자로 위의 파일을 실행할 수 있게 /tmp/sh를
환경 변수에 넣고 그 주소를 인자로 썼었습니다.

환경 변수의 주소가 랜덤으로 변경이 된다고 하면 이용할 수 없기 때문에
/tmp/sh를 주소가 변하지 않는 data 영역의 항상 있을만한 값 \x01 같은 기계어를 파일명으로 사용하여 심볼릭 링크로  /tmp/sh 의 문자열을 링크를 걸고
이 주소를 execl의 인자로 이용하는 방법입니다.

일반 계정으로 하면 됩니다.

심볼릭 링크를 이용

 

기계어는 나타낼 수 없어서?로 글자가 깨져 보인다.

 

심볼릭 링크는 파일에 대한 주소를 값을 가지고 있습니다.
이렇게 되면 \x01에 대한 sh 링크가 설정되었습니다. 원본 파일은 ->로 알려줍니다.

이제 \x01에 대한 주소를 파악해보겠습니다.

0x08048000

 

0x08048000은 data 영역의 주소입니다.
해당 주솟값에서
01 값을 쓸 수 있는데 01값 이후의 값이 00으로 null 값이 와야 사용이 가능합니다.
그리고 \x01 값이 아니라 이후의 값에 00이 있다면 모두 사용이 가능합니다.
위에 값에서 이용 가능한 곳을 표시하자면

이렇게 이용할 수 있겠습니다.

주소를 읽는 방법은

표시한 곳의 \x01을 이용한다고 했을 때

\x02 자리가 0x08048010
\x00 자리가 0x08048011
\x03 자리가 0x08048012
\x00 자리가 0x08048013

\x01 자리가 0x08048014

이렇게 진행됩니다.
위에서 심볼릭 링크로 설정한 \x01 의 주소를 0x08048014 이걸로 쓸 수 있습니다.
(\x01의 가진 값 중에 뒤의 값이 00이 있다면 그 주소를 쓸 수도 있습니다.)


bof2는 공격을 이용할 취약한 프로그램입니다.

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


execl의 함수 주소를 확인합니다.

gdb에서 run 해야 주소를 확인 가능

 

buffer의 길이를 확인합니다.




문자 셋을 변경합니다.


이전의 RTL 공격과 비슷하나 /tmp/sh 의 주소가 변경된 것이 다릅니다.


./bof "`perl -e 'print "A"x60,"\xa0\xca\x0a\x42","AAAA","\x14\x80\x04\x08"x3;'`"

 

A를 RET까지 채우기 위해서 56에서 4를 더해서 60을 채우고
execl 함수의 주소를 넣으면 이전 EBP 자리를 채우게 되고
execl의 RET의 자리를 AAAA로 채우면서 넘어가게 되고
execl의 인자 값을 넣어주면 됩니다.