e_yejun
Jun_ : Pwn
e_yejun
์ „์ฒด ๋ฐฉ๋ฌธ์ž
์˜ค๋Š˜
์–ด์ œ
  • ๋ถ„๋ฅ˜ ์ „์ฒด๋ณด๊ธฐ (240)
    • Profile (1)
    • Pwnable (54)
    • Reversing (14)
    • Network (8)
    • Forensic (10)
    • Embedded (4)
    • Android (2)
    • Web (18)
    • ์•Œ๊ณ ๋ฆฌ์ฆ˜ (42)
    • ํ”„๋กœ๊ทธ๋ž˜๋ฐ (24)
    • ํ”„๋กœ์ ํŠธ (6)
    • 1-day (7)
    • CTF (15)
    • ๊ธฐํƒ€ (33)
    • ์ผ๊ธฐ์žฅ (0)

๋ธ”๋กœ๊ทธ ๋ฉ”๋‰ด

  • ํ™ˆ
  • ํƒœ๊ทธ
  • ๋ฐฉ๋ช…๋ก

๊ณต์ง€์‚ฌํ•ญ

์ธ๊ธฐ ๊ธ€

ํƒœ๊ทธ

  • dvwa
  • x64
  • how2heap
  • X86
  • 1-day
  • BOF
  • Heap
  • dreamhack.io
  • wargame
  • rev-basic

์ตœ๊ทผ ๋Œ“๊ธ€

์ตœ๊ทผ ๊ธ€

ํ‹ฐ์Šคํ† ๋ฆฌ

hELLO ยท Designed By ์ •์ƒ์šฐ.
e_yejun

Jun_ : Pwn

Pwnable

Heap ๋ฉ”๋ชจ๋ฆฌ ๊ตฌ์กฐ2 - bins

2023. 2. 11. 01:15

Index

bins
fast bin
unsorted bin
small bin
large bin
last_remainder
tcache bin


๐Ÿ’ก
ํ•ด๋‹น ๊ธ€์—์„œ๋Š” tcachebin๋ฅผ ์ œ์™ธํ•œ fastbin, unsortedbin, smallbin, largebin์— ๋Œ€ํ•ด์„œ ์„ค๋ช…ํ•˜๋ฏ€๋กœ, glibc-2.23 ๋ฒ„์ „์„ ๊ธฐ์ค€์œผ๋กœ ํ•œ๋‹ค.

bins

Bin์ด๋ผ๋Š” ๊ตฌ์กฐ๋ฅผ ์ด์šฉํ•˜์—ฌ ํ•ด์ œ๋œ ์ฒญํฌ๋ฅผ ํฌ๊ธฐ ๋‹จ์œ„๋กœ ๊ด€๋ฆฌํ•œ๋‹ค. ์ด๋Š” ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น ์š”์ฒญ์‹œ ์ด์ „์— ์‚ฌ์šฉํ–ˆ๋˜ ํฌ๊ธฐ์˜ chunk๊ฐ€ ์žˆ๋‹ค๋ฉด ์‹ ์†ํ•˜๊ฒŒ ์žฌํ• ๋‹นํ•˜๊ธฐ ์œ„ํ•จ์ด๋‹ค. ํฌ๊ธฐ์— ๋”ฐ๋ผ 4๊ฐ€์ง€ ์œ ํ˜•์œผ๋กœ ๋‚˜๋‰œ๋‹ค(glibc-2.26 ์ดํ›„ tcachebins๊ฐ€ ์ถ”๊ฐ€๋˜์–ด 5๊ฐ€์ง€์˜ bins). ํฌ๊ธฐ๊ฐ€ ํด ์ˆ˜๋ก ํ• ๋‹น/ํ•ด์ œ๊ฐ€ ๋А๋ ค์ง€๊ณ , ํฌ๊ธฐ๊ฐ€ ์ž‘์„ ์ˆ˜๋ก ํ• ๋‹น/ํ•ด์ œ๊ฐ€ ๋น ๋ฅธ bins๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

fast bin

