Guides, Privilege Escalation, Windows

Windows Privilege Escalation – DLL Hijacking

Introduction

DLLs (Dynamic Link Library) are libraries that contain code and procedures used by Windows programs. They are similar to EXE files as they are based on the Portable Executable (PE) file format although they cannot be executed directly. They are similar to .so (Shared Library) files in Unix.

DLL hijacking is a method of injecting malicious code into a given service or application by loading an evil DLL, often replacing the original one, that will be executed when the service starts. This is possible due to the way some Windows applications search and load DLLs, more specifically, if the path to a service’s DLL isn’t already loaded or stored in the system, Windows will start looking for it in the environment path, an attacker can therefore place the malicious DLL in a directory that is part of it to trigger the malicious code.

Identifying Vulnerable Services

If you have access to the machine via a GUI, Process Monitor can be used to identify vulnerable services. Sysinternal’s Process Monitor is a tool that monitors and displays in real-time all file system activity on a Windows system.

Filters can be added to facilitate this process by navigating to Filter->Filter…:

Adding a filter for the process name, as in this case we are only looking at one specific process:

And for a result of “NAME NOT FOUND”, which will let us know when the service could not find its DLL:

Process Monitor indicates that the service was looking for the hijackme.dll DLL in a number of folders (what seem to be the environmental path folders) although it was not able to find it. It looks like one of these folders is C:\Temp:

It appears the current user has access to modify the C:\Temp folder, so a malicious “hijackme.dll” DLL file could be placed there:

If GUI access is not an option, enumeration can still be performed using manual commands. The tasklist command can be used to export a list of the current processes:

Directories that are part of the environmental path can be identified with the following command:

echo %PATH%

Icacls or Accesschk can then be used to find out whether the current user has write access to a certain directory:

icacls [directory]
Accesschk.exe -accepteula -dqv [directory]

Automated scripts such as WinPEAS can also help identify Weak Permissions in services:

winpeas.exe quiet servicesinfo

Exploitation

In order to exploit this vulnerability, all we have to do is generate a malicious DLL file, place it in a directory that is part of the environment PATH and restart the service, in order to execute the evil DLL.

The first step is to generate some shellcode using MSFvenom with the following flags:

  • -p to specify the payload type, in this case, the Windows TCP shell
  • LHOST to specify the localhost IP address to connect to
  • LPORT to specify the local port to connect to
  • the format, in this case DLL

Transferring the hijackme.dll file to the Windows victim machine using the Python web server and the Windows Certutil utility.

Once the malicious DLL has been placed in the right path, the service needs to be restarted so that it will execute the DLL and connect to the listener. With the following command we can verify whether the current user has permission to do so:

sc sdshow [service]

The initial “D:” stands for Discretionary ACL (DACL). The first letter after brackets means: allow (A) or deny (D), the next set of symbols are the assignable permissions:

  • CC — SERVICE_QUERY_CONFIG (request service settings)
  • LC — SERVICE_QUERY_STATUS (service status polling)
  • SW — SERVICE_ENUMERATE_DEPENDENTS
  • LO — SERVICE_INTERROGATE
  • CR — SERVICE_USER_DEFINED_CONTROL
  • RC — READ_CONTROL
  • RP — SERVICE_START
  • WP — SERVICE_STOP
  • DT — SERVICE_PAUSE_CONTINUE

In this case the current user has access to stop and start the service.

The next step is to set up a Netcat listener, which will catch our reverse shell when it is executed by the victim host, using the following flags:

  • -l to listen for incoming connections
  • -v for verbose output
  • -n to skip the DNS lookup
  • -p to specify the port to listen on

Stopping and starting the service with the following commands:

sc stop dllsvc
sc start dllsvc

If the current user does not have access to start/stop the service, we can check whether the service starts at system boot:

sc qc dllsvc

If it does, we can then check if the current user has permission to shutdown/restart the machine:

whoami /priv

It looks like it does. The next step is to run the following command to restart the system:

shutdown /r /t 0

Once the service was restarted, the malicious DLL was executed, therefore connecting back to the listener and granting a system-level shell.

Conclusion

Services are at the core of operating systems and often run with privileged access, as they may need to access restricted files, registry keys, memory sectors, etc. in the operating system to perform their tasks.

This can become a problem when the service DLL or DLL paths aren’t properly configured and can allow users to manipulate the DLLs used by a privileged service. Although this type of vulnerability isn’t very common, it is very dangerous and can potentially result in a full system compromise.