Dark Runes
HackTheBox
"Survivors find a battered laptop in the rubble. Powering it up, they discover a cryptic software interface from an ancient architecture firm, hinting at vital blueprints. They must crack its security protocols. Undeterred, they race against time."
$ ls tags/ techniques/
$ cat /etc/rate-limit
Rate limit reached (20 reads/hour per IP). Showing preview only — full content returns at the next hour roll-over.
Dark Runes — HackTheBox
Description
"Survivors find a battered laptop in the rubble. Powering it up, they discover a cryptic software interface from an ancient architecture firm, hinting at vital blueprints. They must crack its security protocols. Undeterred, they race against time."
Target: http://154.57.164.69:31117
Technology Stack
- Node.js 16.5.0 (Express) — web application
- SQLite — database with
usersanddocumentstables - markdown-pdf v11.0.0 — markdown to PDF conversion via PhantomJS
- sanitize-html — HTML sanitization (only on regular document routes)
- HMAC-like cookie auth — custom cookie generation/validation with random SECRET
- PhantomJS — headless browser used by markdown-pdf for rendering
Architecture
Single Express application with the following route structure:
- Auth routes (
/login,/register) — user registration and login with cookie-based auth - Document routes (
/document/*) — CRUD for markdown documents, content sanitized viasanitize-html - Export routes (
/document/export/:id,/document/debug/export) — PDF generation from markdown/HTML
Key security middleware:
isAuthenticated— validates cookie signature using HMAC with random SECRETisAdmin— checksreq.user.username === "admin"
Access code system:
rotatePass()generates a 4-digit code (0000-9999) viacrypto.randomBytes(2).readUInt16BE() % 10000- Writes the code to a file named with that code
verifyPass()checks the pass; on failure, callsrotatePass()to generate a new code- Only
rotatePass()is called on startup — no admin user is pre-created
Analysis
Vulnerability 1: Missing Admin User — Registration Bypass
The isAdmin middleware checks req.user.username === "admin", but the application never creates an admin user at startup. Only rotatePass() is called in src/index.js. The /register endpoint has no restriction on the username "admin", so anyone can register as admin.
...
$ grep --similar
Similar writeups
- [web][free]Desires— HackTheBox
- [web][free]Blueprint Heist— hackthebox
- [misc][free]Prison Pipeline— HackTheBox Business CTF 2024
- [web][Pro]Lanternfall— neurogrid
- [infra][Pro]Kobold— hackthebox