์ด๋ฆ„ ๊ทธ๋Œ€๋กœ ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น๊ณผ ํ•ด์ œ๊ฐ€ ๊ฐ€์žฅ ๋น ๋ฅธ bin์ด๋‹ค. LIFO(ํ›„์ž…์„ ์ถœ) ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•˜๊ณ , Freed chunk๊ตฌ์กฐ์—์„œ fd์˜ ๊ฐ’์„ ์ด์šฉํ•ด์„œ ๋‹จ์ผ ์—ฐ๊ฒฐ๋ฆฌ์ŠคํŠธ๋กœ chunk๋ฅผ ๊ด€๋ฆฌํ•œ๋‹ค. ์˜ˆ์ œ ์ฝ”๋“œ๋ฅผ ํ†ตํ•ด์„œ chunk์˜ ํ• ๋‹น๊ณผ ํ•ด์ œ ์‹œ ์–ด๋–ป๊ฒŒ ๊ด€๋ฆฌํ•˜๋Š”์ง€ ํ™•์ธํ•ด๋ณด์ž.

//Name : fastbin.c
//Compiler : gcc -o fastbin fastbin.c -no-pie -fno-stack-protector
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

int main(){
        char *chunk0 = (char *)malloc(0x0);
        char *chunk1 = (char *)malloc(0x10);
        char *chunk2 = (char *)malloc(0x20);
        char *chunk3 = (char *)malloc(0x25);
        char *chunk4 = (char *)malloc(0x30);
        char *chunk5 = (char *)malloc(0x80);
        char *chunk6 = (char *)malloc(0x88);
        char *chunk7 = (char *)malloc(0x90);
        free(chunk0);
        free(chunk1);
        free(chunk2);
        strcpy(chunk3, "1234567890123456789012345678901234567");
        free(chunk3);
        free(chunk4);
        free(chunk5);
        free(chunk6);
        free(chunk7);
        return 0;
}

fastbin์ด ๊ด€๋ฆฌํ•˜๋Š” chunk์˜ ํฌ๊ธฐ๋Š” 32bit ์šด์˜์ฒด์ œ์—์„œ๋Š” 16~88byte(10๊ฐœ์˜ bin)์ด๊ณ , 64bit ์šด์˜์ฒด์ œ์—์„œ๋Š” 32~128byte(7๊ฐœ์˜ bin๋งŒ ์‚ฌ์šฉ)์ด๋‹ค. 64bit ๊ธฐ์ค€์œผ๋กœ fastbin์— ์†ํ•˜๋Š” ์—ฌ๋Ÿฌ ์‚ฌ์ด์ฆˆ์˜ ์ฒญํฌ๋ฅผ ํ• ๋‹นํ•˜๊ณ  ํ•ด์ œํ•˜๋ฉด์„œ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ™•์ธํ•ด๋ณด์ž.

์œ„ ๋ฉ”๋ชจ๋ฆฌ ์ƒํƒœ๋Š” ์˜ˆ์ œ ์ฝ”๋“œ์˜ ๋ชจ๋“  chunk๋ฅผ ํ• ๋‹นํ•˜๊ณ , ์•„์ง ํ•ด์ œ(free)๊ฐ€ ์ง„ํ–‰๋˜์ง€ ์•Š์€ ์ƒํƒœ์ด๋‹ค.

free(chunk0);

malloc(0)์ด ํ• ๋‹น๋œ chunk0์ด ํ•ด์ œ๋˜์—ˆ๋‹ค. malloc ์ธ์ž๋กœ 0์„ ์คฌ์ง€๋งŒ, ํ•ด์ œ๋˜์—ˆ์„ ๋•Œ์˜ chunk์˜ ๊ธฐ๋ณธ๊ตฌ์กฐ๋ฅผ ๋‚˜ํƒ€๋‚ด๊ธฐ ์œ„ํ•ด์„œ 0x20์˜ size๋ฅผ ๊ฐ€์ง„๋‹ค. 0x20ํฌ๊ธฐ์˜ chunk๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” fastbin[0]์— ๋“ค์–ด๊ฐ„ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

free(chunk1);

