Heap Introducing
Heap
- là vùng nhớ được khởi tạo động
–-> dùng để lưu trữ dữ liệu –-> theo ý người lập trình
- được dùng trong suốt quá trình chương trình thực thi
- tạo bởi những hàm như malloc(), calloc(), realloc(), …
===> Ảnh hưởng lớn bởi các cuộc tấn công
info Calloc()


- “calloc” or “contiguous allocation”
- calloc() doesn't use Tcache
Info Realloc()


- ptr = NULL -> realloc = malloc(size)
- size = 0 -> realloc = free(ptr)
Dynamic Memory Allocation in C using malloc(), calloc(), free() and realloc() - GeeksforGeeks
Chunks (vùng nhớ)
Image Not Showing
Possible Reasons
- The image was uploaded to a note which you don't have access to
- The note which the image was originally uploaded to has been deleted
Learn More →
- khi 1 chương trình thực thi hàm malloc() sẽ trả về 1 con trỏ
–-> trỏ tới 1 chunk heap (còn được gọi là vùng nhớ)
- được phân làm 2 vùng chính (cấu trúc chung):
- metadata
- prev size : kích thước chunk trước
- size : kích thước chunk hiện tại
- content
trước con trỏ của chunk đó sẽ biểu diễn 2 loại thông tin
prev size và size –-> metadata
rồi ngay con trỏ chunk đó sẽ là content
64 bits |
32 bits |
heap metadata = 0x10 |
heap metadata = 0x8 |
vì 1 size = 8 bytes |
vì 1 size = 4 bytes |
- Size sẽ được làm tròn theo nguyên tắc
- ví dụ:
- thông thường sẽ làm tròn 0x10 (dữ liệu metadata)
- malloc bao nhiêu sẽ tạo chunk có size bao gồm cả metadata
- và sẽ được cộng 1 bit đánh dấu
- nếu ta tạo vùng nhớ quá lớn –-> tạo vùng nhớ riêng ngoài heap –-> bit 0x2 bật cho mmap()
Heap có bộ nhớ tối đa là 0x21000
Image Not Showing
Possible Reasons
- The image was uploaded to a note which you don't have access to
- The note which the image was originally uploaded to has been deleted
Learn More →
Image Not Showing
Possible Reasons
- The image was uploaded to a note which you don't have access to
- The note which the image was originally uploaded to has been deleted
Learn More →
tạo pointer đến vùng nhớ riêng 0x007ffff7f7f010 (địa chỉ trắng)
mà không phải heap (địa chỉ màu xanh)
Image Not Showing
Possible Reasons
- The image was uploaded to a note which you don't have access to
- The note which the image was originally uploaded to has been deleted
Learn More →
Bin (ngăn xếp)
Image Not Showing
Possible Reasons
- The image was uploaded to a note which you don't have access to
- The note which the image was originally uploaded to has been deleted
Learn More →
- chứa chunks đã được giải phóng ( bởi hàm free() )
- có 5 loại bins tất cả :
- 62 doubly-linked small bins (up to 0x200 bytes)
- 63 doubly-linked large bins (over 0x200 bytes)
- 1 doubly-linked unsorted bin (not fit fastbins or tcache bins)
- 7 singly-linked fast bins (0x20 to 0x80 bytes)
- 64 singly-linked tcache bins per thread (0x20 to 0x410 bytes)
The small, large, and unsorted bins implement the basic recycling strategy of the heap
The fast bins and tcache bins are optimizations that layer on top of these.
Confusingly, the small, large, and unsorted bins all live together in the same array in the heap manager’s source code
Index 0 is unused, 1 is the unsorted bin, bins 2-64 are small bins and bins 65-127 are large bins
Image Not Showing
Possible Reasons
- The image was uploaded to a note which you don't have access to
- The note which the image was originally uploaded to has been deleted
Learn More →
👀 fastbins
- đối với libc < 2.27 thì chi có fastbins, k có tcache
- không giới hạn chunk sau khi free()
- là 1 dslk đơn
- free 1 chunk có size từ 0x20 đến 0x80 (đã bao gồm heap metadata) –-> đưa vào fastbins
- ví dụ:
- khi malloc() lại cùng 1 size thì chương trình sẽ lấy cái chunk (cùng size) vừa free đó trả về sử dụng tiếp
- fastbins được tổ chức theo cơ chế LIFO (last in first out)
- cú pháp gọi kiểm tra
👀 tcache
- về cơ bản giống fastbins nhưng có vài điểm khác
- là loại ngăn xếp mới được giới thiệu ở libc 2.26 trở lên
- cũng là 1 dslk đơn
- mỗi thread là 1 tcache khác nhau
- chứa tối đa 7 chunks cùng 1 size (nhưng kích thước lớn hơn, đa dạng hơn)
- các chunk trong bin được liên kết với nhau thông qua
fw_pointer
===> khi malloc() lại sẽ tuân theo quy tắc LIFO (last in first out)
(chunk free() cuối cùng sẽ là chunk đầu trong bin)
(được ra đầu tiên khi malloc() cùng size)
- khi free(), chunk được ưu tiên đưa vào tcache, khi đầy 7 chunks cùng 1 size trong tcache –-> đẩy xuống fastbins | unsortedbin | largebin | .v.v
- ví dụ
- compile code C trên:
gcc run.c -o run
- có thể chứa
64
tcache lists, với idx values khoảng 0-63
, chunk sizes nằm giữa 0x20-0x410
- nhấn mạnh rằng count=7 là tối đa cho mỗi thread tcache, k phải đại diện cho tổng chunk trong tcache
- example: (14 chunks chia vào 2 bins)
đặc điểm chung
- fastbins và tcache đều là dslk đơn
- khi 1 chunk được đưa vào tcachebin hoặc fastbins sẽ có thêm 1 tham số:
- fw (forward pointer): là 1 con trỏ trỏ tới thằng tiếp theo

