본문 바로가기

보안지식/주통기반

[주통기반] 공격 시나리오 정리(버퍼 오버플로우, 포맷 스트링)

안녕하세요 이번에는 실무에서 모의해킹을 할 때 종종 쓰이고 있는 주통기반, 금취분평 중 주통기반에 있는 취약점들을

살펴보려고 합니다!

 

실무에 나가면 저희가 대뜸 해킹을 해서 "어디어디 취약점이 있어요."

라고 하기보단 취약점의 기준점을 정리해 준 게 주통기반과 금취분평입니다.

 

실제로 실무에 나가면 저희가 배운 웹 해킹 기술을 이용해 저 보고서 안에 있는 취약점들을 위주로 해킹을 합니다.

막상 보면 웹에 있는 모든 취약점이 정리되어 있어요! 그래서 오히려 도움이 될 겁니다.

 

주통기반 취약점들

 

정확힌 보안 라이센스을 따는데 필요한 절차들이 정리되어 있는 보고서입니다.

그 안에 웹 취약점 종류별로 있는 거고요.

.

.

.

.

.

.

.

.

 

우선 주통기반 먼저 보겠습니다.

저는 공격 시나리오 즉 이 취약점이 얼마나 심각한지 알아보는 겁니다.

 

대뜸 "취약점 찾았어요" 말하면 개발자 분들이 "이 취약점이 무슨 피해가 있어요?"라고

질문을 하면 자신 있게 "이러이러한 공격으로 큰일 날 수 있어요!" 말하기 위해 공부하는 겁니다.

 

"기준이 그래요." 이 말을 안 하기 위해 연구하는 거죠! 개발자분들은 저희가 말한 취약점을 고치는데만 밤을 새우는데

그저 "기준이 그래요" 이러면 납득이 안 되는뿐더러 화만 돋우죠.

 

시작하겠습니다.

 

우선 이번 포스팅은 1번, 2번을 보겠습니다.

솔직히.. 저희가 실무에서 웹 프로그래밍을 C언어로 안 하는 이상 안 보이는 취약점입니다.

그만큼 99.99% 확률로 안 나오긴 하지만 알아는 둬야죠!

 

 

 

 

 

--버퍼 오버 플로우 공격

 

버퍼란? C언어에서 문자열을 담을 수 있는 크기를 설정한 경우가 있죠?

 

char a[10]; 혹은 int i[100]; 이렇게요.

 

이렇게 선언을 하면 a의 버퍼 크기는 10 i의 버퍼 크기는 100이 됩니다.

 

 

이때 버퍼 크기 보다 더 크게 선언을 하면 어떻게 될까요?

 

나무위키에서 퍼온 사진 입니다.

 

이렇게 뒤에 버퍼 크기 뒤에 있는 자리을 덮어 씌우게 됩니다.

 

버퍼를 설정하면 그 버퍼는 프로그램 내에 어느 위치에 선언이 되어 있을 겁니다.

 

만약 a의 버퍼가 1~5이라는 위치에 선언되어 있다면 저렇게 오버 플로우 공격으로 뒤에 있는 6의 위치 7의 위치까지

자신이 원하는 값을 넣을 수 있는 겁니다.

 

그럼 이걸 어디에 적용시킬까!

 

바로 함수 리턴값입니다. 함수가 호출되는 위치 혹은 함수가 호출되고 난 뒤의 값의 위치를 찾는 겁니다.

그리고 이 버퍼 오버플로우로 위치값까지 덮어 씌운 다음 자신이 원하는 값을 넣는 거죠.

 

계속 a을 치면 언젠가 함수 리턴 주소까지 덮는 그림입니다.

 

 

배그로 따져 볼게요. 배그에 총 맞으면 50이라는 대미지가 리턴한다면 버퍼 오버 플로우로 데미지 함수의 리턴 값에

1을 넣습니다. 그럼 50이 아닌 1이라는 데미지가 나오게 되는 겁니다.

 

실제론 이렇게 안하고 간단하게 예시로 들었습니다.

 

덮어씌우기 공격이라 보시면 돼요.

 

실제 핵 프로그램 만들 때 이 공격을 이용한다고 합니다.

 

문제점은 프로그램은 오류가 없는 이상 그대로 실행을 한다는 문제입니다.

그래서 개발사들은 프로그램을 복잡하게 코딩해서 핵 프로그램을 막는 방법밖에 없는 거죠.

 

 

한 번 실습을 해볼게요.

비주얼 스튜디오에서는 기본적으로 이런 간단한 공격은 잡으니 리눅스에 실습하셔야 돼요!

 

간단하게 비밀번호를 맞춰야만 들어가지는 시스템이 있다고 가정을 하겠습니다.

 

#include <stdio.h>

int main() {
	char check = '0';
	char passwd[10];

	scanf("%s",passwd);

	if(*passwd == *"clear") {
		check = '1';
	}

	if(check == '1') {
		printf("success!");
	}
	else {
		printf("fail!");
	}
}

 