chunk1์€ malloc(0x10)์ด์—ˆ๋‹ค. ํ•˜์ง€๋งŒ chunk์˜ ์‹ค์ œ ํฌ๊ธฐ๋Š” data๋ฅผ ๋‹ด๋Š” ์˜์—ญ(0x10)๊ณผ ํ—ค๋”(0x10)๊ฐ€ ํ•ฉ์ณ์ ธ์„œ 0x20ํฌ๊ธฐ๊ฐ€ ๊ตฌ์„ฑ๋œ๋‹ค. ๊ธฐ๋ณธ ๊ตฌ์„ฑ์„ ๊ฐ–์ถ”๊ธฐ ์œ„ํ•ด 0x20 ํฌ๊ธฐ๋งŒํผ ํ• ๋‹น๋œ chunk0๊ณผ ๊ฐ™์€ ํฌ๊ธฐ๋ฅผ ํ• ๋‹น๋ฐ›๊ฒŒ ๋˜๊ณ , ํ•ด์ œ ์‹œ์— 0x20 ํฌ๊ธฐ๋ฅผ ๋‹ด๋Š” fastbin[0]์— ๋“ค์–ด๊ฐ„๋‹ค. ์ด๋•Œ fastbin์€ LIFO(ํ›„์ž…์„ ์ถœ) ๊ตฌ์กฐ๋ฅผ ๊ฐ€์ง€๊ธฐ ๋•Œ๋ฌธ์— ๋‚˜์ค‘์— ๋“ค์–ด๊ฐ„ chunk1(d49020)์ด ์žฌํ• ๋‹น ํ•„์š” ์‹œ ๋จผ์ € ํ• ๋‹น๋œ๋‹ค. ์œ„ ์‚ฌ์ง„์—์„œ๋„ chunk1(d49020)์˜ fd ๊ฐ’์€ chunk0(0xd49000)์œผ๋กœ fd๋ฅผ ํ†ตํ•ด ์—ฐ๊ฒฐ๋˜์–ด ๊ด€๋ฆฌํ•˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

free(chunk2);

chunk2๋Š” malloc(0x20)์ด๋‹ค. ํ—ค๋” ํฌ๊ธฐ 0x10์„ ๋”ํ•˜์—ฌ 0x30์˜ ํฌ๊ธฐ๋ฅผ ๊ฐ€์ง€๊ณ , ํ•ด์ œ ์‹œ fastbin[1]์— ๋“ค์–ด๊ฐ„ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. ์•ž์„œ ์„ค๋ช…ํ•œ ๋‚ด์šฉ๊ณผ ์ค‘๋ณต๋˜๋Š” ์„ค๋ช…์€ ์ƒ๋žตํ•œ๋‹ค.

strcpy(chunk3, "1234567890123456789012345678901234567");

chunk3์€ malloc(0x25)์œผ๋กœ, ํ—ค๋” ๊ฐ’๊นŒ์ง€ 0x35 ํฌ๊ธฐ์˜ ๊ณต๊ฐ„์ด ํ•„์š”ํ•˜๋‹ค. ์ด๋•Œ, chunk๋Š” 16byte ์ •๋ ฌ๋œ ํฌ๊ธฐ๋กœ ํ• ๋‹น๋œ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด 0x30์œผ๋กœ ๋‹ด์„ ์ˆ˜ ์—†์œผ๋‹ˆ, 0x40์˜ ํฌ๊ธฐ๋ฅผ ํ• ๋‹นํ•  ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ๋‹ค. ํ•˜์ง€๋งŒ ์œ„ ์‚ฌ์ง„์—์„œ size๊ฐ€ 0x30์ธ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

์ƒ‰ ๋ณ„๋กœ ๋‹ค๋ฅธ chunk์ด๋‹ค. ์•„๋ž˜ chunk์˜ prev_size ํ•„๋“œ๊ฐ€ ๋ฎ์—ฌ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ด๊ณ  ์žˆ๋‹ค. allocated chunk์ธ ๊ฒฝ์šฐ, ์ธ์ ‘ํ•œ ๋’ค chunk์—์„œ prev_size ๋ถ€๋ถ„๊นŒ์ง€ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ด์•„ ์‚ฌ์šฉํ•œ๋‹ค.

free(chunk3);

chunk3 ํ•ด์ œ ์‹œ, 0x30 ํฌ๊ธฐ์ธ chunk๋ฅผ ๋‹ด๋Š” fastbin[1]์œผ๋กœ ์ž˜ ๋“ค์–ด๊ฐ”๋‹ค.

