//此套WAF防禦正則表達式規則來源於ShareWAF(http://www.sharewaf.com/)
//測試方法建議:請依下方測試使用的test語句進行,根據true、false,可知是否能識別出***並記錄到數據庫javascript
var regexp_debug = 0;
exports.anti_sqlinj_rule =[
// /select|update|delete|truncate|join|union|exec|insert|drop|count|Sp_sqlexec|order by|’|"|>| /select.+(from|limit)/,
/(?:(union(.*?)select))/,
// /having|rongjitest/,
/sleep\((\s*)(\d*)(\s*)\)/,
/group\s+by.+\(/,
/(?:from\W+information_schema\W)/,
/(?:(?:current_)user|database|schema|connection_id)\s*\(/,php
//新增
/\s*or\s+.*=.*/i,
/order\s+by\s+.*--$/i
];java
if( regexp_debug == 1) {
///select|update|delete|truncate|join|union|exec|insert|drop|count|Sp_sqlexec|order by|’|"|>| //不區分大小寫的字符串匹配,留給影衛字符匹配,這裏不使用mysql
//.匹配除「\n」以外的任何單個字符
//含意:匹配select from或select limit語句
//注意:區分大小寫,如要取消大小寫區分,加:/i
//新增,匹配' or 1=1 –,規則:/空格出現或不出現 or 空格出現1次或屢次 任何字符不限次數 = 任意字符不限次數
console.log( /\s*or\s+.*=.*/i.test("'or 1=1") ); //true
console.log( /\s*or\s+.*=.*/i.test("'or 1!=2") ); //true
console.log( /\s*or\s+.*=.*/i.test("'or 'a'='a'") ); //true
console.log( /\s*or\s+.*=.*/i.test("'or'a'='a'") ); //false
console.log( /\s*or\s+.*=.*/i.test("'or1=1") ); //false
//新增,匹配:order by 1 --
console.log( /order\s+by\s+.*--$/i.test("order by 1 --") ); //true
console.log( /order\s+by\s+.*--$/i.test("order by 2 --") ); //true
console.log( /order\s+by\s+.*--$/i.test("order BY 3 --") ); //true正則表達式
console.log( /select.+(from|limit)/.test("select * from abc") ); //true
console.log( /select.+(from|limit)/.test("select top 10 * from abc") ); //true
console.log( /select.+(from|limit)/.test("select top 10") ); //false
console.log( /select.+(from|limit)/.test("Select top 10 from") ); //falsesql
//(?:X):僅分組
//.:任意字符號
//X*?:字符出現0次或屢次
//(.*):任意字符出現0次或屢次
//含意:匹配union select語法
//注意:區分大小寫,如要取消大小寫區分,加:/i
console.log( /(?:(union(.*?)select))/.test("union select 1,2,3 from") ); //true
console.log( /(?:(union(.*?)select))/.test("UNION select 1,2,3 from") ); //false
console.log( /(?:(union(.*?)select))/.test("abc union abc select 1,2,3 from") ); //true
console.log( /(?:(union(.*?)select))/.test("abc union /* */ select 1,2,3 from") ); //true
console.log( /(?:(union(.*?)select))/.test("abc union /* */") ); //false
console.log( /(?:(union(.*?)select))/.test("select col from table union all select col2 from table2") ); //true
//對這條語法存疑,寫的可能有問題,下面一行的測試說明:(?:)(僅分組,不記錄分組序號,也不捕獲該匹配)是無心義的
console.log( /union(.*?)select/.test("abc union /* */ select 1,2,3 from"),"test" ); //trueshell
//\s :空白字符
//\s* :空白字符出現0次或屢次(出現或不出現)
//\d:數字
//\d*:任意數字出現0次或屢次
//含意:匹配sleep(數字)函數,括號裏能夠有任何空白字符
//注意:區分大小寫,如要取消大小寫區分,加:/i
console.log( /sleep\((\s*)(\d*)(\s*)\)/.test("sleep(1)") ); //true
console.log( /sleep\((\s*)(\d*)(\s*)\)/.test("sleep( 1 )") ); //true
console.log( /sleep\((\s*)(\d*)(\s*)\)/.test("sleep('abc')") ); //false
console.log( /sleep\((\s*)(\d*)(\s*)\)/.test("sleep(' abc')") ); //false
console.log( /sleep\((\s*)(\d*)(\s*)\)/.test("SLEEP(1)") ); //false
//加i,不區分大小寫
console.log( /sleep\((\s*)(\d*)(\s*)\)/i.test("SLEEP(1)"),"test2" ); //true數據庫
//\s :空白字符
//.:任意字符號
//含意:匹配group by語法
//注意:區分大小寫,如要取消大小寫區分,加:/i
//不肯定:這條規則可能有誤,不該該有(符號,group by語句沒有(
console.log( /group\s+by.+\(/.test("group by id(") ); //true
console.log( /group\s+by.+\(/.test("group by id") ); //falsecookie
//information_schema:mysql自帶數據庫
//\W:不能構成單詞的字符,等價於[^A-Za-z0-9_]
//(?:X)僅分組
console.log( /(?:from\W+information_schema\W)/.test("select TABLES from * information_schema * ") ); //true
console.log( /(?:from\W+information_schema\W)/.test("select TABLES from/**/information_schema/**/") ); //true
console.log( /(?:from\W+information_schema\W)/.test("select TABLES from 123 /**/ union information_schema/**/") ); //false
//(?:X)僅分組無心義,應該可改成:
console.log( /from\W+information_schema\W/.test("select TABLES from/**/information_schema/**/") ); //truexss
//(?:X):僅分組
//|:或
//\s:空白字符
//注意:區分大小寫,如要取消大小寫區分,加:/i
console.log( /(?:(?:current_)user|database|schema|connection_id)\s*\(/.test("current_user (") ); //true
console.log( /(?:(?:current_)user|database|schema|connection_id)\s*\(/.test("current_database(") ); //true
console.log( /(?:(?:current_)user|database|schema|connection_id)\s*\(/.test("current_connection_id (") ); //true
console.log( /(?:(?:current_)user|database|schema|connection_id)\s*\(/.test("current_connection_id = (") ); //false
console.log( /(?:(?:current_)user|database|schema|connection_id)\s*\(/.test("connection_id(") ); //true
console.log( /(?:(?:current_)user|database|schema|connection_id)\s*\(/.test("connection_ID(") ); //false
//應該可簡化爲:
console.log( /(?:current_)user|database|schema|connection_id\s*\(/.test("current_connection_id (") ); //true
console.log( /(?:current_)user|database|schema|connection_id\s*\(/.test("connection_id(") ); //true
}
exports.anti_cookieinj_rule =[
/select.+(from|limit)/,
/(?:(union(.*?)select))/,
///having|rongjitest/,
/sleep\((\s*)(\d*)(\s*)\)/,
/benchmark\((.*)\,(.*)\)/,
/base64_decode\(/,
/(?:from\W+information_schema\W)/,
//修改,增長version
/(?:(?:current_)user|database|version|schema|connection_id)\s*\(/,
/(?:etc\/\W*passwd)/,
/into(\s+)+(?:dump|out)file\s*/,
/group\s+by.+\(/,
/xwork.MethodAccessor/,
/(?:define|eval|file_get_contents|include|require|require_once|shell_exec|phpinfo|system|passthru|preg_\w+|execute|echo|print|print_r|var_dump|(fp)open|alert|showmodaldialog)\(/
];
if( regexp_debug == 1) {
//\i大小寫區分問題再也不贅述,廣泛存在
//mysql函數benchmark
//檢測例::benchmark(1000,encode("hello","goodbye"))
console.log( /benchmark\((.*)\,(.*)\)/.test('select BENCHMARK(1000000,encode("hello","goodbye"))') ); //false
console.log( /benchmark\((.*)\,(.*)\)/.test('select benchmark(1000000,encode("hello","goodbye"))'),"benchmark"); //true
///base64_decode\(/
//檢測base64_decode()函數
//到此,大至可理解:此套規則是針對mysql、php的
console.log( /base64_decode\(/.test("base64_decode('abc')") ); //true
console.log( /base64_decode\(/.test("base64_Decode('abc')") ); //false
console.log( /(?:(?:current_)user|database|schema|connection_id)\s*\(/.test("user(") ); //false
console.log( /(?:(?:current_)user|database|schema|connection_id)\s*\(/.test("current_user(") ); //true
console.log( /(?:(?:current_)user|database|schema|connection_id)\s*\(/.test("current_user (") ); //true
console.log( /(?:(?:current_)user|database|schema|connection_id)\s*\(/.test("current_user (") ); //true
console.log( /(?:(?:current_)user|database|schema|connection_id)\s*\(/.test("current_usEr (") ); //false
console.log( /(?:(?:current_)user|database|schema|connection_id)\s*\(/.test("current_user * (") ); //false
//etc路徑加passwd檢測
//\W:不能構成單詞的字符
console.log( /(?:etc\/\W*passwd)/.test("etc/passwd") ); //true
console.log( /(?:etc\/\W*passwd)/.test("etc//passwd") ); //true
console.log( /(?:etc\/\W*passwd)/.test("etc passwd") ); //false
console.log( /(?:etc\/\W*passwd)/.test("etc////passwd") ); //true
console.log( /(?:etc\/\W*passwd)/.test("etc////PASSWD") ); //false
//mysql的file系列函數檢測:dumpfile\outfile
//X+,X字符出現一次或屢次
//\s:空白字符
console.log ( /into(\s+)+(?:dump|out)file\s*/.test("select * from test into outfile '/tmp/test.txt'") ); //true
console.log ( /into(\s+)+(?:dump|out)file\s*/.test("select * from test into dumpfile '/tmp/test.txt'") ); //true
console.log ( /into(\s+)+(?:dump|out)file\s*/.test("select * from test into dumpFILE '/tmp/test.txt'") ); //false
///xwork.MethodAccessor/,
//這是struts2相關的一個漏洞關鍵字
console.log( /xwork.MethodAccessor/.test("xwork.MethodAccessor") ); //true
console.log( /xwork.MethodAccessor/.test("xwork.MethodAccessoR") ); //false
//w+:能夠構成單詞的字符
//檢測各類函數
/(?:define|eval|file_get_contents|include|require|require_once|shell_exec|phpinfo|system|passthru|preg_\w+|execute|echo|print|print_r|var_dump|(fp)open|alert|showmodaldialog)\(/
console.log( /(?:define|eval|file_get_contents|include|require|require_once|shell_exec|phpinfo|system|passthru|preg_\w+|execute|echo|print|print_r|var_dump|(fp)open|alert|showmodaldialog)\(/.test("define") ); //false
console.log( /(?:define|eval|file_get_contents|include|require|require_once|shell_exec|phpinfo|system|passthru|preg_\w+|execute|echo|print|print_r|var_dump|(fp)open|alert|showmodaldialog)\(/.test("define(") ); //true
console.log( /(?:define|eval|file_get_contents|include|require|require_once|shell_exec|phpinfo|system|passthru|preg_\w+|execute|echo|print|print_r|var_dump|(fp)open|alert|showmodaldialog)\(/.test("define(") ); //true
console.log( /(?:define|eval|file_get_contents|include|require|require_once|shell_exec|phpinfo|system|passthru|preg_\w+|execute|echo|print|print_r|var_dump|(fp)open|alert|showmodaldialog)\(/.test("preg_a(") ); //true
}
exports.anti_xss_rule = [
//註釋掉
// /<|>|:|'|""|`|--|()|[]|{}|/,
/\<(iframe|script|body|img|layer|div|meta|style|base|object|input)/,
/(onmouseover|onmousemove|onerror|onload)\=/i,
//新增
/javascript:/i
];
if( regexp_debug == 1){
console.log( /\<(iframe|script|body|img|layer|div|meta|style|base|object|input)/.test(" console.log( /\<(iframe|script|body|img|layer|div|meta|style|base|object|input)/.test("iframe")); //false
console.log( /\<(iframe|script|body|img|layer|div|meta|style|base|object|input)/.test("
console.log( /(onmouseover|onmousemove|onerror|onload)\=/i.test("onerror='alert(1)'")); //true
console.log( /javascript:/i.test("javascript:alert(1);") );
}
exports.anti_folder_iterator_rule = [
/..\/..\//,
// /(?:etc\/\W*passwd\/shadow)/
//修改:
// /(?:etc\/\W*passwd)/i
];
if( regexp_debug == 1){
//匹配:../../
console.log( /..\/..\//.test("../../pass/") ); //true
console.log( /..\/..\//.test("../pass/") ); //false
}
exports.anti_cmdinj_rule = [
//修改
// || 命令
/\|\|.*(?:ls|pwd|whoami|ll|ifconfog|ipconfig|&&|chmod|cd|mkdir|rmdir|cp|mv)/,
//命令||
/(?:ls|pwd|whoami|ll|ifconfog|ipconfig|&&|chmod|cd|mkdir|rmdir|cp|mv).*\|\|/
];
if(regexp_debug == 1){
console.log( /\|\|.*(?:ls|pwd|whoami|ll|ifconfog|ipconfig|&&|chmod|cd|mkdir|rmdir|cp|mv)/.test("||ipconfig") ); //true
console.log( /\|\|.*(?:ls|pwd|whoami|ll|ifconfog|ipconfig|&&|chmod|cd|mkdir|rmdir|cp|mv)/.test("||cd") ); //true
console.log( /\|\|.*(?:ls|pwd|whoami|ll|ifconfog|ipconfig|&&|chmod|cd|mkdir|rmdir|cp|mv)/.test("cd") ); //false
console.log( /\|\|.*(?:ls|pwd|whoami|ll|ifconfog|ipconfig|&&|chmod|cd|mkdir|rmdir|cp|mv)/.test("|cd") ); //false
}
exports.anti_remote_file_include_rule = [
/http:\/\/|https:\/\//,
/(?:define|eval|file_get_contents|include|require|require_once|shell_exec|phpinfo|system|passthru|preg_\w+|execute|echo|print|print_r|var_dump|(fp)open|alert|showmodaldialog)\(/,
//註釋
// /(gopher|doc|php|glob|file|phar|zlib|ftp|ldap|dict|ogg|data)\:\//,
];
if(regexp_debug == 1){
console.log( /http:\/\/|https:\/\/|..\/..\//.test("http://") ); //true
console.log( /http:\/\/|https:\/\/|..\/..\//.test("http:") ); //false
console.log( /http:\/\/|https:\/\/|..\/..\//.test("https:") ); //false
}
exports.anti_local_file_include_rule = [
//這行容易誤報
// /..\//,
/(?:etc\/\W*passwd)/,
//註釋
// /(?:define|eval|file_get_contents|include|require|require_once|shell_exec|phpinfo|system|passthru|preg_\w+|execute|echo|print|print_r|var_dump|(fp)open|alert|showmodaldialog)\(/,
/(gopher|doc|php|glob|file|phar|zlib|ftp|ldap|dict|ogg|data)\:\//
];
if( regexp_debug == 1){
//匹配:etc/ 不能構成單詞的任意字符不出現或出現或出現屢次 password
console.log( /(?:etc\/\W*passwd)/i.test("etc//passwd") ); //true
console.log( /(?:etc\/\W*passwd)/i.test("etc/passwd") ); //true
console.log( /(?:etc\/\W*passwd)/i.test("etc//**/passwd") ); //true
console.log( /(?:etc\/\W*passwd)/i.test("etc\\passwd") ); //false
console.log( /(gopher|doc|php|glob|file|phar|zlib|ftp|ldap|dict|ogg|data)\:\//.test("file:/") ); //true
console.log( /(gopher|doc|php|glob|file|phar|zlib|ftp|ldap|dict|ogg|data)\:\//.test("file:") ); //false
}