> 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/01.-basics.md).

# Binary Exploitation — The Basics

> A beginner-friendly guide to understanding the core concepts before you write a single exploit.

## 📌 What Even Is Binary Exploitation?

When developers write code (usually in C or C++), it gets **compiled** into a binary — a raw executable file that the computer runs directly. Binary exploitation is the art of **finding bugs in these programs and abusing them** to make the program do something it wasn't supposed to do — like give you a shell, leak a secret, or crash in a controlled way.

Think of it like this: the developer built a house (the program), and you're looking for an unlocked window or a loose floorboard (a vulnerability) to get inside.

## 🗺️ The Memory Layout — Where Does Everything Live?

When a program runs, the operating system gives it a chunk of memory. That memory is divided into sections:

```
High addresses  ┌──────────────────┐
                │      Stack       │  ← Function calls, local variables
                │        ↓        │
                │                  │
                │        ↑        │
                │       Heap       │  ← Dynamic memory (malloc, new)
                ├──────────────────┤
                │       BSS        │  ← Uninitialized global variables
                ├──────────────────┤
                │      Data        │  ← Initialized global variables
                ├──────────────────┤
Low addresses   │      Text        │  ← The actual program code
                └──────────────────┘
```

### The Stack

The stack is the most important section to understand for beginners. It works like a stack of plates — **Last In, First Out (LIFO)**.

Every time a function is called, the program **pushes** a "stack frame" onto the stack containing:

* **Local variables** (things declared inside a function)
* The **return address** (where to go back after the function finishes)
* The **saved base pointer** (a bookmark to the previous frame)

When the function ends, the frame is **popped** off and control returns to the caller.

## 📐 What Is an Offset?

An **offset** is just a **distance in bytes** from one point in memory to another.

### Simple Analogy

Imagine a street with houses numbered 0, 1, 2, 3... If you're standing at house 10 and want to reach house 14, the offset is **4**.

### In Exploitation

Say you have a buffer (a chunk of memory) that starts at address `0x7fff1000`, and the return address is stored at `0x7fff1020`.

```
0x7fff1000  [ buffer starts here         ]
0x7fff1010  [                            ]
0x7fff1020  [ return address lives here  ]
```

The **offset from the buffer to the return address** is:

```
0x7fff1020 - 0x7fff1000 = 0x20 = 32 bytes
```

So you'd need to write **32 bytes of junk** before your payload reaches the return address.

### Finding the Offset in Practice

Tools like `pwndbg` + `cyclic` (from pwntools) help find offsets automatically:

```bash
# Generate a cyclic pattern
cyclic 100

# Run the program, let it crash, then check which part of the pattern landed in the return address
cyclic -l <value_in_rip>
```

## 📦 What Is a Buffer?

A **buffer** is just a **fixed-size chunk of memory** reserved to hold data — like an array.

```c
char name[64];  // A buffer that holds 64 bytes
```

The problem? If you try to put MORE than 64 bytes into it and the programmer didn't check, those extra bytes **overflow** into adjacent memory. That's called a **Buffer Overflow** — one of the most classic bugs in binary exploitation.

## 🔤 What Is a String (in binary context)?

In C, a string is just **a sequence of bytes in memory ending with a null byte** (`\x00`). There is no special "string type" — it's just bytes.

```
"Hello" in memory looks like:
48 65 6c 6c 6f 00
H  e  l  l  o  \0
```

### Why Does This Matter?

Many vulnerable functions in C (like `gets`, `strcpy`, `scanf`) **don't check how long the input is**. They just keep reading bytes until they hit a newline or null byte — meaning you can feed them way more data than the buffer can hold.

```c
char buf[32];
gets(buf);       // ← DANGEROUS: reads until newline, no length check
```

## 🏠 What Are Registers?

Registers are **tiny, super-fast storage locations inside the CPU** itself. On a 64-bit system (x86-64), the key ones to know are:

| Register            | Purpose                                                                    |
| ------------------- | -------------------------------------------------------------------------- |
| `rsp`               | Stack pointer — points to the TOP of the stack                             |
| `rbp`               | Base pointer — points to the BOTTOM of the current stack frame             |
| `rip`               | Instruction pointer — holds the address of the NEXT instruction to execute |
| `rax`               | Return value register                                                      |
| `rdi`, `rsi`, `rdx` | First, second, third function arguments                                    |

### The Golden Register: `rip`

If you can **control `rip`**, you control where the program goes next. That's the core goal of most binary exploits — overwrite the return address (which gets loaded into `rip`) to redirect execution.

## 🛡️ Common Protections (and What They Do)

Modern systems have defenses that make exploitation harder. You'll encounter these constantly:

### 1. ASLR — Address Space Layout Randomization

**What it does:** Randomizes the base addresses of the stack, heap, and libraries every time the program runs.

**Why it matters:** You can't hardcode an address in your exploit because it changes each run.

**Bypass idea:** Leak an address at runtime, then calculate where everything else is.

```bash
# Check if ASLR is on
cat /proc/sys/kernel/randomize_va_space
# 0 = off, 2 = full ASLR
```

### 2. NX / DEP — Non-Executable Stack

**What it does:** Marks the stack as non-executable, so you can't just inject shellcode and run it.

**Why it matters:** Classic "put shellcode in the buffer and jump to it" doesn't work.

**Bypass idea:** ROP (Return-Oriented Programming) — chain existing code already in the binary.

```bash
# Check with checksec
checksec --file=./vuln_program
```

### 3. Stack Canary

**What it does:** Places a secret random value between local variables and the return address. Before returning, the program checks if this value was changed.

**Why it matters:** A basic buffer overflow that overwrites the return address will also overwrite the canary, and the program will detect it and abort.

**Bypass idea:** Leak the canary value first, then include it correctly in your payload.

### 4. PIE — Position Independent Executable

**What it does:** Similar to ASLR but for the binary itself — the binary's own code is loaded at a random base address.

**Bypass idea:** Same as ASLR — leak a pointer from the binary, calculate the base.

***

## 🔢 Number Systems You Need to Know

Binary exploitation lives in **hex (base 16)**. Get comfortable with it.

| Decimal | Hex   | Binary      |
| ------- | ----- | ----------- |
| 0       | 0x00  | 0000 0000   |
| 10      | 0x0A  | 0000 1010   |
| 255     | 0xFF  | 1111 1111   |
| 256     | 0x100 | 1 0000 0000 |

### Endianness — The Byte Order Thing

On x86/x64 (most modern systems), values are stored in **little-endian** format — the **least significant byte comes first** in memory.

```
The value 0xdeadbeef stored in memory looks like:
ef be ad de
```

This matters when you're crafting payloads with addresses!

```python
# In pwntools, p64() handles this for you
from pwn import *
p64(0xdeadbeef)  # → b'\xef\xbe\xad\xde\x00\x00\x00\x00'
```

***

## 🧰 Essential Tools for Beginners

| Tool                | What It Does                                                    |
| ------------------- | --------------------------------------------------------------- |
| `gdb` + `pwndbg`    | Debugger — step through a program, inspect memory and registers |
| `pwntools`          | Python library for writing exploits                             |
| `checksec`          | Shows what protections a binary has                             |
| `file`              | Tells you the architecture and type of a binary                 |
| `strings`           | Extracts readable strings from a binary                         |
| `objdump`           | Disassembles a binary                                           |
| `readelf`           | Shows ELF binary structure info                                 |
| `ltrace` / `strace` | Traces library/system calls the program makes                   |

### Quick Start Commands

```bash
# What kind of binary is this?
file ./challenge

# What protections does it have?
checksec --file=./challenge

# Open in gdb with pwndbg
gdb ./challenge

# Inside gdb:
(gdb) run              # run the program
(gdb) info registers   # see all registers
(gdb) x/20gx $rsp      # examine 20 values on the stack
(gdb) disassemble main # disassemble the main function
```

## 📏 What Is a Payload?

A **payload** is the crafted input you send to the vulnerable program. It's usually made of:

1. **Padding** — junk bytes to fill up the buffer and reach the target (like a return address)
2. **The actual exploit data** — an address to jump to, shellcode, ROP chain, etc.

```
[  AAAAAAAAAA...AAA  ][  address_to_jump_to  ]
      padding               overwrite
   (fills the buffer)    (controls rip/eip)
```

In pwntools:

```python
from pwn import *

padding = b"A" * 40          # 40 bytes to reach return address
target  = p64(0x401234)      # address we want to jump to (little-endian)
payload = padding + target

p = process("./vuln")
p.sendline(payload)
p.interactive()
```

***

## 🗂️ Vulnerability Types — Quick Overview

| Vulnerability         | One-Line Description                                                 |
| --------------------- | -------------------------------------------------------------------- |
| **Buffer Overflow**   | Writing more data than a buffer can hold                             |
| **Format String**     | Abusing `printf`-style functions with user-controlled format strings |
| **Use After Free**    | Using a heap pointer after the memory it pointed to was freed        |
| **Integer Overflow**  | Math that wraps around and produces unexpected values                |
| **Command Injection** | Injecting shell commands through unsanitized input (see Part 2)      |
| **Off-by-One**        | Overwriting exactly one extra byte — often enough to hijack control  |

***

## 🧭 The General Exploit Workflow

```
1. Run the binary — understand what it does
         ↓
2. checksec — see what protections are enabled
         ↓
3. Find the vulnerability — static analysis (Ghidra/objdump) or fuzzing
         ↓
4. Figure out the offset — how many bytes to reach the target
         ↓
5. Find your primitive — shellcode? ROP chain? libc leak?
         ↓
6. Write the exploit in pwntools
         ↓
7. Test locally → adjust → test on remote
```

***

## 📚 Recommended Learning Path

1. **Learn C basics** — pointers, arrays, memory allocation
2. **Learn x86-64 assembly** — just enough to read disassembly
3. **Play with GDB** — get comfortable pausing and inspecting programs
4. **Do intro CTF challenges** — pwn.college, picoCTF, CTFlearn
5. **Read** — "Hacking: The Art of Exploitation" by Jon Erickson

***

> 💡 **Remember:** Binary exploitation is about *understanding*, not memorizing. Every time you're confused, open GDB and look at the actual memory. The answers are always there.
