이제 Orc를 잡으러 갑시다!

 

이번 코드에는 처음 보는게 좀 있네요.

extern char **environ;

: 환경변수를 배열 형태로 불러옵니다. 그냥 이렇게만 알고 있으면 됩니다.

void * memset ( void * ptr, int value, size_t num );

: ptr 주소부터 num만큼을 value로 바꿉니다.

 


 

이제 코드 설명을 하도록 하죠

#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);
	}

	// egghunter 
	for(i=0; environ[i]; i++) //환경변수의 값을 모두 0으로 바꿔줍니다.
		memset(environ[i], 0, strlen(environ[i]));

	if(argv[1][47] != '\xbf') //ret부분의 마지막이 \xbf로 이루어지지 않으면 출력됩니다.
	{
		printf("stack is still your friend.\n");
		exit(0);
	}

	strcpy(buffer, argv[1]); 
	printf("%s\n", buffer);
}

 이렇게 설명을 해 볼 수 있겠네요.

환경변수의 (주소)값을 모두 0으로 바꿔주는 코드가 있기 때문에 환경변수를 사용할 수 없습니다.

또한 ret 부분의 마지막 주소가 \xbf로 이루어져야 버퍼 오버플로우가 발생할 수 있습니다

(ret부분인 이유는 더미가 없다는 가정 하에, buffer[40] + sfp[4] + ret[4]이기 때문입니다. 47번째는 ret부분이죠.)

 

이제 새로 컴파일을 하고 gdb를 실행해보겠습니다.

 

하고.. 이제 더미가 없는지 파악해보면

길어서 다 표현할 수가 없네요.

이렇게 나오는데 sub부분이 44만큼이 되어있다는 것을 알 수 있습니다.

분명 40만큼 선언했는데 왜 44지? 라는 생각을 할 수도 있는데요. 그 이유는 int형 변수도 선언했기 때문입니다.

그러니까 buffer[40] + int형[4] = 44바이트인거죠.

아무튼 더미는 없다는게 확인되었습니다.

 

그러면 우리에게 주어진 것은 44바이트의 공간과 4바이트의 ret주소까지입니다.

 

쉘 코드를 44바이트 공간에 넣어도 되지만 저는 nop가 많이 있는게 나은거 같아서 ret주소 뒤에 nop를 넉넉하게 넣고 쉘 코드를 넣도록 하겠습니다.

한번 실험삼아 넣어봤습니다.

\xc4\xfa\xff\xbf

이곳을 ret에 덮어씌어서 BOF를 해보겠습니다.

이렇게! 쉽게 풀 수 있습니다.

앞에 문제를 풀 줄 알면 당연히 풀 수 있는 문제였습니다.

*bash2 꼭 쓰세요... 안쓰면 망합니다 ㅠㅜ

*bash2 써도 안되는 경우가 있더라고요 이건 좀 운빨인거 같습니다...

 

포스팅을 마치기 전에 하나 설명할게 있어서 설명하고 가겠습니다.

0xXXXXXXXX과 같은 주소는 사용 용도에 따라서 약간씩 다른 주소를 가집니다.

0x80XXXXXX : 코드 영역으로 사용
0x40XXXXXX : 라이브러리 영역으로 사용
0xbfXXXXXX : 스택 영역으로 사용

보통 이렇게 나뉜다고 합니다.

0xbfXXXXXX는 스택 영역에만 작성하라는 의미였던 것이죠.

 

정말로 여기까지! 포스팅하겠습니다.

+ Recent posts