free(chunk4);

chunk4๋Š” malloc(0x30)์ด๋‹ค. ์ •์ƒ์ ์œผ๋กœ ์ž˜ free๋˜์—ˆ๋‹ค.

free(chunk5);

chunk5๋Š” malloc(0x80)์„ ํ–ˆ๋‹ค. ํ—ค๋” ์ •๋ณด์˜ ํฌ๊ธฐ์ธ 0x10์„ ๋”ํ•˜๋ฉด 0x90์˜ ํฌ๊ธฐ๋ฅผ ๊ฐ€์ง„๋‹ค. 0x90์€ 144byte์ด๊ณ , 64bit ๊ธฐ์ค€์œผ๋กœ 32~128byte๋ฅผ fastbin์œผ๋กœ ๊ด€๋ฆฌํ•œ๋‹ค๊ณ  ํ–ˆ์œผ๋ฏ€๋กœ, fastbin์— ๋“ค์–ด๊ฐ€์ง€ ์•Š๋Š”๋‹ค. heapinfo ์‹œ size๊ฐ€ 0์ด์—ˆ๋˜ unsorted bin์ด 0x90์œผ๋กœ ๋ฐ”๋€ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๊ณ , ํ•ด์ œ๋œ chunk์˜ ์ฃผ์†Œ ๊ฐ’์ด ์จ์ ธ ์žˆ๋‹ค. ๋˜ํ•œ parseheap์œผ๋กœ ํ•ด๋‹น ์ฒญํฌ์˜ fd์™€ bk๊ฐ€ ์–ด๋– ํ•œ ํŠน์ • ์ฃผ์†Œ ๊ฐ’์œผ๋กœ ๋™์ผํ•˜๊ฒŒ ๋“ค์–ด๊ฐ„ ๊ฒƒ๋„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

free(chunk6);

chunk6์€ malloc(0x88)๋กœ ํ• ๋‹นํ•˜์˜€๊ณ , chunk์˜ ํฌ๊ธฐ๋Š” 0x90์ด๋‹ค. ์ด ๋˜ํ•œ freeํ–ˆ์„ ๋•Œ, fastbin์— ๋“ค์–ด๊ฐˆ ํฌ๊ธฐ๊ฐ€ ์•„๋‹ˆ๋ฉฐ, unsorted bin์— size๊ฐ€ ์ฆ๊ฐ€ํ•œ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. ์ด๋Š” chunk์™€ chunk๊ฐ€ ์ธ์ ‘ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ณ‘ํ•ฉ๊ณผ์ •์ด ์ผ์–ด๋‚œ ๊ฒƒ์ด๋‹ค. ๊ทธ์— ๋ฐ˜ํ•ด fastbin์€ ์ธ์ ‘ํ•œ chunk๋ผ๊ณ  ํ•˜๋”๋ผ๋„, ์•ž์„œ ๋ณธ ๊ฒƒ ์ฒ˜๋Ÿผ ๋ณ‘ํ•ฉ๊ณผ์ •์ด ์ผ์–ด๋‚˜์ง€ ์•Š๋Š”๋‹ค.

free(chunk7);

๋ชจ๋“  chunk๊ฐ€ free๋˜์—ˆ๋‹ค. ๋งˆ์ง€๋ง‰ free์—ฌ์„œ ์ธ๊ฐ€(?)

unsorted bin

์•ž์„œ fastbin์„ ๋ณด๋ฉด์„œ ๋งˆ์ง€๋ง‰์— ์‚ด์ง ํ™•์ธํ–ˆ๋˜ bin์ด๋‹ค. fastbin๊ณผ๋Š” ๋‹ค๋ฅด๊ฒŒ FIFO(์„ ์ž…์„ ์ถœ) ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•˜๊ณ  1๊ฐœ์˜ bin๋งŒ์„ ์‚ฌ์šฉํ•œ๋‹ค. Freed chunk๊ตฌ์กฐ์—์„œ fd์™€ bk๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ด์ค‘ ์—ฐ๊ฒฐ๋ฆฌ์ŠคํŠธ๋กœ ๊ด€๋ฆฌํ•œ๋‹ค.

