当前位置: 首页 > 工具软件 > ModSecurity > 使用案例 >

modsecurity troubleshoting

白萧迟
2023-12-01

modsecurity troubleshoting

最近上了modsecurity做waf, 但几个正常页面报403了, 看页面上的显示错误, 是modsecurity拦截了.

这个页面上是通过执行sql返回结果的, 估计是被识别成了sql注入.

分析问题

打开audit日志

首先要打开modsecurity的audit log, 默认是已经打开 了, 位置在/var/log/modsec_audit.log. 如果没有打开 可以参考以下步骤.

  1. 配置文件**/etc/nginx/modsec/modsecurity.conf**.

  2. 找到以下几行, 做相应的修改

    SecAuditLogType Serial
    SecAuditLog /var/log/nginx/modsec_audit.log #日志路径
    
    SecAuditEngine RelevantOnly #Off关闭, On打开并记所有处理记录, ReleventOnly只记触发了warning和error的.
    SecAuditLogRelevantStatus "^(?:5|4(?!04))" #只记是500和400系统的error和warning, 但排除了404
    SecAuditLogParts ABIJDEFHZ #具体哪部分写入日志, 详细看下表
    
    SectionDescription
    AAudit log header (mandatory)
    BRequest headers
    CRequest body
    DReserved
    EResponse body
    FResponse headers
    GReserved
    HAudit log trailer, which contains additional data
    ICompact request body alternative (to part C), which excludes files
    JInformation on uploaded files
    KContains a list of all rules that matched for the transaction
    ZFinal boundary (mandatory)
  3. 修改好后保存, 重启nginx

分析日志

日志分析过程如下

  1. 先用tail -f /var/log/modsec_audit.log命令实时打印出日志

  2. 在网页上重复一下报错的操作

  3. 新的audit信息会打印到屏幕上

    我的信息大约是下面的输入

    ModSecurity: Warning. Matched "Operator Rx' with parameter(?i)(?:;|{||||||&|&&|\n|\r|)\s*[\(,@\'\"\s]*(?:[\w'\"\./]+/|[\\\\'\"\^]*\w[\\\\'\"\^]*:.*\\\\|[\^\.\w '\"/\\\\]*\\\\)?[\"\^]*(?:s[\"\^]*(?:y[\"\^]*s[\"\^]*(?:t[\"\^]*e[\"\^]*m[\"\^]*(?:p[\"\^]*r[ (5092 characters omitted)' against variableARGS:json.sql’ (Value: `select * from (\x0d\x0aSELECT *\x0d\x0aFROM “db”.“tables”\x0d\x0aLIMIT 100\ (16 characters omitted)’ ) [file “REQUEST-932-APPLICATION-ATTACK-RCE.conf”] [line “274”] [id “932115”] [rev “”] [msg “Remote Command Execution: Windows Command Injection”] [data “Matched Data: \x0d\x0aSELECT found within ARGS:json.sql: select * from (\x0d\x0aSELECT *\x0d\x0aFROM “db”.“tables”\x0d\x0aLIMIT 100\x0d\x0a)\x0d\x0a”] [severity “2”] [ver “OWASP_CRS/3.3.0”] [maturity “0”] [accuracy “0”] [tag “application-multi”] [tag “language-shell”] [tag “platform-windows”] [tag “attack-rce”] [tag “paranoia-level/1”] [tag “OWASP_CRS”] [tag “capec/1000/152/248/88”] [tag “PCI/6.5.2”] [hostname “xxx”] [uri “/sqlurl/”] [unique_id “1598931324”] [ref “o15,8v9,86”]

    ModSecurity: Warning. detected SQLi using libinjection. [file “REQUEST-942-APPLICATION-ATTACK-SQLI.conf”] [line “45”] [id “942100”] [rev “”] [msg “SQL Injection Attack Detected via libinjection”] [data “Matched Data: Eok(E found within ARGS:json.sql: select * from (\x0d\x0aSELECT *\x0d\x0aFROM “db”.“tables”\x0d\x0aLIMIT 100\x0d\x0a)\x0d\x0a”] [severity “2”] [ver “OWASP_CRS/3.3.0”] [maturity “0”] [accuracy “0”] [hostname “xxx”] [uri “/sqlurl/”] [unique_id “1598931324”] [ref “v9,86”]

    ModSecurity: Access denied with code 403 (phase 2). Matched "Operator Ge' with parameter5’ against variable TX:ANOMALY_SCORE' (Value:10’ ) [file “REQUEST-949-BLOCKING-EVALUATION.conf”] [line “80”] [id “949110”] [rev “”] [msg “Inbound Anomaly Score Exceeded (Total Score: 10)”] [data “”] [severity “2”] [ver “OWASP_CRS/3.3.0”] [maturity “0”] [accuracy “0”] [tag “application-multi”] [tag “language-multi”] [tag “platform-multi”] [tag “attack-generic”] [hostname “xxx”] [uri “/sqlurl/”] [unique_id “1598931324”] [ref “”]

  4. 上面 的关键信息有怎么几个

    • ARGS:json.sql : 网页里有个json.sql的参数, 传递了一些数据, 正是这个参数触发了拦截规则

    • file : 具体的规则文件

    • id : 规则ID

    • uri : 访问的uri

确认问题

通过分析上面log, 我们可以发现一些重要信息: 这个页面操作总共触发了三个规则, ID分别是932115, 942110, 949110. 其中前两个是真正的规则触发, 这两个规则每个都会给这个访问加个分数, 到了第三条的时候就是检查部分, 发现总共超过了threshold后, modsecurity 就把访问给拦截了

解决问题

解决思路 相对比较简单, 就是针对信任的页面做个白名单, 上面的audit日志已经可以看出来uri是 /sqlurl/, 就可以针对这个uri进行操作
我的具体操作如下: 这里面涉及到了一些ModSecurity的变量和操作符的东西这里就不说了, 小伙伴们自行google吧

  1. 编辑规则文件

     vi REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf
    
  2. 加入一个排除规则

    SecRule REQUEST_URI "^\/sqlurl\/$" \
        "id:800001, \
        phase:2, \
        log, \
        ctl:ruleRemoveById=942100"
    

    这里做一些说明:

    • REQUEST_URI “^/sqlurl/$” 就是报错那个uri, 用正规表示
    • id:800001 是自己定义的
    • phase:2 指定是在phase 2生效, 也就是request body
    • log 指明针对这条规则记个log
    • ctl:ruleRemoveById=942100 这部分是重点, 就是要做的action, 这里是从后继的检查中去掉了942100这个规则, 即不进行942100的规则检查

    上面的规则涉及到了modsecurity的知识 还请小伙伴们自己google吧. 否则讲不完了

  3. 由于情况是这个页面触发了两个规则, 所以还要再加一条

    SecRule REQUEST_URI "^\/sqlurl\/$" \
        "id:800001, \
        phase:2, \
        log, \
        ctl:ruleRemoveById=932115"
    
  4. 上面的两步是分别加了两条, 如果觉得麻烦, 也可以写一条, ruleRemoveById部分可以这样写

    ctl:ruleRemoveById=932115-942100"
    

    这是直接跳过了一个范围, 写进来容易 , 但安全性上有损失, 所以我没有这样写

  5. 加完后直接保存, 再重启nginx. 再试了一下在页面上做同样的操作这回就不会报错了.

References

Reference Manual (v2.x)

https://www.nginx.com/blog/modsecurity-logging-and-debugging/

Adding Exceptions and Tuning CRS

 类似资料:

相关阅读

相关文章

相关问答