이번 문제는 소스코드가 주어져서 쉽게 해결할 수 있었다.
소스코드가 없었다면, 이 취약점을 찾기 쉽지 않았을 것 같다.

소스코드의 select_menu() 함수가 문제였다.


(문제 코드)



(문제코드)


문제가 되는 함수의 부분이 위의 빨간 부분이다.
select_menu() 함수는 안에서 recursive하게 자기 자신을 호출한다.

화면에 다시 메뉴를 출력하게 할 때, while 문이나 다른 코드로 처리를 하는게 보통인데
참 특이하게 자기자신을 다시 호출하므로써 메뉴를 다시 출력하였다.

재귀적 코드는 깔끔해 보이는 장점이 있지만,
재귀가 많이 반복될 수록 스택 메모리를 많이 잡아먹는 현상이 일어난다.

그래도 함수 마지막에 호출하게하여 Tail Call(Tail Recursion)을 유도했지만,
실제로 gdb로 분석해본 결과 스택메모리를 낭비하며 동작하고 있었다.

그렇다면 스택을 쭉 낮출 수 있다는 것이다.
그리고 랜덤하게 주소를 받는데 그 주소가 스택 주소가 아니란 법도 없다.
더군다나, 여기서 만든 메모리할당 함수를 보면 실행권한까지 떡하니 줘버린다.
쉘코드를 써달라고 애원하는 듯 하다.

내가 exploit을 짜기 전 계획이다.
1. 스택영역의 주소를 얻는다.(계속 반복하여서)
2. 스택을 차곡차곡 쌓아서 주소를 팍 낮춘다. 우리가 구한 스택영역의 주소보다 낮게.
3. 그 다음 메모리할당을 한번 더 받아서 그 안에 쉘코드를 넣어둔다.(이 때 받은 쉘코드의 주소를 기억)
4. 아까 받은 스택영역의 주소에다가 쉘코드주소를 쫙 넣어둔다. 4096바이트만큼 쓸수 있으므로 1024개의 주소로 덮어쓸 수 있다.
5. exit 을 실행하면 스택이 recursive하게 리턴되면서 그 중간에 덮어쓰여진 쉘코드 주소로 뛰게 되고 쉘코드 실행!

exploit을 짜면서 바뀐 계획인데

2번의 과정은 없어도 되었다. 스택영역의 주소를 얻기위해 반복하는 과정에서 자연스레 엄청 낮아졌다.



(스택 영역 주소 구하기)


반복은 받은 주소가 현재 ebp 주소보다 커진 경우까지 반복한다.

그렇게 되면 ret,leave 하면서 쭉 내려갈 테니까!



(clear 함수)


반복하다보면 255개의 배열을 다 쓴다..
그런 경우 255개를 다시 다 지워주는 함수를 만들었다.
(계속 반복 할 수 있도록)

쉘코드 올리기


(쉘코드 올리기)


쉘코드를 올리는 부분이다.



(스택 영역 주소 덮기)


그 후 쉘코드 주소를 스택영역 주소에 덮어쓴다.

그리고 

exploit!



(스택 주소 받기)


엄청난 양을 받는다.

옆에 Stacking 옆의 값은 현재 ebp 값이다.


(clear 중)


clear 도 몇번 실행되었다.



(exploit)


끝내 만족하는 스택영역 주소를 받고
ret 주소를 덮어썼다.

여기서 5를 눌러 exit를 실행하면 최종적으로 shell을 획득할 수 있다.


(쉘 획득)


문제 풀이 끝!

'WarGame > 500 Project' 카테고리의 다른 글

(66/500) pwnable.kr - rsa_calculator  (1) 2018.03.10
(65/500) pwnable.kr - echo2  (0) 2018.03.08
(64/500) backdoor - Enter the matrix  (0) 2017.10.31
(63/500) pwnable.kr - syscall  (2) 2017.10.22
(62/500) NOE.systems - BURYBURY  (0) 2017.10.01

+ Recent posts