unsorted bin์€ fastbin์— ๋“ค์–ด๊ฐ€์ง€ ์•Š๋Š” chunk๊ฐ€ small bin๊ณผ large bin์— ๋“ค์–ด๊ฐ€๊ธฐ ์ „, ํ• ๋‹น๊ณผ ํ•ด์ œ์˜ ์†๋„๋ฅผ ๋†’์ด๊ธฐ ์œ„ํ•ด chunk๋ฅผ unsorted bin์— ์ž ์‹œ ์ €์žฅํ•œ๋‹ค. chunk๋ฅผ ํ• ๋‹นํ•  ๋•Œ fastbin์— ๋งž๋Š” ํฌ๊ธฐ๊ฐ€ ์—†๋‹ค๋ฉด, unsorted bin์„ ํ™•์ธํ•˜์—ฌ ์žฌํ• ๋‹น๋˜๊ฑฐ๋‚˜ ์›๋ž˜์˜ bin์œผ๋กœ ๋Œ์•„๊ฐ„๋‹ค. unsorted bin์— ๋“ค์–ด๊ฐ„ chunk๋Š” NON_MAIN_ARENA ํ”Œ๋ž˜๊ทธ๊ฐ€ true๊ฐ€ ๋˜์ง€ ์•Š๋Š”๋‹ค.

unsorted bin์œผ๋กœ free๋˜๋Š” ๊ณผ์ •์„ ์˜ˆ์ œ ์ฝ”๋“œ๋กœ ํ™•์ธํ•ด๋ณด์ž.

//Name : unsortedbin.c
//Compiler : gcc -o unsortedbin unsortedbin.c -no-pie -fno-stack-protector
#include <stdio.h>
#include <stdlib.h>
int main()
{
        char* chunk1 = malloc(0x80);
        char* chunk2 = malloc(0x10);
        char* chunk3 = malloc(0x80);
        char* chunk4 = malloc(0x10);
        char* chunk5 = malloc(0x80);
        char* chunk6 = malloc(0x10);
        free(chunk1);
        free(chunk3);
        free(chunk5);
				char* chunk7 = malloc(0x500);
        free(chunk7);
				return 0;
}

์œ„ ์‚ฌ์ง„์€ ์˜ˆ์ œ ์ฝ”๋“œ์—์„œ ๋ชจ๋“  chunk๊ฐ€ ํ• ๋‹น๋œ ์ƒํƒœ์˜ ๋ฉ”๋ชจ๋ฆฌ ๊ตฌ์กฐ์ด๋‹ค. ๋จผ์ €, unsorted bin์œผ๋กœ ๋„ฃ์„ chunk๋Š” fastbin์˜ ํฌ๊ธฐ ๋ฒ”์œ„๋ณด๋‹ค ํฐ 0x90์œผ๋กœ ํ• ๋‹นํ•ด์คฌ๊ณ , ์ด 0x90 ํฌ๊ธฐ์˜ chunk๋“ค์ด ์—ฐ์†์ ์œผ๋กœ ์ธ์ ‘ํ•ด์žˆ์œผ๋ฉด ํ•ด์ œ๊ณผ์ •์—์„œ ๋ณ‘ํ•ฉ์ด ์ด๋ค„์ง€๊ธฐ ๋•Œ๋ฌธ์— ์ค‘๊ฐ„์ค‘๊ฐ„ fastbin ํฌ๊ธฐ์˜ chunk๋ฅผ ํ• ๋‹นํ•ด์คฌ๋‹ค.

free(chunk1);

