当前位置:首页 > 网络黑客 > 正文内容

基于OWASP Modsecurity CRS规则的误报率和漏报率调试

访客5年前 (2019-09-26)网络黑客1270

一款成熟的waf产品应该包含全方位的防御手段,一个优秀的waf必然是一个装满利器的工具箱。

工具箱里面有:字符解码,强大的解码覆盖能力,双重嵌套解码,智能识别出编码方式再解码;

正则匹配加速:可以使用Intel的高性能的正则表达式匹配库;

Hyperscan:可以使用自动机或者多模匹配手段。

灵活的自定义规则:主要是针对http请求/响应的行头体特征,具有正则/包含/大小于/网段/相等多种计算方法,具有多条自定义规则&&的判断逻辑。

强大的默认规则库:需要人工去收集各种规则,收集手段包括离线waf日志分析/owasp crs规则提取/cve漏洞曝出攻击特征/万能的github,要具有针对性,不能在linux系统跑一些防止win系统攻击规则,白白浪费匹配性能。规则能够动态更新,一定要减少nginx reload。

语义分析可以使用自动机,自然语言处理,数据标签化特征匹配等等,语义分析可以用来实时分析请求,判别是否为恶意攻击。

机器学习在实际应用中,特别适合事后分析,我们可以提取一些攻击日志,提取一些正常日志,作为训练样本的数据。应避免样本数据过于重复,在筛选攻击日志时可以使用余弦相似度算法。然后可以通过词频向量,逆文本频率指数等手段,离线分析我们的正常和攻击日志,判断误报和漏报的请求。不断优化我们的训练样本,跑我们的正常和拦截日志,总会有意外收获。

以上只是提到了几个方面,其他还包括:通过web上传webshell检测、防爬、地域封禁、全方位实时数据分析、回源到vpc虚拟网络、精准智能人机识别、图片鉴黄等等,只要是与web应用安全相关的都属于waf范畴。

waf产品的防护功能核心指标,即误报率和漏报率。

下面分析我的一次调试优化误报率/漏报率的过程。

crs规则中默认inbound_anomaly_score_threshold=5阈值5

paranoia_level=1 严格等级默认为1,调高会匹配高等级规则

critical_anomaly_score=5命中严重异常规则的请求会加5分

error_anomaly_score=4 命中错误异常规则的请求会加4分

warning_anomaly_score=3 命中警告异常的请求会加3分

notice_anomaly_score=2 命中提示异常的请求会加2分

全部采用默认配置,选用全部默认规则结果如下

产生较多误报

分析误报请求

[12, 26, 28, 32, 39, 51, 56, 58, 89, 91, 94, 99, 111, 133, 140, 149, 152, 164, 197, 199, 209, 218, 226, 227, 229, 232, 236, 263, 276, 281, 288, 290, 307, 312, 315, 323, 330, 336, 341, 352, 353, 355, 383, 389, 391, 392, 399, 402, 403, 411, 412, 416, 428, 438, 454, 467, 472, 483, 484, 489, 491, 497, 498, 499, 501, 503, 526, 538, 549, 575, 587, 595, 596, 599, 608, 616, 618, 625, 651, 655, 657, 659, 677, 699, 736, 764, 767, 781, 785, 797, 845, 854, 884, 892, 908, 925, 932, 955, 959, 977, 982, 986, 997, 1003, 1004, 1048, 1068, 1073, 1095, 1102, 1125, 1160, 1173, 1192, 1193, 1195, 1205, 1215, 1221, 1224, 1235, 1236, 1240, 1259, 1262, 1264, 1270, 1274, 1296, 1314, 1320, 1328, 1332, 1333, 1342, 1362, 1365, 1369, 1380, 1382, 1392, 1403, 1404, 1424, 1445, 1451, 1466, 1477, 1481, 1490, 1509, 1517, 1546, 1552, 1574, 1584, 1595, 1596, 1626, 1627, 1646, 1658, 1691, 1698, 1700, 1731, 1733, 1741, 1756, 1760, 1771, 1777, 1808, 1824, 1831, 1846]

拦截日志如下

