Initial Reconnaissance
nmap -sC -sV headache.nyxPress enter or click to view image in full size

Only two services are exposed:
- 22/tcp — SSH
- 80/tcp — HTTP
No additional services are reachable externally, strongly suggesting the web application is the intended attack surface.
Discovering the API Surface
Press enter or click to view image in full size

Web Server returns 404 this confirms there is no public-facing website, We checked for hidden directories
Press enter or click to view image in full size

We found /api this tells us two things:
- The service is API-driven
- Enumeration should continue under the
/api/namespace
Press enter or click to view image in full size

Press enter or click to view image in full size

Abusing the Search API
Press enter or click to view image in full size

The /api/search endpoint appears harmless at first, It returns an empty result set for normal usage
Operator Injection
Press enter or click to view image in full size

Instead of filtering results, the endpoint returns all indexed documents, This behavior indicates that backend filtering logic trusts user-controlled operators — a classic NoSQL-style logic bug
Internal Documentation Leakage
The dumped search index entries are not arbitrary text; they include internal API contracts and architectural notes that describe how different components of the platform interact.
Carefully reviewing these documents reveals two key pieces of information:
- An internal gateway service responsible for job execution, bound to
localhost:8080, exposing an endpoint named/executeJob. - A description of the portal–gateway relationship, explaining that the public-facing portal validates incoming requests and then forwards job creation requests internally.
One of the indexed documents explicitly references a portal endpoint used for this purpose: /api/dispatchJob
This endpoint is described as a forwarding mechanism that proxies validated job creation requests to the internal gateway’s /executeJob endpoint.
This explains how jobs can be created externally even though the gateway itself is not directly reachable.
At this stage, the player has not guessed any endpoint names; the system has documented its own architecture via leaked contracts.
Server-Side Request Forgery (SSRF)
The preview endpoint can be used to interact with internal services. Enumerating gateway routes:
jq is a powerful command-line utility used for processing and manipulating JSON data in Kali Linux, much like
sedorawkare used for text. It is commonly used in scripting for working with REST APIs and analyzing JSON logs
curl -s -X POST http://headache.nyx/api/preview \
-H "Content-Type: application/json" \
-d '{"url":"http://127.0.0.1:8080/routes"}' | jqPress enter or click to view image in full size

The response confirms the internal API surface
Get TirexV2’s stories in your inbox
Join Medium for free to get updates from this writer.
Querying the gateway status endpoint:
curl -s -X POST http://headache.nyx/api/preview \
-H "Content-Type: application/json" \
-d '{"url":"http://127.0.0.1:8080/status"}' | jqPress enter or click to view image in full size

Returns operational metadata including:
- The service instance name
- The runtime service account
- The current date
This information is later used for authentication
Authentication Token Generation
Another internal endpoint documents how authentication tokens are derived:
curl -s -X POST http://headache.nyx/api/preview \
-H "Content-Type: application/json" \
-d '{"url":"http://127.0.0.1:8080/auth/token_hint"}' | jqPress enter or click to view image in full size

The token is:
sha256(instance + ':' + yyyy-mm-dd)Using the values obtained from /status we can compute a valid token locally
Gaining Initial Access via Job Abuse
With a valid token we can submit a job through the externally exposed dispatcher
The write_file template writes data to an SSH authorized_keys file, and template variables are expanded verbatim
By abusing path confusion in the USER field we can write our SSH key into the real service account’s home directory
Once the asynchronous job runner processes the task SSH access becomes available
Press enter or click to view image in full size

TOKEN=$(printf "%s:%s" "$INSTANCE" "$DAY" | sha256sum | awk '{print $1}')Press enter or click to view image in full size

Press enter or click to view image in full size

Press enter or click to view image in full size

Privilege Escalation via Plugin Execution
After gaining access as the service user, inspecting runner logs reveals:
- Jobs are post-processed by plugins
- Plugin selection is controlled via a writable metadata file
- Plugins are loaded using unsafe deserialization
By overwriting the plugin metadata and dropping a malicious serialized payload, We achieve code execution as root
Press enter or click to view image in full size

Check the plugin metadata file:
ls -l /var/lib/jobs/metadata.json
cat /var/lib/jobs/metadata.jsonThis file directly controls which plugin the root runner loads.
Overwrite the metadata file to point to a new plugin name and create a Python pickle payload that executes code when loaded
Press enter or click to view image in full size

Then re-check the logs
Press enter or click to view image in full size

Bridge to the localhost-only root service
Press enter or click to view image in full size
