FTZ level16 포인터 변조 1

2017. 5. 23. 14:39SystemHacking/FTZ

 

 

 

level16에서 새롭게 등장한 개념은  " 함수포인터 " 입니다



#include<stdio.h>


void function(){

printf("Hello\n");

}


int main(){
    

void (*call)() ;            // 매개변수와 리턴값이 없는 함수 포인터 선언

call = function ;         // function 함수의 메모리주소를 call 함수포인터에 저장 

call();                       // 함수포인터로 function 함수를 호출한다

 //  => "hello" 출력   


// 또는 한 번에 선언과 초기화를 같이 시켜주는 방법도 가능하다

// void (*call)() = function;

// call();

}




문제를 보면서 해당 개념을 다시 익혀보도록 하겠습니다

힌트파일의 소스를 복사해서 임시로 파일을 생성합니다 ( attackme파일은 break + run 권한이 제한되어있음 )


< 그림 16.1 >




힌트 파일 소스 해석

main(){

int crap;

voi (*call)() = printit();       // 함수포인터 call에 printit함수의 메모리 주소를 저장한다     

char buf[20];                       

fgets(buf,45,stdin);            // 45byte 만큼의 문자열을 입력받고 buf에 저장한다

call();                             // 함수포인터를 이용하여 printit함수를 호출한다

}




해당 소스를 gdb분석해보겠습니다


< 그림 16.2 >


[1] Procedure Prelude

$0x38 = 56byte만큼의 공간을 지역변수에게 할당한다

buf 20byte + crap 4byte + call 4byte = 28byte  => 28byte크기의 dummy가 존재한다


[2] fgets( buf , 48 , stdin )

<main+34>:    lea    0xffffffc8(%ebp), %eax 

"0xffffffc8" 주소를 eax레지스터로 복사한다 그리고 해당 주소는 fgets의 첫번째 인자로 들어간다

=> buf의 주소는 "0xffffffc8" 임을 알 수 있다


[3] call()

현재 함수포인터 call에는 printit함수의 주소가 있으므로 printit함수가 호출된다

<main+46>:    mov    0xfffffff0(%ebp), %eax

"0xfffffff0" 주소의 값을 eax레지스터로 복사한다 그리고 해당 값을 * 연산자로 실행한다

=> 함수포인터 call 의 주소가 "0xfffffff0" 임을 알 수 있고 *call => call() 이 실행되어짐을 예상할 수 있다


gdb분석을 통해서 buf와 call 변수 사이의 거리를 알아낼 수 있다

0xfffffff0 - 0xffffffc8 = 40byte = buf ( 20byte ) + dummy ( 20byte )


총 스택구조의 구조를 그림으로 나타내면 다음과 같습니다



< 그림 16.3 >


call 함수가 실행되는 부분에서 Break를 걸어주고 프로세스를 실행시킨 다음 메모리를 분석해보도록 하겠습니다

(gdb) x/20xw $esp 명령어


< 그림 16.4 >


AAAA문자가 위치해있는 "0xbfffe3a0" 지점이 buf의 시작주소임을 알 수있다

buf의 시작주소에 40byte를 더해주면 check변수의 주소가 나온다 ( "0xbfffe3c8" )

check주소의 값은 현재  printit함수의 시작주소임을 알 수 있습니다. 해당 check주소에 있는 값을 shell함수의 주소로 바꾸면 공격은 성공입니다


gdb를 이용해서 shell함수의 주소를 구하도록 하겠습니다


< 그림 16.5 >


shell함수를 디스어셈블 했을 때 처음으로 시작하는 주소가 바로 shell함수의 주소입니다 "0x080483ec"

이제 해당 주소값을 check메모리 공간에 덮어 씌여주면 성공입니다

위에서 분석한 파일은 임시로 생성한 파일이므로 attackme파일을 gdb로 디버깅하여 해당주소값을 알아낸 후 공격해보겠습니다


< 그림 16.6 >


attackme 실행파일 내의 shell함수의 주소는 " 0x080484d0 " 입니다

실행코드를 만들어 해당파일을 공격해보겠습니다

40byte만큼 버퍼 오버 플로우 시킨 뒤 check메모리 공간에 해당 주소값을 덮어 씌우겟습니다


< 그림 16.7 >




level17쉘이 떨어지는 것을 확인 할 수 있습니다. level17로 넘어가도록 하겠습니다



'SystemHacking > FTZ' 카테고리의 다른 글

FTZ level18 포인터 특성 활용  (0) 2017.05.28
FTZ level17 포인터 변조 2  (0) 2017.05.28
FTZ level15 분기 루틴 2  (0) 2017.05.23
FTZ level14 분기루틴 1  (0) 2017.05.23
FTZ level13 스택 가드 ( Stack Guard )  (0) 2017.05.23