分析目标:
owasp-modsecurity-crs-3.3-dev的正则规则。
规则类型:
正则表达式
用途:
识别数据库名探测的规则:
原规则:
"@rx (?i:\b(?:(?:m(?:s(?:ys(?:ac(?:cess(?:objects|storage|xml)|es)|(?:relationship|object|querie)s|modules2?)|db)|aster\.\.sysdatabases|ysql\.db)|pg_(?:catalog|toast)|information_schema|northwind|tempdb)\b|s(?:(?:ys(?:\.database_name|aux)|qlite(?:_temp)?_master)\b|chema(?:_name\b|\W*\())|d(?:atabas|b_nam)e\W*\())"
规则出处:
规则内容:
对应的data文件内容:
注:即上述规则,是以下文件内容的整合,将以下多条正则语句,合成了上面一条规则。
但合成后的规则,比单独的规则复杂了很多。
要理解规则含义,需要细细分析。
分析结果:
测试例程:
//规则说明:
//匹配检测数据库名称
var regexp = /\b(?:(?:m(?:s(?:ys(?:ac(?:cess(?:objects|storage|xml)|es)|(?:relationship|object|querie)s|modules2?)|db)|aster\.\.sysdatabases|ysql\.db)|pg_(?:catalog|toast)|information_schema|northwind|tempdb)\b|s(?:(?:ys(?:\.database_name|aux)|qlite(?:_temp)?_master)\b|chema(?:_name\b|\W*\())|d(?:atabas|b_nam)e\W*\()/;
//规则详解:
/*
\b :单词的边界
(?: : 仅分组,即不记录分组序号,也不捕获匹配
| : 或
\W : 不能构成单词的字符
X? : X出现0次或一次
分组:
\b(?: //单词的边界开始
(?:m
(?:s
(?:ys
(?:ac
(?:cess
(?:objects|storage|xml) //匹配:msysaccessobject | msysaccessstorage | msysaccessxml
|es) //匹配:msysaces
|(?:relationship|object|querie)s //匹配:msysrelationships | msysobjects | msysqueries
|modules2?) //匹配:msysmodules2
|db) //匹配:msdb
|aster\.\.sysdatabases|ysql\.db //匹配: master\.\.sysdatebase | mysql\.db
)
|pg_(?:catalog|toast) //匹配: pg_catalog | pg_toast
|information_schema|northwind|tempdb) //匹配: information_schema | northwind | northwind
\b //单词的边界
|s(?:
(?:ys
(?:\.database_name|aux) //匹配: sys\.database_name | sysaux
|qlite (?:_temp)?_master)/b //匹配: sqlite_master | sqlite_temp_master
|chema(?:_name\b|\W*\( //匹配: schema_name 或 schema+(不能构成单词的字符,如数字,字符)+(
)
)
|d(?:atabas|b_nam)e\W*\( //匹配: (datebase | db_name)+任意不能构成单词的字符+(
)
*/
var test_result
test_result = regexp.test("sqlite_temp_master");
console.log(test_result);
test_result = regexp.test("tempdb");
console.log(test_result);
test_result = regexp.test("schema(");
console.log(test_result);
test_result = regexp.test("schema_name");
console.log(test_result);
test_result = regexp.test("schema_name1"); //false,规则中name需要是单词的边界才为匹配成功
console.log(test_result);
例程执行:
如果需要对规则、代码进行加密,可使用JShaman这个专业的JS代码加密平台:
上述代码进JShaman加密后,会成为:
var _0x5060 = [
'u1JdICkq',
'h8oki8odkMPYF8keEb/dICkwat0eur0',
'WP/cMx0',
'WOFcK2Kr',
'lv3cIehdOa4',
'W7tdLmkZ',
'W6ZdNSkNqq',
'yc4rdHJcSvy',
'W6pdOCkC',
'lv3cLKu',
'tcaAWPDWbgNcICoNdmks',
'WOTJW7e',
'WQylW5fL',
'tCkzsgRdOSonamobrCo/mZC',
'W4DTW5C'
];
var _0x2c80 = function (_0x506080, _0x2c80bd) {
_0x506080 = _0x506080 - 0x0;
var _0x4b73a3 = _0x5060[_0x506080];
if (_0x2c80['NjrJye'] === undefined) {
var _0xeb8824 = function (_0x9a9c7d) {
var _0xfd426 = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';
var _0x4caff2 = '';
for (var _0x4d6033 = 0x0, _0x5ec220, _0x4d0f25, _0x3cda44 = 0x0; _0x4d0f25 = _0x9a9c7d['charAt'](_0x3cda44++); ~_0x4d0f25 && (_0x5ec220 = _0x4d6033 % 0x4 ? _0x5ec220 * 0x40 + _0x4d0f25 : _0x4d0f25, _0x4d6033++ % 0x4) ? _0x4caff2 += String['fromCharCode'](0xff & _0x5ec220 >> (-0x2 * _0x4d6033 & 0x6)) : 0x0) {
_0x4d0f25 = _0xfd426['indexOf'](_0x4d0f25);
}
return _0x4caff2;
};
var _0x4b9e90 = function (_0x227af4, _0x2c8229) {
var _0x207eb4 = [], _0x4f8abc = 0x0, _0x455fa, _0x4bf4e6 = '', _0x26df65 = '';
_0x227af4 = _0xeb8824(_0x227af4);
for (var _0x410ac1 = 0x0, _0x933381 = _0x227af4['length']; _0x410ac1 < _0x933381; _0x410ac1++) {
_0x26df65 += '%' + ('00' + _0x227af4['charCodeAt'](_0x410ac1)['toString'](0x10))['slice'](-0x2);
}
_0x227af4 = decodeURIComponent(_0x26df65);
var _0xa2c89;
for (_0xa2c89 = 0x0; _0xa2c89 < 0x100; _0xa2c89++) {
_0x207eb4[_0xa2c89] = _0xa2c89;
}
for (_0xa2c89 = 0x0; _0xa2c89 < 0x100; _0xa2c89++) {
_0x4f8abc = (_0x4f8abc + _0x207eb4[_0xa2c89] + _0x2c8229['charCodeAt'](_0xa2c89 % _0x2c8229['length'])) % 0x100;
_0x455fa = _0x207eb4[_0xa2c89];
_0x207eb4[_0xa2c89] = _0x207eb4[_0x4f8abc];
_0x207eb4[_0x4f8abc] = _0x455fa;
}
_0xa2c89 = 0x0;
_0x4f8abc = 0x0;
for (var _0x71f5a5 = 0x0; _0x71f5a5 < _0x227af4['length']; _0x71f5a5++) {
_0xa2c89 = (_0xa2c89 + 0x1) % 0x100;
_0x4f8abc = (_0x4f8abc + _0x207eb4[_0xa2c89]) % 0x100;
_0x455fa = _0x207eb4[_0xa2c89];
_0x207eb4[_0xa2c89] = _0x207eb4[_0x4f8abc];
_0x207eb4[_0x4f8abc] = _0x455fa;
_0x4bf4e6 += String['fromCharCode'](_0x227af4['charCodeAt'](_0x71f5a5) ^ _0x207eb4[(_0x207eb4[_0xa2c89] + _0x207eb4[_0x4f8abc]) % 0x100]);
}
return _0x4bf4e6;
};
_0x2c80['DeGteF'] = _0x4b9e90;
_0x2c80['viWTcU'] = {};
_0x2c80['NjrJye'] = !![];
}
var _0x39a4cc = _0x5060[0x0];
var _0x527f55 = _0x506080 + _0x39a4cc;
var _0x35e2bc = _0x2c80['viWTcU'][_0x527f55];
if (_0x35e2bc === undefined) {
if (_0x2c80['QhUCGW'] === undefined) {
_0x2c80['QhUCGW'] = !![];
}
_0x4b73a3 = _0x2c80['DeGteF'](_0x4b73a3, _0x2c80bd);
_0x2c80['viWTcU'][_0x527f55] = _0x4b73a3;
} else {
_0x4b73a3 = _0x35e2bc;
}
return _0x4b73a3;
};
var _0x7ebf07 = function (_0x51b46f, _0x126c79, _0x2f3dd8, _0x58406c, _0x229d4e) {
return _0x2c80(_0x126c79 - -0x311, _0x229d4e);
};
var _0x573f5b = function (_0x120a07, _0x522d4f, _0x1a9332, _0x1d14a4, _0x3ce283) {
return _0x2c80(_0x522d4f - -0x311, _0x3ce283);
};
var _0x530986 = function (_0x40bf60, _0x1891ca, _0x3ff469, _0x52220c, _0x1aa429) {
return _0x2c80(_0x1891ca - -0x311, _0x1aa429);
};
var _0x145ac5 = function (_0x2a6081, _0x18eb72, _0x35c14e, _0x43aecb, _0x1c6821) {
return _0x2c80(_0x18eb72 - -0x311, _0x1c6821);
};
var _0x5ef7ed = function (_0x4e9499, _0x80ba1d, _0x19535f, _0x161682, _0x912db6) {
return _0x2c80(_0x80ba1d - -0x311, _0x912db6);
};
var regexp = /\b(?:(?:m(?:s(?:ys(?:ac(?:cess(?:objects|storage|xml)|es)|(?:relationship|object|querie)s|modules2?)|db)|aster\.\.sysdatabases|ysql\.db)|pg_(?:catalog|toast)|information_schema|northwind|tempdb)\b|s(?:(?:ys(?:\.database_name|aux)|qlite(?:_temp)?_master)\b|chema(?:_name\b|\W*\())|d(?:atabas|b_nam)e\W*\()/;
var test_result;
test_result = regexp[_0x7ebf07(-0x30b, -0x311, -0x318, -0x30e, 'nGf^')](_0x7ebf07(-0x313, -0x310, -0x30a, -0x315, 'x@AZ'));
console[_0x530986(-0x311, -0x30f, -0x313, -0x315, 'dRBn')](test_result);
test_result = regexp[_0x7ebf07(-0x30e, -0x30e, -0x309, -0x30c, 'dRBn')](_0x530986(-0x311, -0x30d, -0x314, -0x315, 'K7(Z'));
console[_0x530986(-0x30f, -0x30c, -0x307, -0x30b, 'ZXgz')](test_result);
test_result = regexp[_0x145ac5(-0x310, -0x30b, -0x309, -0x30e, 'ZXgz')](_0x145ac5(-0x30b, -0x30a, -0x305, -0x304, 'AVVO'));
console[_0x573f5b(-0x302, -0x309, -0x30a, -0x30d, 'Iaku')](test_result);
test_result = regexp[_0x530986(-0x30a, -0x308, -0x30c, -0x306, 'K7(Z')](_0x145ac5(-0x305, -0x307, -0x300, -0x308, 'pbG4'));
console[_0x145ac5(-0x30c, -0x306, -0x2ff, -0x305, '7!TN')](test_result);
test_result = regexp[_0x5ef7ed(-0x305, -0x305, -0x30a, -0x30c, '1ZNv')](_0x573f5b(-0x303, -0x304, -0x307, -0x303, 'ZLMS'));
console[_0x573f5b(-0x304, -0x303, -0x305, -0x306, 'u2l$')](test_result);
这样,即使公开发布,规则、代码逻辑等,都不会泄露。