chunk1์˜ ํ•ด์ œ๊ฐ€ ์ด๋ค„์ง€๋ฉด unsorted bin์œผ๋กœ chunk๊ฐ€ ๋“ค์–ด๊ฐ„๋‹ค. ์ด๋•Œ, ํ•ด์ œ๋œ ์ฒญํฌ๋Š” ์ด์ค‘ ์—ฐ๊ฒฐ๋ฆฌ์ŠคํŠธ๋กœ ๊ด€๋ฆฌ๊ฐ€ ๋œ๋‹ค. fd์™€ bk๋ฅผ ๋ณด๋ฉด ์ฃผ์†Œ ๊ฐ’์ด ๋“ค์–ด๊ฐ€ ์žˆ๋‹ค. ์ด ๊ฐ’์„ ํ™•์ธํ•ด๋ณด๋ฉด main_arena+88 ์œ„์น˜์˜ ์ฃผ์†Œ์ธ ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค. ๋งŒ์•ฝ ์ด ์ฃผ์†Œ๋ฅผ leak ํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด, ์ด๋ฅผ ํ†ตํ•ด libc base๋ฅผ ๊ตฌํ•  ์ˆ˜ ์žˆ๋‹ค.

free(chunk3);

chunk3์ด ํ•ด์ œ๋˜๋ฉด, ์—ญ์‹œ unsorted bin์— ์šฐ์„ ์ ์œผ๋กœ ๋“ค์–ด๊ฐ„๋‹ค. main_arena+88์„ ๊ธฐ์ค€์œผ๋กœ fd์™€ bk๋กœ chunk๊ฐ€ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. ๋งŒ์•ฝ ์—ฌ๊ธฐ์„œ ์žฌํ• ๋‹น์ด ์ด๋ฃจ์–ด์ง€๋ฉด, ๋จผ์ €๋“ค์–ด์™”๋˜ 0xa7d000์ด ํ• ๋‹น๋˜๊ฒŒ ๋  ๊ฒƒ์ด๋‹ค.

free(chunk5);

chunk5๊ฐ€ ํ•ด์ œ๋œ ๋ฉ”๋ชจ๋ฆฌ ๊ตฌ์กฐ์ด๋‹ค. ์•ž์„  ์„ค๋ช…๊ณผ ๊ฐ™์ด unsorted bin์— ์ž˜ ๋“ค์–ด๊ฐ”๋‹ค. ํ˜„์žฌ๊นŒ์ง€์˜ bins ์ƒํƒœ์—์„œ ์žฌํ• ๋‹น์„ ํ•˜๋ฉด์„œ bins์˜ ๋ณ€ํ™”๋ฅผ ์‚ดํŽด๋ณด์ž.

char* chunk7 = malloc(0x500);

chunk7์— malloc(0x500)์„ ํ•ด์คฌ๋‹ค. ํ• ๋‹น ์‹œ ์ œ์ผ ๋จผ์ € fast bin ํฌ๊ธฐ๊ฐ€ ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— unsorted bin์—์„œ ์•Œ๋งž๋Š” chunk๋ฅผ ํ™•์ธํ•  ๊ฒƒ์ด๋‹ค. ํ•˜์ง€๋งŒ unsorted bin์˜ chunk๋“ค์˜ ํฌ๊ธฐ๋Š” 0x90์ด์—ˆ์œผ๋ฏ€๋กœ, malloc(0x500)์— ์ ํ•ฉํ•˜์ง€ ์•Š๋‹ค. ์žฌํ• ๋‹น ๊ณผ์ •์ด unsorted bin์—์„œ ์ด๋ค„์ง€์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— ํ•ด๋‹น chunk๋“ค์„ ํฌ๊ธฐ์— ๋งž๋Š” small bin์œผ๋กœ ์˜ฎ๊ธด๋‹ค.

free(chunk7);

๋‹ค์‹œ 0x500 ํฌ๊ธฐ์˜ chunk7์„ ํ•ด์ œํ•ด์ฃผ๋ฉด, unsorted bin์— ๋“ค์–ด๊ฐ€์ง€ ์•Š์•˜๋‹ค. ์ด ๊ณผ์ •์€ top chunk์™€ ๋ฐ”๋กœ ์ธ์ ‘ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ณ‘ํ•ฉ๊ณผ์ •์ด ์ด๋ค„์ง„ ๊ฒƒ์ด๋‹ค. ๋งŒ์•ฝ ๊ทธ ์•„๋ž˜ ๋‹ค๋ฅธ chunk๊ฐ€ ์กด์žฌํ–ˆ๋‹ค๋ฉด, unsorted bin์— ๋“ค์–ด๊ฐ”์„ ๊ฒƒ์ด๋‹ค.

