客串逆向工程,一瞬获取悬镜WAF规则

0x01引言

         悬镜是我见过最恶心的WAF之一,这个拦截那个拦截,根本不搞语法分析,见到不对劲的就拦截,根本绕不过。
         我的意思并不是觉得它做的太好了所以我觉得恶心,不是这样的。我就是单纯很不服气,像长亭科技的那个SQLCHOP搞的语法分析,精准拦截payload我绕不过是我菜,我输得心服口服。像悬镜这样看见/*就拦截完全是作弊嘛。
         除此之外悬镜的拦截规则也很奇妙,比如说我来个id=1'它要拦截,但是id=1111'就不拦截,Union注入的测试不拦截,但是真的要查点什么敏感的东西又要拦截。这究竟是什么奇葩规则啊啊啊啊啊啊。
         因此我很想一窥悬镜的规则,于是从一个搞Web的跨界逆向,抄起IDA一探究竟

0x02寻找规则

         打开悬镜的目录,我们可以根据名字很容易找libruleset.so文件,看起来就是处理规则的。拖到IDA里一下找到了函数


         这说明那个/usr/share/xmirror/rules/apache/rule.db就是规则,哈哈哈直接放在db里面结果被我找到了。
         可惜事情并没有这么简单
         当我打开这个DB的时候发现这个只是配置文件,用于描述哪些防护策略生效了而并没有描述规则的具体内容
         后来我多尝试了几个so文件后发现有个叫做mod_xmirrorsec.so的文件内有玄机有个叫做get_rule_set的函数尤为起眼。
         
         这个函数直接读入xmirror_rule.so这个文件,是直接读而不是load,而这个文件之前用IDA无法识别,很显然这就是真正的规则!

0x03编写程序,读取规则

         这个代码并不复杂,无非就是读取并解密。因此剩下要做的事情很简单,抄抄改改代码的事嘛。
#include <iostream>
#include <openssl/aes.h>
using namespace std;
unsigned char ivec[16];
unsigned char key_hex[16];
int i;
long length;
FILE *stream;
AES_KEY key;
unsigned char * ptr;
unsigned char* plain;
int main()
{
for ( i = 0; i <= 0xF; ++i )
key_hex[i] = i + 32;
for ( i = 0; i <= 0xF; ++i )
ivec[i] = 0;
stream = fopen("xmirror_rule.so", "r");
AES_set_decrypt_key(key_hex,128,&key);
fseek(stream, 0LL, 2);
length=ftell(stream);
ptr = (unsigned char*)malloc(length + 1);
plain = (unsigned char*)malloc(length + 1);
fseek(stream, 0LL, 0);
fread(ptr, length, 1uLL, stream);
fclose(stream);
AES_cbc_encrypt(ptr, plain, length, &key, ivec, 0LL);
cout<<plain;
}
规则传gayhub上了

0x04有了规则可以干什么?

         有了规则应该可以更容易地找到bypass的策略,以来这些规则都是明文不需要自己推断,另一方面可以大大加速fuzz的速度,因为只需要本地测试语句的合法性和正则不需要发包了

0x05抄袭疑云

         评论区里面有一个机智的网友指出规则似乎是抄modsecurity的,为了确认这一猜测,博主我下载了最新的modsecurity规则与之对照,并且随手写了个垃圾的小脚本来统计(代码怕各位反胃就不贴了),在去掉非XSS/SQLI规则并去重后统计,发现在悬镜205条规则中有21个是modsecurity的规则,暂不认为是抄袭

评论

发表评论

此博客中的热门博文

入侵钓鱼站并溯源

██大学通用型WAF不完全绕过(持续非定期更新)