tmxklab

[FTZ] Level18 풀이 본문

War Game/FTZ

[FTZ] Level18 풀이

tmxk4221 2020. 1. 12. 21:21

1. 문제확인

 

1) 사용자 및 패스워드 : level18 / why did you do it

 

2) 파일확인

 

3) hint 코드 설명

#include <stdio.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
void shellout(void);
int main()
{
	char string[100]; // 사용자의 입력받은 문자열을 저장하는 배열
	int check;
	int x=0; // 사용자의 입력을 1byte씩 저장하는 변수
	int count=0; // string배열에서 인덱스 역할
	fd_set fds; // 파일 디스크립터(fd)를 저장하는 구조체 변수 선언(배열 형태)
	printf("Enter your command: ");
	fflush(stdout); // 출력 버퍼를 비움
	while(1)
	{
		// 밑에 switch문의 default문이 실행되면 count값 증가
		if(count >= 100)
			printf("what are you tyring to do?\n");
		// check가 0xdeadbeef면 shellout()호출(공격해야하는 부분)
		if(check == 0xdeadbeef)
			shellout();
		else // check가 0xdeadbeef가 아닌 경우 실행
		{
			FD_ZERO(&fds); // fds구조체 변수 초기화
			// STDIN_FILENO의 값은 0 표준 입력 파일 디스크립터 값
			// STDIN_FILENO의 값이 0이므로 fds배열의 0번째에 1로 세팅
			FD_SET(STDIN_FILENO, &fds); 
		
			// select함수는 fds에 할당된 fd의 이벤트가 발생하면 어떤 fd이벤트가 발생했는지 알려줌
			// return값은 -1: 오류발생, 0: 타임아웃, 0보다 큰 수: 변화 발생 파일 디스크립터 수
			if(select(FD_SETSIZE, &fds, NULL, NULL, NULL) >= 1)
			{
				// fileno함수는 stream과 현재 연관된 파일 핸들을 판별
				// stdin은 0이므로 fileno(stdin)의 리턴 값은 0을 리턴함
				// fds구조체 변수에 0으로 세팅되면 0이 아닌 값 return 
				if(FD_ISSET(fileno(stdin), &fds))
				{
					// 표준 입력으로 1byte만큼 x에 저장(사용자 입력 가능)
					read(fileno(stdin), &x, 1);
					// x의 값에 따라 switch문 실행
					switch(x)
					{
						case '\r':
						case '\n':
							printf("\a");
							break;
						case 0x08:
							count--;
							printf("\b \b");
							break;
						default:
							string[count] = x;
							count++;
							break;
					}
				}
			}
		}
	}
}
// level19의 쉘 권한을 얻는 함수
void shellout(void)
{
	setreuid(3099, 3099); // level19의 ruid와 euid값으로 변경
	// execl()는 다른 프로그램을 실행하고 자신은 종료하는 함수
	// 첫 번째 인자는 path, 두 번째 인자는 실행 파일명
	// 즉, path에 지정한 경로명의 파일을 실행하며 argv0~argvn을 인자로 전달 
	execl("/bin/sh", "sh", NULL); 
}
  • select()와 관련된 매크로 및 함수들은 여기서 다루지 않음(소켓 프로그래밍 관련)
  • while문이 무한으로 돌면서 1byte씩 사용자의 입력을 받아 x의 값에 따라 switch문 실행
  • 또한, while문 처음부분에 2개의 if문이 실행되면서 계속 check와 count변수의 값 검사

2. 접근방법

 

1) attackme 디버깅

  • <main+12, 19> : 처음 hint 코드에서 0으로 초기화 시키는 값은 x와 count변수, 따라서 x먼저 0으로 초기화 시키므로 [ebp-108]에 x변수가 존재하고 [ebp-112]에 count변수 존재
  • <main+72, 76> : [ebp-112]와 0x63(99)와 비교하므로 [ebp-112]는 count변수 재확인
  • <main+91> : [ebp-104]와 0xdeadbeaf를 비교하므로 [ebp-104]에 check변수 존재

  • <main+417, 420> : [ebp-108]위치의 값을 edi에 그리고 다시 [ebp-252]위치에 넣음, 그리고 밑에 case문에서 지정된 값과 비교하는 것을 통해 switch문의 시작임을 알 수 있음
  • <main+499 ~ 538> : <main+499>에서 [ebp-100]의 주소 값을 eax로 이동, [ebp-100]에 string의 주소 값 존재하며 밑에 행들을 보면 switch문의 default부분임을 알 수 있음
  • <main+532> : x의 값이 들어있는 al을 count의 주소 값이 들어있는 edx와 string의 주소 값이 들어있는 ecx를 더한 [edx+ecx]에 넣는 것을 알 수 있음 → string[count] = x;

 

2) 스택구조

 

3) 공격방법 생각

  • 현재 사용자의 입력 값을 받을 수 있는 부분은 1byte의 x값임
  • check부분을 조작해야 하지만 스택구조를 보면 check가 string보다 더 낮은 주소에 위치
  • 생각해 볼 수 있는 방법은 [ebp-100]에 위치한 string변수를 [ebp-104]로 옮겨야 함
  • 따라서, string의 주소 값을 조작할 수 있는 부분은 switch문의 default 즉, stirng[count]=x;
  • 초기 count값은 0이므로 string값을 읽어들일 때 [ebp-100]부터 읽게 됨, 하지만 string의 인덱스가 음수인 -값을 가질 때 어디서부터 읽는지 시도해봐야함

 

4) 0x08을 넣어 string 인덱스 값 조작

input값에 따른 변화

① 0x08의 개수 1~4까지 넣은 경우

  • 0x08의 개수가 증가될수록 string의 인덱스인 count값이 처음 초기 값 0x00000000에서 0xffffffff, 0xfffffffe, 0xfffffffd, 0xfffffffc로 변함
  • count의 값과 string의 주소 값을 더한 [edx+ecx]가 결국 x가 들어가는 위치이며 0x08의 개수가 증가될수록 [ebp-100]부터 [ebp-104]로 낮은주소로 향하는 것을 알 수 있음

② 0x08 4개와 쓰레기 값(0x99)의 개수 1~4까지 넣은 경우

  • 0x08의 개수가 4개인 경우 check의 주소 값인 [ebp-104]를 참조하는 것을 알 수 있으므로 쓰레기 값을 증가 시켜 [ebp-104]의 위치에 어떤 값이 채워지는지 확인

 

※ 참고
gdb 실행 중 입력 값 넣는 방법
1) (gdb) r <<< $(python -c 'print "A"*3')
2) (gdb) r <<< "AAAAAAAAA"
3) (gdb) r <<< python -c 'print "A"*3'

 

5) 결론

  • 0x08의 개수가 4개인 경우 string의 변수가 check의 주소 값인 [ebp-104]부터 참조하는 것을 알 수 있음
  • 또한, 4개의 0x08을 넣고 추가적으로 쓰레기 값을 넣었을 때 check의 값이 쓰레기 값들로 채워지는 것을 알 수 있음
  • 따라서, 4개의 0x08과 0xdeadbeef를 채우면 check의 값이 deadbeef로 채울 수 있음

3. 풀이

 

1) 공격 코드 작성 및 bof 수행

'War Game > FTZ' 카테고리의 다른 글

[FTZ] Level19 풀이  (0) 2020.01.12
[FTZ] Level17 풀이  (0) 2020.01.12
[FTZ] Level16 풀이  (0) 2020.01.12
[FTZ] Level15 풀이  (0) 2020.01.12
[FTZ] Level14 풀이  (0) 2020.01.12
Comments