2019/09/26 11:46:43 [error] 10616#0: *42 [lua] waf.lua:494: _process_rule(): 943120 collection...0 pattern...0..value....0...rule.var...{["type"]="REQUEST_HEADERS",["length"]=true,["collection_key"]="REQUEST_HEADERS|specific|Referer",["parse"]={[1]="specific",[2]="Referer",},}, client: 10.232.132.53, server: cert.placuna.cn, request: "GET /mobsong_notfound.html HTTP/1.1", host: "cert.placuna.cn:8080" 2019/09/26 11:46:43 [error] 10616#0: *42 [lua] waf.lua:519: _process_rule(): after match rule.actions...{["disrupt"]="SCORE",["nondisrupt"]={[1]={["data"]={["value"]="%{rule.msg}",["key"]="MSG",["col"]="TX",},["action"]="setvar",},[2]={["data"]={["inc"]=true,["value"]="%{TX.CRITICAL_ANOMALY_SCORE}",["key"]="SESSION_FIXATION_SCORE",["col"]="TX",},["action"]="setvar",},[3]={["data"]={["inc"]=true,["value"]="%{TX.CRITICAL_ANOMALY_SCORE}",["key"]="ANOMALY_SCORE_PL1",["col"]="TX",},["action"]="setvar",},[4]={["data"]={["value"]="%{TX.0}",["key"]="943120-OWASP_CRS/WEB_ATTACK/SESSION_FIXATION-REQUEST_HEADERS",["col"]="TX",},["action"]="setvar",},},}, client: 10.232.132.53, server: cert.placuna.cn, request: "GET /mobsong_notfound.html HTTP/1.1", host: "cert.placuna.cn:8080"

从拦截日志中可以看出为id为943120的规则误拦

将规则文件REQUEST-943-APPLICATION-ATTACK-SESSION-FIXATION.conf屏蔽掉

再测

误报基本没有

召回率由70.422%下降至66.549%、

研究session会话攻击的规则,id:943120为链式规则,第一步先匹配请求中是否有特殊sessionid字段,如果没有不拦截,如果有进入第二步,判断此请求的header中是否有referer,如果有则不拦截,没有则对此请求增加critical得分=5,默认阈值为5,所以直接触发拦截行为。所以对此逻辑造成误报率过高的初步解决方法是将critical得分改为warning得分3,来降低误报率。

修改后测试结果

相当于把943文件屏蔽掉了。

探究召回率下降的原因。修改后增加的漏报的请求为

[11, 82, 122, 128, 462, 463, 508, 552, 610, 634, 682, 722, 734, 746, 911, 987, 1098, 1138, 1176, 1199, 1223, 1263, 1371, 1439, 1498, 1570, 1614, 1619, 1692, 1727, 1847, 1848, 1849]

即这些请求在未修改前会被943规则阻拦。

(在此过程中发现500错误)

2019/09/27 17:44:45 [error] 7067#0: *5 lua entry thread aborted: runtime error: .https://www.freebuf.com/articles/kswaf/openresty20190423/waf_lua_ng/resty/core/regex.lua:374: attempt to get length of local 'subj' (a number value)

原因是在初始化阶段向matched_var中写入数字,后面的等级2规则中需要对.data文件中的字符串和matched_var中的内容进行匹配,匹配方式为refind,这要求其不能为数字,否则会报错。

解决办法:在向写入matched_var写入数据时加一层数据类型校验避免这一错误

继续分析943处理后增加的漏报问题

[11, 82, 122, 128, 462, 463, 508, 552, 610, 634, 682, 722, 734, 746, 911, 987, 1098, 1138, 1176, 1199, 1223, 1263, 1371, 1439, 1498, 1570, 1614, 1619, 1692, 1727, 1847, 1848, 1849]

将943的规则文件调值默认发送上述单个请求。

请求的行号: 11

请求的label: 1

响应状态: 403

method: GET urlpath: /jobs/jobs-list.php?key=%C7%EB%CA%E4%C8%EB%D6%B0%CE%BB%C3%FB%B3%C6%A1%A2%B9%AB%CB%BE%C3%FB%B3%C6%A1%A2%BC%BC%DC%CC%D8%B3%A4%A1%A2%D1%A7%D0%A3%B5%C8%B9%D8%BC%FC%D7%D6...&Submit=%CB%D1%D6%B0%CE%BB%22%20and%20%22a%22=%22a postbody: None headers: {'Cookie': 'PHPSESSID=45a1i8dljhmcp4bfm5bdv7c6u0', 'User-Agent': 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; SLCC1; .NET CLR 2.0.50727; Media Center PC 5.0; .NET CLR 3.0.04506; .NET CLR 1.1.4322)'}

其中11,82,122,128,463,508,552,682,610,634,722,734,911,1176,1263,1371, 1498,1570,1614,1692,1727,1847,1848,1849为疑似sql注入请求,加粗部分sql注入在 body中,所以lable为1,但实际拦截为943文件,拦截依据是cookie中含有sessionid字段且无referer。

746,987,1098,1138,1199,1223,1439,1619为疑似会话固定攻击

