2017. 6. 12. 13:42ㆍSystemHacking/Protostar
Protostar Stack6번 문제입니다
RTL ( Return to Libc ) 기법을 사용하는 문제입니다
RTL을 응용해서 Channing RTL 기법까지 사용해보겠습니다
[ 그림1 ]
소스코드를 보시면 변수 " ret "에 __builtin_return_address(0) 함수를이용해서 getpath()함수의 리턴주소를 저장합니다
" ret "의 값과 " 0xbf000000 " 을 and연산합니다. 즉," ret "에 저장된 주소의 시작부분이 " bf "일 때 함수는 종료됩니다
이러한 방어기법은 쉘 코드를 버퍼에 올린 후 쉘 코드 주소를 RET에 덮어씌우는 공격을 방어하려고 고안되었습니다
해당 방어기법을 무력화시킨 공격기법이 바로 " RTL "입니다 ( http://itsaessak.tistory.com/98 RTL의 자세한 설명 )
[RTL공격을 위해 필요한 것]
[1] 공격대상이 될 파일의 메모리 구조 파악
[2] libc에서 system()함수의 주소
[3] libc에서 exit()함수의 주소( 완벽한 공격을 위해서, 필수는 아닙니다 )
[4] 환경변수의 주소를 구하는 코드
[1] 먼저 메모리 구조부터 파악하도록 하겠습니다
[ 그림2 ]
gets(buffer) 명령이 실행 된 직후에 break를 걸어주었습니다
그리고 최상위 레지스터 $esp의 내용을 출력시켰습니다
[ 그림4 ]
(gdb) x/30xw $esp
$esp레지스터에 " AAA...GGGG " 문자열이 들어있음을 확인 할 수 있습니다
(gdb) x/x $ebp
$ebp레지스터에 있는 값을 확인 할 수 있습니다. 해당값은 SFP( 스택프레임이 가르키고 있는 위치 )
SFP에서 +4byte지점이 return address 가 된다 <= 우리가 공격해야할 지점
# 참고 #
왜 $ebp가 SFP일까? 처음 프로세스가 실행될 때 Procedure prelude과정이 실행됩니다
[ Procedure prelude과정 ]
0x08048408 <main+0>: push %ebp // 함수의 복귀지점을 스택에 push 0x08048409 <main+1>: mov %esp,%ebp // %esp레지스터의 값을 %ebp값에 복사한다 => 이부분때문에 x/x $ebp레지스터를 확인하면 SFP입니다 => ebp의 주소에 +4byte를 해주면 실제 return address임 0x0804840b <main+3>: and $0xfffffff0,%esp 0x0804840e <main+6>: sub $0x50,%esp // 지역변수의 공간을 할당해주는 과정 |
위 방식처럼 stack6파일의 getpath함수를 디스어셈블해보면 지역변수의 공간을 104byte할당해주고 있습니다
따라서 stack6파일의 메모리 구조를 그려보면 다음과 같습니다
ret(4byte) |
dummy(16byte) |
buffer(64byte) |
dummy(12byte) |
SFP(4byte) |
RET(4byte) |
이제 우리는 64+12+4=80byte만큼 버퍼오버플로우 시켜서 RET의 값을 변질시키면 됨을 알 수 있습니다
RET주소공간에 우리가 넣어야 할 주소는 무엇일까요? " 0xbf.... "형태의 주소가 아닌 system()함수의 주소입니다 !
[2] 함수들의 주소 구하기
[ 그림5 ]
임의로 system()함수와 exit()함수를 사용하는 소스코드를 하나 작성한 다음 gdb로 해당 파일을 디스어셈블하면 됩니다
[ 임의로 작성한 코드 ]
int main(){ system("/bin/sh"); exit(0); return 0; } |
주의할 점은 프로세스의 시작부분에서 break를 걸어주어야 합니다 !
우리가 찾는 주소는 libc내에서 존재하는 system()함수와 exit()함수의 주소입니다.
<main+16> , <main+28>지점에 나와있는 주소는 해당 함수들을 호출한 주소일 뿐, 실제 함수들의 주소가 아닙니다
따라서 프로세스의 시작지점에 break를 걸어주고, 각 함수들의 주소를 출력해서 알아냅시다
이제 마지막 과정입니다
[3] 환경변수를 선언하고 그 주소를 얻어오기
[ 그림6 ]
[3]-1
$export code="/bin/sh" 환경변수 code를 선언하고 초기화시킵니다. 이 환경변수의 주소를 구하면 됩니다
[ 환경변수의 주소를 구하는 코드 getaddr.c ]
#include<stdio.h> #include<string.h> int main( int argc, char **argv ){ char ptr*; ptr = getenv( argv[1] ); // 환경변수의 주소를 얻어온다 ptr += ( strlen(argv[0]) - strlen(argv[2]) )*2; // 환경변수의 주소는 실행파일의 길이에 따라 오차가 발생하는데 // 그 오차를 없애주는 역할 printf( "%s Address : %x\n" , argv[1] , ptr ); // 환경변수의 실제 주소를 출력 return 0; } |
[3]-2
$gcc -o getaddr getaddr.c 컴파일 후 환경변수의 주소구했습니다
run$ ./getaddr code /opt/porotostar/bin/stack6 |
argv[0] = ./getaddr , argv[1] = code , argv[2] = /opt/protostar/bin/stack6
[3]-3
공격코드 작성
ret(4byte) | dummy(16byte) | buffer(64byte) | dummy(12byte) | SFP(4byte) | RET(4byte) | 4byte | &code |
|
| A*64 | A*12 | A*4 | &system | &exit() | /bin/sh |
80byte만큼 오버플로우 시킨뒤에 system함수의 주소와 exit()함수의 주소 그리고 인자로 /bin/sh를 입력하면 됩니다
쉘이 떨어지는 것을 확인 할 수 있습니다 유저명은 user인데 권한은 root입니다. 현재 시스템에서 system()함수의 권한이 아직 패치가 안되어있습니다
libc 2.x 버전부터는 system()함수의 권한이 낮아져서 해당 소유자의 권한을 얻어 올 수 없습니다
이 때 Channing RTL기법을 사용합니다 ( system()함수를 실행하기 전에 setreuid()함수를 실행시키면 됩니다 )
[Channing RTL]
ROP를 이용해 함수들을 연결시켜서 공격코드를 작성하는 것입니다
ROP ( Return Oriented Programming )
ROP는 취약한 프로그램 내부에 있는 기계어 코드 가젯을 이용하여 BOF공격시 특정명령을 실행하는 방법
보통 가젯은 함수 끝에 기술되어 있는 ret명령어를 포함한 상위 몇가지 명령어들의 집합이다
" objdump "명령어를 통해서 필요한 가젯을 찾아 낼 수 있습니다 ㅡ 그림7
[ 그림7 ]
우리가 사용할 가젯은 PPR가젯입니다 ( Pop-Pop-Ret )
해당 가젯을 이용해 setreuid()함수의 인자 0x00000000 두개를 Pop하고 system()함수를 리턴시키면 됩니다
buffer변수 이전에 위치해있는 ret변수와 dummy는 생략했고, 메모리구조를 다음과 구성시키면 됩니다
buffer(64) |
dummy(12) |
SFP(4) |
RET |
&ppr |
인자 |
인자 |
&system |
&exit |
인자 |
A*64 |
A*12 |
A*4 |
&setreuid |
|
0 |
0 |
|
|
&code |
[ 그림8 ]
&setreuid() : 0xb7f5b700
&ppr : 08048452
인자값 2개 : 0x00000000 , 0x00000000
&system() : 0xb7ecffb0
&exit() : 0xbfffffbe
&code : 0xbfffffbe
setreuid(0,0)함수가 실행된 후 쉘 코드가 실행되어서 root의 권한으로 쉘이 실행되었습니다 !
'SystemHacking > Protostar' 카테고리의 다른 글
Protostar Format0 [ FSB ] (0) | 2017.06.13 |
---|---|
Protostar Stack7 [ROP] (0) | 2017.06.12 |
Protostar Stack5 [RTL] (0) | 2017.06.11 |
Protostar Stack4 [gdb] (0) | 2017.06.11 |
Protostar Stack3 [objdump] (0) | 2017.06.11 |