๋‹ค์Œ ์˜ˆ์ œ ์ฝ”๋“œ๋กœ small bin๊ณผ large bin, ๊ทธ๋ฆฌ๊ณ  last_remainder์— ๋Œ€ํ•ด ์•Œ์•„๋ณด์ž.

//Name : bins.c
//Compiler : gcc -o bins bins.c -no-pie -fno-stack-protector
#include <stdio.h>
#include <stdlib.h>
void main()
{
        char* chunk1 = malloc(1000);
        char* chunk2 = malloc(0x10);
        char* chunk3 = malloc(1024);
        char* chunk4 = malloc(0x10);
        free(chunk1);
        free(chunk3);
        char* chunk5 = malloc(1200);
        char* chunk6 = malloc(0x10);
        free(chunk5);
}

small bin

์•ž์„œ unsorted bin์—์„œ ์žฌํ• ๋‹น๋˜์ง€ ๋ชปํ•œ ๊ฒฝ์šฐ, chunk์˜ ํฌ๊ธฐ๊ฐ€ fast bin๋ณด๋‹ค ํฌ๊ณ  512byte(64bit ์šด์˜์ฒด์ œ์ธ ๊ฒฝ์šฐ 1024byte) ๋ณด๋‹ค ๋ฏธ๋งŒ์ธ ๊ฒฝ์šฐ์— small bin์œผ๋กœ ๊ด€๋ฆฌํ•˜๊ฒŒ ๋œ๋‹ค. ์ด bin ๋˜ํ•œ FIFO(์„ ์ž…์„ ์ถœ) ๋ฐฉ์‹์ด๊ณ , ํฌ๊ธฐ์— ๋”ฐ๋ผ 62๊ฐœ์˜ bin์„ ๊ฐ€์ง„๋‹ค.

chunk4๊นŒ์ง€ ํ• ๋‹น๋˜๊ณ  chunk1๊ณผ chunk3์„ freeํ•œ ์ƒํƒœ์ด๋‹ค. ์ด ์ƒํƒœ์—์„œ 1200byte ํฌ๊ธฐ๋กœ malloc์„ ํ•ด์ฃผ๋ฉด, unsorted bin์—์„œ ํ•ด๋‹นํ•˜๋Š” ํฌ๊ธฐ์˜ chunk๊ฐ€ ์—†์œผ๋ฏ€๋กœ, unsorted bin ์•ˆ์˜ ๋‘๊ฐœ์˜ chunk๋Š” ๊ฐ์ž ํฌ๊ธฐ์— ํ•ด๋‹นํ•˜๋Š” bin์— ๋“ค์–ด๊ฐˆ ๊ฒƒ์ด๋‹ค.

์ด๋•Œ smallbin์— ๋“ค์–ด๊ฐ„ chunk๋ฅผ ํ™•์ธํ•ด๋ณด์ž.

์—ญ์‹œ๋‚˜ fd์™€ bk๋ฅผ ์ด์šฉํ•ด์„œ chunk๋ฅผ ๊ด€๋ฆฌํ•˜๊ณ , ํฌ๊ธฐ์— ๋”ฐ๋ผ main_arena๋ฅผ ๊ธฐ์ค€์œผ๋กœ ๊ด€๋ฆฌํ•œ๋‹ค.

large bin

์•ž์„œ ์„ค๋ช…ํ–ˆ๋˜ small bin๊ณผ ๊ฐ™์ด FIFO(์„ ์ž…์„ ์ถœ) ๋ฐฉ์‹์ด๋ฉฐ, 63๊ฐœ์˜ bin์„ ๊ฐ€์ง„๋‹ค. 512byte(64bit ์šด์˜์ฒด์ œ์ธ ๊ฒฝ์šฐ 1024byte) ๋ณด๋‹ค ํฐ chunk๋ฅผ ๊ด€๋ฆฌํ•œ๋‹ค.

small bin์— ์žˆ๋Š” ์‚ฌ์ง„๊ณผ ๋™์ผํ•˜๋‹ค. ์ด๋•Œ largebin์„ ๋“ค์–ด๊ฐ„ chunk๋ฅผ ํ™•์ธํ•ด๋ณด์ž.