漏报猜测:sql注入漏报,sql注入规则等级过低。

初步处理方式,单独调高sql注入拦截的等级,看误报是否会减少。

结果

因为每个等级有每个等级的得分,只有当默认等级设置为跟高等级,阻断时才会将各个等级的得分相加,所以单独设置某个规则文件的等级对阻断是没有意义的,但是可以从日志中查看是否会命中高等级的规则。

(调试过程中遇到转码问题,发现1849请求中的unicode在解析过程中没有被转码,导致规则匹配不成功,调试do_transform函数,解决办法:保留缓存命中率高的collection_key

的格式,在第一次遇到缓存未命中时对数据进行全部类型解码,之前进行的是replacetr和alltransform两种解码,造成解码不完全的问题。)

2019/09/29 18:21:02 [error] 12468#0: *11 [lua] waf.lua:496: _process_rule(): 942130 collection...{[1]="45a1i8dljhmcp4bfm5bdv7c6u0",[2]="λУ...",[3]="λ and a=a",} pattern...(?i:([\s'"`]*?)([\d\w]++)([\s'"`]*?)(?:<(?:=(?:([\s'"`]*?)(?!\2)([\d\w]+)|>([\s'"`]*?)(?:\2))|>?([\s'"`]*?)(?!\2)([\d\w]+))|(?:not\s+(?:regexp|like)|is\s+not|>=?|!=|\^)([\s'"`]*?)(?!\2)([\d\w]+)|(?:(?:sounds\s+)?like|r(?:egexp|like)|=)([\s'"`]*?)(?:\2)))..value....table: 0x400b8250...rule.var...{["type"]="REQUEST_ARGS",["collection_key"]="REQUEST_ARGS|values|true",["parse"]={[1]="values",[2]=true,},}, client: 10.232.11.16, server: cert.placuna.cn, request: "GET /jobs/jobs-list.php?key=%C7%EB%CA%E4%C8%EB%D6%B0%CE%BB%C3%FB%B3%C6%A1%A2%B9%AB%CB%BE%C3%FB%B3%C6%A1%A2%BC%BC%DC%CC%D8%B3%A4%A1%A2%D1%A7%D0%A3%B5%C8%B9%D8%BC%FC%D7%D6...&Submit=%CB%D1%D6%B0%CE%BB%22%20and%20%22a%22=%22a HTTP/1.1", host: "cert.placuna.cn:8080" 2019/09/29 18:21:02 [error] 12468#0: *11 [lua] waf.lua:521: _process_rule(): after match rule.actions...{["disrupt"]="SCORE",["nondisrupt"]={[1]={["data"]={["value"]="%{rule.msg}",["key"]="MSG",["col"]="TX",},["action"]="setvar",},[2]={["data"]={["inc"]=true,["value"]="%{TX.CRITICAL_ANOMALY_SCORE}",["key"]="SQL_INJECTION_SCORE",["col"]="TX",},["action"]="setvar",},[3]={["data"]={["inc"]=true,["value"]="%{TX.CRITICAL_ANOMALY_SCORE}",["key"]="ANOMALY_SCORE_PL2",["col"]="TX",},["action"]="setvar",},[4]={["data"]={["value"]="%{TX.0}",["key"]="%{RULE.ID}-OWASP_CRS/WEB_ATTACK/SQL_INJECTION-%{MATCHED_VAR_NAME}",["col"]="TX",},["action"]="setvar",},},}, client: 10.232.11.16, server: cert.placuna.cn, request: "GET /jobs/jobs-list.php?key=%C7%EB%CA%E4%C8%EB%D6%B0%CE%BB%C3%FB%B3%C6%A1%A2%B9%AB%CB%BE%C3%FB%B3%C6%A1%A2%BC%BC%DC%CC%D8%B3%A4%A1%A2%D1%A7%D0%A3%B5%C8%B9%D8%BC%FC%D7%D6...&Submit=%CB%D1%D6%B0%CE%BB%22%20and%20%22a%22=%22a HTTP/1.1", host: "cert.placuna.cn:8080"

从日志中发现,sql注入规则文件的二三四等级均有对当前漏报产生critical等级的提醒,证明这些请求对于crs规则来说并不算是漏报,只是crs认为这些请求只有在严格要求的时候才会阻拦,正常模式下是会放过这些请求的。所以目前的调整策略是优先遵从crs规则,后期根据实际场景和业务再进行调整。

继续分析误报请求

[164, 352, 596, 659, 767, 1365, 1731]

149和596为底层默认规则拦截误报。

请求352请求内容及相应状态如下

拦截的日志如下:

