시스템/시스템 보안

RET값 변조

비니화이팅 2018. 1. 27. 15:12

* 문제)

-> 다음 코드에서 RET 값을 적절히 변경하여 첫 번째 printf함수가 아닌 다음 printf함수가 수행되도록 수정해본다.


* cdecl 함수호출 규약에서의 풀이

- 일단 아래와 같이 코드를 바꿔주면 문제를 해결할 수 있다.


- 우선 main함수에서 0040101C가 Func함수, 00401029가 첫 번째 printf함수, 00401036이 두 번째 printf함수라는 것을 확인한다.

- 첫 번째 함수를 건너 뛰고 두 번째 함수를 실행시켜야 하기 때문에 RET값을 첫 번째 printf함수를 실행하고 난 뒤의 주소로 바꾸어 줘야 한다.


- 포인터 연산으로 RET값을 바꾸기 전에는 아래와 같이 RET값이 정상적으로 들어가져 있다.


- 포인터 연산을 한 뒤에는 두 번째 함수를 실행하기 바로 전의 주소가 들어간다.


- *(&p+2)+=4; <-은 p변수가 위치한 주소에서 2만큼 더한 주소, 즉 RET값에 4를 더하라는 뜻이다.

4를 더하는 이유는 바꿀 주소가 RET와 16(16진수)만큼 떨어져 있기 때문이다. (int형 포인터 연산이기 때문에 16이 아니라 4를 더해준다.)


* stdcall 함수 호출 규약에서의 풀이


- 우선 main함수에서 0040101E가 Func함수, 00401028가 첫 번째 printf함수, 00401035이 두 번째 printf함수라는 것을 확인한다.

- 첫 번째 함수를 건너 뛰고 두 번째 함수를 실행시켜야 하기 때문에 RET값을 첫 번째 printf함수를 실행하고 난 뒤의 주소로 바꾸어 줘야 한다.


- 포인터 연산으로 RET값을 바꾸기 전에는 아래와 같이 RET값이 정상적으로 들어가져 있다.


- 포인터 연산을 한 뒤에는 두 번째 함수를 실행하기 바로 전의 주소가 들어간다.

- *(&p+2)+=13; <-은 p변수가 위치한 주소에서 2만큼 더한 주소, 즉 RET값에 13를 더하라는 뜻이다.

13를 더하는 이유는 바꿀 주소가 RET와 D(16진수)만큼 떨어져 있기 때문이다.