Poison_null_byte.c
1 |
|
null byte 2.0!
테스트 환경: Ubuntu 14.04 64bit.
이 기법은 glibc에서 tcache 옵션이 disabled된 상태에만 작동한다.
이 기법은 null바이트를 이용하여 malloc된 영역으로 off-by-one할때 사용할 수 있다.
'a’에 0x100 bytes 할당한다.
a: 0x603010
우리는 'a’에 overflow가 발생하는 것을 원하기 때문에, 'a’의 ‘진짜’ 크기를 알 필요가 있다. (반올림 때문에 0x100 이상이 될 수 있음): 0x108
b: 0x603120
c: 0x603330
barrier를 0x603440에 할당하면, c는 free될 때 top-chunk로 consolidate되지 않는다.
barrier가 엄격하게 필요한 건 아니지만 상황을 덜 혼란스럽게 만든다.
glibc의 새 버전에서 ‘chunksize§ != prev_size (next_chunk§)’ 검사를 통과하려면 b안에 변경된(updated) 크기를 가지고 있어야 한다.
b.size: 0x211
b.size: (0x200 + 0x10) | prev_in_use
우리는 'b’의 metadata에 있는 single null byte를 이용해서 'a’를 overflow한다.
b.size: 0x200
c.prev_size: 0x210
우리는 chunksize§ == 0x200 == 0x200 == prev_size (next_chunk§) 이후로 검사를 통과할 것이다.
b1: 0x603120
이제 우리는 'b1’을 malloc한다. 그것은 'b’에 있던 곳에 위치할 것이다. 이 시점에서 c.prev_size가 변경됐어야 했지만, 그렇지 않았다: 0x210
흥미롭게도, c.prev_size의 변경된 값은 c.prev_size 앞에 0x10 bytes로 write됐다: f0
‘victim’ chunk에 'b2’를 malloc한다.
b2: 0x603230
현재 b2 content:
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
이제 우리는 'b1’과 c를 free한다: 'b1’과 'c’청크는 consolidate될 것이다.(b2를 잊어버리고)
마지막으로, 'd’를 할당해서 'b2’를 overlapping한다.
d: 0x603120
'd’와 'b2’가 overlap되었다.
바뀐 b2 content: DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD