An ACE in the Hole - Stealthy Host Persistence via Security Descriptors
1. An ACE in the Hole
Stealthy Host Persistence via
Security Descriptors
2. Who We Are
× @tifkin_ / @enigma0x3 / @harmj0y
× Red teamers/researchers at
SpecterOps
× Code on code on code
× Cons on cons on cons
2
3. What This Is
× Offensive applications
× Intro to securable objects
× Our Research Process
× Securable object takeover primitives
× Case studies/demos
× Defense
3
5. “As an offensive
researcher, if you can
dream it, someone has
likely already done
it...and that someone
isn’t the kind of person
who speaks at security
cons”
5
Matt “f’ing” Graeber
BlackHat 2015
8. Why Care (really)?
× It’s often difficult to determine whether a
specific security descriptor misconfiguration
was set maliciously or configured by accident
× These changes also have a minimal different
forensic footprint and grant:
× Bug longevity! Privesc! Persistence!
× They might already be on your system ;)
× Living off the land++ (existed since NT was
born!)
8
9. Big Point(s)
× Most defenders are not aware of this
general persistence approach, much less
how to find and remediate it!
× You don’t need to leave malicious
code/logic on a system to regain access!
× What if this change was made to an
organization’s “gold image”?
9
10. Responsibly Evil ;)
× Also, you don’t need to set the
principal/trustee (who has the rights) to
S-1-1-0!
× Security descriptor backdoors can be set
for specific trustees in a targeted manner
so exposure in the environment is
minimized
10
11. ¯_(ツ)_/¯
× “if an attacker has code execution on your
system, you’re screwed already, so who
cares“
× “You need admin rights to do this, this is
stupid!“
× To this we say: domain joined boxes
!= isolated home systems
× we guess the defensive industry should just
pack up and leave…
11
16. Where are these
descriptors?
× Found in the registry, the file system, in
the kernel, ntds.dit....
× Really depends on the type of object
× Finding what objects are securable, much
less exactly where their descriptors are
located, isn’t as easy as you’d think...
16
17. From DACLs to
SACLs
17
× Access Control List (ACL) is basically shorthand for
the DACL/SACL superset
× An object’s Discretionary Access Control List
(DACL) and Security Access Control List (SACL) are
ordered collections of Access Control Entries
(ACEs)
× DACL - What principals/trustees have what rights over
the object
× The SACL - Specifies how to audit access to the object
19. More on DACLs
19
× Null DACL != no DACL
× Inheritance… can be a >_<
× General interpretation:
× Explicit Deny
× Explicit Allow
× Inherited Deny
× Inherited Allow
21. Our Research
Approach
Objects accessible from user-mode with a focus on one's
usable for persistence/lateral movement
1. Discover securable object
1. Offline and Online Security Descriptors Enumeration
1. Analyze Access mask
a. What object-specific rights are there (if any)?
b. What rights permit persistence/lateral movement?
1. Operational Weaponization and Detection
21
22. 1. Discovering
Securable Objects
× Windows documentation lists about 20-30 securable
objects*
× We’ve identified 70+! (There’s *many* more)
× Microsoft Protocol Specifications
× Very useful for RPC servers
× Find-RegistrySecurityDescriptors.ps1
22*https://msdn.microsoft.com/en-us/library/windows/desktop/aa379557(v=vs.85).aspx
24. 2. Online vs Offline
Security Descriptors
× Where do objects get their security descriptor?
× Offline - Security descriptor derived from
registry, file, ntds.dit, etc.
× Online - Security descriptor is in memory
Our approach to enumeration:
× Locally as an unprivileged user
× Locally as a privileged user
× Remotely as an unprivileged user
× Remotely as a privileged user
24
25. Existing Tooling
× Use existing tools
× Accesschk.exe
× WindowsDACLEnumProject
× Google’s sandbox analysis tools
× NtObjectManager woot woot!
× BloodHound
× Most do not distinguish between
online/offline security descriptors
× Implication: How do you know if an object
has been modified after creation?
25
26. Enumeration Caveats
× “Online” vs offline security descriptors
× Necessary token privileges
× Some objects are “invisible” to user-mode
enumeration
× Kernel private namespaces
× Does an object with no name have a security
descriptor?
× https://googleprojectzero.blogspot.co.uk/2014/10/did-man-with-no-name-feel-
insecure.html
26
29. Generic Object
Takeover Primitives
× Attacker is owner (implies WRITE_DAC)
× Attacker has WRITE_DAC/WRITE_OWNER
× Attacks has STANDARD_RIGHTS_ALL
× Attacker has GENERIC_ALL*
× Object has NULL security descriptor (implies
Everyone has GENERIC_ALL)
29
Depends on how the object maps the generic right to standard/object-specific rights.
Usually this includes WRITE_DAC/WRITE_OWNER, but doesn’t have to
30. Object-specific
Takeover Primitives
× Each securable object can define its own
rights
× Example: Process Rights
× PROCESS_CREATE_PROCESS
× PROCESS_CREATE_THREAD
× PROCESS_SUSPEND_RESUME
× PROCESS_QUERY_INFORMATION
× PROCESS_TERMINATE
× The specific object and its rights determine
its offensive usefulness (priv esc, lateral
movement, persistence, etc.)
30
32. Service Control
Manager RPC Server
× “RPC server that enables service
configuration and control of service
programs.” - MS-SCMR
× Applicable Securable Objects
× Service Control Manager Server
× Windows Services
32
33. SCM Server
Applicable Rights
33
SC_MANAGER_CONNECT Permits connecting to service
SC_MANAGER_CREATE_SERVICE Ability to add a new service
SC_MANAGER_ENUMERATE_SERVICE List out services
By default, unauthenticated users can enumerate
the security descriptor of the SCM Server!
35. WinRM/WinRS
× Windows Remote
Management/Windows Remote Shell
× Provides the ability to remotely interface
with a host
× Think PowerShell Remoting
× Create backdoored ACE and apply it to
either the WinRM or WinRS DACL
× Or both!!
× Defined user (via SID) will be able to
remotely interact with the host without
admin privs 35
36. WinRM/WinRS
× Security Descriptor can be accessed by pulling the
SecurityDescriptorSDDL property of Get-
PSSessionConfiguration
× Build the new DACL via DiscretionaryAcl.AddAccess()
of Security.AccessControl.CommonSecurityDescriptor
× PowerShell Remoting:
× Set the new DACL via -SecurityDescriptorSddl of
Set-PSSessionConfiguration
× WinRS
× Set WSMan:localhostServiceRootSDDL to the
new DACL via Set-Item
36
37. WinRM/WinRS
× Already weaponized here:
https://github.com/ssOleg/Useful_code/blo
b/master/Set-RemoteShellAccess.ps1
× In 2014….
× Takes a domain SID and adds an ACE for
that SID to both PowerShell Remoting and
WinRS DACLs
× Allows that specific user/group to remotely
interface with WinRM/WinRS without
having any additional privilege
37
38. DCOM
× Distributed Component Object Model
× Been around since 1996… >_<
× Secured via Launch and Activation
Permissions
× Local/Remote, perms reside in the registry
× Can you use interesting DCOM
applications to get code-execution?
× Applications with “ExecuteShellCommand()”
× Backdoor your favorite DCOM application for a
specific user/group’s SID :-)
38
39. DCOM
× Access is determined via machine-wide permissions first
and then application specific permissions
× Add target user/group to allow machine-wide Remote
Activation/Launch Permissions
× Instead of editing the Default, just edit the Limit
× HKLM:SoftwaremicrosoftoleMachineLaunchRestriction
× A;;CCRPLC;;;$SID
× Backdoor a specific DCOM Application for a domain
user/group
× HKLM:SoftwareClassesAppID{GUID}LaunchPermission
× HKLM:SoftwareClassesAppID{GUID}AccessPermission
× Requires: SeTakeOwnershipPrivilege, SeRestorePrivilege,
SeSecurityPrivilege if installing locally 39
42. WMI NameSpaces
× Contains a collection of WMI classes that
host various methods/properties
× Each namespace has associated DACLs
× Windows checks the DCOM machine-wide
launch permissions for the first stage of
access
× If successful, the DACLs on the WMI namespace
are then checked
× Backdoor a NameSpace that contains a class
with a useful method
× Create() method of Win32_Process, for example
42
43. WMI NameSpaces
× Call GetSecurityDescriptor() on the target WMI
namespace (local requires SeSecurityPrivilege)
× Use Win32_Ace to set our Access Mask and
flags
× Use Win32_Trustee to assign the user
× Set the “Trustee” property of Win32_Ace to our
Win32_Trustee object
× Add our new ACE to the target namespace
DACL: $NameSpaceACL.DACL +=
$Ace.PSObject.ImmediateBaseObject
× Call SetSecurityDescriptor() with the newly
updated NameSpace object to set it
43
46. × Securable Objects
a. Printer Servers
HKLMSYSTEMCurrentControlSetControl
PrintServerSecurityDescriptor
a. Printer Objects
HKEY_LOCAL_MACHINESOFTWAREMicrosoft
Windows NTCurrentVersionPrintPrinters
Security
a. Print Jobs - Not very interesting offensively
Specifications: MS-RPRN, MS-PAR, MS-PAN, MS-PRSOD
46
Printers
51. Remote Registry
× Allows permitted users/groups to access the
registry remotely via .NET/Win32 API
× [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey()
× The RemoteRegistry service has to be enabled
and the calling user has to have access
× By default in Windows 7/10, this service is
disabled
× Remote access to the registry == ability to
dump hashes (among other things) 😈
51
52. Remote Registry
× Imagine this scenario: Remotely dumping an
endpoint’s machine account hash as an
unprivileged user
× Remotely backdoor the winreg key for a specified
user/group
× Located at
HKLM:SYSTEMCurrentControlSetControl
SecurePipeServerswinreg
× The DACL on this key decides who is allowed to
connect via remote registry
52
53. Remote Registry
× Can be accomplished via WMI’s StdRegProv
provider
× Call SetSecurityDescriptor() with an ACE that defines the
user/permissions for the backdoor
× Why not just use StdRegProv?
× Dumping the machine account hash requires obtaining
various Registry Key classes.
× Can only be obtained via RegQueryInfoKey()
× Use Set-Service to remotely set the service
StartupType to “Manual”
× Set-Service -Name "RemoteRegistry" -ComputerName
$Computer -StartupType "Manual"
53
54. Remote Registry
× Remotely take ownership of the SECURITY registry hive
and add an ACE to the DACL for the backdoor user
× As that user, remotely call RegConnectRegistry()
× Open the required keys and pull the Key’s Class
× SYSTEMCurrentControlSetControlLsa<JD,Skew1,GBG,DATA>
× RegOpenKeyEx(), RegQueryInfoKey()
× Combine these Class values and compute the BootKey
× Use the BootKey to decrypt the LSA key
× Use the LSA key to decrypt the machine account hash
54
58. × A system access control list
× “Enables administrators to log attempts to
access a secured object”
× Not used as extensively as they should
be!
SACLs:
the other ACL
58
59. Defensive
Enumeration
× More research is needed- you can’t
defend against what you aren’t aware of!
× Defensive PowerUp++ ? Operational
test framework for the detection of
backdoor scenarios?
× Integration into BloodHound?
59
60. Takeaways
× The host-control graph is *MUCH* bigger than
“is member of local admin group”
× What is the real attack surface of a Windows
host?
× Many “forgotten” or unexplored RPC/DCOM
servers
× Many other securable objects we haven’t looked
at
60
62. × Implications of other securable objects
× Real-time analysis
× Enumeration of objects visible only to the
kernel
× Chaining host + AD security descriptor
abuse
Takeaways &
Future Work
62