top | item 7936384

Every C99.php shell is backdoored

130 points| chewxy | 11 years ago |thehackerblog.com

91 comments

order
[+] kijin|11 years ago|reply
The whole thing is a backdoor. Backdoor in a backdoor? Surprise! Of course it's backdoors all the way down ;)

But of course, script kiddies aren't particularly good at securing the servers they pwned, are they? [1]

A couple of months ago, I wrote QADE [2] for fun, a "quick and dirty" PHP-based text editor and webshell for editing files and running commands remotely. I deliberately failed to implement any authentication-related feature, because I didn't want to give an illusion of security. A secure webshell is an oxymoron.

[1] https://blog.avast.com/2014/06/09/are-hackers-passwords-stro...

[2] https://github.com/kijin/qade

[+] leni536|11 years ago|reply
What about putting it behind https and use basic http auth? If it's only for you you can always have a self signed certificate.
[+] astrodust|11 years ago|reply
Why would anyone who's not completely insane install anything like C99 in the first place?

Not only is the idea completely nuts, but all Google produces for C99shell is how it's used in backdoor tools.

Surprises: Zero.

[+] scintill76|11 years ago|reply
Apparently it's mostly used by script kiddies who compromise someone else's server and install it.
[+] aaron695|11 years ago|reply
What should people use?

C99shell is easy to use and common.

Why is it nuts?? You're using it for quick and easy defacements and compromises.

This is a numbers game often from people with low skill levels. I see no issues here at all. If your defacements were getting quickly taken back by another crew it might be an issue, but I've seen no evidence of this happening.

Just because there's a security issue it's not the end of the world. Risk management still comes into it.

Easy to use = more defacements. Might have a hole, well is there evidence we are losing enough defacements to justify the retraining of the crew and added costs?

And more importantly, be agile. Defacements getting retaken over at unacceptable levels, just move to a different product.

[+] lucastx|11 years ago|reply
I've used it in the past so I could run commands on a server, when the administrator only gave me FTP access.

Uploading PHP files with system() calls works too, but C99 is much easier to use.

But yes, I only came to know it when I was a stupid defacer teen. Shame on me.

[+] rplnt|11 years ago|reply
Why would anyone who's not completely insane use anything like php in the first place?

There are always reasons, sometimes valid reasons, to do insane things.

[+] Udo|11 years ago|reply
In all my years of writing PHP code I have yet to find a legitimate use case for extract() - PHP should have gotten rid of it generations ago.
[+] adamors|11 years ago|reply
Frameworks tend to use it, to create variables in a view that were sent from a controller. For similar usecases it also makes sense (you want a bunch of variables created from an associative array).
[+] kijin|11 years ago|reply
It's not terribly bad if you use it inside a function or method. Creating global variables is what causes all the issues, but then again, if you're handling global variables, you're asking for trouble anyway.

What's really bad about extract() is that the default behavior is to overwrite existing variables. This is just a recipe for disaster, no less than the infamous register_globals.

I once wrote a framework where the controller would pass variables to the view as $view->currentUser and the template would access it as $currentUser instead of the more verbose $this->currentUser. This was implemented with extract(), but I went to great lengths to make sure that the scope was clean.

PHP probably ain't gonna get rid of extract() any time soon, but at least they should change the default to EXTR_SKIP.

[+] ars|11 years ago|reply
You can use it to pass a bunch of variables between functions, without having to constantly get them from an array.

    function qux() {
      return compact('foo', 'bar', 'baz');
    }
And in the other function:

    extract(qux());
You can have one "preparer" function that works on the data and sets up the variables, then several others that work on it, and all call the same preparer. Or the reverse.

Obviously you can do the same thing by just passing arrays but sometimes a simple variable is easier and less cumbersome.

[+] yeahbutbut|11 years ago|reply
I've found exactly two:

Ghetto templating (using a PHP file as a template). Extract an object from the database into local vars to echo in the "template".

Parsing fixed width files, zip the columns with their names, then extract in the processing function.

In both cases you know exactly which vars are being replaced. The real WTF is extract on $_{REQUEST,GET,POST,SERVER,...}.

[+] thefreeman|11 years ago|reply
I think it is a useful construct for specifically the scenario it is mis-used in here. Overriding default values, or a kwargs polyfill

    function foo($option1=1, $option2=2, $option3=3, $option4=4) {
        //do stuff with params
    }
this is unwieldy and difficult to reason about when you see it used, especially if you are trying to use some of the initial default values. ie.

    foo(null, null, null, 10)
vs.

    function foo($options) {
        $option1 = 1;
        $option2 = 2;
        $option3 = 3;
        $option4 = 4;

        extract($options);

        //do stuff with params
    }
With this, you can just do

    foo(array('option4'=>10));
obviously its a preference thing, but I think it is a somewhat harmless use case. If there are any params which you do not want to be overriden you move them beneath the call to extract.
[+] zapt02|11 years ago|reply
Wordpress shortcodes, to extract variables from an array into local scope. Works great and even lets you set default values easily.
[+] p4bl0|11 years ago|reply
I agree with you, but here the problem is not the extract() call as everyone here seems to imply.

The security problem lies in the fact that the authentication code is conditionally called depending on user input.

    if ($login) { … }
is not less safe than

    if ($_POST['c99shcook']['login']) { … }
would have been.
[+] mtdewcmu|11 years ago|reply
Drupal uses it to implement templates. I always got the feeling that it's one of those language features where you want to take a deep breath before using it; sort of like when you type `rm -rf *` and haven't pressed enter yet.
[+] Spoom|11 years ago|reply
Agreed. The sane alternative is to extract specific, expected inputs to scope once they have been filtered and escaped. Any API I've written has this sort of validation built-in.
[+] dikei|11 years ago|reply
Exactly, I'm all for getting rid of black magics such as extract() and compact().
[+] gnyman|11 years ago|reply
I have only every seen the c99.php shell used by script kiddies which utilizes some well known php vulnerability and uploads this as the control point.

It would be cool if somebody wrote an automated script which would seek out these c99 and try to identify those which are used on hacked sites. It could then use this to get access and remove this script and fix the original exploit.

Using exploits to help people is of course a can or worms but I like the idea of good hackers helping everyone.

[+] tomkwok|11 years ago|reply
>> "a can or worms"

There's a typo ...

and I'm afraid "bad hackers" react even more quickly,

so I'm hoping "good hackers" can hurry ...

but watch out! Don't mess things up and cause a disaster :O

[+] norswap|11 years ago|reply
Got confused for a minute. Why the hell call your shell after a C language standard? Also, the term "shell" is terribly overloaded nowadays.
[+] leigh_t|11 years ago|reply
> due to a vulnerability in the extract() command

No.

This is due to insane usage of the extract() function. Not a vulnerability with the function itself.

You can pass user-supplied input directly to plenty of other functions which have equally idiotic outcomes, it doesn't mean that they have vulnerabilities, it means the author is a liability.

[+] mandatory|11 years ago|reply
Right, didn't mean that in the original post - obviously this is how the function is designed to work. Fixed up the wording to clarify.
[+] cstrat|11 years ago|reply
After reading these comments I am intrigued. Whenever I have used PHP I pretty much always run extract three times:

    extract($_GET, EXTR_PREFIX_ALL|EXTR_REFS, 'gVar');
    extract($_POST, EXTR_PREFIX_ALL|EXTR_REFS, 'pVar');
    extract($_COOKIE, EXTR_PREFIX_ALL|EXTR_REFS, 'cVar');
It makes working with get/post/cookies much easier. All variables are extracted with a prefix... so:

http://www.yyy.com/script.php?hello=world Results with: $gVar_hello being the variables holding 'world'.

Is this poor form?

I previously used: `import_request_variables` - but thats been sidelined.

[+] TimWolla|11 years ago|reply
Why is using $gVar_hello easier than $_GET['hello']? Also $_GET and friends have the benefit of being super global.
[+] brokentone|11 years ago|reply
Yes this is poor form. Prefixing, you don't have to deal with serious security issues, but this is just a step you really don't have to take--if this is part of your normal "bootstrap" you're likely doing it wrong.
[+] drivingmenuts|11 years ago|reply
A tool that's pretty much only useful for hacking is backdoored? Heaven forbid!

How is this even news?

[+] pogue|11 years ago|reply
I think the trouble is now, if this was just released, is that you can easily google for c99.php and find vulnerable servers with this file hosted on it, from pre-existing backdoors/phishing hosts, or what have you, and this allows anyone and everyone to use it, not just the original person who placed the backdoor. Which, I suppose, kind of enhances the problem exponentially.

As far as I'm concerned though, Google and Firefox's malware checker engines should blacklist any domain that has the c99.php file located on it and block their webbrowsers from connecting to it in the first place.

Of course - correct me if I'm wrong here.

[+] drunkcatsdgaf|11 years ago|reply
actually, google is pretty far ahead of this. trying searching allinurl:c99.php, most of the returns are actually about the script.
[+] mmaunder|11 years ago|reply
The only reason you have C99 on your server is because you've already been hacked. Its' one of the oldest shells used for backdooring a hacked site - you rarely see it anymore because there are much better shells now.
[+] nnnnni|11 years ago|reply
So... what's the best way to tell if C99 is "installed" on your server(s)?

    grep -Ri c99 /path/to/htdocs 
would be my guess
[+] mkarr|11 years ago|reply
There are thousands of variations of C99 used by various 'hackers'. Many of which are obfuscated (base64, gzip, other more obscure encodings). Generally, searching for a combination of 'base64_decode', 'gzdecode', and 'eval' will find a great deal of them. Others may require more manual inspection. Just searching for 'eval' alone tends to find a lot.

There are a few tools floating about that try to use a more signature-based approach to searching, and clamav has some signatures for the shells, but they can be hit-and-miss, as the obfuscation often changes.

[+] laurent123456|11 years ago|reply
Is the C99.php shell any popular? This is such a classic exploit of `extract()` that it seems like very amateurish job. If they even use this function at all I imagine the rest of the script is not that secure either.
[+] Jach|11 years ago|reply
I thought everyone knew this already ~10 years ago...
[+] nodesocket|11 years ago|reply
Founder of https://commando.io. It is utterly frightening that anybody would consider using c99. If you're interested in a parallel SSH web-based interface, check us out. Commando.io does not provide an interactive shell, but instead operates through pre-defined scripts we called recipes (written in shell, bash, perl, python, ruby, go, or node.js). Recipes are fully versioned, and we keep a full audit trail of all executions run on your infrastructure.
[+] meowface|11 years ago|reply
People are messing with you because C99 is used almost exclusively by script kiddies as a web shell into servers they compromise. Almost no one has ever used it as an actual administration shell for their own servers.
[+] mahouse|11 years ago|reply
Are you recommending us to use your software on servers that we compromise?
[+] fl0wenol|11 years ago|reply
Or we could, you know, use SSH (and sudo if we were so inclined). I don't think anyone uses a PHP shell willingly unless they're trying to do something they shouldn't.