본문 바로가기

System Hacking/CTF

Codegate 2015 - Bookstore


메모리 보호기법이 있는대로 다 걸려있다. 이런 문제는 처음이라 당황스러웠는데

eip를 컨트롤하기 위해 주소값을 알아내야 하고, 이를 위해

메모리릭이 필요한 점 외에 다른 부분은 크게 신경쓰지 않고 풀었다.


책 정보에대한 구조체.

특이한점은 alloca함수에 의해 스택에 메모리가 할당된다는 점과 함수포인터를 2개 가지고 있다는 점.

전체적인 흐름을 보면 구조체가 스택을 통해서 복붙하는 방식으로 진행된다.

아래 함수를 보면..


이 부분을 통해 스택에 스프레이식으로 임의의 값을 뿌릴 수 있는데, 특정 조건에 따라 eip컨트롤이 가능하다.


과정이 살짝 복잡한데 UAF 유형 문제와 비슷하게 생각하면 쉽다. 변수 free_ship에 대한 세팅 (위 그림에서 v14변수)이 0일경우

구조체 내부에 존재하는 함수포인터를 초기화하지 않고 진행한다.

이후 memcpy를 통해 구조체가 통째로 복사되면, 스택에 존재하던 메모리가 함수포인터 위치에 존재한채로

 그대로 복사되어져 함수 포인터를 조작할 수 있다. -> 스프레이식으로 뿌려둔 메모리값을 이용함.


그리고 해당 구조체를 출력하는 함수를 진행하는 도중에 함수포인터(변수 a12)가 실행된다 ( free-ship이 1로 세팅되어 있을경우)

이때 인자로 넘어가는 값은 구조체의 book_name값이다(변수 a3)

flag를 읽어오기위해 사용한 open_func함수


익스플로잇 과정 설명은 생략하고 간단하게 흐름만 적자면


구조체의 생김새를 보면 중간에 bookname-price-stock-함수포인터1 이런 형식으로 되어있다.

bookname을 20바이트 가득채우고, price와 stock을 모두 0x11111111로 세팅하여

bookname부터 함수포인터까지 NULL바이트 없이 쭉 이어지게 했다. 그리고 bookname을 출력하게 해주어

함수포인터의 주소(binary의 주소값)을 메모리 릭해서 바이너리 영역의 주소를 구했다.


다른 주소에는 접근할수있는 부분이 보이지않았기 때문에, 바이너리영역에 존재하는 부분만 접근이 가능함..

프로그램의 초반에 사용된 open_Func(인자로 전달된 파일을 open하여 read, 출력해준다.)을 이용하면 될것같아서

메모리릭한 주소값에다가 오프셋을 계산하여 open_Func의 주소값을 얻어낸후 스택에 스프레이식으로 뿌려 함수포인터에 세팅하였다.


그리고 인자로 전달될값 rdi 레지스터(구조체의 bookname이 들어감)를 &("/home/bookstore/key")로 세팅해주고 함수포인터 실행




...생략...



'System Hacking > CTF' 카테고리의 다른 글

Plaid_CTF 2014 - ezhp  (0) 2015.05.15
CodeGate 2015 Quals - Sokoban  (1) 2015.05.15
B-Sides Vancouver 2015 - Ownable 400  (0) 2015.03.18
Codegate 2015 푼거 + 풀다만거 정리  (0) 2015.03.16
CSAW 2014 pwn_500 xorcise  (0) 2015.01.07