LAB 11(Unsafe Unlink)

728x90

Unsafe Unlink 공격이 실행되기 위한 조건

  1. free 시키려는 청크의 이전청크의 사이즈와 free 시키려는 현 청크의 prev_size가 같아야한다.

change_item 함수로 청크의 size와 fd를 조작 가능하다.

우선 small bin사이즈 크기 3개 할당.

그 후, Unsafe Unlink의 조건을 맞춰주기 위해 첫번째로 할당한 chunk에 fake chunk를 만들어준다.

Fake chunk의 구조는 다음과 같다

prev_size = 0 | size = 0

fd = 원하는 주소(전역변수) - 24 | bk = 원하는 주소(전역변수) - 16

데이터

다음 청크(2번째) prev_size = fake chunk의 사이즈 | 다음 청크 size = 첫번째 chunk의 사이즈 - 1

 

payload = ''
payload += p64(0)*2
payload += p64(itemlist-0x18) + p64(itemlist-0x10)
payload += "A"*0x60
payload += p64(0x80)+p64(0x90)

 

prev_size와 size를 0으로 맞추는 이유

현재 청크의 Size와 다음 청크의 Prev_Size를 비교해서 다르면 에러를 발생시킨다.

다음 청크는 현재 청크의 위치에서 자신의 Size 값을 더해서 계산하는데, 값이 0이라면 다음 청크가 자신이다.

 

FD 값과 BK 값에서 각각 24와 16을 빼는 이유도 보안 기능을 우회하기 위해서

unlink시에 P->fd->bk와 P->bk->fd의 값이 다르면 에러가 출력이 된다.

이부분을 조금 다르게 표현해보면 P->fd + 24와 P->bk + 16을 비교하는 것이다.

 

왜냐하면 bk의 위치는 Prev_Size와 Size와 FD 이후에 존재하고 각각 8byte이다.(64bit 기준)

FD의 위치는 Prev_Size와 Size 이후에 존재하고 마찬가지로 각각 8byte이다.

그래서 FD는 전역 변수로부터 24를 빼고, BK는 전역 변수로부터 16을 빼면 우회할 수 있다.

 

Prev_Size를 0x10 만큼 빼주는 이유는 그렇게해야 Fake Chunk를 가르키기 때문이다.

힙에서 이전 청크의 계산은 현재 청크의 위치에서 Prev_Size를 빼는 것으로 한다.

해당 부분을 조작 함으로서 이전 청크의 위치를 Fake Chunk로 인식하도록 할 수 있다.

 

Size를 1 빼는 이유는 PREV_INUSE 비트를 없앰으로서 이전 청크가 Free 되었다고 인식하도록 하기 위함이다.

그러면 병합이 일어나게 되고 Unlink Macro가 불리게 되어서 취약점이 발생

 

fake chunk 생성후 다음 chunk의 prev_inuse와 size, prev_size를 수정하고 난 후 힙의 상태

직접적으로 free를 해주지는 않았지만, prev_inuse의 값을 1 → 0으로 변경하였기 때문에 내부적으로 free가 되었다고 착각함.

 

그 후, 2번째 청크를 free 해보자. 원래는 0x8e70b0을 해제해야하지만 double free 버그가 뜨면서 되지 않았다. 그래서 7140 → 70b0을 해제할때는 잘되었다. 왜 그런지는 좀더 공부해봐야겠다.

하지만 여기서 주의 해야할 점이 있다.

전역변수로 itemlist를 사용할건데, gdb로 본 itemlist의 주소는 0x6020c0이다. 그리고 add를 할때 itemlist에서 주소를 가리켜주는데, c0으로 하면 원래 힙을 가리키는 포인터자리가 아닌 그 앞자리에 쓰게되어 오류가 뜬다. 따라서 c8로 하여 포인터를 덮어씌워야한다.

그럼 이제 값을 수정할때 저 0x6020b0에 수정된 값이 들어갈 것이다. 그럼 저 0x6020b0을 puts_got로 변경해보자.

 

잘 덮였다. 그럼 저 printf_got를 magic으로 덮는다면, printf함수가 실행될 떄, magic함수가 실행될 것이다.

하지만 mgaic함수를 puts_got나 printf_got로 덮으면 magic까지는 가지만 그 이후로 실행이 되지 않는다. 하지만 atoi_got를 덮었을때는 magic가 실행이 된다.

왜 그럴까?

atoi 함수에 magic 함수를 덮어쓰는 게 가장 적절해보인다. 그 이유는 인자 값을 바로 이 전에 입력을 받을 수 있기 때문에 만약 one_gadget이 안될 경우엔 system으로 overwrite하고 /bin/sh를 입력해주면 되기 때문이다.

[Hitcon-Training] Lab11 - bamboobox (unsafe unlink)

위 블로그를 참조하여 알게되었다.

728x90

'Hitcon Training' 카테고리의 다른 글

LAB 14(Unsorted bin Attack)  (0) 2021.07.25
LAB 12(Fastbin attack)  (0) 2021.07.25
LAB 5  (0) 2021.07.25
LAB 5 - 미완성  (0) 2021.07.25
LAB 3  (0) 2021.07.25