medium.com

Headache VulNyx — Official Writeup

TirexV2

TirexV2

Initial Reconnaissance

nmap -sC -sV headache.nyx

Press 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

Operator Query

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:

  1. An internal gateway service responsible for job execution, bound to localhost:8080, exposing an endpoint named /executeJob.
  2. 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 sed or awk are 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"}' | jq

Press 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"}' | jq

Press 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"}' | jq

Press 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.json

This 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