tmxklab

[FTZ] Level16 풀이 본문

War Game/FTZ

[FTZ] Level16 풀이

tmxk4221 2020. 1. 12. 21:21

1. 문제확인

 

1) 사용자 및 패스워드 : level16 / about to cause mass

 

2) 파일확인

 

3) hint 코드 설명

#include <stdio.h>

// level17 쉘 권한 획득할 수 있는 함수
void shell(){
	setreuid(3097, 3097);
	system("/bin/sh");
}

void printit(){
	printf("Hello there!\n");
}

main()
{ int crap;
	void (*call)()=printit; // 함수 포인터call변수가 printit함수의 주소를 가리킴
	char buf[20];
	fgets(buf, 48, stdin);
	call(); // printit함수 호출
}
  • shell()은 level17 쉘 권한을 획득할 수 있는 함수이며 printit()은 printf() 한 줄
  • 함수 포인터 call변수가 printit()를 호출하도록 되어있음
  • fgets()로 인해 buf(20bytes)배열의 크기보다 더 큰 입력 받을 수 있음 -> bof 취약점 존재

2. 접근방법

 

1) attackme 디버깅

  • mov DWORD PTR [ebp-16], 0x8048500 : 0x8048500 printit()의 시작 주소 값이므로 함수 포인터의 위치가 [ebp-16]임을 알 수 있음
  • <main+24>부터 보면 eax에 [ebp-56]의 주소 값을 넣고 push한 뒤 fgets함수를 호출함 → fgets함수의 첫 번째 인자는 buf이므로 buf의 위치는 [ebp-56]
  • <main+36>부터 보면 eax에 [ebp-16]의 값을 넣고 call에 의해 호출함(정상 흐름에는 printit함수가 호출됨)

  • shell() 시작 주소 값 : 0x080484d0
  • printit() 시작 주소 값 : 0x08048500

 

2) 스택구조

 

3) 결론

  • printit()대신에 shell()를 호출하기 위해 함수 포인터 call변수에 shell()의 시작 주소 값을 넣어야 함
  • 따라서, fgets()를 통해서 buf배열의 크기(20bytes)보다 더 큰 입력 값을 받을 수 있으므로 call변수의 위치를 찾아 shell()의 시작 주소 값을 채워 넣으면 됨
  • buf에 call변수 직전인 40bytes만큼 쓰레기 값을 채우고 다음에 오는 call 변수에 shell()의 시작 주소 값인 0x080484d0을 채워 넣으면됨

3. 풀이

 

1) 공격 코드 작성

buf[20bytes] + dummy[20bytes] + call[4bytes, shell() 시작 주소 값]

 

2) bof 수행

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

[FTZ] Level18 풀이  (0) 2020.01.12
[FTZ] Level17 풀이  (0) 2020.01.12
[FTZ] Level15 풀이  (0) 2020.01.12
[FTZ] Level14 풀이  (0) 2020.01.12
[FTZ] Level13 풀이  (0) 2020.01.12
Comments