heap tcache poisoning & double free

2022. 8. 2. 15:46·Tips & theory
728x90
반응형

tcache

libc > 2.25 이후부터 적용된 heap 관리 방법이며, 2.29부터는 패치 되었다.

사실 아래 내용 다 필요 없이 같은 공간에 free가 두번 들어가며, free 시 앞에 사용한 heap 영역의 주소를 가져오기 때문에  tcache 영역에 임의의 주소를 덮어씌울 수 있다.


우선 두번의 32 byte heap 영역 할당을 통해 아래와 같이 데이터가 들어있다고 가정하자.

gef➤  heap chunks
Chunk(addr=0x602010, size=0x290, flags=PREV_INUSE)
    [0x0000000000602010     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................]
Chunk(addr=0x6022a0, size=0x30, flags=PREV_INUSE)
    [0x00000000006022a0     61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61    aaaaaaaaaaaaaaaa]
Chunk(addr=0x6022d0, size=0x30, flags=PREV_INUSE)
    [0x00000000006022d0     62 62 62 62 62 62 62 62 62 62 62 62 62 62 62 62    bbbbbbbbbbbbbbbb]
Chunk(addr=0x602300, size=0x20d10, flags=PREV_INUSE)
    [0x0000000000602300     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................]
Chunk(addr=0x602300, size=0x20d10, flags=PREV_INUSE)  ←  top chunk

gef➤  x/40gx 0x602010
0x602010:       0x0000000000000000      0x0000000000000000
...
0x602290:       0x0000000000000000      0x0000000000000031
0x6022a0:       0x6161616161616161      0x6161616161616161
0x6022b0:       0x6161616161616161      0x0061616161616161
0x6022c0:       0x0000000000000000      0x0000000000000031
0x6022d0:       0x6262626262626262      0x6262626262626262
0x6022e0:       0x6262626262626262      0x0062626262626262
0x6022f0:       0x0000000000000000      0x0000000000020d11

이후 가장 마지막 heap 영역을 free 하면 tcache에 fd 주소가 저장된다.

gef➤  heap chunks
Chunk(addr=0x602010, size=0x290, flags=PREV_INUSE)
    [0x0000000000602010     00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00    ................]
Chunk(addr=0x6022a0, size=0x30, flags=PREV_INUSE)
    [0x00000000006022a0     61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61    aaaaaaaaaaaaaaaa]
