CTF/포너블

[TGHACK] Boofy - 포너블 / 버퍼오버플로우

SecurityMan 2022. 4. 15. 15:30

 

이번 문제는 대회 끝나고 풀어서 제대로 된 캡쳐를 하지 못했다.

 

간단한 포너블 문제이다.

 

반응형

 

boofy 라는 바이너리 파일과 해당 파일의 소스코드가 주어진다.

 

boofy는 ELF파일로 리눅스에서 실행가능한 프로그램이다.

 

리눅스의 EXE파일이라고 생각하면 된다.

 

프로그램을 먼저 실행시켜 보자.

 

 

프로그램을 실행시키면

 

Please enter the password? 라고하면서 비밀번호를 물어본다.

 

abcd 라고 입력해봤는데, 당연히 올바른 비밀번호가 아니기 때문에

 

Sorry, but that's not the right password... 라는 문구가 출력된다.

 

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>

void get_flag()
{
	printf("TG20{the real flag is on the server}\n");
}

void try_password()
{
	char password[20] = { 0 };
	int correct = 0;	
	printf("Please enter the password?\n");
	gets(password);
	if (correct == 1) {
		get_flag();
	} else {
		printf("Sorry, but that's not the right password...\n");
	}
	
}

int main()
{
	setvbuf(stdout, NULL, _IONBF, 0);
	try_password();
	return 0;
}

 

소스코드를 살펴보자.

 

get_flag(), try_password(), main() 세가지 함수로 구성되어 있다.

 

main() 함수가 가장 먼저 실행되면서 try_password() 함수를 호출한다.

 

try_password() 함수는 char형의 길이가 20인 password 변수와 

 

int형의 correct 변수를 선언하고 

 

gets 함수로 사용자의 비밀번호 입력을 받는다.

 

이때 만약에 correct의 값이 1이라면 get_flag() 함수를 호출해서 플래그를 출력해준다.

 

사용자가 비밀번호를 입력하면 password 변수에 저장되기 때문에

 

correct 변수의 값은 일반적인 방법으로 바꿀 수 없다.

 

password 변수에 값을 저장할 때 gets 함수에서 입력값에 대한 길이를 검증하지 않고 있는걸 볼 수 있다.

 

password 변수의 크기는 20이지만 입력값의 길이가 20보다 커도 저장이 된다는 것이다.

 

그렇게 되면 password 뒤에 선언된 correct 변수의 영역까지 침범하여 

 

correct 변수의 값을 변경시킬 수 있다.

 

python -c "print('\x01'*21)" | ./boofy

 

터미널에서 이렇게 명령어를 실행시키면 된다.

 

python -c 옵션을 주면 커맨드라인에서 실행이 가능하다.

 

print로 \x01을 21개를 출력하는데

 

이는 correct 변수의 값을 1로 변경시키기 위함이다. 

 

참고로 숫자 '1' 을 그대로 넣으면 안된다.

 

왜냐면 1은 사람이 볼때는 1이지만 컴퓨터 입장에서는 \x31 이라는 값을 가지고 있기 때문이다.

 

21개를 출력하는 이유는 password 변수의 크기가 20이고, 

 

password 변수 바로 뒤에 correct 변수를 선언했기 때문이다.

 

password 변수를 가득 채우고, 다음칸에 1 이라는 값을 넣기 위해서이다.

 

그런다음 출력값을 | 파이프라인을 통해서 ./boofy 바이너리 파일에 입력으로 넣어준다.

 

 

참고로 이렇게 해도 풀린다.

 

a라는 값을 20개 넣어서 password 변수를 가득 채우고,

 

그다음 \x01 이라는 값을 추가해서 correct 변수의 값을 변경시키는 것이다.

반응형