profile image

L o a d i n g . . .

article thumbnail image
Published 2021. 5. 8. 18:19

1. 문제

보호기법 확인

canary, nx 가 켜져있다.

 

바이너리 실행

메뉴 화면이 나오고, 1~4번까지 선택지가 주어진다.

각 선택지에 따라 다른 함수들이 실행된다.

 

main 함수

ida 로 까본모습이다.

v3에 저장된 값에 따라 각 함수들이 실행된다.

 

 

add_note() 함수

노트를 추가하는 add_note() 함수이다.

먼저 notelist 배열 값이 비어있는지 확인한다. notelist 란 전역에 선언된 배열로써 최대 5개의 노트까지 추가할 수 있다.

 

add_note() 에서는 총 두 번 malloc()이 호출된다.

- print_note_content 라는 함수 포인터 저장을 위해

- 실제 데이터를 저장하기 위해

 

0x10 씩 할당된 모습이다.

0x804c008 : 함수 포인터가 저장되어 있다.

0x804c018 : 입력한 데이터가 저장되어 있다.

 

 

del_note() 함수

노트를 삭제하는 del_note() 함수이다.

add_note() 를 하면 notelist 의 배열에 첫번째 인덱스부터 값이 차례로 채워진다.

그래서 del_note() 에서는 먼저 어떤 인덱스를 지울건지 묻고 두 번 free 를 해준다.

1. 실제 데이터 부분 chunk 를 해제

2. 함수 포인터 부분 chunk 를 해제

 

 

print_note() 함수

print_note_content() 함수 포인터를 실행해서 실제 데이터를 출력한다.

 

 

magic() 함수

flag 파일을 실행하는 magic() 함수가 존재한다.

-> magic() 함수를 실행하는 것이 최종 목표일 것이다.

-> uaf 를 이용해서 print_note_content() 함수 포인터를 magic() 함수 주소로 변경하면 될 것같다.

 

 

 

2. 문제 해결 과정

재할당한 후 데이터 영역이 그 전에 함수 포인터 영역이여야한다. (그래야지 magic() 함수 주소로 수정해서 다시 실행할 수 있으니까)

-> 그런데 한번만 할당하면 그것이 성립하지 않아서, 다음과 같이 총 두번 할당하고 모두 해제한 뒤 다시 할당하면 실제 데이터 chunk가 첫번째 인덱스의 함수 포인터 chunk 부분을 받게 된다. 

 

함수 포인터 할당 (8)

실제 데이터 할당(size)

 

함수 포인터2 할당(8)

실제 데이터2 할당(size)

 

모두 해제 후 다시 할당

 

함수 포인터 할당(8)

실제 데이터 할당(8)

 

 

그런 다음 할당받은 데이터 영역에 magic() 함수 주소를 overwrite 한다.

그리고 다시 첫번째 인덱스로 print_note() 함수를 실행하면, overwrite 된 magic() 함수가 실행될 것이다.

 

 

 

3. 익스플로잇

 

익스플로잇 코드

 

 

플래그 획득!

'Wargame > HackCTF' 카테고리의 다른 글

[HackCTF] Unexploitable #2  (0) 2021.05.23
[HackCTF] Unexploitable #1  (0) 2021.05.23
[HackCTF] Beginner_Heap  (0) 2021.05.08
[HackCTF] Look at me (sysrop)  (0) 2021.04.23
[HackCTF] SysROP  (0) 2021.04.23
복사했습니다!