Created
May 26, 2025 08:57
-
-
Save si458/43222e3db06932e56a3d3664841108db to your computer and use it in GitHub Desktop.
Get Plesk Passwords From Database
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// Configuration | |
$config = [ | |
'server' => 'localhost', | |
'username' => 'admin', | |
'password' => trim(file_get_contents("/etc/psa/.psa.shadow")), | |
'key' => file_get_contents("/etc/psa/private/secret_key"), | |
'database' => 'psa' | |
]; | |
// Database queries and output files configuration | |
$queries = [ | |
'database_passwords' => [ | |
'sql' => "SELECT domains.name AS domain_name, data_bases.name AS database_name, | |
db_users.login, accounts.password FROM data_bases, db_users, domains, accounts | |
WHERE data_bases.dom_id = domains.id AND db_users.db_id = data_bases.id | |
AND db_users.account_id = accounts.id ORDER BY domain_name", | |
'format' => function($row) { | |
return "Host: {$row['domain_name']}\nDatabase name: {$row['database_name']}\n" . | |
"Username: {$row['login']}\nPassword: " . decryptPleskPassword($row['password'], $GLOBALS['config']['key']) . "\n\n"; | |
}, | |
'filter' => fn($row) => !empty($row['domain_name']) | |
], | |
'mail_passwords' => [ | |
'sql' => "SELECT accounts.id, mail.mail_name, accounts.password, domains.name | |
FROM domains LEFT JOIN mail ON domains.id = mail.dom_id | |
LEFT JOIN accounts ON mail.account_id = accounts.id", | |
'format' => function($row) { | |
return "Email: {$row['mail_name']}@{$row['name']}\n" . | |
"Password: " . decryptPleskPassword($row['password'], $GLOBALS['config']['key']) . "\n\n"; | |
}, | |
'filter' => fn($row) => !empty($row['mail_name']) | |
], | |
'ftp_passwords' => [ | |
'sql' => "SELECT REPLACE(sys_users.home,'/home/httpd/vhosts/','') AS domain, | |
sys_users.login, accounts.password FROM sys_users | |
LEFT JOIN accounts on sys_users.account_id=accounts.id ORDER BY sys_users.home ASC", | |
'format' => function($row) { | |
$domain = str_replace("/var/www/vhosts/", "", $row["domain"]); | |
$domain = explode("/", $domain); | |
return "Host: ftp.{$domain[0]}\nLogin: {$row['login']}\nPassword: " . | |
decryptPleskPassword($row['password'], $GLOBALS['config']['key']) . "\n\n"; | |
}, | |
'filter' => fn($row) => !empty($row['domain']) | |
] | |
]; | |
// Decryption function | |
function decryptPleskPassword($encryptedString, $key) { | |
$parts = explode('$', $encryptedString); | |
if (count($parts) < 4) throw new Exception("Invalid encrypted string format"); | |
return trim(openssl_decrypt( | |
base64_decode($parts[3]), | |
$parts[1], | |
$key, | |
OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, | |
base64_decode($parts[2]) | |
)); | |
} | |
// Main execution | |
try { | |
$conn = new mysqli($config['server'], $config['username'], $config['password'], $config['database']); | |
if ($conn->connect_error) throw new Exception("Connection failed: " . $conn->connect_error); | |
foreach ($queries as $filename => $query) { | |
$result = $conn->query($query['sql']); | |
if (!$result) throw new Exception("Query failed: " . $conn->error); | |
if ($result->num_rows > 0) { | |
$output = ''; | |
while ($row = $result->fetch_assoc()) { | |
if ($query['filter']($row)) { | |
$output .= $query['format']($row); | |
} | |
} | |
file_put_contents($filename, $output); | |
} | |
} | |
$conn->close(); | |
} catch (Exception $e) { | |
die("Error: " . $e->getMessage()); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment