Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Mayhem – A hidden threat for *nix web servers (virusbtn.com)
153 points by WestCoastJustin on July 18, 2014 | hide | past | favorite | 54 comments


I read and then rescanned as best I could, does the article actually bother to explain the infection process? How the code gets on the system?

Presumably I have to get this onto my system via some flaw for it to be executed.

I mean of course you can be a pain in the ass with limited access, I didn't realize that was up for debate. That's not that interesting as I see it. Actual vulnerabilities relating to holes these things can get through to get onto your system is what we need to be worried about.

The attack it self seems pretty run of the mill for shared hosting attacks as we had seen many of at my previous job, often infecting through old unpatched Wordpress installations, old copies of phpbb and plesk admins. Honestly I curse Wordpress to this day for the trouble it would cause us.


Remote file inclusion (RFI)

Brute force FTP accounts

Brute force logins, eg wordpress login


As far as malware attacks go, this seems to be pretty run-of-the-mill (no clever vulnerabilities used). The key seems to be that the automated malware dropping is adapted to all sorts of 'restricted environments' (i.e. chroot, virtual servers, non-root accounts, etc). It doesn't look like there is any privilege escalation involved (which, say in the case of most targeted attacks, there usually is).


I think the point of the article was showing that none were really needed to still cause massive damage.


> I think the point of the article was showing that none were really needed to still cause massive damage.

No privilege escalation needed?

I disagree, this article shows nothing new at all unless it shows how the malware gains privileges on the system. As an SELinux user that is what I am most interested in.

Normally these malwares make it in through some poorly secured web server, in my experience.


While the dropper was written in PHP, it's important to keep in mind that Perl, Python or other language could just as easily have been used. If you're using a shared host that otherwise doesn't allow many configuration changes, you're very limited in what you can do to protect yourself.

If you use PHP, you can add the following to php.ini to mitigate risks like these (mitigate != bulletproof) :

  ; Mayhem dropper uses "system" so let's kill that and other dangerous functions
  disable_functions = system,eval,curl_exec,curl_multi_exec,exec,passthru,shell_exec,show_source
If this breaks your software, your software is badly written.

Allowing write permissions in the script directory is always a dangerous thing. It's best to put the application files outside root and enable execute permissions only on the script directory. If uploading files is allowed, it should be to read/write enabled directories only. Execute permissions should be turned off.

The dropper tries to kill critical processes as mentioned so chrooting services individually is a good idea.

Or you could just use OpenBSD ;-)


Do you really understand what each of these functions does?

Go look up show_source in the PHP manual. Tell me, what do you think disabling it, but not disabling highlight_file will get you? What does disabling either of these to prevent the functionally identical highlight_string(file_get_contents(...))? And how in the blue blazes is this functionality supposed to be used in some sort of exploit?

What does disabling curl get you? There's nothing that it does that can't be done through the built in stream handlers. Why don't you try and disable those as well?

Why disable exec but not create_function? assert can also be used to evaluate string as code.

This smells like some PHP4-era copy/paste cargo cult crap that should be avoided, not recommended.


I've addressed these concerns and more in my subsequent replies. Your tone suggests my efforts to reply here will be wasted. Have a nice day.


I don't understand why you would include curl in your listing? There are plenty of legitimate uses for it, for example as part of my work I recently used it on a data processing server to trigger post creation of Wordpress posts via the xmlrpc server which is built in to Wordpress.



> If this breaks your software, your software is badly written.

That's a silly blanket statment. There are times a system call is nessessary. Also there's a lot more ways to get system calls than you list, namely the deadly back tick operator, as well as process control just as a start.

Update: Also curl_exec? cUrl is how you do ANYTHING http more advanced than fetching with a few headers. Everything that accesses any sort of API in a serious manner will use cUrl.


The list is limited to a very specific set of functions that PHP is an ill fit to utilise and I have never seen used in a positive context. These are best done with a non-scripted program or perhaps Python.

Of course, no matter the language used, input sanitising is essential.

Edit: Since you've edited your post to add cURL to your criticism, please note I originally replied "These are best done with a non-scripted program or perhaps Python" for exactly this reason.

Much of the criticism of PHP can be leveled against its misuse as much as the language's own shortcomings.


I love Python over PHP any day, but how exactly is Python better, if it has os.system() ?


Python and PHP need not be adversaries is my point. Long running, ex. polling, bots, scrapers etc... can be better dealt with in Python as it has dedicated tools and frameworks for those purposes. Backend applications that don't directly deal with the web front allow for better compartmentalisation of priorities and privileges.

Think of it this way; if a layer of your stack has the capability to destroy a system, it's probably best left speaking to another layer that actually speaks to a user.

PHP for web and Python for backend is not a foreign concept and so it makes little sense to apply one hammer to all variety of nails.


Besides trying to fire at "If this breaks your software, your software is badly written." like other's already did, there's the more obvious fact:

