Osori Development Studio

[동아리CTF] FastFood Write-up 본문

전공쪽/동아리 관련

[동아리CTF] FastFood Write-up

OSOR2 2020. 10. 2. 15:52

이번 가을 CTF용으로 만든 문제다.

 

 

개요 


일단은 기본적으로 보호기법은 PIE 빼고 다 걸어놨다. PIE는 디버깅 하는 사람들을 위한 배려이기도 하고, 가젯을 주기 위함이다. 사실 Relro는 Partial만 주려고 했는데, 이론상 언인텐디드가 나올 수도 있을 것 같아서 걸었다.  

맨날 풀때기같은 초록색만 덕지덕지 칠해진 것을 보다가 빨간색을 보니 기분이 좋다. 

seccomp whitelist 이다. mprotect이용해 orw 하는것을 유도. 

 

친절하게 바이너리에 힌트도 있다. calloc 으로 rop하는 것을 저 lazyhouse 문제에서 배웠기 때문이다. 

 

본 문제는 기본적으로는 calloc 의 취약점을 이용하여 푸는 문제이다. Calloc 의 내부 과정을 보면 

출차 : https://faraz.faith/2019-10-24-hitconctf-lazyhouse-balsn-exploit-analysis/

이런 과정이 있는데 [1]에서는 rbp에 rdi를 옮기고 [2]에서는 rbp*rsi 한 값을 rbp에 저장한다. 

이를 이용해서 malloc_hook에 leave_ret을 넣어주면 ROP가 가능한 것이다. 

 

그런데 본 문제에서는 calloc의 size를 변조할 수 있는 방법이 정상적인 방법으로는 없다. 

 

그러나 쓰지 않는 함수 중 하나가 이 기능을 제공해 준다. 그러면 이 함수를 이용하기 위해서는 어떻게 해야 할까? 

malloc_hook에 덮게 되면 leave_ret가젯을 사용할 수 없으니, free_hook에 덮어야 한다. 그런데 또 재밌는 기능이 있다. 

malloc.h의 __free_hook을 이용하면 bss영역으로 __free_hook이 이동하고 이를 이용해 free_hook을 사용자가 변조했는지 알 수 있는데, free를 하기 전에 free_hook이 덮여있으면 exit 해버린다. 그러면 어떻게 해야 할까?

정답은 exit 함수다. main에서 exit하기 전에도 힌트를 제공했었는데 exit함수의 내부 루틴에서는 free를 하는 부분이 존재한다. 

initial+0 부분을 0이아닌 아무 값이나 , initial+8부분을 0으로 덮어주면 free를 하는 루틴이 있다. 

자세한 것은 아래 블로그 참조. 설명을 잘 해놓았다. 

https://m.blog.naver.com/PostView.nhn?blogId=yjw_sz&logNo=221559719664&proxyReferer=https:%2F%2Fwww.google.com%2F

 

32. exit() 함수의 내부 동작을 이용한 exploit

이번에 HackCTF에 AdultFSB를 출제했는데 그것과 관련있는 내용을 정리하고자 한다.​glibc 2.23을...

blog.naver.com

그래서 전체적인 시나리오는 malloc_hook -> leave ret , free_hook -> 0x400d80(calloc을 해주는 부분), initial 변조 뒤 exit를 호출해서 free 호출 후 rop를 하는 것이다. 

 

자 그래서 이걸 어떻게 덮을까를 고민해보면.. 

malloc_hook-35 에는 0x7f짜리 size가 존재한다. -> fastbin attack 

free_hook 은 ?

 

뭐 여기 적을 수 있는 정상적인 방법은 없다. 그리고 heap이 아닌 영역에 fastbin 이 아닌 것으로 쓰기는 힘들다. 

일단은 한칸 땡기면 0x200이 있다. 

 

initial도 마찬가지, 0x100이 있다. 

 

그래서 이걸 왜 보여줬냐? global_max_fast를 변조해서 이 청크들 다 fake로 넣어줄 것이다. bins에 .

global_max_fast변조는 unsorted bin attack으로 할 것이고, unsorted bin attack은 double free와 unsafe unlink를 이용할 것이다. global_max_fast 변조하는 문제를 한번 만들어 보고 싶었다 ㅎㅎ . 

이 문제는 io_buf_end조작을 통하여 setcontext 가젯을 이용하는 것을 막기위해 모든 입력은 read로 구성되어있다. 

