Skip to content

Latest commit

 

History

History
101 lines (63 loc) · 3.62 KB

pinpointing-low-level-bugs-in-android-heap-exploitation.md

File metadata and controls

101 lines (63 loc) · 3.62 KB
description cover coverY
06/26/2024
-8

🔍 Pinpointing Low-Level Bugs in Android: Heap Exploitation

Introduction

Attacking dynamic memory region vulnerabilities!

{% hint style="info" %} :rotating_light: Let me just start this one off as a preface:

Wow, if you thought heap exploitation was crazy before, just wait until you finish reading this one. {% endhint %}

References

{% embed url="https://www.synacktiv.com/en/publications/exploring-android-heap-allocations-in-jemalloc-new" %} Synack {% endembed %}

{% embed url="https://ir0nstone.gitbook.io/notes/types/heap" %} ir0nstone {% endembed %}

What is Heap Spraying and Heap Grooming?

Wait, Heap Feng Shui?

{% hint style="info" %} :biohazard: This is an "Exploit Delivery Technique". {% endhint %}

This helps an attacker to be able to replace newly freed objects with objects of the attacker's choice.

Knowing information and sizing ahead of time will allow us to overwrite important objects on the heap.

  • This really comes in handy with attacks such as Use-After-Free (UAF's)

Why is This so Revalent in a UAF Attack?

This is because when an object becomes freed (free()), the location itself is now freed, but the object pointer still remains available to the attacker. This is known as a dangling pointer. I always pictured dangling pointers as being similar to the Anglerfish that can be found within the deepest parts of the ocean, known as abysses. Better yet, a Danglerfish 😉.

Simply put, a dangling pointer is a pointer that has been recently freed but it's still a pointer that points to invalid data. This can lead to unexpected results or code execution.

Depiction of a dangling pointer. -- Danglerfish

Allocation Size Classes

Different allocation regions when allocating memory with JEMalloc

How Does This Work?

Given the following C code:

#include <stdio.h>
#include <stdlib.h>

int main() {
    size_t size = 1337; // Number of bytes to allocate
    void *ptr;

    // Allocate memory dynamically for 512 bytes
    ptr = malloc(size);

    if (ptr == NULL) {
        printf("Memory allocation failed\n");
        return 1;
    }

    printf("Memory allocated successfully: %zu bytes\n", size);

    // Free the allocated memory
    free(ptr);

    return 0;
}

Output:

Memory allocated successfully: 1337 bytes

We have allocated 1,337-bytes of data within the heap memory region of the virtual process space.

This means that we our object will be stored within the 22nd bucket (23rd if you're counting from 0, but still 22nd from labeling) with a max of 1,536 bytes that can be allocated. It can't be stored in the 21st bucket as it is only optimized for 1,280-bytes, not enough for 1,337.

This means when we are spraying the heap, we'll be able to spray for the same sized object.

For Visualization:

Visual aid for allocating 1,337-bytes on the heap -- It will be stored within the 22nd bucket