分析日志可知,该请求被规则id941130(xss)的var拦截

[2]=> table: 0x656b80 { ? ? ? ? ? ? ? ? ? ? ? ?[type]=> "COOKIES" ? ? ? ? ? ? ? ? ? ? ? ?[collection_key]=> "COOKIES|keys|true" ? ? ? ? ? ? ? ? ? ? ? ?[parse]=> table: 0x657000 { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? [1]=> "keys" ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? [2]=> true ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? ?}

因为该请求的cookie的key为‘union-indexhtml’,匹配到了 (?i)[\s\S](?:x(?:link:href|html|mlns)|!ENTITY.*?SYSTEM|data:text/html|pattern(?=.*?=)|formaction|\@import|base64)\b,命中后的action为下,直接加一个critical得分(5)导致拦截。

[3]=> table: 0x658bb0 { ? ? ? ? ? ? ? ? ? ? ? ?[data]=> table: 0x659010 { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?[value]=> "%{TX.CRITICAL_ANOMALY_SCORE}" ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?[key]=> "ANOMALY_SCORE_PL1" ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?[inc]=> true ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?[col]=> "TX" ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?} ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?[action]=> "setvar" ? ? ? ? ? ? ? ? ? ? ? ? }

规则解析如下

解决方法:先将此条规则屏蔽,后期研究此条规则(941130)的优化。

解决后误报消除,漏报没有增加。

至此,误报问题解决,接下来研究漏报请求

请求11如下:

urlpath: /jobs/jobs-list.php?key=%C7%EB%CA%E4%C8%EB%D6%B0%CE%BB%C3%FB%B3%C6%A1%A2%B9%AB%CB%BE%C3%FB%B3%C6%A1%A2%BC%BC%DC%CC%D8%B3%A4%A1%A2%D1%A7%D0%A3%B5%C8%B9%D8%BC%FC%D7%D6...&Submit=%CB%D1%D6%B0%CE%BB%22%20and%20%22a%22=%22a postbody: None headers: {'Cookie': 'PHPSESSID=45a1i8dljhmcp4bfm5bdv7c6u0', 'User-Agent': 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; SLCC1; .NET CLR 2.0.50727; Media Center PC 5.0; .NET CLR 3.0.04506; .NET CLR 1.1.4322)'}

不会被crs拦截,但是sql注入引擎942130会在level2等级对其产生critical得分,尝试将此条规则写入level1,。查看结果漏报减少约10%,但是此条规则会增加10%的误报。误报请求如下:

{[1]="cnzz_eid=1850184636-1394596016-http%3a%2f%2fwww.yaose.net%2f&ntime=1394596016&cnzz_a=2&sin=none<ime=1394595991292"

会命中“n=n”产生误报

处理方法:将此条规则设置为level2等级,遵从crs本身设定,后期研究此条规则942130,消除误报

除信息泄露等低危请求漏报,剩余漏报如下:

[11, 13, 48, 49, 53, 67, 79, 81, 82, 105, 113, 122, 124, 127, 128, 131, 139, 142, 145, 161, 168, 175, 177, 180, 193, 212, 214, 238, 246, 254, 333, 344, 357, 367, 370, 375, 397, 409, 410, 413, 419, 430, 444, 445, 449, 459, 463, 488, 508, 517, 520, 533, 552, 554, 555, 558, 562, 566, 581, 591, 598, 610, 620, 629, 634, 654, 668, 674, 682, 704, 705, 722, 734, 737, 746, 768, 772, 780, 788, 808, 836, 856, 870, 873, 879, 906, 911, 915, 917, 924, 931, 935, 936, 949, 952, 953, 965, 987, 994, 1013, 1024, 1025, 1027, 1050, 1053, 1062, 1078, 1085, 1088, 1113, 1117, 1121, 1129, 1135, 1138, 1144, 1167, 1176, 1199, 1203, 1214, 1223, 1243, 1263, 1279, 1282, 1315, 1319, 1331, 1351, 1354, 1356, 1360, 1371, 1374, 1401, 1405, 1412, 1415, 1423, 1434, 1439, 1443, 1446, 1449, 1470, 1473, 1479, 1488, 1498, 1529, 1544, 1558, 1560, 1567, 1570, 1571, 1577, 1585, 1591, 1598, 1599, 1610, 1614, 1618, 1619, 1632, 1648, 1652, 1676, 1684, 1685, 1692, 1696, 1701, 1718, 1727, 1737, 1740, 1750, 1751, 1781, 1786, 1794, 1796, 1805, 1810, 1833, 1834, 1840, 1847, 1848, 1849]

此类漏报大部分为sql注入和php代码注入漏报

如1840-1849

请求如下:

method: GET urlpath: /user/category/1)%20AND%20(SELECT%204037%20FROM(SELECT%20COUNT(*),CONCAT(CHAR(58,100,114,108,58),(SELECT%20(CASE%20WHEN%20(4037=4037)%20THEN%201%20ELSE%200%20END)),CHAR(58,122,103,111,58),FLOOR(RAND(0)*2))x%20FROM%20information_schema.tables%20GROUP%20BY%20x)a)%20AND%20(9909=9909 postbody: None headers: {'User-Agent': 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 1.1.4322)'}

经一系列转码后出现sql注入特殊字符

解决方法:增加base64解码功能。结果如下

这里只是记录一次调试和优化过程。

扫描二维码推送至手机访问。

版权声明:本文由黑客接单发布,如需转载请注明出处。

本文链接:https://therlest.com/106847.html

分享给朋友:

“基于OWASP Modsecurity CRS规则的误报率和漏报率调试” 的相关文章

奥运会遭到俄罗斯黑客攻击!黑客攻击微信聊天记录

人民网2021年8月13日02:28:03的消息,黑客攻击微信聊天记录 东京奥运会惨遭俄罗斯黑客攻击! 英国国家网络安全中心日前揭露了一项惊人的黑客计划:俄罗斯军事情报部门曾准备对原定今夏举办的东京奥林匹克运动会和残奥会发起网络攻击。据悉,其攻击目标涵盖赛事组织者、后勤公司和赞助商。 打开百...

【干货知识】高級不断渗透第八季-demo就是远程控制

本季度是《高級不断渗透-第七季demo的发展》的持续。 点一下文尾左下角“阅读”可阅读文章第七季文章正文。 在第一季有关后门中,文章内容提及再次编译程序notepad ,来引入有目标源代码后门结构。 在第六季有关后门中,文章内容假定不在获知notepad 的源代码,来引入无目标源代码沟...

为什么反复烧开的水会有毒?

为什么反复烧开的水会有毒? 千滚水就是在炉上沸腾了一夜或很长时间的水,还有电热水器中反复煮沸的水。这种水因煮过久,水中不挥发性物质,如钙、镁等重金属成分和亚硝酸盐因浓缩后含量很高。久饮这种水,会干扰人的胃肠功能,出现暂时腹泻、腹胀;有毒的亚硝酸盐还会造成机体缺氧,严重者会昏迷惊厥,甚至死亡。 蒸...

茯苓多少钱一克贵吗 - 土茯苓和茯苓哪个贵

因为很难挖到。茯苓2点5-3点5元一两,2016年1月4日更新。 30元左右一斤,还有以后.药店的销售价格通常在20,价格更高些,我在这边收购,2011年茯苓价格分两种价格,也就是两种产品,心;脾;肺;肾经。也和并不容易挖到。 4]渗湿利水;健脾和胃;宁心安神。即使在茯苓产地的山里面,茯苓价格悄悄地...

如厕阅读-如厕时读书看报有哪些坏处?

如厕阅读-如厕时读书看报有哪些坏处? 读书、看报兼如厕,不少人有这样的习惯。然而这一习惯非常不好。蹲厕时读书看报,会干扰大脑对排便传导神经的指挥,延长排便时间。现代医学研究证实,蹲厕超过3分钟即可直接导致直肠静脉曲张淤血,易诱发痔疮,且病情的轻重与时间长短有关。蹲厕时间越长,发病几率越高。因为久蹲...

怎样辨别有农药残留的蔬菜?

怎样辨别有农药残留的蔬菜? 一、不吃形状、颜色异常的蔬菜: 形状:颜色正常的蔬菜,一般是常规栽培,是未用激素等化学品处理的,可以放心地食用。 “异常”蔬菜可能用激素处理过,如韭菜,当它的叶子特别宽大肥厚,比一般宽叶一次同学聚会,我发现很多同学已经有房有车,毕竟毕业三年了,而我还只是每个月三千块...

评论列表

酒奴森槿
3年前 (2022-05-28)

1%A7%D0%A3%B5%C8%B9%D8%BC%FC%D7%D6...&Submit=%CB%D1%D6%B0%CE%BB%22%20and%20%22a%22=%22apostbo

鸽吻西奺
3年前 (2022-05-28)

1424, 1445, 1451, 1466, 1477, 1481, 1490, 1509, 1517, 1546, 1552, 1574, 1584, 1595, 1596, 1626, 1627, 1646, 1658, 1691, 1698, 1700, 1731, 1733, 1

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。