취약점


 

일단 구조체 구조이다. 깔끔하게 그림으로 정리해 왔다. 

일단 첫번째 name을 꽉채우면 뒤의 힙주소까지 같이 출력 된다. [1] 

눈여겨 볼점은 Is_removed라는 놈이있는데, 청크가 삭제되면 저 removed flag가 1이 되고, removed 된 청크는 view를 통해 보거나 edit을 통해 수정할 수 없다. 

그러나 delete를 할 때에는 이 removed를 검사하지 않아서 double free가 막된다! [2]

 

그리고 또 다른 취약점으로는 make burger 부분이 있다. 

여기서는 마음대로 malloc을 통해 원하는 사이즈를 할당 받을 수 있다, 일단 이것도 큰 문제긴 한데, 저기 빵사이에 재료를 끼우는 부분에서 oob가 난다. index에 음수를 넣어주면 할당받은 부분 뒷 부분에 값을 넣어 줄 수 있다. [3]

 

와아~ 이거 쓰면 bad system call 난다. seccomp 걸어놔서 ORW로 풀어야 한다. 

 

일단 먼저 main_arena leak을 하는 방법이다. 

 

unsafe unlink를 위해서 청크를 다음과 같이 배치가 되어야 한다. make_burger가 원하는 사이즈의 청크를 malloc해주는 것을 이용하면 쉽게 이 상태를 만들 수 있다. 

 

이렇게 consolidate를 통한 double free를 해주면 prev_inuse플래그가 fastbin 으로 할당 받을 때에는 바뀌지 않아서 unsafe unlink를 터트려 줄 수 있다. 

보라색으로 된놈이 타겟 청크다. unsafe unlink가 되면 저녀석이 0x16b8938로 바뀐다. 

사진이 바뀐 것 같다..주소가 다름

그 후 청크가 합병이 되서 0xf1짜리 free 청크가 unsorted bin 에 들어갔고 description addr은 0x16b8938이 되었다. 이를 이용해 description addr을 0x16b8970 으로 바꿔서 unsorted bin을 가르키게 한후 leak, 그리고 bk를 global_max_fast-0x10으로 바꾸어 global_max_fast를 main_arena+88으로 만들어버린다. 

 

그리고 그 후로 smallbin이 오염 됬기 때문에 unsafe unlink를 쓰기는 힘들어 보인다. 이렇게 청크가 배치된 이유는 unsafe unlink를 통해 이상한 위치에서 fake chunk가 free되었는데, 기존에 우리가 미리 free한 청크와 범위가 겹치기 때문이다. 잘 하면 될지도?  

 

이제 global maxt fast값이 변조되었으니 fast bin attack을 하자, 시작에 앞서 앞에서 청크의 corrupt 문제도 이

있곻 하니 미리 앞에서 각 사이즈의 청크들을 만들어 주었다. 

 

이를 이용해 앞에서 표기한 malloc_hook, free_hook, initial을 다 덮어준다. 

 

먼저 initial 값이다. 가장 독립적이기 때문에 먼저 하겠다. 

 

initial은 fastbin에 넣어준뒤 make burger에서 음수 인덱스에 값을 집어넣을 수 있다는 취약점을 이용해서 initial+8은 0으로 initial은 값을 넣어주었다. 

 

free hook은 기존의 위치가 아닌 bss 영역에 넣어줘야 한다.  이상태에서 exit를 해주면 free hook -> calloc ->leave_ret 순으로 실행 된다. 그리고 이 청크들을 구성할때 미리 ROP 코드를 넣어줘야 한다.

이렇게 말이다. 그리고 마지막으로는 RBP값을 지정해주는데, rop 코드가 적힌 값 -8 을 넣어줘야 한다. leave 하면서 rsp가 이동하기 때문에.. (Input this 라고 적힌 값은 jump할 힙주소를 적어준 것이다! )

 

 

 

*충격적인 unintended가 있었다. 아무래도 땜빵식 코딩을 하다 보니 오버플로 체크를 못한듯..*

'전공쪽 > 동아리 관련' 카테고리의 다른 글

앞으로 스스로 공부할 것  (1) 2020.10.24
동아리 가을 CTF write up  (0) 2020.10.11
FSB를 위한 함수  (0) 2020.08.31
StackPivot 문제  (1) 2020.07.31
[동아리 CTF] 문제 CheckSum  (0) 2020.07.31