If it's YOUR software, you're supposed to trust it! (yeah, including trusting it that it's not so badly written somebody can inject code into it) ...this type of setting should only make sense for when you have to use dubious quality third-party code (which can happen quite often... WordPress plugins being an obvious example)

...the sensible thing to do is to basically partition your php code base into "trustworthy and/or written by us" and "non-trustworthy" and always run these types of code with different settings, and never mix them, just have services that communicate via APIs.


Thank you. That's actually far more constructive advice.


Does PHP have a whitelist counterpart to disable_functions, or maybe something like Lua's environment tables that would allow a more effective sandbox to be created?


There's Suhosin which does a great deal to lockdown the core and has largely limited functions to the essentials http://www.suhosin.org/stories/index.html

On debian, I've used : apt-get install php5-suhosin

My recommendation to use OpenBSD, while a bit of toung-in-cheek, is actually because the PHP (5.4.24 as of the 5.5 OS release) is installed with the patch and Nginx is also chrooted.


A bit


curl_exec and curl_multi_exec ???


These are often used on crawlers, bots - not necessarily of the harmful variety - and other automated retrieval, transfer and storage scripts. They're very useful, but highly specialised for those particular tasks and often not needed on traditional web applications. Of course, these are often abused for retrieving malware payloads as well so enable at your own risk.


... Because nothing communicates over HTTP except for crawlers, bots and malware droppers...


I'm super confused as to how I'm supposed to communicate with an external API in PHP without `curl_exec`. Anything that requires even remotely complex header setups means you need curl?


If the API uses HTTP, it's fairly straightforward. PHP has had streams available for quite some time : https://php.net/manual/en/stream.contexts.php

Many shared hosts often don't have cURL and so stream_create_context is an alternative https://php.net/manual/en/function.stream-context-create.php

There's even a REST helper from 2006/2010 : http://www.wezfurlong.org/blog/2006/nov/http-post-from-php-w...


So apparently the streams API is deep magic that malware will never use? If you're going to pass around "cargo cult crap" (thanks McGlockenshire), at least make sure you're locking down _every_ equivalent of "dangerous function" that only malware and "badly written software" supposedly would use. To add a few to the holes others have listed, you should disable proc_open, popen, pcntl_exec. How about dl(), to close a (rare) vector for loading native code?

While we're doing drop-in magic stuff to mitigate problems, don't forget to put libxml_disable_entity_loader(true); at the beginning of every script.[0]

Why not disable file_put_contents? I always thought that was kind of a shoddy practice, and likely to appear in malware, too!

Why not set allow_url_include = off ? Surely this is in "badly written software" territory that is exploited by malware?

Obviously this isn't exhaustive, either. My point is that you can't wave a few boilerplate configurations over any PHP application to make it secure. That may be a sizable flaw in the platform, but if so, say that rather than trying to give people copy-paste "protection."

[0] https://www.idontplaydarts.com/2011/02/scanning-the-internal...


Which is why I suggested Suhoshin above: https://news.ycombinator.com/item?id=8056907 And on a number of replies advocated for certain precautions in addition to the much maligned disable_functions list.

I'm not going to visit this thread any longer as it's getting to be an exhausting exercise of having to wade through snark and general malaise. I'm reminded, once again, why I waited so long before making a single post on this forum.


You might want to look into lightening up a little. You gave objectively bad advice, backed by objectively bad reasoning, and were educated about your mistakes for free. There was a bit of snark, but not a single drop of general malaise, and most of what was said to you was very helpful considering your professed aims.

You found yourself in "Wovon man nicht sprechen kann, darüber muß man schweigen" territory on this topic, but don't be disheartened. Proper security is notably difficult.


Which specifically of my points will be addressed by adding Suhosin?

You gave some good advice. Assuming your software still works without cURL and with Suhosin, yes, you are probably going to avoid some attacks by using your disable_functions list and Suhosin. Still, I think what I and several others take issue with, is giving an example php.ini that was so incomplete and inconsistent with its reasoning.


To be fair, I've noticed allow_url_include is off by default.


I mean, I just use Guzzle to be honest, but my point is that Curl is super useful in day-to-day usage and handles certain things far better than the streams API. I mean heck, the streams API using SSL context defaults to not verifying the damned certificate! Curl on the other hand, won't even connect until you tell it what to explicitly trust.

Granted, IIRC they are fixing that SSL issue in 5.6, but there are a number of other things, and frankly you haven't given a good enough reason to get rid of `curl_exec`. Others, like system calls I can completely agree with! But frankly, if PHP can make a call out to the web somehow, which you need it to if you're using APIs, then there will always be a vector for getting external exploits on to the server provided you've got remote execution already.


Streams used to be the less secure option and CURL was recommended instead because it meant fopen() calls couldn't be hijacked for remote include vulnerabilities and the programmer had to at least mean to include a remote file.

I have to admit I've continued to avoid streams much of the time for this reason - even though they are useful.


Now with a second reply it's going to seem like I'm attacking you, but: Doesn't your method require allow_url_fopen? I hope I'm not jumping to conclusions here, but saying allow_url_fopen is required and virtuous, and cURL is evil, is absolutely crazy IMO. Please correct me if allow_url_fopen is not needed for your method.


Can someone explain how this infects and gets activated on a system? It sounds like I have to download a certain PHP file onto the system and then execute it. Is this correct, or are attackers using other ways to automatically start the malware?


The dropper has to be present on the server somehow to get the rest of the payload so you have to have uploaded it there, allowed a user to upload it[1] or be in some way included by a malformed script or some other existing vulnerability. This includes a very large scope of potential access points.

Ex: This particular sample was in PHP so Wordpress comes to mind. Plugins in particular are notorious for poor programming practices that allow such file inclusions.

[1] Disallowing by extension doesn't always work as some filters allow img.php.png or img.png.php. Besides this, an image can skip the .php altogether and still be executed as a PHP script

Ex: https://security.stackexchange.com/a/32970 and https://security.stackexchange.com/a/32969

Note however, this doesn't just apply to PHP. There are potential vectors in Perl, Python and Ruby when adequate measures are not taken to sanitise user input and filter arbitrary uploads.


It's important to not only to try to prevent them from being uploaded, but to make sure that any directory which is writable by the web server or php engine, is not executable. In the case of WordPress, this can largely be mitigated by using specific location parameters in nginx which allow the execution of your intended entry points such as the primary index.php file, rather than a blanket fastcgi forward for all urls ending in .php.

`location ~ .php$ { [forward to fcgi] }`

This is a common configuration that allows the client to execute any php file within the web root. If you accidentally allow a php file to be uploaded, it may be executed.

Instead something like the following means that the web server will not allow arbitrary php files to be executed, only the ones you want to be executed:

`location ~ /(index\.php|wp-admin/ajax.php)$ { [cgi] }`

(Just an approximation - I don't feel like looking up the exact expression I use.)


I've converted my colleagues over to nginx from Apache, and one of the nicest parts of it (for PHP) is how easy it is to make sure nginx is only serving exactly what you want it to, and no more. The blanket "run any PHP in /var/www" configs that seem to be the copy-pasta default make me sad.


Of course - there is still the possibility that an uploaded script can be executed by the framework, but at least it requires an exploit to do the upload and another one to make your application execute it. If arbitrary php files can be executed, they only need to be able to upload them.


Common mode of infection I have seen with Wordpress is through site owners downloading premium themes that have been uploaded into file sharing sites by malware authors.

The site owners can't, in most cases, poke around to see what is in the code. And the code often contains hooks that inject various things into the installation.

The other route in is through scripts like TimThumb, which is included in a lot of themes. TT has had some serious security holes in it, the last one being fairly recent that allows for remote file execution. At that point, at least the account hosting the file is a goner.


Brute force password guessing is very common. There's ludicrous numbers of WordPress password guessers running. That's right, someone will make several thousand password guesses over the course of a few hours.


Sigh, if only people this clever were trying to do good in this world.


The number of people this clever or more doing good in the world is enormous, but their exploits largely go unnoticed and unheralded. Because things going well can often be difficult to differentiate from a non-event. Think about all of the sophisticated technology behind something as common as smartphone. Or, just think about the clever folks working on, say, the linux kernel. Other than Linus most of those people are not famous and a great many people who use linux every day don't even realize they are doing so or know anyone involved with the project, even Linus (such as android phone users, anyone who uses a website or service hosted on linux, people who use devices running linux in the firmware, etc.)


This is a very well reasoned point. Thank you for writing this.


In case you get 503 error, article snapshot at http://www.peeep.us/9dcbdec9


So I assume I'm safe if I have no PHP on server?


Its not about PHP, any vulnerable software may be used for infection.

PS You're safe if you have no server :)


The malware described in the article uses PHP.


the php dropper discussed is the least interesting part of the article. it could be implemented in any language.


Furthermore, if your web server (or database server, or any other interet-facing service) is vulnerable, it won't matter which programming language you are using. Assume that all input is hostile.


Only as the dropper. Presumably the other parts of the malware (libworker.so, etc.) could be repurposed and coupled with a different infection system.


Good crap, 4 downvotes for a factual statement with no hints of aggression or disdainfulness?


I'm assuming the down votes are because you missed the point of your parent. The example uses a PHP script for uploading the payload, but that can be swapped out for nearly any language on a server. They all require an exploit to get the dropper on there anyway, so that's a barrier. PHP isn't the point here though, it's the interesting damage the exploit that gets pulled down by the dropper can achieve, without needing to use privilege escalation.


Interesting ... now How detect if is it (or any other similar ) on our web servers ? And How remove it and protect against it ?


root_ordner: german only word





Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: