Challenge Name:
Nissehalla
Category:
Reversing
Challenge Description:
Alle nisser drømmer om at få risengrød og gløgg i Nissehalla, find de to nøgler og luk porten op for de stakkels hungrende nisser.
Start server på TryHackMe og forbind med nc 8080
https://tryhackme.com/jr/nissehalla2o25v1
Approach
Reconnaissance:
- Scanning the target IP revealed port 8080 was open.
- Visiting
http://<IP>:8080showed a “Nissehalla” access page with a form requiring two files (fileAandfileB).
Reverse Engineering:
- Analyzing the binary provided, in
objdump/ Ghidra revealed a custom hash functionweird_hash64. - The hash function initializes a state and processes the input buffer.
- Crucially, it processes the buffer by visiting indices in a pseudo-random order determined by a linear congruential generator (LCG)-like update:
step = ((5 * step + 3) & 7) + 1. - The loop condition
test r13b, 0x3controls an inner processing loop. - Maybe for certain file lengths, the traversal logic might miss some indices completely.
- Analyzing the binary provided, in
Vulnerability Analysis:
- I then wrote the script solve_collision.py to simulate the index visitation logic of the hash function.
- The script checked lengths from 10 to 300.
- It discovered that for length 10, the hash function never reads the bytes at indices 3, 7, 8, and 9.
- This means any changes to these bytes do not affect the resulting hash.
Exploitation:
Flag
NC3{!H45H_colLi5ION_m45T3R_2025!}
Reflections and Learnings
- Static Analysis pays off: Ghidra and static analysis is hard… But instead of blindly fuzzing, understanding the code revealed a deterministic flaw.
- Coverage matters: The hash function failed to process the entire input for certain lengths, violating a core property of secure hashing.
- Side Note: The “Truncated hash” output from the server hinted at weakness, but the real flaw was in the input processing logic (skipping bytes) rather than just the output size.