fd์™€ bk๋ฅผ ์ด์šฉํ•ด์„œ chunk๋ฅผ ๊ด€๋ฆฌํ•œ๋‹ค. ํ•˜์ง€๋งŒ, ๊ทธ ์•„๋ž˜ fd_nextsize์™€ bk_nextsize์˜ ํ•„๋“œ ๊ฐ’์ด ๋“ค์–ด๊ฐ„ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. ํ˜„์žฌ์˜ chunk ํฌ๊ธฐ๋ณด๋‹ค ์ž‘์€ chunk๋ฅผ fd_nextsize, ํฐ chunk๋ฅผ bk_nextsize๋กœ ์„ค์ •ํ•˜์—ฌ chunk๋ฅผ ๊ด€๋ฆฌํ•œ๋‹ค. ํ˜„์žฌ๋Š” ํ•˜๋‚˜์˜ chunk๊ฐ€ ์กด์žฌํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋‘ ํ•„๋“œ์˜ ๊ฐ’์ด ๊ฐ™๋‹ค.

last_remainder

chunk6์˜ ํ• ๋‹น์ด ์ด๋ค„์ง„ ์ƒํƒœ์˜ ๋ฉ”๋ชจ๋ฆฌ ๊ตฌ์กฐ์ด๋‹ค.

fast bin ํฌ๊ธฐ์ด๊ณ , small bin์— ์žˆ๋Š” chunk๋ฅผ ๋ถ„๋ฆฌํ•˜์—ฌ 0x18a3000 ์ฃผ์†Œ๋ฅผ ๊ฐ€์ง€๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. ์ด๋•Œ fast bin ๋งŒํผ ํฌ๊ธฐ๋ฅผ ํ• ๋‹นํ•ด์ฃผ๊ณ , top chunk์™€๋Š” ์ธ์ ‘ํ•˜์ง€ ์•Š์•„ ๋ณ‘ํ•ฉ๋˜์ง€ ์•Š๋Š”๋‹ค. ์ด๋Ÿฌํ•œ chunk๋ฅผ last_remainder chunk๋ผ๊ณ  ํ•œ๋‹ค.

์ž์„ธํžˆ ํ™•์ธํ•ด๋ณด๋ฉด 0x20๋งŒํผ fastbin์œผ๋กœ ๋ถ„๋ฆฌํ•˜๊ณ , 0x18a3020๋ถ€ํ„ฐ ๋‹ค์‹œ chunk๋ฅผ ๊ตฌ์„ฑํ•œ๋‹ค. ์ด๋•Œ ์•ž ์ฒญํฌ๊ฐ€ ์‚ฌ์šฉ์ค‘์ด๋ฏ€๋กœ, sizeํ•„๋“œ์˜ PREV_INUSE ํ”Œ๋ž˜๊ทธ๊ฐ€ true๊ฐ€ ๋œ๋‹ค.

tcache bin

๐Ÿ’ก
glibc 2.26๋ถ€ํ„ฐ ๋ฉ€ํ‹ฐ ์Šค๋ ˆ๋“œ ํ™˜๊ฒฝ์—์„œ ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น ์†๋„๋ฅผ ๋†’์ด๊ธฐ ์œ„ํ•ด ์ƒ๊ฒจ๋‚ฌ๋‹ค. ๊ธฐ๋ณธ์ ์ธ heap ๊ตฌ์กฐ๋ฅผ ๋จผ์ € ์ดํ•ดํ•˜๊ณ , ์ถ”ํ›„์— ๋”ฐ๋กœ ๊ณต๋ถ€ํ•  ๊ณ„ํš์ด๋‹ค.


Uploaded by N2T

    'Pwnable' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€
    • [Dreamhack] tcache_dup - write up
    • [Dreamhack] Tcache Poisoning - write up
    • Heap ๋ฉ”๋ชจ๋ฆฌ ๊ตฌ์กฐ1 - Chunk ํ•„๋“œ์™€ ์ข…๋ฅ˜
    • [Dreamhack] uaf_overwrite - write up
    e_yejun
    e_yejun
    ์ •๋ฆฌ๋…ธํŠธ •_•

    ํ‹ฐ์Šคํ† ๋ฆฌํˆด๋ฐ”