fw của thằng 93c0 là 9390
tương tự thì fw của 9390 là 9360
👀 unsorted, large, small bins
- là dslk đôi
- về cơ bản chúng giống nhau
- là thằng sau trỏ tới thằng trước, thằng trước lại trỏ ra thằng sau
- khi free 1 chunk có size lớn hơn 0x410 (maximum của tcache và out of range fastbins) –-> đưa vào unsorted bin

free p2[i] lần 1
chunk 9420, size=0x420

free p2[i] lần 2
chunk 9420, size=0x840
- ở đây k tạo cái chunk thứ 2 có size là 0x420 mà lại gộp chunk thành size 0x840 và sài chung 1 địa chỉ 9420. tại sao ?
🟥 unsorted bin sẽ có 3 dạng
👉 gộp chunks

- hiện tượng gộp chunk, dslk đôi sẽ cho ta 2 con trỏ fw (forward ptr) và bk (backward ptr) cùng trỏ tới 1 vùng, và vùng đó gọi là main_arena
👉 phân bổ chunks
- giả sử ta có 1 ubin (exploit trên libc2.23 không có tcache)

ubin 4020 có size 0xa1

- khi ta request 1 chunk có size khác 0x70 (tránh lấy lại fastbin) như là size 0x78
- thì sự phân bổ diễn ra như sau

xuất hiện ubin mới 40a0
chunk 4020 có size mình request là 0x80
(nếu không ow data nào thì fw_pointer vẫn là main_area)
ubin 40a0 có size còn lại từ size cũ (0xa0-0x80=0x20)

👉 trỏ tới chunk kế tiếp
- source code lúc này sẽ xen kẽ chunk nhỏ chunk lớn
- khi free chunk nhỏ –-> đưa vào tcachebins
- khi free chunk lớn –-> đưa vào unsorted bin
- tiếp tục loop, free chunk nhỏ rồi tới chunk lớn

khi free có chunk chen giữa, xảy ra hiện tượng trỏ
con trỏ fw và bk sẽ khác
- chunk đầu tiên là 9720, có fw trỏ tiếp thằng 92d0
thằng 92d0 là thằng 92c0 ngay x/20xg đầu tiên
chỉ là 92d0 trỏ ngay phần content, còn 92c0 trỏ ngay phần heap metadata
- có luôn bk trỏ về main_arena

- đặc biệt là chunk đầu trỏ về chunk sau và chunk sau lại trỏ về chunk đầu

9710 là phần heap metadata, 9720 là chunk đầu
===> Không gộp vì do giữa 2 chunk cùng size bị ngăn cách bới 1 chunk khác
🤌 small bins | large bins

lúc này khi free 2 lần của p2[i]
- tiếp tục malloc() có kích thước 0x200
- kiểm tra ở tcache và fastbin k có kích thước nào thoả –-> loại
- nhưng ở unsorted bin có 1 chunk size=0x840, lớn hơn 0x200
–-> trích bớt 0x200+0x10 size
- lúc này unsorted bin còn 0x630

xem ở 2 dòng highlight
- nếu tiếp tục malloc() cho kích thước 0x2000
- cả tcache, fastbins, unsorted bin đều k thoả –-> lấy từ top chunk

before

after
- lúc này unsorted bin chứa chunk có size 0x630 , khi malloc() 1 kích thước còn lớn hơn cả unsorted bin thì từ unsorted thành sorted =)))))))))
- theo nghĩa tiếng anh là chunk size 0x630 ấy chưa dc phân loại, khi mà đc malloc() cho 1 chunk lớn hơn 0x630 thì lúc này sẽ phân chunk 0x630 ấy xuống large bins, còn chunk nhỏ 0x30 sẽ phân vào small bins

small bin lấy từ fastbins xuống
🟥 từ unsorted xuống large hoặc small
- khi unsorted bin chứa chunk có size < 0x410 đồng thời malloc() 1 chunk có size lớn hơn
–-> phân vào small bins
–-> còn lại lớn hơn 0x410 phân vào large bins

Consolidation (sự gộp chunk)
- nói đơn giản thì đây là 1 cái proctect combat fragmentation (chống tấn công phân mảnh)
- ví dụ: nếu allocate 1 đống chunk tiny khiến lãng phí –-> bộ nhớ chia làm nhiều phần
- và vấn đề xảy ra khi cố gắng malloc() để cấp phát 1 bộ nhớ khủng hơn nó –-> phải dùng bộ nhớ khác cho nó và lãng phí tài nguyên
- bằng cách gợp freed chunks liền kề thành 1 freed chunk lớn hơn –-> nhiều space có thể malloc() lại hơn
Top chunk
- là vùng bộ nhớ khi mình malloc() sẽ lấy từ top chunk ra
- có thể nói để giữ các khối bộ nhớ chưa được phân bổ
- khi các bin không thoả size, malloc() sẽ lấy từ top chunk cắt một đoạn để phân bổ bộ nhớ do yêu cầu của malloc()
🎯 Top chunk consolidation
- rất nhiều loại heap attack –-> chuyển qua list bin
- cần các freed chunks trong các bins
- gộp chunk với top chunk có thể ngăn chặn điều đó
🎯 ngăn gộp top chunk
- malloc() một đoạn nhỏ ở giữa các freed chunks và top chunk
Main Arena
- contains the head pointers for the bin lists
Heap Exploitation
Deep understanding of heap implementation