Chunk(addr=0x6022d0, size=0x30, flags=PREV_INUSE)
    [0x00000000006022d0     02 06 00 00 00 00 00 00 10 20 60 00 00 00 00 00    ......... `.....]
Chunk(addr=0x602300, size=0x20d10, flags=PREV_INUSE)
    [0x0000000000602300     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................]
Chunk(addr=0x602300, size=0x20d10, flags=PREV_INUSE)  ←  top chunk
gef➤  x/40gx 0x602010
0x602010:       0x0000000000010000      0x0000000000000000
...
0x602090:       0x0000000000000000      0x00000000006022d0
0x6020a0:       0x0000000000000000      0x0000000000000000
...
0x602290:       0x0000000000000000      0x0000000000000031
0x6022a0:       0x6161616161616161      0x6161616161616161
0x6022b0:       0x6161616161616161      0x0061616161616161
0x6022c0:       0x0000000000000000      0x0000000000000031
0x6022d0:       0x0000000000000602      0x0000000000602010
0x6022e0:       0x6262626262626262      0x0062626262626262
0x6022f0:       0x0000000000000000      0x0000000000020d11

여기서 보듯이 tcache의 첫번째 8 byte 내에는 free된 횟수가 들어있고, 이후 free 된 heap 영역의 주소가 들어있다.

그리고 heap 영역에는 tcache의 시작 주소가 들어가 있다.

 

만일 heap 영역을 다시 확보하고 데이터를 넣으려고하면 0x6022d0이 tcache에 있기에 여기부터 할당되려고 할 것이다.

즉, tcache는 다음에 heap 영역 할당 시 사용될 주소를 저장한 곳이다.


tcache에서는 free 시 double free를 확인하기 위해

tcache 영역에 저장된 free heap 영역 주소와 bk 영역 값을 확인한다.

 

만일 bk 값이 변조 가능하다면 어떻게 될까.

즉, 아래와 같이 현재 bk 값인 0x602010에서 1 byte만 변조하고

gef➤  x/40gx 0x602010
...
0x6022d0:       0x6363636363636363      0x000000000060200a
...

다시 free 해보면 free가 가능한 것을 확인할 수 있고, tcache 첫번째 8 byte 내에 2가 표기된 것을 보아 2개가 free된 것으로 인식하고 있음을 알 수 있다.

gef➤  x/40gx 0x602010
0x602010:       0x0000000000020000      0x0000000000000000
0x602020:       0x0000000000000000      0x0000000000000000
...
0x602080:       0x0000000000000000      0x0000000000000000
0x602090:       0x0000000000000000      0x00000000006022d0
0x6020a0:       0x0000000000000000      0x0000000000000000
...
0x602290:       0x0000000000000000      0x0000000000000031
0x6022a0:       0x6161616161616161      0x6161616161616161
0x6022b0:       0x6161616161616161      0x0061616161616161
0x6022c0:       0x0000000000000000      0x0000000000000031
0x6022d0:       0x00000000006024d2      0x0000000000602010
0x6022e0:       0x6262626262626262      0x0062626262626262
0x6022f0:       0x0000000000000000      0x0000000000020d11

만일 최초 free 및 bk 값 변경 후 다시 heap 영역 할당 및 값을 넣으려하면 어떻게될까?

32 byte heap 할당 및 데이터를 넣은 후 free한 상태는 아래와 같다.

gef➤  x/40gx 0x602010
0x602010:       0x0000000000010000      0x0000000000000000
...
0x602090:       0x0000000000000000      0x00000000006022a0
...
0x602290:       0x0000000000000000      0x0000000000000031
0x6022a0:       0x0000000000000602      0x0000000000602010
0x6022b0:       0x6161616161616161      0x0061616161616161
0x6022c0:       0x0000000000000000      0x0000000000020d41
...

이후 bk 영역의 값을 수정하고

0x602290:       0x0000000000000000      0x0000000000000031
0x6022a0:       0x6262626262626262      0x6363636363636363
0x6022b0:       0x616161616161610a      0x0061616161616161
0x6022c0:       0x0000000000000000      0x0000000000020d41

다시 heap 할당을 해보니

gef➤  x/40gx 0x602010
0x602010:       0x0000000000000000      0x0000000000000000
...
0x602090:       0x0000000000000000      0x6262626262626460
...
0x602290:       0x0000000000000000      0x0000000000000031
0x6022a0:       0x6464646464646464      0x6464646464646464
0x6022b0:       0x6464646464646464      0x0064646464646464
0x6022c0:       0x0000000000000000      0x0000000000020d41

tcache에 heap 영역의 값이 일부 삽입된 것을 볼 수 있으며 이는 다음에 heap 영역이 할당될 주소를 가지고 있음을 이야기 한다.


다만 위의 값에서는 tcache 첫 8 byte가 0이기에 tcache 내에 다음에 사용할 주소 값이 있어도 사용하지는 않는다.

만일 여기서 tcache 첫 8 byte에 값이 1 이상으로 남아있다면 어떻게 될까.

heap 할당 -> free -> bk 변조 -> free -> bk 변조 후 heap의 모양은 아래와 같다.

gef➤  x/40gx 0x602010
0x602010:       0x0000000000020000      0x0000000000000000
...
0x602090:       0x0000000000000000      0x00000000006022a0
...
0x602290:       0x0000000000000000      0x0000000000000031
0x6022a0:       0x6262626262626262      0x6262626262626262
0x6022b0:       0x6262626262626262      0x0062626262626262
0x6022c0:       0x0000000000000000      0x0000000000020d41

이후 heap 할당을 1회 하면 heap 모양은 아래와 같다.

gef➤  x/40gx 0x602010
0x602010:       0x0000000000010000      0x0000000000000000
...
0x602090:       0x0000000000000000      0x6262626262626460
...
0x602290:       0x0000000000000000      0x0000000000000031
0x6022a0:       0x6363636363636363      0x6363636363636363
0x6022b0:       0x6363636363636363      0x0063636363636363
0x6022c0:       0x0000000000000000      0x0000000000020d41

여기서 만약에 heap 할당을 한번 더 하면, tcache에 값이 남아있기에 해당 주소에 값을 쓰려할 것이다.

다만 로컬 환경의 libc 버전이 높아 double free를 check하는 부분이 추가되었으며 이에 대한 시연을 하기는 어려우니 다음기회에...


아래 예제를 참조하자.

https://wyv3rn.tistory.com/80

 

tcache_dup

// gcc -o tcache_dup tcache_dup.c -no-pie #include #include #include #include char *ptr[10]; void alarm_handler() { exit(-1); } void initialize() { setvbuf(stdin, NULL, _IONBF, 0); setvbuf(stdout,..

wyv3rn.tistory.com

 

728x90
반응형
저작자표시 비영리 변경금지 (새창열림)

'Tips & theory' 카테고리의 다른 글

함수의 offset은 왜 strings로 찾아지지 않는가?  (0) 2022.08.03
pwntools - elf, symbol을 가져올때  (0) 2022.08.03
보호 기법 및 공격 시나리오 요약  (0) 2022.08.01
heap tcache & main_arena  (0) 2022.08.01
fsb  (0) 2022.07.30
'Tips & theory' 카테고리의 다른 글
  • 함수의 offset은 왜 strings로 찾아지지 않는가?
  • pwntools - elf, symbol을 가져올때
  • 보호 기법 및 공격 시나리오 요약
  • heap tcache & main_arena
wyv3rn
wyv3rn
아저씨의 흔한 취미. wyv3rn#1249
  • wyv3rn
    think storage
    wyv3rn
  • 전체
    오늘
    어제
    • 분류 전체보기 (500) N
      • To do list (7) N
        • Doing (1) N
        • Complete (6)
      • Diary (35)
      • Tips & theory (77)
      • Kernel Exploit (27) N
        • Theory (15)
        • Exercise (5) N
      • Wargame (313)
        • pwn.college (34)
        • Dreamhack (148)
        • pwnable.kr (15)
        • Lord of Sqlinjection (3)
        • Cryptohack (20)
        • Root me (27)
        • CodeEngn (4)
        • Exploit Education (22)
        • ROP Emporium (8)
        • H4C (10)
        • Hackerchool (22)
      • CTF (41) N
        • Solved (39) N
        • Unsolved (2)
      • Script (0)
  • 블로그 메뉴

    • 홈
    • 방명록
  • 링크

  • 공지사항

    • PWN wargame 모음 (및 느낀점)
    • 비공개 글들에 대해.
    • 뭐라도 하나 얻어가시길...
  • 인기 글

  • 태그

    CANARY
    hackerschool
    lob
    pwntools
    32bit
    RTL
    libc
    BOF
    tcache
    x86
    64bit
    cryptohack
    la ctf
    phoenix
    root-me
    root
    vtable
    FSB
    _IO_FILE
    Format String Bug
    rop
    Buffer Overflow
    pwnable.kr
    ROOT ME
    Me
    heap
    exploit education
    dreamhack
    docker
    x64
  • 최근 댓글

  • 최근 글

  • 250x250
    반응형
  • hELLO· Designed By정상우.v4.10.3
wyv3rn
heap tcache poisoning & double free
상단으로

티스토리툴바