[UNDEAD] The House of Mind
The House of Mind
fwd->bk = p
``c *(&bins[0] + 8)->bk = p`` ,
``c *(*(&bins[0] + 8) + 12 ) = p`` 이므로
``c *(&bins[0] + 8) + 12`` 번지에 `` p``에 있는 값이 대입
따라서, ``c &bins[0] + 8`` 번지에 ``c Execution point addr - 12`` 주소를 넣는다.
⇒ ``c *(&bins[0] + 8) = Execution point addr - 12``가 되므로, `` Execution point addr``번지에 `` p``를 대입하게 된다.
원래 House of Mind는 이 포인터를 이용하는데, 지금은 patch되어 사용할 수 없다.
bck->fd = p
&bins[0] + 8 && Execution point |
&p |
그래서 조건을 충족시키기가 꽤나 어렵다.
[UNDEAD] fastbin method가 이와 동일한 방법으로 동작한다.
exploit
- overflow를 이용하는 방식으로는 main_arena bins[0]에 직접 값을 쓸 수는 없다.
⇒ fake bins[0] ( fake arena )가 필요하다. - ``c free(chunk)`` 시 main_arena가 아니라 fake arena를 사용하도록 해야 한다.
⇒ fake heap_info가 필요하다. - ``c free(chunk)`` 시 fake arena와 연결된 fake heap_info를 사용하도록 해야 한다.
⇒ chunk가 main_arena heap range 밖에 있어야 하며, NON_MAIN_ARENA가 set 되어야 한다.
Note) 그림을 조금 잘못 그렸는데, ``c bins[0]``에서 나가는 노란색 화살표가 가리키는 chunk는 실제로는 없고, arena 내부에 있는 것으로 간주한다. 따라서 ``c bins[2] == bins[0]'s fd``다.
* consolidate를 막기 위해 `` P``에 `` PREV_INUSE`` flag도 있어야 한다.
* `` P``를 비롯한 chunk들은 모두 heap에 정상적으로 할당된 chunk들 이며, `` P`` 이후에는 top chunk가 위치하기 때문에 free's next size check는 따로 신경쓰지 않아도 된다.
* 8 bytes A..A는 위쪽 chunk를 free 하면서 `` fd/bk``가 채워지는 자리이므로, 이 부분 이후에 arena가 시작된다.
사실 위쪽 chunk를 굳이 free할 필요는 없는 듯.
* 이후 위치하는 8 bytes도 free 하면서 0으로 초기화되므로 뒤 쪽 4 bytes 0을 mutex로 이용한다.
```c
free(p+8); // free(0x081002a0)
-> 0x08100298 : p's value
-> 0x08100000 : fake heap_info AND ar_ptr
-> 0x0804a010 : fake arena
-> 0x0804a010 + x + 8 : &ar->bins[0]
```
`` p``가 가리키는 곳은 chunk의 `` prev_size(0x08100298)``이므로 여기에 shellcode를 넘기면 되는데 그 아래 field가 망가지면 안된다.
따라서 `` p``가 가리키는 곳에는 jmp instruction을 넣고, field 아래에 shellcode를 넣어 그리로 jmp할 수 있도록 구성한다.
DEAD
check를 통과하기 위해서는 ``c *(&bins[0] + 8) + 12`` 번지에 있는 값이, ``c &bins[0]`` 이어야만 한다.
``c &bins[0] + 8`` 번지의 값이 가리키는 B chunk의 `` bk``의 값이 ``c &bins[0]``이어야 한다.( ↖ )
최종적으로 `` P``가 대입되는 곳(B chunk의 `` bk``)의 값이 ``c &bins[0]``인 경우에만 사용할 수 있기 때문에, 사실상 사용할 수 없다.
* 최종적으로 `` P``가 대입되는 곳을 ``c &bins[0]``으로 만들어 주는 것은, 이미 target의 값을 조작할 수 있다는 것을 의미하므로 모순이다.
[UNDEAD] fastbin method
```c
p->fd = *fb;
*fb = p;
```
* 소스가 조금 변경되어 ``c *fp = p`` 부분을 매크로에서 처리하는 것 같지만, 별다른 check가 새로 생긴 것 같지는 않아 아직 동작한다. (2.24)
``c fwd->bk = p``를 활용하는 House of Mind 방법과는 꽤나 다른 것이, 포인터를 한 번 덜 거치기 때문에 아예 arena를 Execution point를 포함하는 영역으로 잡아버려야 한다.
* fastbin 처리 부분은 ``c _int_free()``에서 두 가지 기본적인 check 이후 바로 등장하기 때문에 fastbin size라면 바로 fastbin 처리 부분을 수행하게 된다.
* ``c ar_ptr = arena_for_chunk(p);``는 ``c _int_free()`` 이전에 이미 구해져서 넘어오기 때문에 fastbin도 다른 arena를 참조하도록 하는 것이 가능하다.
사실상 arena가 다음과 같이 구성되어 있을 때 `` fastbins[idx]``에 값을 쓰게 되는 건데,
`` mutex == 00000000``이어야만 하며, `` system_mem``도 너무 작으면 안된다.
(원래는 `` max_fast``도 신경 써주어야 하지만 버전이 올라가면서 `` flag``로 변경되었다.)
mutex |
flag || max_fast ( old version ) |
fastbinsY[0] |
... |
system_mem ( av+1848 ) |
따라서 Execution point 근처에서 두 가지 정도만 만족한다면 사용할 수 있다.
그러나 문제는 이 방법을 이용해 Execution point에 대입할 수 있는 값은 heap addr인 ``c p``(chunk's addr)뿐인데, heap에 X 권한이 없다. ( 원하는 값을 아무거나 쓸 수는 없다. "arena에 ``c p``만" 쓸 수 있다. / NX가 해제되어 있어도 보통 stack에만 X권한 있고 heap에는 없다. )
따라서 Execution point의 값이 ``c p``로 변경된다고 해도 ``c p``위치에 있는(mchunkptr) instruction을 실행할 수 없다는게 문제.
그래서 instruction까지 가기 위해 포인터를 한 번 더 거치는 Execution point에만 사용할 수 있다.
GOT에는 ``c &func``가 들어가기 때문에, ``c p``위치에 바로 instruction이 있어야 해서 사용 불가.
``c func@plt + 2``에 대입하는 방법도 생각해 볼 수 있겠지만, 여기는 쓰기 권한이 없다.
따라서 double function pointer 정도로 사용처가 제한되기 때문에, 상당히 적용하기가 그렇다.
'Security > System Exploit' 카테고리의 다른 글
The House of Einherjar (0) | 2017.08.16 |
---|---|
The House of Force (0) | 2017.08.15 |
unsorted bin attack (0) | 2017.08.15 |
[UNDEAD] unlink (0) | 2017.08.15 |
The House of Lore (0) | 2017.08.15 |