C언어입니다!

 

그리고 컴파일을 하고 실행을 해보겠습니다.

 

-fno-stack-protector 은 스택 보호하는 것을 해제하는 겁니다.

 

저희가 버퍼의 위치, 함수의 위치, 리턴 값 위치 말한 곳이 스택입니다. 그 스택을 보호하는 것을 해제하면

기본적인 버퍼 오버플로우 공격이 통하겠죠. 실습을 위해 하겠습니다.

 

실행하면

 

clear이 비밀번호 입니다.

 

clear 비밀번호 치면 이렇게 success가 나옵니다.

 

다른 값은 fail 나와야 정상이죠.

 

그럼 버퍼 오버 플로우 공격을 해보겠습니다. clear을 모르는 사람이 aaaaaaaaaa1

이렇게 passwd 버퍼 크기 10을 넘기고 1을 입력해 보는 겁니다.

 

passwd 변수 바로 뒤에 있던 if문의 리턴 값에 1을 덮어 씌워서 check에 1을 강제로 저장하게 한 거죠.

 

여기에 더 나아가서 간단하게 값을 변경하는 것뿐만 아니라 함수가 끝나고 복귀하는 주소가 적혀 있는 위치가 있습니다.

 

이 위치를 알아내어서 자신이 원하는 함수를 실행하는 주소로 변경하면?

시스템에게 명령어 내릴 수 있는 함수 주소로 변경을 하면?

 

시스템 장악을 할 수 있는 거죠. 또한 프로그램 흐름을 망쳐 놓을 수 있습니다.

 

그래서 C언어에서는 strcpy 사용 금지, scanf_s 사용하는 겁니다.

 

 

 

 

-- 포맷 스트링

 

http://wiki.hash.kr/index.php/%ED%8F%AC%EB%A7%B7%EC%8A%A4%ED%8A%B8%EB%A7%81_%EA%B3%B5%EA%B2%A9

참고한 위치입니다.

 

완전.. 진짜 완전.. 옛날 취약점입니다.(1999년 발견)

이 공격은 메모리의 위치값을 알아낼 수 있는 매우 강력한 공격이었습니다.

 

C언어에 %s, %d, %n 등등 이게 포맷 스트링인 것은 아실 겁니다!

 

옛날 개발자 분들은 C언어 코드를 할 때

 

str = "hello world";
printf("%s", str);

 

이렇게 안 하시고

 

str = "hello world";
printf(str);

 

printf에 str만 적어서 출력되게 했습니다. 왜냐하면 코드 수를 줄이기 위해서라고 해요.

 

이렇게 작성을 하다 보니 취약점이 발견하게 된 겁니다.

만약 str에 scanf 통해 값을 입력받는다고 가정을 합시다.

 

그럼 str 입력할 때 "%s" 라고 입력하면 어떻게 될까요?

 

그럼 printf("%s"); 라고 입력이 됩니다. 그럼 printf에 %s 는 뒤에 있는 특정 문자열을 출력하는 건데

보시다시피 아무것도 없잖아요? 그런데 %s는 문자열 출력을 하기 위해 주소가 담긴 스택에 접근을 하는 겁니다.

 

이를 이용해 내가 프로그램을 다운시키고 싶으면 "%s%s%s%s%s%s" 입력만 하면 한 %s 당 4바이트을 읽어서

총 24바이트을 거슬러 올라가다 보니 segmentation fault(잘못된 메모리 참조) 오류가 나와 다운이 됩니다.

 

%p%p%p%p%p%p 라고 입력을 하면 printf가 실행된 스택 주소도 알 수 있다고 합니다.

 

실습은 간단하게 해 볼게요.

 

#include <stdio.h>

int main() {
	char a[5];
	scanf("%s",a);
    
	printf("%s\n\n",a);

	printf(a);
}

 

입력해서 첫 줄에는 안전하게 코딩되어서 나온 a

 

그다음 줄엔 위험하게 코딩인 된 a을 나오게 했습니다.

 

다음에 컴파일을 하고 

 

gcc -o ccc ccc.c

 

그다음에 실행을 해보는데 저는 %p%p%p%p%p 입력을 해봤습니다.

 

 

맨 첫 줄은 입력을 한 것이고 그리고 다음 줄엔 잘 나오는 것을 알 수 있으나

위험하게 코딩한 것은 저렇게 주소 값이 나오는 것을 알 수 있습니다.

 

nil은 0 즉 null을 뜻해요.

 

그럼 %s%s%s%s%s%s 을 주면 프로그램이 종료된다는데 보겠습니다.

 

 

segfault 발생

 

이렇게 프로그램이 오류가 발생해 종료하게 할 수 있습니다.

 

 

오늘은 간단하게 1,2번을 봐보 았습니다. 이렇게 계속 쭉쭉 취약점을 공부하고 연구해서

공격 시나리오도 짜보겠습니다. 주통기반 하곡 난 뒤엔 금취분평도 할 예정입니다!