Skip to main content

Overview

The how2heap repository supports multiple glibc versions, allowing you to learn and test heap exploitation techniques across different environments. Each technique is verified to work on corresponding Ubuntu releases that ship with specific glibc versions.
We use Ubuntu’s libc releases as the gold standard. Each technique is verified to work on corresponding Ubuntu releases.

Supported glibc Versions

The repository currently supports the following glibc versions:
  • 2.23 - Ubuntu 16.04 LTS (Xenial)
  • 2.24 - Ubuntu 16.10 (Yakkety)
  • 2.27 - Ubuntu 18.04 LTS (Bionic)
  • 2.31 - Ubuntu 20.04 LTS (Focal)
  • 2.32 - Debian Bullseye / Ubuntu 20.10
  • 2.33 - Ubuntu 21.04
  • 2.34 - Ubuntu 21.10
  • 2.35 - Ubuntu 22.04 LTS (Jammy)
  • 2.36 - Debian Bookworm
  • 2.37 - Experimental
  • 2.38 - Debian Testing
  • 2.39 - Latest stable
  • 2.40 - Development
  • 2.41 - Latest development
Techniques are organized in version-specific directories (glibc_<version>/) to accommodate patches and mitigations introduced in each version.

Testing with Specific Versions

There are two primary approaches to testing heap exploitation techniques with specific glibc versions:

Method 1: Using System libc (Quick Setup)

This is the fastest way to get started. It compiles binaries using your system’s installed libc.
This method links binaries with your system libc. If you want to test with other libc versions, use Method 2 or Method 3.
This method links binaries directly with the target libc version, avoiding symbol versioning issues.
What this does:
  • Downloads and sets up the specified glibc version
  • Links all binaries against the target libc
  • Includes debug symbols for easier debugging
  • Allows testing any libc version on your host machine
Replace 2.23 with any supported version (2.23, 2.27, 2.31, 2.35, 2.39, etc.)

Method 3: Docker-Based Approach

This uses Docker containers to compile binaries inside an old Ubuntu environment, ensuring compatibility with the target libc version.
Verify the setup:

Using H2H_USE_SYSTEM_LIBC

The H2H_USE_SYSTEM_LIBC environment variable controls which compilation method is used: Examples:

Version-Specific Compilation

The Makefile provides targets for each supported version:

Testing Techniques

You can automatically test all techniques for a specific version:
This will run each technique up to 20 times to account for ASLR and randomization.

Docker vs Native Approach

Docker Approach

Advantages:
  • Guarantees environment compatibility
  • Isolated from host system
  • Can use old Ubuntu versions
  • No conflicts with system libraries
Disadvantages:
  • Requires Docker installation
  • Slower build times
  • Additional complexity
  • Larger disk space usage

Native Approach (H2H_USE_SYSTEM_LIBC=N)

Advantages:
  • Faster compilation
  • Direct debugging with gdb
  • Includes debug symbols
  • Works on any host system
  • No Docker required
Disadvantages:
  • May encounter symbol versioning issues
  • Requires handling multiple libc versions
  • First download can be slow
For most users, the native approach with H2H_USE_SYSTEM_LIBC=N is recommended. It provides the best balance of speed, flexibility, and debugging capability.

Prerequisites

Before compiling techniques, ensure you have the required packages:

Troubleshooting

Symbol Versioning Issues

If you encounter symbol versioning errors when using LD_PRELOAD:

Missing libc Version

If a specific libc version is not available:

Compilation Errors

Ensure all dependencies are installed:

Example Workflow

Here’s a complete workflow for testing a technique on glibc 2.35:

Additional Resources

For more information on setting up your environment:
  • [Getting Started Guide/quickstart)
  • [Heap Exploitation Tools/tools/debugging-tools)
  • [Debugging Heap Issues/tools/debugging-tools)