본문 바로가기

system

[how2heap translation] house_of_einherjar.c

# 환경은 ubuntu 16.04 64bit 에서 진행했습니다.

# House of Einherjar 는 malloc() 에 의해 반환 된 포인터를 제어하기 위해 null byte 로 off-by-one 오버플로우를 사용한다.

# 이 기술은 Poison Null Byte 보다 더 강력한 원초적인 기술이지만, 추가적으로 heap leak 이 필요하다.

 

 

포인터 변수 a, b, c, d 선언한다. 그리고 우리는 'a' 에 0x38 bytes 만큼 할당한다. 

우리는 'a' 에 overflow 를 원하기 때문에, 0x38 을 반올림 한 후의 'a' 의 실제 크기가 필요하다. 

a : 0x603420

real_a_size : 0x38 

 

 

우리는 우리가 원하는 어느 곳이든 fake chunk 를 만든다. 이 글에서 우리는 stack 에 chunk 를 만들 것이다.

그러나, 너는 그 주소를 아는 한 heap 이든 bss 든 chunk 를 만들 수 있다.

우리는 unlink checks 를 우회하기 위해 fwd 와 bck 포인터들을 fake_chunk 를 가리키도록 설정한다.

그러나 우리는 일부의 시나리오에서 unsafe unlink 기술을 사용할 수 있다.

 

Our fake chunk at 0x7fffffffe4d0 looks like:

prev_size (not used): 0x41414141

size : 0x100

fwd : 0x7fffffffe4d0

bck : 0x7fffffffe4d0

 

 

우리는 'b' 에 0xf8 bytes 만큼 할당한다. 그리고 우리는 3rd chunk 를 'c' 에 0x60 bytes 만큼 할당한다.

 

b : 0x603460

real_b_size : 0xf8

c : 0x603560

 

 

우리는 'a' 에서 single null byte 를 'b' 의 메타 데이터에 overflow 한다. 

 

[ overflow 전 ]

b_size_ptr : 0x603458 -> 0x101

b.size : 0x101

 

[ overflow 후 ]

b.size : 0x100

 

이것은 b.size 가 0x100 의 배수라면 가장 쉽다. 너는 b 의 size 를 바꿀 필요 없이 오직 prev_inuse bit 만 바꾸면 된다.

만약 그것이 변경되었다면, 우리는 다음 chunk 를 병합하려고 하는 b 의 안에 fake chunk 가 필요할 것이다.

 

 

// a 의 끝에 fake prev_size 를 쓰자.

우리는 fake prev_size 를 a 의 마지막 8 byte 에 작성하여 그것이 우리의 fake chunk 와 병합시키도록 할 것이다.

우리의 fake prev_size 는 0x603450(b - prev_size -> 0x0) - 0x7fffffffe4d0(fake chunk - prev_size -> 0x41414141) = 0xffff800000604f80

 

fake size : 0x7fffffffe4c0 -> 0xffff800000604f80

&a[0x38] - 0x8 = 0xffff800000604f80    // 0x603450 -> 0xffff800000604f80

 

// 'b' 를 free 하고 그것은 fake chunk 와 병합할 것이다.

이제 우리는 b 를 free 하고, b 의 prev_inuse 가 unset 이기 때문에 이것은 fake chunk 와 병합할 것이다.

 

Our fake chunk size is now 0xffff800000605081 (b.size + fake_prev_size)

우리는 fake chunk 를 수정할 수 있고, 그것은 크기 검사를 통과할 수 있을 정도로 작다.

만약 fake chunk 가 top chunk 라면 ( 'c' 를 할당하지 않았다면 ) 필요하지 않다.

 

 

새로운 fake_chunk size : 0x1000

지금 우리는 malloc() 을 호출할 수 있고, 그것은 fake chunk 에서부터 시작할 것이다.

 

d = 0x7fffffffe4e0

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

x32, x64 에서의 fastbin 크기가 다르다.

E.g. on x64, 0x30-0x38 will all be rounded to 0x40.

'system' 카테고리의 다른 글

arm in qemu  (0) 2018.02.10
2017년 KUCIS 영남권 세미나  (0) 2017.06.30
[how2heap translation] overlapping_chunk.c  (0) 2017.06.26
[how2heap translation] house_of_lore.c  (0) 2017.06.21
[how2heap translation] poison_null_byte.c  (0) 2017.06.19