mirror of
https://github.com/alibaba/higress.git
synced 2026-03-19 17:57:31 +08:00
Go WAF Plugin (#400)
This commit is contained in:
3
plugins/wasm-go/extensions/waf/Dockerfile
Normal file
3
plugins/wasm-go/extensions/waf/Dockerfile
Normal file
@@ -0,0 +1,3 @@
|
||||
FROM scratch
|
||||
|
||||
COPY local/main.wasm /plugin.wasm
|
||||
52
plugins/wasm-go/extensions/waf/README.md
Normal file
52
plugins/wasm-go/extensions/waf/README.md
Normal file
@@ -0,0 +1,52 @@
|
||||
# 功能说明
|
||||
waf插件实现了基于ModSecurity的规则防护引擎,可以根据用户配置的规则屏蔽可疑请求,并支持OWASP CRS,为站点提供基础的防护功能。
|
||||
|
||||
# 配置字段
|
||||
| 名称 | 数据类型 | 填写要求 | 默认值 | 描述 |
|
||||
| -------- | -------- | -------- | -------- | -------- |
|
||||
| useCRS | bool | 选填 | false | 是否开启OWASP CRS,详情可参考[coreruleset](https://github.com/coreruleset/coreruleset/tree/v3.3.2) |
|
||||
| secRules | array of string | 选填 | - | 用户自定义的waf防护规则,语法规则可参考[ModSecurity中文手册](http://www.modsecurity.cn/chm/) |
|
||||
|
||||
# 配置示例
|
||||
```yaml
|
||||
useCRS: true
|
||||
secRules:
|
||||
- "SecDebugLogLevel 3"
|
||||
- "SecRuleEngine On"
|
||||
- "SecAction \"id:100,phase:1,pass\""
|
||||
- "SecRule REQUEST_URI \"@streq /admin\" \"id:101,phase:1,t:lowercase,deny\""
|
||||
- "SecRule REQUEST_BODY \"@rx maliciouspayload\" \"id:102,phase:2,t:lowercase,deny\""
|
||||
```
|
||||
|
||||
根据该配置,以下请求将被禁止访问:
|
||||
```bash
|
||||
curl http://example.com/admin
|
||||
curl http://example.com -d "maliciouspayload"
|
||||
```
|
||||
|
||||
# 对特定路由或域名开启
|
||||
```yaml
|
||||
useCRS: true
|
||||
secRules:
|
||||
- "SecDebugLogLevel 3"
|
||||
- "SecRuleEngine On"
|
||||
- "SecAction \"id:100,phase:1,pass\""
|
||||
- "SecRule REQUEST_URI \"@streq /admin\" \"id:101,phase:1,t:lowercase,deny\""
|
||||
- "SecRule REQUEST_BODY \"@rx maliciouspayload\" \"id:102,phase:2,t:lowercase,deny\""
|
||||
_rules_:
|
||||
- _match_route_:
|
||||
- "route-1"
|
||||
secRules:
|
||||
- "SecDebugLogLevel 3"
|
||||
- "SecRuleEngine On"
|
||||
- "SecAction \"id:102,phase:1,deny\""
|
||||
- _match_domain_:
|
||||
- "*.example.com"
|
||||
- test.com
|
||||
secRules:
|
||||
- "SecDebugLogLevel 3"
|
||||
- "SecRuleEngine On"
|
||||
- "SecAction \"id:102,phase:1,pass\""
|
||||
```
|
||||
|
||||
此例 `_match_route_` 中指定的 `route-1` 即在创建网关路由时填写的路由名称,当匹配到这两个路由时,将使用此段配置; 此例 `_match_domain_` 中指定的 `*.example.com` 和 `test.com` 用于匹配请求的域名,当发现域名匹配时,将使用此段配置; 配置的匹配生效顺序,将按照 `_rules_` 下规则的排列顺序,匹配第一个规则后生效对应配置,后续规则将被忽略。
|
||||
37
plugins/wasm-go/extensions/waf/go.mod
Normal file
37
plugins/wasm-go/extensions/waf/go.mod
Normal file
@@ -0,0 +1,37 @@
|
||||
module github.com/corazawaf/coraza-proxy-wasm
|
||||
|
||||
go 1.19
|
||||
|
||||
require (
|
||||
github.com/alibaba/higress/plugins/wasm-go v0.0.0-20230504075705-7e358eb1db7c
|
||||
github.com/corazawaf/coraza-wasilibs v0.0.0-20230408002644-e2e3af21f503
|
||||
github.com/corazawaf/coraza/v3 v3.0.0-rc.1.0.20230407165813-a18681b1ec28
|
||||
github.com/stretchr/testify v1.8.0
|
||||
github.com/tetratelabs/proxy-wasm-go-sdk v0.22.0
|
||||
github.com/tidwall/gjson v1.14.4
|
||||
github.com/wasilibs/nottinygc v0.2.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/corazawaf/libinjection-go v0.1.2 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/google/uuid v1.3.0 // indirect
|
||||
github.com/kr/pretty v0.1.0 // indirect
|
||||
github.com/magefile/mage v1.14.0 // indirect
|
||||
github.com/petar-dambovaliev/aho-corasick v0.0.0-20211021192214-5ab2d9280aa9 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/tetratelabs/wazero v1.0.1 // indirect
|
||||
github.com/tidwall/match v1.1.1 // indirect
|
||||
github.com/tidwall/pretty v1.2.1 // indirect
|
||||
github.com/wasilibs/go-aho-corasick v0.3.0 // indirect
|
||||
github.com/wasilibs/go-libinjection v0.2.1 // indirect
|
||||
github.com/wasilibs/go-re2 v1.0.0 // indirect
|
||||
golang.org/x/net v0.9.0 // indirect
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
rsc.io/binaryregexp v0.2.0 // indirect
|
||||
)
|
||||
|
||||
replace (
|
||||
github.com/alibaba/higress/plugins/wasm-go v0.0.0-20230504075705-7e358eb1db7c => github.com/rinfx/higress/plugins/wasm-go v0.0.0-20230508112120-f2d89b0606ee
|
||||
)
|
||||
65
plugins/wasm-go/extensions/waf/go.sum
Normal file
65
plugins/wasm-go/extensions/waf/go.sum
Normal file
@@ -0,0 +1,65 @@
|
||||
github.com/alibaba/higress/plugins/wasm-go v0.0.0-20230504075705-7e358eb1db7c h1:RKZJGYAkczZVqvJ/CuNJSY6YI5oyJjzm12MVzf3Z7/U=
|
||||
github.com/alibaba/higress/plugins/wasm-go v0.0.0-20230504075705-7e358eb1db7c/go.mod h1:AzSnkuon5c26nIePTiJQIAFsKdhkNdncLcTuahpGtQs=
|
||||
github.com/corazawaf/coraza-wasilibs v0.0.0-20230408002644-e2e3af21f503 h1:hGXspDwUBHQUne1NT2D6PmkR9wFCXsibjaJpz7xhf+g=
|
||||
github.com/corazawaf/coraza-wasilibs v0.0.0-20230408002644-e2e3af21f503/go.mod h1:bTc+NV7T2wQevFQHDDWhD/+IAA5bvKbbK4CxzfvJx/o=
|
||||
github.com/corazawaf/coraza/v3 v3.0.0-rc.1.0.20230407165813-a18681b1ec28 h1:Jrlvhe4YCR/PMCazDEBeun/XTYhlzczBN0WN4/ejORo=
|
||||
github.com/corazawaf/coraza/v3 v3.0.0-rc.1.0.20230407165813-a18681b1ec28/go.mod h1:TKREBLh55w3SiBbLsQpH9EFzjBAmEUH4KRaZ/kFYz20=
|
||||
github.com/corazawaf/libinjection-go v0.1.2 h1:oeiV9pc5rvJ+2oqOqXEAMJousPpGiup6f7Y3nZj5GoM=
|
||||
github.com/corazawaf/libinjection-go v0.1.2/go.mod h1:OP4TM7xdJ2skyXqNX1AN1wN5nNZEmJNuWbNPOItn7aw=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/foxcpp/go-mockdns v1.0.0 h1:7jBqxd3WDWwi/6WhDvacvH1XsN3rOLXyHM1uhvIx6FI=
|
||||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/magefile/mage v1.14.0 h1:6QDX3g6z1YvJ4olPhT1wksUcSa/V0a1B+pJb73fBjyo=
|
||||
github.com/magefile/mage v1.14.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A=
|
||||
github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA=
|
||||
github.com/petar-dambovaliev/aho-corasick v0.0.0-20211021192214-5ab2d9280aa9 h1:lL+y4Xv20pVlCGyLzNHRC0I0rIHhIL1lTvHizoS/dU8=
|
||||
github.com/petar-dambovaliev/aho-corasick v0.0.0-20211021192214-5ab2d9280aa9/go.mod h1:EHPiTAKtiFmrMldLUNswFwfZ2eJIYBHktdaUTZxYWRw=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/rinfx/higress/plugins/wasm-go v0.0.0-20230508112120-f2d89b0606ee h1:5qHbEcei04hDcUTzvoFNtYtZiewnTgVv6wR9co8Ih6c=
|
||||
github.com/rinfx/higress/plugins/wasm-go v0.0.0-20230508112120-f2d89b0606ee/go.mod h1:AzSnkuon5c26nIePTiJQIAFsKdhkNdncLcTuahpGtQs=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/tetratelabs/proxy-wasm-go-sdk v0.22.0 h1:kS7BvMKN+FiptV4pfwiNX8e3q14evxAWkhYbxt8EI1M=
|
||||
github.com/tetratelabs/proxy-wasm-go-sdk v0.22.0/go.mod h1:qkW5MBz2jch2u8bS59wws65WC+Gtx3x0aPUX5JL7CXI=
|
||||
github.com/tetratelabs/wazero v1.0.1 h1:xyWBoGyMjYekG3mEQ/W7xm9E05S89kJ/at696d/9yuc=
|
||||
github.com/tetratelabs/wazero v1.0.1/go.mod h1:wYx2gNRg8/WihJfSDxA1TIL8H+GkfLYm+bIfbblu9VQ=
|
||||
github.com/tidwall/gjson v1.14.4 h1:uo0p8EbA09J7RQaflQ1aBRffTR7xedD2bcIVSYxLnkM=
|
||||
github.com/tidwall/gjson v1.14.4/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
|
||||
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
||||
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
||||
github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4=
|
||||
github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
||||
github.com/wasilibs/go-aho-corasick v0.3.0 h1:ScfPQhAwop/ELIkwY0dfMTFb/bwOdYI/MB3mkX2WOZI=
|
||||
github.com/wasilibs/go-aho-corasick v0.3.0/go.mod h1:LKW6EW9NWuWYE8PII+sFpRbbY3UcrMUgfUTkGaoWyMY=
|
||||
github.com/wasilibs/go-libinjection v0.2.1 h1:1aSwyE4oNpPGpFw3i3hoM15sF3qn1s4P0jC2jgFM2Qk=
|
||||
github.com/wasilibs/go-libinjection v0.2.1/go.mod h1:ZUoVe+HLQYq+QPBNTSgg3fxGvZsvXiDbi0UomBlsGzo=
|
||||
github.com/wasilibs/go-re2 v1.0.0 h1:pvrqtMzZgTMHVPfXJrk4YZwiqIXOKdfo5aed6CzUAW4=
|
||||
github.com/wasilibs/go-re2 v1.0.0/go.mod h1:8g69JapfgjSCx49dKOQij1dqA3sOvoH5NteaUy1X0SA=
|
||||
github.com/wasilibs/nottinygc v0.2.0 h1:cXz2Ac9bVMLkpuOlUlPQMWowjw0K2cOErXZOFdAj7yE=
|
||||
github.com/wasilibs/nottinygc v0.2.0/go.mod h1:oDcIotskuYNMpqMF23l7Z8uzD4TC0WXHK8jetlB3HIo=
|
||||
golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8=
|
||||
golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM=
|
||||
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
|
||||
golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU=
|
||||
golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
rsc.io/binaryregexp v0.2.0 h1:HfqmD5MEmC0zvwBuF187nq9mdnXjXsSivRiXN7SmRkE=
|
||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||
14
plugins/wasm-go/extensions/waf/init_tinygo.go
Normal file
14
plugins/wasm-go/extensions/waf/init_tinygo.go
Normal file
@@ -0,0 +1,14 @@
|
||||
//go:build tinygo
|
||||
|
||||
package main
|
||||
|
||||
import _ "github.com/wasilibs/nottinygc"
|
||||
|
||||
// Compiled by nottinygc for delayed free but Envoy doesn't stub it yet,
|
||||
// luckily nottinygc doesn't actually call the function, so it's fine to
|
||||
// stub it out.
|
||||
|
||||
//export sched_yield
|
||||
func sched_yield() int32 {
|
||||
return 0
|
||||
}
|
||||
3
plugins/wasm-go/extensions/waf/local/Dockerfile
Normal file
3
plugins/wasm-go/extensions/waf/local/Dockerfile
Normal file
@@ -0,0 +1,3 @@
|
||||
FROM liuxr25/flask-helloworld:latest
|
||||
|
||||
COPY app.py /work/app.py
|
||||
14
plugins/wasm-go/extensions/waf/local/app.py
Normal file
14
plugins/wasm-go/extensions/waf/local/app.py
Normal file
@@ -0,0 +1,14 @@
|
||||
from flask import Flask, request
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
@app.route("/flask/test1", methods=["GET", "POST"])
|
||||
def test1():
|
||||
return "body normal", 200, [("test-header", "hahaha")]
|
||||
|
||||
@app.route("/flask/test2", methods=["GET", "POST"])
|
||||
def test2():
|
||||
return "body attack", 200, []
|
||||
|
||||
if __name__ == "__main__":
|
||||
app.run("0.0.0.0", 5000)
|
||||
96
plugins/wasm-go/extensions/waf/local/docker-compose.yaml
Normal file
96
plugins/wasm-go/extensions/waf/local/docker-compose.yaml
Normal file
@@ -0,0 +1,96 @@
|
||||
services:
|
||||
httpbin:
|
||||
image: kennethreitz/httpbin
|
||||
environment:
|
||||
- MAX_BODY_SIZE=15728640 # 15 MiB
|
||||
ports:
|
||||
- 8083:8080
|
||||
command:
|
||||
- "gunicorn"
|
||||
- "-b"
|
||||
- "0.0.0.0:8080"
|
||||
- "httpbin:app"
|
||||
- "-k"
|
||||
- "gevent"
|
||||
- --log-file
|
||||
- /home/envoy/logs/httpbin.log
|
||||
volumes:
|
||||
- logs:/home/envoy/logs:rw
|
||||
|
||||
flask:
|
||||
# image: liuxr25/flask-helloworld:latest
|
||||
build: .
|
||||
environment:
|
||||
- MAX_BODY_SIZE=15728640 # 15 MiB
|
||||
ports:
|
||||
- 8084:5000
|
||||
|
||||
chown:
|
||||
image: alpine:3.16
|
||||
command:
|
||||
- /bin/sh
|
||||
- -c
|
||||
- chown -R 101:101 /home/envoy/logs
|
||||
volumes:
|
||||
- logs:/home/envoy/logs:rw
|
||||
|
||||
envoy:
|
||||
depends_on:
|
||||
- chown
|
||||
- httpbin
|
||||
- flask
|
||||
image: higress-registry.cn-hangzhou.cr.aliyuncs.com/higress/envoy:1.20
|
||||
command:
|
||||
- -c
|
||||
- /conf/envoy-config.yaml
|
||||
- --log-level
|
||||
- info
|
||||
- --component-log-level
|
||||
- wasm:debug
|
||||
- --log-format [%Y-%m-%d %T.%f][%t][%l][%n] [%g:%#] %v
|
||||
- --log-path
|
||||
- /home/envoy/logs/envoy.log
|
||||
volumes:
|
||||
- .:/build
|
||||
- .:/conf
|
||||
- logs:/home/envoy/logs:rw
|
||||
ports:
|
||||
- 8080:8080
|
||||
- 8082:8082
|
||||
|
||||
# envoy-logs:
|
||||
# depends_on:
|
||||
# - envoy
|
||||
# - wasm-logs
|
||||
# image: debian:11-slim
|
||||
# entrypoint: bash
|
||||
# command:
|
||||
# - -c
|
||||
# - tail -c +0 -f /home/envoy/logs/envoy.log
|
||||
# volumes:
|
||||
# - logs:/home/envoy/logs:ro
|
||||
|
||||
wasm-logs:
|
||||
depends_on:
|
||||
- envoy
|
||||
image: debian:11-slim
|
||||
entrypoint: bash
|
||||
command:
|
||||
- -c
|
||||
- tail -c +0 -f /home/envoy/logs/envoy.log | grep --line-buffered "[critical][wasm]"
|
||||
volumes:
|
||||
- logs:/home/envoy/logs:ro
|
||||
|
||||
# debug-logs:
|
||||
# depends_on:
|
||||
# - envoy
|
||||
# image: debian:11-slim
|
||||
# entrypoint: bash
|
||||
# command:
|
||||
# - -c
|
||||
# - tail -c +0 -f /home/envoy/logs/envoy.log | grep --line-buffered "unreachable"
|
||||
# volumes:
|
||||
# - logs:/home/envoy/logs:ro
|
||||
|
||||
volumes:
|
||||
logs:
|
||||
143
plugins/wasm-go/extensions/waf/local/envoy-config.yaml
Normal file
143
plugins/wasm-go/extensions/waf/local/envoy-config.yaml
Normal file
@@ -0,0 +1,143 @@
|
||||
stats_config:
|
||||
stats_tags:
|
||||
# Envoy extracts the first matching group as a value.
|
||||
# See https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/metrics/v3/stats.proto#config-metrics-v3-statsconfig.
|
||||
- tag_name: phase
|
||||
regex: "(_phase=([a-z_]+))"
|
||||
- tag_name: rule_id
|
||||
regex: "(_ruleid=([0-9]+))"
|
||||
|
||||
static_resources:
|
||||
listeners:
|
||||
- address:
|
||||
socket_address:
|
||||
address: 0.0.0.0
|
||||
port_value: 8080
|
||||
filter_chains:
|
||||
- filters:
|
||||
- name: envoy.filters.network.http_connection_manager
|
||||
typed_config:
|
||||
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
|
||||
stat_prefix: ingress_http
|
||||
codec_type: auto
|
||||
route_config:
|
||||
virtual_hosts:
|
||||
- name: local_route
|
||||
domains:
|
||||
- "*"
|
||||
routes:
|
||||
- name: "route_1"
|
||||
match:
|
||||
path: "/headers"
|
||||
route:
|
||||
cluster: httpbin_server
|
||||
- name: "route_2"
|
||||
match:
|
||||
path: "/user-agent"
|
||||
route:
|
||||
cluster: httpbin_server
|
||||
- name: "route_flask"
|
||||
match:
|
||||
prefix: "/flask"
|
||||
route:
|
||||
cluster: flask_server
|
||||
- name: "route_httpbin"
|
||||
match:
|
||||
prefix: "/"
|
||||
route:
|
||||
cluster: httpbin_server
|
||||
# - name: "route_mock"
|
||||
# match:
|
||||
# prefix: "/"
|
||||
# direct_response:
|
||||
# status: 200
|
||||
# body:
|
||||
# inline_string: "mock response\n"
|
||||
http_filters:
|
||||
- name: envoy.filters.http.wasm
|
||||
typed_config:
|
||||
"@type": type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm
|
||||
config:
|
||||
name: "coraza-filter"
|
||||
root_id: ""
|
||||
configuration:
|
||||
"@type": "type.googleapis.com/google.protobuf.StringValue"
|
||||
value: |
|
||||
{
|
||||
"useCRS": true,
|
||||
"secRules": [
|
||||
"SecDebugLogLevel 3",
|
||||
"SecRuleEngine On",
|
||||
"SecRule REQUEST_URI \"@streq /admin\" \"id:101,phase:1,t:lowercase,deny\"",
|
||||
"SecRule REQUEST_BODY \"@rx maliciouspayload\" \"id:102,phase:2,t:lowercase,deny\"",
|
||||
"SecRule RESPONSE_HEADERS::status \"@rx 406\" \"id:103,phase:3,t:lowercase,deny\"",
|
||||
"SecRule RESPONSE_HEADERS:test-header \"@streq hahaha\" \"id:104,phase:3,t:lowercase,deny\"",
|
||||
"SecRule RESPONSE_BODY \"@rx attack\" \"id:105,phase:4,t:lowercase,deny\""
|
||||
],
|
||||
"_rules_": [
|
||||
{
|
||||
"_match_route_": [
|
||||
"route_1"
|
||||
],
|
||||
"secRules": [
|
||||
"SecDebugLogLevel 3",
|
||||
"SecRuleEngine On",
|
||||
"SecAction \"id:102,phase:1,deny\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"_match_route_": [
|
||||
"route_2"
|
||||
],
|
||||
"secRules": [
|
||||
"SecDebugLogLevel 3",
|
||||
"SecRuleEngine On",
|
||||
"SecAction \"id:102,phase:1,pass\""
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
vm_config:
|
||||
runtime: "envoy.wasm.runtime.v8"
|
||||
vm_id: "10086"
|
||||
code:
|
||||
local:
|
||||
filename: "build/main.wasm"
|
||||
- name: envoy.filters.http.router
|
||||
typed_config:
|
||||
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
|
||||
|
||||
clusters:
|
||||
- name: httpbin_server
|
||||
connect_timeout: 6000s
|
||||
type: STRICT_DNS
|
||||
lb_policy: ROUND_ROBIN
|
||||
load_assignment:
|
||||
cluster_name: httpbin_server
|
||||
endpoints:
|
||||
- lb_endpoints:
|
||||
- endpoint:
|
||||
address:
|
||||
socket_address:
|
||||
address: httpbin
|
||||
port_value: 8080
|
||||
- name: flask_server
|
||||
connect_timeout: 6000s
|
||||
type: STRICT_DNS
|
||||
lb_policy: ROUND_ROBIN
|
||||
load_assignment:
|
||||
cluster_name: flask_server
|
||||
endpoints:
|
||||
- lb_endpoints:
|
||||
- endpoint:
|
||||
address:
|
||||
socket_address:
|
||||
address: flask
|
||||
port_value: 5000
|
||||
|
||||
admin:
|
||||
access_log_path: "/dev/null"
|
||||
address:
|
||||
socket_address:
|
||||
address: 0.0.0.0
|
||||
port_value: 8082
|
||||
16
plugins/wasm-go/extensions/waf/mage.go
Normal file
16
plugins/wasm-go/extensions/waf/mage.go
Normal file
@@ -0,0 +1,16 @@
|
||||
//go:build ignore
|
||||
// +build ignore
|
||||
|
||||
// Entrypoint to mage for running without needing to install the command.
|
||||
// https://magefile.org/zeroinstall/
|
||||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/magefile/mage/mage"
|
||||
)
|
||||
|
||||
func main() {
|
||||
os.Exit(mage.Main())
|
||||
}
|
||||
16
plugins/wasm-go/extensions/waf/magefiles/go.mod
Normal file
16
plugins/wasm-go/extensions/waf/magefiles/go.mod
Normal file
@@ -0,0 +1,16 @@
|
||||
module github.com/corazawaf/coraza-proxy-wasm/magefiles
|
||||
|
||||
go 1.19
|
||||
|
||||
require (
|
||||
fortio.org/fortio v1.38.4
|
||||
github.com/magefile/mage v1.14.0
|
||||
github.com/tetratelabs/wabin v0.0.0-20220927005300-3b0fbf39a46a
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/google/uuid v1.3.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20221111204811-129d8d6c17ab // indirect
|
||||
golang.org/x/net v0.2.0 // indirect
|
||||
golang.org/x/text v0.4.0 // indirect
|
||||
)
|
||||
21
plugins/wasm-go/extensions/waf/magefiles/go.sum
Normal file
21
plugins/wasm-go/extensions/waf/magefiles/go.sum
Normal file
@@ -0,0 +1,21 @@
|
||||
fortio.org/assert v1.1.2 h1:t6WGDqPD5VFrUvx30U0+3mgXXcoPonrdKqt0vfJHn8E=
|
||||
fortio.org/fortio v1.38.4 h1:HkVsu9E4emMU+i2D2HjPll1Dbu5IqCRTeKeoiYWxFWA=
|
||||
fortio.org/fortio v1.38.4/go.mod h1:xZTReCI6wlPJQN+JssVO6jsqXJV2vC32dcZJrUaqmcU=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
|
||||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/magefile/mage v1.14.0 h1:6QDX3g6z1YvJ4olPhT1wksUcSa/V0a1B+pJb73fBjyo=
|
||||
github.com/magefile/mage v1.14.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
|
||||
github.com/tetratelabs/wabin v0.0.0-20220927005300-3b0fbf39a46a h1:P0R3+CTAT7daT8ig5gh9GEd/eDQ5md1xl4pkYMcwOqg=
|
||||
github.com/tetratelabs/wabin v0.0.0-20220927005300-3b0fbf39a46a/go.mod h1:m9ymHTgNSEjuxvw8E7WWe4Pl4hZQHXONY8wE6dMLaRk=
|
||||
golang.org/x/exp v0.0.0-20221111204811-129d8d6c17ab h1:1S7USr8/C0Sgk4egxq4zZ07zYt2Xh1IiFp8hUMXH/us=
|
||||
golang.org/x/exp v0.0.0-20221111204811-129d8d6c17ab/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
|
||||
golang.org/x/net v0.2.0 h1:sZfSu1wtKLGlWI4ZZayP0ck9Y73K1ynO6gqzTdBVdPU=
|
||||
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
|
||||
golang.org/x/sys v0.2.0 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A=
|
||||
golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg=
|
||||
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
81
plugins/wasm-go/extensions/waf/magefiles/loadtest.go
Normal file
81
plugins/wasm-go/extensions/waf/magefiles/loadtest.go
Normal file
@@ -0,0 +1,81 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"fortio.org/fortio/fhttp"
|
||||
"fortio.org/fortio/fnet"
|
||||
"fortio.org/fortio/periodic"
|
||||
"github.com/magefile/mage/sh"
|
||||
)
|
||||
|
||||
// LoadTest runs load tests against the ftw deployment.
|
||||
func LoadTest() error {
|
||||
for _, threads := range []int{1, 2, 4} {
|
||||
for _, payloadSize := range []int{0, 100, 1000, 10000} {
|
||||
for _, conf := range []string{"envoy-config.yaml", "envoy-config-nowasm.yaml"} {
|
||||
if err := doLoadTest(conf, payloadSize, threads); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func doLoadTest(conf string, payloadSize int, threads int) error {
|
||||
if err := sh.RunV("docker-compose", "--file", "ftw/docker-compose.yml", "build", "--pull"); err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
_ = sh.RunV("docker-compose", "--file", "ftw/docker-compose.yml", "kill")
|
||||
_ = sh.RunV("docker-compose", "--file", "ftw/docker-compose.yml", "down", "-v")
|
||||
}()
|
||||
if err := sh.RunWithV(map[string]string{"ENVOY_CONFIG": fmt.Sprintf("/conf/%s", conf)}, "docker-compose",
|
||||
"--file", "ftw/docker-compose.yml", "run", "--service-ports", "--rm", "-d", "envoy"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Wait for Envoy to start.
|
||||
for i := 0; i < 1000; i++ {
|
||||
if resp, err := http.Get("http://localhost:8080/anything"); err != nil {
|
||||
continue
|
||||
} else {
|
||||
if resp.Body != nil {
|
||||
resp.Body.Close()
|
||||
}
|
||||
if resp.StatusCode == http.StatusOK {
|
||||
break
|
||||
}
|
||||
}
|
||||
time.Sleep(50 * time.Millisecond)
|
||||
}
|
||||
|
||||
opts := &fhttp.HTTPRunnerOptions{
|
||||
RunnerOptions: periodic.RunnerOptions{
|
||||
QPS: 100,
|
||||
NumThreads: threads,
|
||||
Duration: 10 * time.Second,
|
||||
},
|
||||
HTTPOptions: fhttp.HTTPOptions{
|
||||
URL: "http://localhost:8080/anything",
|
||||
Payload: fnet.GenerateRandomPayload(payloadSize),
|
||||
},
|
||||
}
|
||||
|
||||
fmt.Printf("Running load test with config=%s, payloadSize=%d, threads=%d\n", conf, payloadSize, threads)
|
||||
res, err := fhttp.RunHTTPTest(opts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rr := res.Result()
|
||||
fmt.Printf("All done %d calls (plus %d warmup) %.3f ms avg, %.1f qps\n",
|
||||
rr.DurationHistogram.Count,
|
||||
0,
|
||||
1000.*rr.DurationHistogram.Avg,
|
||||
rr.ActualQPS)
|
||||
|
||||
return nil
|
||||
}
|
||||
271
plugins/wasm-go/extensions/waf/magefiles/magefile.go
Normal file
271
plugins/wasm-go/extensions/waf/magefiles/magefile.go
Normal file
@@ -0,0 +1,271 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/magefile/mage/mg"
|
||||
"github.com/magefile/mage/sh"
|
||||
"github.com/tetratelabs/wabin/binary"
|
||||
"github.com/tetratelabs/wabin/wasm"
|
||||
)
|
||||
|
||||
var minGoVersion = "1.19"
|
||||
var tinygoMinorVersion = "0.27"
|
||||
var addLicenseVersion = "04bfe4ee9ca5764577b029acc6a1957fd1997153" // https://github.com/google/addlicense
|
||||
var golangCILintVer = "v1.48.0" // https://github.com/golangci/golangci-lint/releases
|
||||
var gosImportsVer = "v0.3.1" // https://github.com/rinchsan/gosimports/releases/tag/v0.3.1
|
||||
|
||||
var errCommitFormatting = errors.New("files not formatted, please commit formatting changes")
|
||||
var errNoGitDir = errors.New("no .git directory found")
|
||||
|
||||
func init() {
|
||||
for _, check := range []func() error{
|
||||
checkTinygoVersion,
|
||||
checkGoVersion,
|
||||
} {
|
||||
if err := check(); err != nil {
|
||||
fmt.Printf("Error: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// checkGoVersion checks the minimum version of Go is supported.
|
||||
func checkGoVersion() error {
|
||||
v, err := sh.Output("go", "version")
|
||||
if err != nil {
|
||||
return fmt.Errorf("unexpected go error: %v", err)
|
||||
}
|
||||
|
||||
// Version can/cannot include patch version e.g.
|
||||
// - go version go1.19 darwin/arm64
|
||||
// - go version go1.19.2 darwin/amd64
|
||||
versionRegex := regexp.MustCompile("go([0-9]+).([0-9]+).?([0-9]+)?")
|
||||
compare := versionRegex.FindStringSubmatch(v)
|
||||
if len(compare) != 4 {
|
||||
return fmt.Errorf("unexpected go semver: %q", v)
|
||||
}
|
||||
compare = compare[1:]
|
||||
if compare[2] == "" {
|
||||
compare[2] = "0"
|
||||
}
|
||||
|
||||
base := strings.SplitN(minGoVersion, ".", 3)
|
||||
if len(base) == 2 {
|
||||
base = append(base, "0")
|
||||
}
|
||||
for i := 0; i < 3; i++ {
|
||||
baseN, _ := strconv.Atoi(base[i])
|
||||
compareN, _ := strconv.Atoi(compare[i])
|
||||
if baseN > compareN {
|
||||
return fmt.Errorf("unexpected go version, minimum want %q, have %q", minGoVersion, strings.Join(compare, "."))
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// checkTinygoVersion checks that exactly the right tinygo version is supported because
|
||||
// tinygo isn't stable yet.
|
||||
func checkTinygoVersion() error {
|
||||
v, err := sh.Output("tinygo", "version")
|
||||
if err != nil {
|
||||
return fmt.Errorf("unexpected tinygo error: %v", err)
|
||||
}
|
||||
|
||||
// Assume a dev build is valid.
|
||||
if strings.Contains(v, "-dev") {
|
||||
return nil
|
||||
}
|
||||
|
||||
if !strings.HasPrefix(v, fmt.Sprintf("tinygo version %s", tinygoMinorVersion)) {
|
||||
return fmt.Errorf("unexpected tinygo version, wanted %s", tinygoMinorVersion)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Format formats code in this repository.
|
||||
func Format() error {
|
||||
if err := sh.RunV("go", "mod", "tidy"); err != nil {
|
||||
return err
|
||||
}
|
||||
// addlicense strangely logs skipped files to stderr despite not being erroneous, so use the long sh.Exec form to
|
||||
// discard stderr too.
|
||||
if _, err := sh.Exec(map[string]string{}, io.Discard, io.Discard, "go", "run", fmt.Sprintf("github.com/google/addlicense@%s", addLicenseVersion),
|
||||
"-c", "The OWASP Coraza contributors",
|
||||
"-s=only",
|
||||
"-y=",
|
||||
"-ignore", "**/*.yml",
|
||||
"-ignore", "**/*.yaml",
|
||||
"-ignore", "examples/**", "."); err != nil {
|
||||
return err
|
||||
}
|
||||
return sh.RunV("go", "run", fmt.Sprintf("github.com/rinchsan/gosimports/cmd/gosimports@%s", gosImportsVer),
|
||||
"-w",
|
||||
"-local",
|
||||
"github.com/corazawaf/coraza-proxy-wasm",
|
||||
".")
|
||||
}
|
||||
|
||||
// Lint verifies code quality.
|
||||
func Lint() error {
|
||||
if err := sh.RunV("go", "run", fmt.Sprintf("github.com/golangci/golangci-lint/cmd/golangci-lint@%s", golangCILintVer), "run"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
mg.SerialDeps(Format)
|
||||
|
||||
if sh.Run("git", "diff", "--exit-code") != nil {
|
||||
return errCommitFormatting
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Test runs all unit tests.
|
||||
func Test() error {
|
||||
return sh.RunV("go", "test", "./...")
|
||||
}
|
||||
|
||||
// Coverage runs tests with coverage and race detector enabled.
|
||||
func Coverage() error {
|
||||
if err := os.MkdirAll("build", 0755); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := sh.RunV("go", "test", "-race", "-coverprofile=build/coverage.txt", "-covermode=atomic", "-coverpkg=./...", "./..."); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return sh.RunV("go", "tool", "cover", "-html=build/coverage.txt", "-o", "build/coverage.html")
|
||||
}
|
||||
|
||||
// Doc runs godoc, access at http://localhost:6060
|
||||
func Doc() error {
|
||||
return sh.RunV("go", "run", "golang.org/x/tools/cmd/godoc@latest", "-http=:6060")
|
||||
}
|
||||
|
||||
// Check runs lint and tests.
|
||||
func Check() {
|
||||
mg.SerialDeps(Lint, Test)
|
||||
}
|
||||
|
||||
// Build builds the Coraza wasm plugin.
|
||||
func Build() error {
|
||||
if err := os.MkdirAll("local", 0755); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
buildTags := []string{"custommalloc", "no_fs_access"}
|
||||
if os.Getenv("TIMING") == "true" {
|
||||
buildTags = append(buildTags, "timing", "proxywasm_timing")
|
||||
}
|
||||
if os.Getenv("MEMSTATS") == "true" {
|
||||
buildTags = append(buildTags, "memstats")
|
||||
}
|
||||
|
||||
buildTagArg := fmt.Sprintf("-tags='%s'", strings.Join(buildTags, " "))
|
||||
|
||||
// ~100MB initial heap
|
||||
initialPages := 2100
|
||||
if ipEnv := os.Getenv("INITIAL_PAGES"); ipEnv != "" {
|
||||
if ip, err := strconv.Atoi(ipEnv); err != nil {
|
||||
return err
|
||||
} else {
|
||||
initialPages = ip
|
||||
}
|
||||
}
|
||||
|
||||
if err := sh.RunV("tinygo", "build", "-gc=custom", "-opt=2", "-o", filepath.Join("local", "mainraw.wasm"), "-scheduler=none", "-target=wasi", buildTagArg); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := patchWasm(filepath.Join("local", "mainraw.wasm"), filepath.Join("local", "main.wasm"), initialPages); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := sh.RunV("rm", filepath.Join("local", "mainraw.wasm")); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// E2e runs e2e tests with a built plugin against the example deployment. Requires docker-compose.
|
||||
func E2e() error {
|
||||
if err := sh.RunV("docker-compose", "--file", "e2e/docker-compose.yml", "build", "--pull"); err != nil {
|
||||
return err
|
||||
}
|
||||
return sh.RunV("docker-compose", "-f", "e2e/docker-compose.yml", "up", "--abort-on-container-exit", "tests")
|
||||
}
|
||||
|
||||
// Ftw runs ftw tests with a built plugin and Envoy. Requires docker-compose.
|
||||
func Ftw() error {
|
||||
if err := sh.RunV("docker-compose", "--file", "ftw/docker-compose.yml", "build", "--pull"); err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
_ = sh.RunV("docker-compose", "--file", "ftw/docker-compose.yml", "down", "-v")
|
||||
}()
|
||||
env := map[string]string{
|
||||
"FTW_CLOUDMODE": os.Getenv("FTW_CLOUDMODE"),
|
||||
"FTW_INCLUDE": os.Getenv("FTW_INCLUDE"),
|
||||
"ENVOY_IMAGE": os.Getenv("ENVOY_IMAGE"),
|
||||
}
|
||||
if os.Getenv("ENVOY_NOWASM") == "true" {
|
||||
env["ENVOY_CONFIG"] = "/conf/envoy-config-nowasm.yaml"
|
||||
}
|
||||
task := "ftw"
|
||||
if os.Getenv("MEMSTATS") == "true" {
|
||||
task = "ftw-memstats"
|
||||
}
|
||||
return sh.RunWithV(env, "docker-compose", "--file", "ftw/docker-compose.yml", "run", "--rm", task)
|
||||
}
|
||||
|
||||
// RunExample spins up the test environment, access at http://localhost:8080. Requires docker-compose.
|
||||
func RunExample() error {
|
||||
return sh.RunWithV(map[string]string{"ENVOY_IMAGE": os.Getenv("ENVOY_IMAGE")}, "docker-compose", "--file", "example/docker-compose.yml", "up", "-d", "envoy-logs")
|
||||
}
|
||||
|
||||
// TeardownExample tears down the test environment. Requires docker-compose.
|
||||
func TeardownExample() error {
|
||||
return sh.RunV("docker-compose", "--file", "example/docker-compose.yml", "down")
|
||||
}
|
||||
|
||||
var Default = Build
|
||||
|
||||
func patchWasm(inPath, outPath string, initialPages int) error {
|
||||
raw, err := os.ReadFile(inPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
mod, err := binary.DecodeModule(raw, wasm.CoreFeaturesV2)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
mod.MemorySection.Min = uint32(initialPages)
|
||||
|
||||
for _, imp := range mod.ImportSection {
|
||||
switch {
|
||||
case imp.Name == "fd_filestat_get":
|
||||
imp.Name = "fd_fdstat_get"
|
||||
case imp.Name == "path_filestat_get":
|
||||
imp.Module = "env"
|
||||
imp.Name = "proxy_get_header_map_value"
|
||||
}
|
||||
}
|
||||
|
||||
out := binary.EncodeModule(mod)
|
||||
if err = os.WriteFile(outPath, out, 0644); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
14
plugins/wasm-go/extensions/waf/main.go
Normal file
14
plugins/wasm-go/extensions/waf/main.go
Normal file
@@ -0,0 +1,14 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/corazawaf/coraza-proxy-wasm/wasmplugin"
|
||||
wasilibs "github.com/corazawaf/coraza-wasilibs"
|
||||
)
|
||||
|
||||
func main() {
|
||||
wasilibs.RegisterRX()
|
||||
wasilibs.RegisterPM()
|
||||
wasilibs.RegisterSQLi()
|
||||
wasilibs.RegisterXSS()
|
||||
wasmplugin.PluginStart()
|
||||
}
|
||||
79
plugins/wasm-go/extensions/waf/wasmplugin/fs.go
Normal file
79
plugins/wasm-go/extensions/waf/wasmplugin/fs.go
Normal file
@@ -0,0 +1,79 @@
|
||||
package wasmplugin
|
||||
|
||||
import (
|
||||
"embed"
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
//go:embed rules
|
||||
crs embed.FS
|
||||
root fs.FS
|
||||
)
|
||||
|
||||
func init() {
|
||||
rules, _ := fs.Sub(crs, "rules")
|
||||
root = &rulesFS{
|
||||
rules,
|
||||
map[string]string{
|
||||
"@recommended-conf": "coraza.conf-recommended.conf",
|
||||
"@demo-conf": "coraza-demo.conf",
|
||||
"@crs-setup-demo-conf": "crs-setup-demo.conf",
|
||||
"@ftw-conf": "ftw-config.conf",
|
||||
"@crs-setup-conf": "crs-setup.conf.example",
|
||||
},
|
||||
map[string]string{
|
||||
"@owasp_crs": "crs",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
type rulesFS struct {
|
||||
fs fs.FS
|
||||
filesMapping map[string]string
|
||||
dirsMapping map[string]string
|
||||
}
|
||||
|
||||
func (r rulesFS) Open(name string) (fs.File, error) {
|
||||
return r.fs.Open(r.mapPath(name))
|
||||
}
|
||||
|
||||
func (r rulesFS) ReadDir(name string) ([]fs.DirEntry, error) {
|
||||
for a, dst := range r.dirsMapping {
|
||||
if a == name {
|
||||
return fs.ReadDir(r.fs, dst)
|
||||
}
|
||||
|
||||
prefix := a + "/"
|
||||
if strings.HasPrefix(name, prefix) {
|
||||
return fs.ReadDir(r.fs, fmt.Sprintf("%s/%s", dst, name[len(prefix):]))
|
||||
}
|
||||
}
|
||||
return fs.ReadDir(r.fs, name)
|
||||
}
|
||||
|
||||
func (r rulesFS) ReadFile(name string) ([]byte, error) {
|
||||
return fs.ReadFile(r.fs, r.mapPath(name))
|
||||
}
|
||||
|
||||
func (r rulesFS) mapPath(p string) string {
|
||||
if strings.IndexByte(p, '/') != -1 {
|
||||
// is not in root, hence we can do dir mapping
|
||||
for a, dst := range r.dirsMapping {
|
||||
prefix := a + "/"
|
||||
if strings.HasPrefix(p, prefix) {
|
||||
return fmt.Sprintf("%s/%s", dst, p[len(prefix):])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for a, dst := range r.filesMapping {
|
||||
if a == p {
|
||||
return dst
|
||||
}
|
||||
}
|
||||
|
||||
return p
|
||||
}
|
||||
339
plugins/wasm-go/extensions/waf/wasmplugin/plugin.go
Normal file
339
plugins/wasm-go/extensions/waf/wasmplugin/plugin.go
Normal file
@@ -0,0 +1,339 @@
|
||||
package wasmplugin
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/alibaba/higress/plugins/wasm-go/pkg/wrapper"
|
||||
"github.com/corazawaf/coraza/v3"
|
||||
ctypes "github.com/corazawaf/coraza/v3/types"
|
||||
"github.com/tetratelabs/proxy-wasm-go-sdk/proxywasm"
|
||||
"github.com/tetratelabs/proxy-wasm-go-sdk/proxywasm/types"
|
||||
"github.com/tidwall/gjson"
|
||||
)
|
||||
|
||||
func PluginStart() {
|
||||
wrapper.SetCtx(
|
||||
"waf-plugin-go",
|
||||
wrapper.ParseConfigBy(parseConfig),
|
||||
wrapper.ProcessRequestHeadersBy(onHttpRequestHeaders),
|
||||
wrapper.ProcessRequestBodyBy(onHttpRequestBody),
|
||||
wrapper.ProcessResponseBodyBy(onHttpResponseBody),
|
||||
wrapper.ProcessResponseHeadersBy(onHttpResponseHeaders),
|
||||
wrapper.ProcessStreamDoneBy(onHttpStreamDone),
|
||||
)
|
||||
}
|
||||
|
||||
type WafConfig struct {
|
||||
waf coraza.WAF
|
||||
//tx ctypes.Transaction
|
||||
}
|
||||
|
||||
func parseConfig(json gjson.Result, config *WafConfig, log wrapper.Log) error {
|
||||
var secRules []string
|
||||
var value gjson.Result
|
||||
value = json.Get("useCRS")
|
||||
if value.Exists() {
|
||||
if value.Bool() {
|
||||
secRules = append(secRules, "Include @demo-conf")
|
||||
secRules = append(secRules, "Include @crs-setup-demo-conf")
|
||||
secRules = append(secRules, "Include @owasp_crs/*.conf")
|
||||
secRules = append(secRules, "SecRuleEngine On")
|
||||
}
|
||||
}
|
||||
value = json.Get("secRules")
|
||||
if value.Exists() {
|
||||
for _, item := range json.Get("secRules").Array() {
|
||||
rule := item.String()
|
||||
secRules = append(secRules, rule)
|
||||
}
|
||||
}
|
||||
|
||||
// log.Debugf("[rinfx log] %s", strings.Join(secRules, "\n"))
|
||||
conf := coraza.NewWAFConfig().WithRootFS(root)
|
||||
// error: Failed to load Wasm module due to a missing import: wasi_snapshot_preview1.fd_filestat_get
|
||||
// because without fs.go
|
||||
waf, err := coraza.NewWAF(conf.WithDirectives(strings.Join(secRules, "\n")))
|
||||
|
||||
config.waf = waf
|
||||
if err != nil {
|
||||
log.Errorf("Failed to create waf conf: %v", err)
|
||||
return errors.New("failed to create waf conf")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func onHttpRequestHeaders(ctx wrapper.HttpContext, config WafConfig, log wrapper.Log) types.Action {
|
||||
ctx.SetContext("interruptionHandled", false)
|
||||
ctx.SetContext("processedRequestBody", false)
|
||||
ctx.SetContext("processedResponseBody", false)
|
||||
ctx.SetContext("tx", config.waf.NewTransaction())
|
||||
|
||||
tx := ctx.GetContext("tx").(ctypes.Transaction)
|
||||
|
||||
// Note the pseudo-header :path includes the query.
|
||||
// See https://httpwg.org/specs/rfc9113.html#rfc.section.8.3.1
|
||||
uri, err := proxywasm.GetHttpRequestHeader(":path")
|
||||
if err != nil {
|
||||
log.Error("Failed to get :path")
|
||||
return types.ActionContinue
|
||||
}
|
||||
|
||||
// This currently relies on Envoy's behavior of mapping all requests to HTTP/2 semantics
|
||||
// and its request properties, but they may not be true of other proxies implementing
|
||||
// proxy-wasm.
|
||||
|
||||
if tx.IsRuleEngineOff() {
|
||||
// log.Infof("[rinfx log] OnHttpRequestHeaders, RuleEngine Off, url = %s", uri)
|
||||
return types.ActionContinue
|
||||
}
|
||||
// OnHttpRequestHeaders does not terminate if IP/Port retrieve goes wrong
|
||||
srcIP, srcPort := retrieveAddressInfo(log, "source")
|
||||
dstIP, dstPort := retrieveAddressInfo(log, "destination")
|
||||
|
||||
tx.ProcessConnection(srcIP, srcPort, dstIP, dstPort)
|
||||
|
||||
// proxywasm.LogInfof("[rinfx log] OnHttpRequestHeaders, RuleEngine On, url = %s", uri)
|
||||
|
||||
method, err := proxywasm.GetHttpRequestHeader(":method")
|
||||
if err != nil {
|
||||
log.Error("Failed to get :method")
|
||||
return types.ActionContinue
|
||||
}
|
||||
|
||||
protocol, err := proxywasm.GetProperty([]string{"request", "protocol"})
|
||||
if err != nil {
|
||||
// TODO(anuraaga): HTTP protocol is commonly required in WAF rules, we should probably
|
||||
// fail fast here, but proxytest does not support properties yet.
|
||||
protocol = []byte("HTTP/2.0")
|
||||
}
|
||||
|
||||
ctx.SetContext("httpProtocol", string(protocol))
|
||||
|
||||
tx.ProcessURI(uri, method, string(protocol))
|
||||
|
||||
hs, err := proxywasm.GetHttpRequestHeaders()
|
||||
if err != nil {
|
||||
log.Error("Failed to get request headers")
|
||||
return types.ActionContinue
|
||||
}
|
||||
|
||||
for _, h := range hs {
|
||||
tx.AddRequestHeader(h[0], h[1])
|
||||
}
|
||||
|
||||
// CRS rules tend to expect Host even with HTTP/2
|
||||
authority, err := proxywasm.GetHttpRequestHeader(":authority")
|
||||
if err == nil {
|
||||
tx.AddRequestHeader("Host", authority)
|
||||
tx.SetServerName(parseServerName(log, authority))
|
||||
}
|
||||
|
||||
interruption := tx.ProcessRequestHeaders()
|
||||
if interruption != nil {
|
||||
return handleInterruption(ctx, "http_request_headers", interruption, log)
|
||||
}
|
||||
|
||||
return types.ActionContinue
|
||||
}
|
||||
|
||||
func onHttpRequestBody(ctx wrapper.HttpContext, config WafConfig, body []byte, log wrapper.Log) types.Action {
|
||||
// log.Info("[rinfx log] OnHttpRequestBody")
|
||||
|
||||
if ctx.GetContext("interruptionHandled").(bool) {
|
||||
log.Error("OnHttpRequestBody, interruption already handled")
|
||||
return types.ActionContinue
|
||||
}
|
||||
|
||||
tx := ctx.GetContext("tx").(ctypes.Transaction)
|
||||
|
||||
if tx.IsRuleEngineOff() {
|
||||
return types.ActionContinue
|
||||
}
|
||||
|
||||
// Do not perform any action related to request body data if SecRequestBodyAccess is set to false
|
||||
if !tx.IsRequestBodyAccessible() {
|
||||
log.Info("Skipping request body inspection, SecRequestBodyAccess is off.")
|
||||
// ProcessRequestBody is still performed for phase 2 rules, checking already populated variables
|
||||
ctx.SetContext("processedRequestBody", true)
|
||||
interruption, err := tx.ProcessRequestBody()
|
||||
if err != nil {
|
||||
log.Error("Failed to process request body")
|
||||
return types.ActionContinue
|
||||
}
|
||||
|
||||
if interruption != nil {
|
||||
return handleInterruption(ctx, "http_request_body", interruption, log)
|
||||
}
|
||||
|
||||
return types.ActionContinue
|
||||
}
|
||||
|
||||
interruption, _, err := tx.WriteRequestBody(body)
|
||||
if err != nil {
|
||||
log.Error("Failed to write request body")
|
||||
return types.ActionContinue
|
||||
}
|
||||
|
||||
if interruption != nil {
|
||||
return handleInterruption(ctx, "http_request_body", interruption, log)
|
||||
}
|
||||
|
||||
ctx.SetContext("processedRequestBody", true)
|
||||
interruption, err = tx.ProcessRequestBody()
|
||||
if err != nil {
|
||||
log.Error("Failed to process request body")
|
||||
return types.ActionContinue
|
||||
}
|
||||
if interruption != nil {
|
||||
return handleInterruption(ctx, "http_request_body", interruption, log)
|
||||
}
|
||||
|
||||
return types.ActionContinue
|
||||
}
|
||||
|
||||
func onHttpResponseHeaders(ctx wrapper.HttpContext, config WafConfig, log wrapper.Log) types.Action {
|
||||
// log.Info("[rinfx log] OnHttpResponseHeaders")
|
||||
|
||||
if ctx.GetContext("interruptionHandled").(bool) {
|
||||
log.Error("OnHttpResponseHeaders, interruption already handled")
|
||||
return types.ActionContinue
|
||||
}
|
||||
|
||||
tx := ctx.GetContext("tx").(ctypes.Transaction)
|
||||
|
||||
if tx.IsRuleEngineOff() {
|
||||
return types.ActionContinue
|
||||
}
|
||||
|
||||
// Requests without body won't call OnHttpRequestBody, but there are rules in the request body
|
||||
// phase that still need to be executed. If they haven't been executed yet, now is the time.
|
||||
if !ctx.GetContext("processedRequestBody").(bool) {
|
||||
ctx.SetContext("processedRequestBody", true)
|
||||
interruption, err := tx.ProcessRequestBody()
|
||||
if err != nil {
|
||||
log.Error("Failed to process request body")
|
||||
return types.ActionContinue
|
||||
}
|
||||
if interruption != nil {
|
||||
return handleInterruption(ctx, "http_response_headers", interruption, log)
|
||||
}
|
||||
}
|
||||
|
||||
status, err := proxywasm.GetHttpResponseHeader(":status")
|
||||
if err != nil {
|
||||
log.Error("Failed to get :status")
|
||||
return types.ActionContinue
|
||||
}
|
||||
code, err := strconv.Atoi(status)
|
||||
if err != nil {
|
||||
code = 0
|
||||
}
|
||||
|
||||
hs, err := proxywasm.GetHttpResponseHeaders()
|
||||
if err != nil {
|
||||
log.Error("Failed to get response headers")
|
||||
return types.ActionContinue
|
||||
}
|
||||
|
||||
for _, h := range hs {
|
||||
tx.AddResponseHeader(h[0], h[1])
|
||||
// log.Infof("[rinfx debug] ResponseHeaders %s: %s", h[0], h[1])
|
||||
}
|
||||
|
||||
interruption := tx.ProcessResponseHeaders(code, ctx.GetContext("httpProtocol").(string))
|
||||
if interruption != nil {
|
||||
return handleInterruption(ctx, "http_response_headers", interruption, log)
|
||||
}
|
||||
|
||||
return types.ActionContinue
|
||||
}
|
||||
|
||||
func onHttpResponseBody(ctx wrapper.HttpContext, config WafConfig, body []byte, log wrapper.Log) types.Action {
|
||||
// log.Info("[rinfx log] OnHttpResponseBody")
|
||||
|
||||
if ctx.GetContext("interruptionHandled").(bool) {
|
||||
// At response body phase, proxy-wasm currently relies on emptying the response body as a way of
|
||||
// interruption the response. See https://github.com/corazawaf/coraza-proxy-wasm/issues/26.
|
||||
// If OnHttpResponseBody is called again and an interruption has already been raised, it means that
|
||||
// we have to keep going with the sanitization of the response, emptying it.
|
||||
// Sending the crafted HttpResponse with empty body, we don't expect to trigger OnHttpResponseBody
|
||||
log.Warn("Response body interruption already handled, keeping replacing the body")
|
||||
// Interruption happened, we don't want to send response body data
|
||||
return replaceResponseBodyWhenInterrupted(log, replaceResponseBody)
|
||||
}
|
||||
|
||||
tx := ctx.GetContext("tx").(ctypes.Transaction)
|
||||
|
||||
if tx.IsRuleEngineOff() {
|
||||
return types.ActionContinue
|
||||
}
|
||||
|
||||
// Do not perform any action related to response body data if SecResponseBodyAccess is set to false
|
||||
if !tx.IsResponseBodyAccessible() {
|
||||
log.Debug("Skipping response body inspection, SecResponseBodyAccess is off.")
|
||||
// ProcessResponseBody is performed for phase 4 rules, checking already populated variables
|
||||
ctx.SetContext("processedResponseBody", true)
|
||||
interruption, err := tx.ProcessResponseBody()
|
||||
if err != nil {
|
||||
log.Error("Failed to process response body")
|
||||
return types.ActionContinue
|
||||
}
|
||||
|
||||
if interruption != nil {
|
||||
// Proxy-wasm can not anymore deny the response. The best interruption is emptying the body
|
||||
// Coraza Multiphase evaluation will help here avoiding late interruptions
|
||||
return handleInterruption(ctx, "http_response_body", interruption, log)
|
||||
}
|
||||
return types.ActionContinue
|
||||
}
|
||||
|
||||
interruption, _, err := tx.WriteResponseBody(body)
|
||||
// log.Infof("[rinfx debug] ResponseBody %s", string(body))
|
||||
if err != nil {
|
||||
log.Error("Failed to write response body")
|
||||
return types.ActionContinue
|
||||
}
|
||||
if interruption != nil {
|
||||
return handleInterruption(ctx, "http_response_body", interruption, log)
|
||||
}
|
||||
|
||||
// We have already sent response headers, an unauthorized response can not be sent anymore,
|
||||
// but we can still drop the response to prevent leaking sensitive content.
|
||||
// The error will also be logged by Coraza.
|
||||
ctx.SetContext("processedResponseBody", true)
|
||||
interruption, err = tx.ProcessResponseBody()
|
||||
if err != nil {
|
||||
log.Error("Failed to process response body")
|
||||
return types.ActionContinue
|
||||
}
|
||||
if interruption != nil {
|
||||
return handleInterruption(ctx, "http_response_body", interruption, log)
|
||||
}
|
||||
return types.ActionContinue
|
||||
}
|
||||
|
||||
func onHttpStreamDone(ctx wrapper.HttpContext, config WafConfig, log wrapper.Log) {
|
||||
// log.Info("[rinfx log] OnHttpStreamDone")
|
||||
|
||||
tx := ctx.GetContext("tx").(ctypes.Transaction)
|
||||
|
||||
if !tx.IsRuleEngineOff() {
|
||||
// Responses without body won't call OnHttpResponseBody, but there are rules in the response body
|
||||
// phase that still need to be executed. If they haven't been executed yet, now is the time.
|
||||
if !ctx.GetContext("processedResponseBody").(bool) {
|
||||
ctx.SetContext("processedResponseBody", true)
|
||||
_, err := tx.ProcessResponseBody()
|
||||
if err != nil {
|
||||
log.Error("Failed to process response body")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tx.ProcessLogging()
|
||||
|
||||
_ = tx.Close()
|
||||
log.Info("Finished")
|
||||
}
|
||||
253
plugins/wasm-go/extensions/waf/wasmplugin/rules/coraza-demo.conf
Normal file
253
plugins/wasm-go/extensions/waf/wasmplugin/rules/coraza-demo.conf
Normal file
@@ -0,0 +1,253 @@
|
||||
# -- Rule engine initialization ----------------------------------------------
|
||||
|
||||
# Enable Coraza, attaching it to every transaction. Use detection
|
||||
# only to start with, because that minimises the chances of post-installation
|
||||
# disruption.
|
||||
#
|
||||
SecRuleEngine On
|
||||
|
||||
|
||||
# -- Request body handling ---------------------------------------------------
|
||||
|
||||
# Allow Coraza to access request bodies. If you don't, Coraza
|
||||
# won't be able to see any POST parameters, which opens a large security
|
||||
# hole for attackers to exploit.
|
||||
#
|
||||
SecRequestBodyAccess On
|
||||
|
||||
# Enable XML request body parser.
|
||||
# Initiate XML Processor in case of xml content-type
|
||||
#
|
||||
SecRule REQUEST_HEADERS:Content-Type "^(?:application(?:/soap\+|/)|text/)xml" \
|
||||
"id:'200000',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=XML"
|
||||
|
||||
# Enable JSON request body parser.
|
||||
# Initiate JSON Processor in case of JSON content-type; change accordingly
|
||||
# if your application does not use 'application/json'
|
||||
#
|
||||
SecRule REQUEST_HEADERS:Content-Type "^application/json" \
|
||||
"id:'200001',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=JSON"
|
||||
|
||||
# Sample rule to enable JSON request body parser for more subtypes.
|
||||
# Uncomment or adapt this rule if you want to engage the JSON
|
||||
# Processor for "+json" subtypes
|
||||
#
|
||||
#SecRule REQUEST_HEADERS:Content-Type "^application/[a-z0-9.-]+[+]json" \
|
||||
# "id:'200006',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=JSON"
|
||||
|
||||
# Maximum request body size we will accept for buffering. If you support
|
||||
# file uploads then the value given on the first line has to be as large
|
||||
# as the largest file you are willing to accept. The second value refers
|
||||
# to the size of data, with files excluded. You want to keep that value as
|
||||
# low as practical.
|
||||
#
|
||||
SecRequestBodyLimit 13107200
|
||||
|
||||
SecRequestBodyInMemoryLimit 131072
|
||||
|
||||
SecRequestBodyNoFilesLimit 131072
|
||||
|
||||
# What to do if the request body size is above our configured limit.
|
||||
# Keep in mind that this setting will automatically be set to ProcessPartial
|
||||
# when SecRuleEngine is set to DetectionOnly mode in order to minimize
|
||||
# disruptions when initially deploying Coraza.
|
||||
#
|
||||
SecRequestBodyLimitAction Reject
|
||||
|
||||
# Verify that we've correctly processed the request body.
|
||||
# As a rule of thumb, when failing to process a request body
|
||||
# you should reject the request (when deployed in blocking mode)
|
||||
# or log a high-severity alert (when deployed in detection-only mode).
|
||||
#
|
||||
SecRule REQBODY_ERROR "!@eq 0" \
|
||||
"id:'200002', phase:2,t:none,log,deny,status:400,msg:'Failed to parse request body.',logdata:'%{reqbody_error_msg}',severity:2"
|
||||
|
||||
# By default be strict with what we accept in the multipart/form-data
|
||||
# request body. If the rule below proves to be too strict for your
|
||||
# environment consider changing it to detection-only. You are encouraged
|
||||
# _not_ to remove it altogether.
|
||||
#
|
||||
SecRule MULTIPART_STRICT_ERROR "!@eq 0" \
|
||||
"id:'200003',phase:2,t:none,log,deny,status:400, \
|
||||
msg:'Multipart request body failed strict validation: \
|
||||
PE %{REQBODY_PROCESSOR_ERROR}, \
|
||||
BQ %{MULTIPART_BOUNDARY_QUOTED}, \
|
||||
BW %{MULTIPART_BOUNDARY_WHITESPACE}, \
|
||||
DB %{MULTIPART_DATA_BEFORE}, \
|
||||
DA %{MULTIPART_DATA_AFTER}, \
|
||||
HF %{MULTIPART_HEADER_FOLDING}, \
|
||||
LF %{MULTIPART_LF_LINE}, \
|
||||
SM %{MULTIPART_MISSING_SEMICOLON}, \
|
||||
IQ %{MULTIPART_INVALID_QUOTING}, \
|
||||
IP %{MULTIPART_INVALID_PART}, \
|
||||
IH %{MULTIPART_INVALID_HEADER_FOLDING}, \
|
||||
FL %{MULTIPART_FILE_LIMIT_EXCEEDED}'"
|
||||
|
||||
# Did we see anything that might be a boundary?
|
||||
#
|
||||
# Here is a short description about the Coraza Multipart parser: the
|
||||
# parser returns with value 0, if all "boundary-like" line matches with
|
||||
# the boundary string which given in MIME header. In any other cases it returns
|
||||
# with different value, eg. 1 or 2.
|
||||
#
|
||||
# The RFC 1341 descript the multipart content-type and its syntax must contains
|
||||
# only three mandatory lines (above the content):
|
||||
# * Content-Type: multipart/mixed; boundary=BOUNDARY_STRING
|
||||
# * --BOUNDARY_STRING
|
||||
# * --BOUNDARY_STRING--
|
||||
#
|
||||
# First line indicates, that this is a multipart content, second shows that
|
||||
# here starts a part of the multipart content, third shows the end of content.
|
||||
#
|
||||
# If there are any other lines, which starts with "--", then it should be
|
||||
# another boundary id - or not.
|
||||
#
|
||||
# After 3.0.3, there are two kinds of types of boundary errors: strict and permissive.
|
||||
#
|
||||
# If multipart content contains the three necessary lines with correct order, but
|
||||
# there are one or more lines with "--", then parser returns with value 2 (non-zero).
|
||||
#
|
||||
# If some of the necessary lines (usually the start or end) misses, or the order
|
||||
# is wrong, then parser returns with value 1 (also a non-zero).
|
||||
#
|
||||
# You can choose, which one is what you need. The example below contains the
|
||||
# 'strict' mode, which means if there are any lines with start of "--", then
|
||||
# Coraza blocked the content. But the next, commented example contains
|
||||
# the 'permissive' mode, then you check only if the necessary lines exists in
|
||||
# correct order. Whit this, you can enable to upload PEM files (eg "----BEGIN.."),
|
||||
# or other text files, which contains eg. HTTP headers.
|
||||
#
|
||||
# The difference is only the operator - in strict mode (first) the content blocked
|
||||
# in case of any non-zero value. In permissive mode (second, commented) the
|
||||
# content blocked only if the value is explicit 1. If it 0 or 2, the content will
|
||||
# allowed.
|
||||
#
|
||||
|
||||
#
|
||||
# See #1747 and #1924 for further information on the possible values for
|
||||
# MULTIPART_UNMATCHED_BOUNDARY.
|
||||
#
|
||||
SecRule MULTIPART_UNMATCHED_BOUNDARY "@eq 1" \
|
||||
"id:'200004',phase:2,t:none,log,deny,msg:'Multipart parser detected a possible unmatched boundary.'"
|
||||
|
||||
# Some internal errors will set flags in TX and we will need to look for these.
|
||||
# All of these are prefixed with "MSC_". The following flags currently exist:
|
||||
#
|
||||
# COR_PCRE_LIMITS_EXCEEDED: PCRE match limits were exceeded.
|
||||
#
|
||||
SecRule TX:/^COR_/ "!@streq 0" \
|
||||
"id:'200005',phase:2,t:none,deny,msg:'Coraza internal error flagged: %{MATCHED_VAR_NAME}'"
|
||||
|
||||
|
||||
# -- Response body handling --------------------------------------------------
|
||||
|
||||
# Allow Coraza to access response bodies.
|
||||
# You should have this directive enabled in order to identify errors
|
||||
# and data leakage issues.
|
||||
#
|
||||
# Do keep in mind that enabling this directive does increases both
|
||||
# memory consumption and response latency.
|
||||
#
|
||||
SecResponseBodyAccess On
|
||||
|
||||
# Which response MIME types do you want to inspect? You should adjust the
|
||||
# configuration below to catch documents but avoid static files
|
||||
# (e.g., images and archives).
|
||||
#
|
||||
SecResponseBodyMimeType text/plain text/html text/xml application/json
|
||||
|
||||
# Buffer response bodies of up to 512 KB in length.
|
||||
SecResponseBodyLimit 524288
|
||||
|
||||
# What happens when we encounter a response body larger than the configured
|
||||
# limit? By default, we process what we have and let the rest through.
|
||||
# That's somewhat less secure, but does not break any legitimate pages.
|
||||
#
|
||||
SecResponseBodyLimitAction ProcessPartial
|
||||
|
||||
|
||||
# -- Filesystem configuration ------------------------------------------------
|
||||
|
||||
# The location where Coraza stores temporary files (for example, when
|
||||
# it needs to handle a file upload that is larger than the configured limit).
|
||||
#
|
||||
# This default setting is chosen due to all systems have /tmp available however,
|
||||
# this is less than ideal. It is recommended that you specify a location that's private.
|
||||
#
|
||||
SecTmpDir /tmp/
|
||||
|
||||
# The location where Coraza will keep its persistent data. This default setting
|
||||
# is chosen due to all systems have /tmp available however, it
|
||||
# too should be updated to a place that other users can't access.
|
||||
#
|
||||
SecDataDir /tmp/
|
||||
|
||||
|
||||
# -- File uploads handling configuration -------------------------------------
|
||||
|
||||
# The location where Coraza stores intercepted uploaded files. This
|
||||
# location must be private to Coraza. You don't want other users on
|
||||
# the server to access the files, do you?
|
||||
#
|
||||
#SecUploadDir /opt/coraza/var/upload/
|
||||
|
||||
# By default, only keep the files that were determined to be unusual
|
||||
# in some way (by an external inspection script). For this to work you
|
||||
# will also need at least one file inspection rule.
|
||||
#
|
||||
#SecUploadKeepFiles RelevantOnly
|
||||
|
||||
# Uploaded files are by default created with permissions that do not allow
|
||||
# any other user to access them. You may need to relax that if you want to
|
||||
# interface Coraza to an external program (e.g., an anti-virus).
|
||||
#
|
||||
#SecUploadFileMode 0600
|
||||
|
||||
|
||||
# -- Debug log configuration -------------------------------------------------
|
||||
|
||||
# Default debug log path
|
||||
# Debug levels:
|
||||
# 0: No logging (least verbose)
|
||||
# 1: Error
|
||||
# 2: Warn
|
||||
# 3: Info
|
||||
# 4-8: Debug
|
||||
# 9: Trace (most verbose)
|
||||
# Most logging has not been implemented because it will be replaced with
|
||||
# advanced rule profiling options
|
||||
#SecDebugLog /opt/coraza/var/log/debug.log
|
||||
SecDebugLogLevel 3
|
||||
|
||||
|
||||
# -- Audit log configuration -------------------------------------------------
|
||||
|
||||
# Log the transactions that are marked by a rule, as well as those that
|
||||
# trigger a server error (determined by a 5xx or 4xx, excluding 404,
|
||||
# level response status codes).
|
||||
#
|
||||
SecAuditEngine On
|
||||
SecAuditLogRelevantStatus "^(?:(5|4)(0|1)[0-9])$"
|
||||
|
||||
# Log everything we know about a transaction.
|
||||
SecAuditLogParts ABIJDEFHZ
|
||||
|
||||
# Use a single file for logging. This is much easier to look at, but
|
||||
# assumes that you will use the audit log only occasionally.
|
||||
#
|
||||
SecAuditLogType Serial
|
||||
|
||||
|
||||
# -- Miscellaneous -----------------------------------------------------------
|
||||
|
||||
# Use the most commonly used application/x-www-form-urlencoded parameter
|
||||
# separator. There's probably only one application somewhere that uses
|
||||
# something else so don't expect to change this value.
|
||||
#
|
||||
SecArgumentSeparator &
|
||||
|
||||
# Settle on version 0 (zero) cookies, as that is what most applications
|
||||
# use. Using an incorrect cookie version may open your installation to
|
||||
# evasion attacks (against the rules that examine named cookies).
|
||||
#
|
||||
SecCookieFormat 0
|
||||
@@ -0,0 +1,253 @@
|
||||
# -- Rule engine initialization ----------------------------------------------
|
||||
|
||||
# Enable Coraza, attaching it to every transaction. Use detection
|
||||
# only to start with, because that minimises the chances of post-installation
|
||||
# disruption.
|
||||
#
|
||||
SecRuleEngine DetectionOnly
|
||||
|
||||
|
||||
# -- Request body handling ---------------------------------------------------
|
||||
|
||||
# Allow Coraza to access request bodies. If you don't, Coraza
|
||||
# won't be able to see any POST parameters, which opens a large security
|
||||
# hole for attackers to exploit.
|
||||
#
|
||||
SecRequestBodyAccess On
|
||||
|
||||
# Enable XML request body parser.
|
||||
# Initiate XML Processor in case of xml content-type
|
||||
#
|
||||
SecRule REQUEST_HEADERS:Content-Type "^(?:application(?:/soap\+|/)|text/)xml" \
|
||||
"id:'200000',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=XML"
|
||||
|
||||
# Enable JSON request body parser.
|
||||
# Initiate JSON Processor in case of JSON content-type; change accordingly
|
||||
# if your application does not use 'application/json'
|
||||
#
|
||||
SecRule REQUEST_HEADERS:Content-Type "^application/json" \
|
||||
"id:'200001',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=JSON"
|
||||
|
||||
# Sample rule to enable JSON request body parser for more subtypes.
|
||||
# Uncomment or adapt this rule if you want to engage the JSON
|
||||
# Processor for "+json" subtypes
|
||||
#
|
||||
#SecRule REQUEST_HEADERS:Content-Type "^application/[a-z0-9.-]+[+]json" \
|
||||
# "id:'200006',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=JSON"
|
||||
|
||||
# Maximum request body size we will accept for buffering. If you support
|
||||
# file uploads then the value given on the first line has to be as large
|
||||
# as the largest file you are willing to accept. The second value refers
|
||||
# to the size of data, with files excluded. You want to keep that value as
|
||||
# low as practical.
|
||||
#
|
||||
SecRequestBodyLimit 13107200
|
||||
|
||||
SecRequestBodyInMemoryLimit 131072
|
||||
|
||||
SecRequestBodyNoFilesLimit 131072
|
||||
|
||||
# What to do if the request body size is above our configured limit.
|
||||
# Keep in mind that this setting will automatically be set to ProcessPartial
|
||||
# when SecRuleEngine is set to DetectionOnly mode in order to minimize
|
||||
# disruptions when initially deploying Coraza.
|
||||
#
|
||||
SecRequestBodyLimitAction Reject
|
||||
|
||||
# Verify that we've correctly processed the request body.
|
||||
# As a rule of thumb, when failing to process a request body
|
||||
# you should reject the request (when deployed in blocking mode)
|
||||
# or log a high-severity alert (when deployed in detection-only mode).
|
||||
#
|
||||
SecRule REQBODY_ERROR "!@eq 0" \
|
||||
"id:'200002', phase:2,t:none,log,deny,status:400,msg:'Failed to parse request body.',logdata:'%{reqbody_error_msg}',severity:2"
|
||||
|
||||
# By default be strict with what we accept in the multipart/form-data
|
||||
# request body. If the rule below proves to be too strict for your
|
||||
# environment consider changing it to detection-only. You are encouraged
|
||||
# _not_ to remove it altogether.
|
||||
#
|
||||
SecRule MULTIPART_STRICT_ERROR "!@eq 0" \
|
||||
"id:'200003',phase:2,t:none,log,deny,status:400, \
|
||||
msg:'Multipart request body failed strict validation: \
|
||||
PE %{REQBODY_PROCESSOR_ERROR}, \
|
||||
BQ %{MULTIPART_BOUNDARY_QUOTED}, \
|
||||
BW %{MULTIPART_BOUNDARY_WHITESPACE}, \
|
||||
DB %{MULTIPART_DATA_BEFORE}, \
|
||||
DA %{MULTIPART_DATA_AFTER}, \
|
||||
HF %{MULTIPART_HEADER_FOLDING}, \
|
||||
LF %{MULTIPART_LF_LINE}, \
|
||||
SM %{MULTIPART_MISSING_SEMICOLON}, \
|
||||
IQ %{MULTIPART_INVALID_QUOTING}, \
|
||||
IP %{MULTIPART_INVALID_PART}, \
|
||||
IH %{MULTIPART_INVALID_HEADER_FOLDING}, \
|
||||
FL %{MULTIPART_FILE_LIMIT_EXCEEDED}'"
|
||||
|
||||
# Did we see anything that might be a boundary?
|
||||
#
|
||||
# Here is a short description about the Coraza Multipart parser: the
|
||||
# parser returns with value 0, if all "boundary-like" line matches with
|
||||
# the boundary string which given in MIME header. In any other cases it returns
|
||||
# with different value, eg. 1 or 2.
|
||||
#
|
||||
# The RFC 1341 descript the multipart content-type and its syntax must contains
|
||||
# only three mandatory lines (above the content):
|
||||
# * Content-Type: multipart/mixed; boundary=BOUNDARY_STRING
|
||||
# * --BOUNDARY_STRING
|
||||
# * --BOUNDARY_STRING--
|
||||
#
|
||||
# First line indicates, that this is a multipart content, second shows that
|
||||
# here starts a part of the multipart content, third shows the end of content.
|
||||
#
|
||||
# If there are any other lines, which starts with "--", then it should be
|
||||
# another boundary id - or not.
|
||||
#
|
||||
# After 3.0.3, there are two kinds of types of boundary errors: strict and permissive.
|
||||
#
|
||||
# If multipart content contains the three necessary lines with correct order, but
|
||||
# there are one or more lines with "--", then parser returns with value 2 (non-zero).
|
||||
#
|
||||
# If some of the necessary lines (usually the start or end) misses, or the order
|
||||
# is wrong, then parser returns with value 1 (also a non-zero).
|
||||
#
|
||||
# You can choose, which one is what you need. The example below contains the
|
||||
# 'strict' mode, which means if there are any lines with start of "--", then
|
||||
# Coraza blocked the content. But the next, commented example contains
|
||||
# the 'permissive' mode, then you check only if the necessary lines exists in
|
||||
# correct order. Whit this, you can enable to upload PEM files (eg "----BEGIN.."),
|
||||
# or other text files, which contains eg. HTTP headers.
|
||||
#
|
||||
# The difference is only the operator - in strict mode (first) the content blocked
|
||||
# in case of any non-zero value. In permissive mode (second, commented) the
|
||||
# content blocked only if the value is explicit 1. If it 0 or 2, the content will
|
||||
# allowed.
|
||||
#
|
||||
|
||||
#
|
||||
# See #1747 and #1924 for further information on the possible values for
|
||||
# MULTIPART_UNMATCHED_BOUNDARY.
|
||||
#
|
||||
SecRule MULTIPART_UNMATCHED_BOUNDARY "@eq 1" \
|
||||
"id:'200004',phase:2,t:none,log,deny,msg:'Multipart parser detected a possible unmatched boundary.'"
|
||||
|
||||
# Some internal errors will set flags in TX and we will need to look for these.
|
||||
# All of these are prefixed with "MSC_". The following flags currently exist:
|
||||
#
|
||||
# COR_PCRE_LIMITS_EXCEEDED: PCRE match limits were exceeded.
|
||||
#
|
||||
SecRule TX:/^COR_/ "!@streq 0" \
|
||||
"id:'200005',phase:2,t:none,deny,msg:'Coraza internal error flagged: %{MATCHED_VAR_NAME}'"
|
||||
|
||||
|
||||
# -- Response body handling --------------------------------------------------
|
||||
|
||||
# Allow Coraza to access response bodies.
|
||||
# You should have this directive enabled in order to identify errors
|
||||
# and data leakage issues.
|
||||
#
|
||||
# Do keep in mind that enabling this directive does increases both
|
||||
# memory consumption and response latency.
|
||||
#
|
||||
SecResponseBodyAccess On
|
||||
|
||||
# Which response MIME types do you want to inspect? You should adjust the
|
||||
# configuration below to catch documents but avoid static files
|
||||
# (e.g., images and archives).
|
||||
#
|
||||
SecResponseBodyMimeType text/plain text/html text/xml
|
||||
|
||||
# Buffer response bodies of up to 512 KB in length.
|
||||
SecResponseBodyLimit 524288
|
||||
|
||||
# What happens when we encounter a response body larger than the configured
|
||||
# limit? By default, we process what we have and let the rest through.
|
||||
# That's somewhat less secure, but does not break any legitimate pages.
|
||||
#
|
||||
SecResponseBodyLimitAction ProcessPartial
|
||||
|
||||
|
||||
# -- Filesystem configuration ------------------------------------------------
|
||||
|
||||
# The location where Coraza stores temporary files (for example, when
|
||||
# it needs to handle a file upload that is larger than the configured limit).
|
||||
#
|
||||
# This default setting is chosen due to all systems have /tmp available however,
|
||||
# this is less than ideal. It is recommended that you specify a location that's private.
|
||||
#
|
||||
SecTmpDir /tmp/
|
||||
|
||||
# The location where Coraza will keep its persistent data. This default setting
|
||||
# is chosen due to all systems have /tmp available however, it
|
||||
# too should be updated to a place that other users can't access.
|
||||
#
|
||||
SecDataDir /tmp/
|
||||
|
||||
|
||||
# -- File uploads handling configuration -------------------------------------
|
||||
|
||||
# The location where Coraza stores intercepted uploaded files. This
|
||||
# location must be private to Coraza. You don't want other users on
|
||||
# the server to access the files, do you?
|
||||
#
|
||||
#SecUploadDir /opt/coraza/var/upload/
|
||||
|
||||
# By default, only keep the files that were determined to be unusual
|
||||
# in some way (by an external inspection script). For this to work you
|
||||
# will also need at least one file inspection rule.
|
||||
#
|
||||
#SecUploadKeepFiles RelevantOnly
|
||||
|
||||
# Uploaded files are by default created with permissions that do not allow
|
||||
# any other user to access them. You may need to relax that if you want to
|
||||
# interface Coraza to an external program (e.g., an anti-virus).
|
||||
#
|
||||
#SecUploadFileMode 0600
|
||||
|
||||
|
||||
# -- Debug log configuration -------------------------------------------------
|
||||
|
||||
# Default debug log path
|
||||
# Debug levels:
|
||||
# 0: No logging (least verbose)
|
||||
# 1: Error
|
||||
# 2: Warn
|
||||
# 3: Info
|
||||
# 4-8: Debug
|
||||
# 9: Trace (most verbose)
|
||||
# Most logging has not been implemented because it will be replaced with
|
||||
# advanced rule profiling options
|
||||
#SecDebugLog /opt/coraza/var/log/debug.log
|
||||
#SecDebugLogLevel 3
|
||||
|
||||
|
||||
# -- Audit log configuration -------------------------------------------------
|
||||
|
||||
# Log the transactions that are marked by a rule, as well as those that
|
||||
# trigger a server error (determined by a 5xx or 4xx, excluding 404,
|
||||
# level response status codes).
|
||||
#
|
||||
SecAuditEngine RelevantOnly
|
||||
SecAuditLogRelevantStatus "^(?:(5|4)(0|1)[0-9])$"
|
||||
|
||||
# Log everything we know about a transaction.
|
||||
SecAuditLogParts ABIJDEFHZ
|
||||
|
||||
# Use a single file for logging. This is much easier to look at, but
|
||||
# assumes that you will use the audit log only occasionally.
|
||||
#
|
||||
SecAuditLogType Serial
|
||||
|
||||
|
||||
# -- Miscellaneous -----------------------------------------------------------
|
||||
|
||||
# Use the most commonly used application/x-www-form-urlencoded parameter
|
||||
# separator. There's probably only one application somewhere that uses
|
||||
# something else so don't expect to change this value.
|
||||
#
|
||||
SecArgumentSeparator &
|
||||
|
||||
# Settle on version 0 (zero) cookies, as that is what most applications
|
||||
# use. Using an incorrect cookie version may open your installation to
|
||||
# evasion attacks (against the rules that examine named cookies).
|
||||
#
|
||||
SecCookieFormat 0
|
||||
@@ -0,0 +1,727 @@
|
||||
# ------------------------------------------------------------------------
|
||||
# OWASP ModSecurity Core Rule Set ver.4.0.0-rc1
|
||||
# Copyright (c) 2006-2020 Trustwave and contributors. All rights reserved.
|
||||
# Copyright (c) 2021-2022 Core Rule Set project. All rights reserved.
|
||||
#
|
||||
# The OWASP ModSecurity Core Rule Set is distributed under
|
||||
# Apache Software License (ASL) version 2
|
||||
# Please see the enclosed LICENSE file for full details.
|
||||
# ------------------------------------------------------------------------
|
||||
|
||||
|
||||
#
|
||||
# -- [[ Introduction ]] --------------------------------------------------------
|
||||
#
|
||||
# The OWASP ModSecurity Core Rule Set (CRS) is a set of generic attack
|
||||
# detection rules that provide a base level of protection for any web
|
||||
# application. They are written for the open source, cross-platform
|
||||
# ModSecurity Web Application Firewall.
|
||||
#
|
||||
# See also:
|
||||
# https://coreruleset.org/
|
||||
# https://github.com/coreruleset/coreruleset
|
||||
# https://owasp.org/www-project-modsecurity-core-rule-set/
|
||||
#
|
||||
|
||||
|
||||
#
|
||||
# -- [[ System Requirements ]] -------------------------------------------------
|
||||
#
|
||||
# CRS requires ModSecurity version 2.8.0 or above.
|
||||
# We recommend to always use the newest ModSecurity version.
|
||||
#
|
||||
# The configuration directives/settings in this file are used to control
|
||||
# the OWASP ModSecurity CRS. These settings do **NOT** configure the main
|
||||
# ModSecurity settings (modsecurity.conf) such as SecRuleEngine,
|
||||
# SecRequestBodyAccess, SecAuditEngine, SecDebugLog, and XML processing.
|
||||
#
|
||||
# The CRS assumes that modsecurity.conf has been loaded. It is bundled with
|
||||
# ModSecurity. If you don't have it, you can get it from:
|
||||
# 2.x: https://raw.githubusercontent.com/SpiderLabs/ModSecurity/v2/master/modsecurity.conf-recommended
|
||||
# 3.x: https://raw.githubusercontent.com/SpiderLabs/ModSecurity/v3/master/modsecurity.conf-recommended
|
||||
#
|
||||
# The order of file inclusion in your webserver configuration should always be:
|
||||
# 1. modsecurity.conf
|
||||
# 2. crs-setup.conf (this file)
|
||||
# 3. rules/*.conf (the CRS rule files)
|
||||
#
|
||||
# Please refer to the INSTALL file for detailed installation instructions.
|
||||
#
|
||||
|
||||
|
||||
#
|
||||
# -- [[ Mode of Operation: Anomaly Scoring vs. Self-Contained ]] ---------------
|
||||
#
|
||||
# The CRS can run in two modes:
|
||||
#
|
||||
# -- [[ Anomaly Scoring Mode (default) ]] --
|
||||
# In CRS3, anomaly mode is the default and recommended mode, since it gives the
|
||||
# most accurate log information and offers the most flexibility in setting your
|
||||
# blocking policies. It is also called "collaborative detection mode".
|
||||
# In this mode, each matching rule increases an 'anomaly score'.
|
||||
# At the conclusion of the inbound rules, and again at the conclusion of the
|
||||
# outbound rules, the anomaly score is checked, and the blocking evaluation
|
||||
# rules apply a disruptive action, by default returning an error 403.
|
||||
#
|
||||
# -- [[ Self-Contained Mode ]] --
|
||||
# In this mode, rules apply an action instantly. This was the CRS2 default.
|
||||
# It can lower resource usage, at the cost of less flexibility in blocking policy
|
||||
# and less informative audit logs (only the first detected threat is logged).
|
||||
# Rules inherit the disruptive action that you specify (i.e. deny, drop, etc).
|
||||
# The first rule that matches will execute this action. In most cases this will
|
||||
# cause evaluation to stop after the first rule has matched, similar to how many
|
||||
# IDSs function.
|
||||
#
|
||||
# -- [[ Alert Logging Control ]] --
|
||||
# In the mode configuration, you must also adjust the desired logging options.
|
||||
# There are three common options for dealing with logging. By default CRS enables
|
||||
# logging to the webserver error log (or Event viewer) plus detailed logging to
|
||||
# the ModSecurity audit log (configured under SecAuditLog in modsecurity.conf).
|
||||
#
|
||||
# - To log to both error log and ModSecurity audit log file, use: "log,auditlog"
|
||||
# - To log *only* to the ModSecurity audit log file, use: "nolog,auditlog"
|
||||
# - To log *only* to the error log file, use: "log,noauditlog"
|
||||
#
|
||||
# Examples for the various modes follow.
|
||||
# You must leave one of the following options enabled.
|
||||
# Note that you must specify the same line for phase:1 and phase:2.
|
||||
#
|
||||
|
||||
# Default: Anomaly Scoring mode, log to error log, log to ModSecurity audit log
|
||||
# - By default, offending requests are blocked with an error 403 response.
|
||||
# - To change the disruptive action, see RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf.example
|
||||
# and review section 'Changing the Disruptive Action for Anomaly Mode'.
|
||||
# - In Apache, you can use ErrorDocument to show a friendly error page or
|
||||
# perform a redirect: https://httpd.apache.org/docs/2.4/custom-error.html
|
||||
#
|
||||
SecDefaultAction "phase:1,log,auditlog,pass"
|
||||
SecDefaultAction "phase:2,log,auditlog,pass"
|
||||
|
||||
# Example: Anomaly Scoring mode, log only to ModSecurity audit log
|
||||
# - By default, offending requests are blocked with an error 403 response.
|
||||
# - To change the disruptive action, see RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf.example
|
||||
# and review section 'Changing the Disruptive Action for Anomaly Mode'.
|
||||
# - In Apache, you can use ErrorDocument to show a friendly error page or
|
||||
# perform a redirect: https://httpd.apache.org/docs/2.4/custom-error.html
|
||||
#
|
||||
# SecDefaultAction "phase:1,nolog,auditlog,pass"
|
||||
# SecDefaultAction "phase:2,nolog,auditlog,pass"
|
||||
|
||||
# Example: Self-contained mode, return error 403 on blocking
|
||||
# - In this configuration the default disruptive action becomes 'deny'. After a
|
||||
# rule triggers, it will stop processing the request and return an error 403.
|
||||
# - You can also use a different error status, such as 404, 406, et cetera.
|
||||
# - In Apache, you can use ErrorDocument to show a friendly error page or
|
||||
# perform a redirect: https://httpd.apache.org/docs/2.4/custom-error.html
|
||||
#
|
||||
# SecDefaultAction "phase:1,log,auditlog,deny,status:403"
|
||||
# SecDefaultAction "phase:2,log,auditlog,deny,status:403"
|
||||
|
||||
# Example: Self-contained mode, redirect back to homepage on blocking
|
||||
# - In this configuration the 'tag' action includes the Host header data in the
|
||||
# log. This helps to identify which virtual host triggered the rule (if any).
|
||||
# - Note that this might cause redirect loops in some situations; for example
|
||||
# if a Cookie or User-Agent header is blocked, it will also be blocked when
|
||||
# the client subsequently tries to access the homepage. You can also redirect
|
||||
# to another custom URL.
|
||||
# SecDefaultAction "phase:1,log,auditlog,redirect:'http://%{request_headers.host}/',tag:'Host: %{request_headers.host}'"
|
||||
# SecDefaultAction "phase:2,log,auditlog,redirect:'http://%{request_headers.host}/',tag:'Host: %{request_headers.host}'"
|
||||
|
||||
|
||||
#
|
||||
# -- [[ Paranoia Level Initialization ]] ---------------------------------------
|
||||
#
|
||||
# The Paranoia Level (PL) setting allows you to choose the desired level
|
||||
# of rule checks that will add to your anomaly scores.
|
||||
#
|
||||
# With each paranoia level increase, the CRS enables additional rules
|
||||
# giving you a higher level of security. However, higher paranoia levels
|
||||
# also increase the possibility of blocking some legitimate traffic due to
|
||||
# false alarms (also named false positives or FPs). If you use higher
|
||||
# paranoia levels, it is likely that you will need to add some exclusion
|
||||
# rules for certain requests and applications receiving complex input.
|
||||
#
|
||||
# - A paranoia level of 1 is default. In this level, most core rules
|
||||
# are enabled. PL1 is advised for beginners, installations
|
||||
# covering many different sites and applications, and for setups
|
||||
# with standard security requirements.
|
||||
# At PL1 you should face FPs rarely. If you encounter FPs, please
|
||||
# open an issue on the CRS GitHub site and don't forget to attach your
|
||||
# complete Audit Log record for the request with the issue.
|
||||
# - Paranoia level 2 includes many extra rules, for instance enabling
|
||||
# many regexp-based SQL and XSS injection protections, and adding
|
||||
# extra keywords checked for code injections. PL2 is advised
|
||||
# for moderate to experienced users desiring more complete coverage
|
||||
# and for installations with elevated security requirements.
|
||||
# PL2 comes with some FPs which you need to handle.
|
||||
# - Paranoia level 3 enables more rules and keyword lists, and tweaks
|
||||
# limits on special characters used. PL3 is aimed at users experienced
|
||||
# at the handling of FPs and at installations with a high security
|
||||
# requirement.
|
||||
# - Paranoia level 4 further restricts special characters.
|
||||
# The highest level is advised for experienced users protecting
|
||||
# installations with very high security requirements. Running PL4 will
|
||||
# likely produce a very high number of FPs which have to be
|
||||
# treated before the site can go productive.
|
||||
#
|
||||
# All rules will log their PL to the audit log;
|
||||
# example: [tag "paranoia-level/2"]. This allows you to deduct from the
|
||||
# audit log how the WAF behavior is affected by paranoia level.
|
||||
#
|
||||
# It is important to also look into the variable
|
||||
# tx.enforce_bodyproc_urlencoded (Enforce Body Processor URLENCODED)
|
||||
# defined below. Enabling it closes a possible bypass of CRS.
|
||||
#
|
||||
# Uncomment this rule to change the default:
|
||||
#
|
||||
SecAction \
|
||||
"id:900000,\
|
||||
phase:1,\
|
||||
pass,\
|
||||
t:none,\
|
||||
nolog,\
|
||||
setvar:tx.blocking_paranoia_level=1"
|
||||
|
||||
|
||||
# It is possible to execute rules from a higher paranoia level but not include
|
||||
# them in the anomaly scoring. This allows you to take a well-tuned system on
|
||||
# paranoia level 1 and add rules from paranoia level 2 without having to fear
|
||||
# the new rules would lead to false positives that raise your score above the
|
||||
# threshold.
|
||||
# This optional feature is enabled by uncommenting the following rule and
|
||||
# setting the tx.detection_paranoia_level.
|
||||
# Technically, rules up to the level defined in tx.detection_paranoia_level
|
||||
# will be executed, but only the rules up to tx.blocking_paranoia_level affect the
|
||||
# anomaly scores.
|
||||
# By default, tx.detection_paranoia_level is set to tx.blocking_paranoia_level.
|
||||
# tx.detection_paranoia_level must not be lower than tx.blocking_paranoia_level.
|
||||
#
|
||||
# Please notice that setting tx.detection_paranoia_level to a higher paranoia
|
||||
# level results in a performance impact that is equally high as setting
|
||||
# tx.blocking_paranoia_level to said level.
|
||||
#
|
||||
#SecAction \
|
||||
# "id:900001,\
|
||||
# phase:1,\
|
||||
# pass,\
|
||||
# t:none,\
|
||||
# nolog,\
|
||||
# setvar:tx.detection_paranoia_level=1"
|
||||
|
||||
|
||||
#
|
||||
# -- [[ Enforce Body Processor URLENCODED ]] -----------------------------------
|
||||
#
|
||||
# ModSecurity selects the body processor based on the Content-Type request
|
||||
# header. But clients are not always setting the Content-Type header for their
|
||||
# request body payloads. This will leave ModSecurity with limited vision into
|
||||
# the payload. The variable tx.enforce_bodyproc_urlencoded lets you force the
|
||||
# URLENCODED body processor in these situations. This is off by default, as it
|
||||
# implies a change of the behaviour of ModSecurity beyond CRS (the body
|
||||
# processor applies to all rules, not only CRS) and because it may lead to
|
||||
# false positives already on paranoia level 1. However, enabling this variable
|
||||
# closes a possible bypass of CRS so it should be considered.
|
||||
#
|
||||
# Uncomment this rule to change the default:
|
||||
#
|
||||
#SecAction \
|
||||
# "id:900010,\
|
||||
# phase:1,\
|
||||
# pass,\
|
||||
# t:none,\
|
||||
# nolog,\
|
||||
# setvar:tx.enforce_bodyproc_urlencoded=1"
|
||||
|
||||
|
||||
#
|
||||
# -- [[ Anomaly Scoring Mode Severity Levels ]] --------------------------------
|
||||
#
|
||||
# Each rule in the CRS has an associated severity level.
|
||||
# These are the default scoring points for each severity level.
|
||||
# These settings will be used to increment the anomaly score if a rule matches.
|
||||
# You may adjust these points to your liking, but this is usually not needed.
|
||||
#
|
||||
# - CRITICAL severity: Anomaly Score of 5.
|
||||
# Mostly generated by the application attack rules (93x and 94x files).
|
||||
# - ERROR severity: Anomaly Score of 4.
|
||||
# Generated mostly from outbound leakage rules (95x files).
|
||||
# - WARNING severity: Anomaly Score of 3.
|
||||
# Generated mostly by malicious client rules (91x files).
|
||||
# - NOTICE severity: Anomaly Score of 2.
|
||||
# Generated mostly by the protocol rules (92x files).
|
||||
#
|
||||
# In anomaly mode, these scores are cumulative.
|
||||
# So it's possible for a request to hit multiple rules.
|
||||
#
|
||||
# (Note: In this file, we use 'phase:1' to set CRS configuration variables.
|
||||
# In general, 'phase:request' is used. However, we want to make absolutely sure
|
||||
# that all configuration variables are set before the CRS rules are processed.)
|
||||
#
|
||||
SecAction \
|
||||
"id:900100,\
|
||||
phase:1,\
|
||||
pass,\
|
||||
t:none,\
|
||||
nolog,\
|
||||
setvar:tx.critical_anomaly_score=5,\
|
||||
setvar:tx.error_anomaly_score=4,\
|
||||
setvar:tx.warning_anomaly_score=3,\
|
||||
setvar:tx.notice_anomaly_score=2"
|
||||
|
||||
|
||||
#
|
||||
# -- [[ Anomaly Scoring Mode Blocking Threshold Levels ]] ----------------------
|
||||
#
|
||||
# Here, you can specify at which cumulative anomaly score an inbound request,
|
||||
# or outbound response, gets blocked.
|
||||
#
|
||||
# Most detected inbound threats will give a critical score of 5.
|
||||
# Smaller violations, like violations of protocol/standards, carry lower scores.
|
||||
#
|
||||
# [ At default value ]
|
||||
# If you keep the blocking thresholds at the defaults, the CRS will work
|
||||
# similarly to previous CRS versions: a single critical rule match will cause
|
||||
# the request to be blocked and logged.
|
||||
#
|
||||
# [ Using higher values ]
|
||||
# If you want to make the CRS less sensitive, you can increase the blocking
|
||||
# thresholds, for instance to 7 (which would require multiple rule matches
|
||||
# before blocking) or 10 (which would require at least two critical alerts - or
|
||||
# a combination of many lesser alerts), or even higher. However, increasing the
|
||||
# thresholds might cause some attacks to bypass the CRS rules or your policies.
|
||||
#
|
||||
# [ New deployment strategy: Starting high and decreasing ]
|
||||
# It is a common practice to start a fresh CRS installation with elevated
|
||||
# anomaly scoring thresholds (>100) and then lower the limits as your
|
||||
# confidence in the setup grows. You may also look into the Sampling
|
||||
# Percentage section below for a different strategy to ease into a new
|
||||
# CRS installation.
|
||||
#
|
||||
# [ Anomaly Threshold / Paranoia Level Quadrant ]
|
||||
#
|
||||
# High Anomaly Limit | High Anomaly Limit
|
||||
# Low Paranoia Level | High Paranoia Level
|
||||
# -> Fresh Site | -> Experimental Site
|
||||
# ------------------------------------------------------
|
||||
# Low Anomaly Limit | Low Anomaly Limit
|
||||
# Low Paranoia Level | High Paranoia Level
|
||||
# -> Standard Site | -> High Security Site
|
||||
#
|
||||
# Uncomment this rule to change the defaults:
|
||||
#
|
||||
#SecAction \
|
||||
# "id:900110,\
|
||||
# phase:1,\
|
||||
# pass,\
|
||||
# t:none,\
|
||||
# nolog,\
|
||||
# setvar:tx.inbound_anomaly_score_threshold=5,\
|
||||
# setvar:tx.outbound_anomaly_score_threshold=4"
|
||||
|
||||
|
||||
#
|
||||
# -- [[ Application Specific Rule Exclusions ]] --------------------------------
|
||||
#
|
||||
# CRS 3.x contained exclusion packages to tweak the CRS for use with common
|
||||
# web applications, lowering the number of false positives.
|
||||
#
|
||||
# In CRS 4, these are no longer part of the CRS itself, but they are available
|
||||
# as "CRS plugins". Some plugins improve support for web applications, and others
|
||||
# may bring new functionality. Plugins are not installed by default, but can be
|
||||
# downloaded from the plugin registry:
|
||||
# https://github.com/coreruleset/plugin-registry
|
||||
#
|
||||
# For detailed information about using and installing plugins, please see:
|
||||
# https://coreruleset.org/docs/concepts/plugins/
|
||||
|
||||
|
||||
#
|
||||
# -- [[ Anomaly Score Reporting Level ]] ---------------------------------------
|
||||
#
|
||||
# When a request is blocked due to the anomaly score meeting or exceeding the
|
||||
# anomaly threshold then the blocking rule will also report the anomaly score.
|
||||
# This applies to the separate inbound and outbound anomaly scores.
|
||||
#
|
||||
# In phase 5, there are additional rules that can perform additional reporting
|
||||
# of anomaly scores with a verbosity that depends on the reporting level defined
|
||||
# below.
|
||||
#
|
||||
# By setting the reporting level you control whether you want additional
|
||||
# reporting beyond the blocking rule or not and, if yes, which requests should
|
||||
# be covered. The higher the reporting level, the more verbose the reporting is.
|
||||
#
|
||||
# There are 6 reporting levels:
|
||||
#
|
||||
# 0 - Reporting disabled
|
||||
# 1 - Reporting for requests with a blocking anomaly score >= a threshold
|
||||
# 2 - Reporting for requests with a detection anomaly score >= a threshold
|
||||
# 3 - Reporting for requests with a blocking anomaly score greater than 0
|
||||
# 4 - Reporting for requests with a detection anomaly score greater than 0
|
||||
# 5 - Reporting for all requests
|
||||
#
|
||||
# Note: Reporting levels 1 and 2 make it possible to differentiate between
|
||||
# requests that are blocked and requests that are *not* blocked but would have
|
||||
# been blocked if the blocking PL was equal to detection PL. This may be useful
|
||||
# for certain FP tuning methodologies, for example moving to a higher PL.
|
||||
#
|
||||
# A value of 5 can be useful on platforms where you are interested in logging
|
||||
# non-scoring requests, yet it is not possible to report this information in
|
||||
# the request/access log. This applies to Nginx, for example.
|
||||
#
|
||||
#SecAction \
|
||||
# "id:900115,\
|
||||
# phase:1,\
|
||||
# pass,\
|
||||
# t:none,\
|
||||
# nolog,\
|
||||
# setvar:tx.reporting_level=4"
|
||||
|
||||
|
||||
#
|
||||
# -- [[ Early Anomaly Scoring Mode Blocking ]] ------------------------------
|
||||
#
|
||||
# The anomaly scores for the request and the responses are generally summed up
|
||||
# and evaluated at the end of phase:2 and at the end of phase:4 respectively.
|
||||
# However, it is possible to enable an early evaluation of these anomaly scores
|
||||
# at the end of phase:1 and at the end of phase:3.
|
||||
#
|
||||
# If a request (or a response) hits the anomaly threshold in this early
|
||||
# evaluation, then blocking happens immediately (if blocking is enabled) and
|
||||
# the phase 2 (and phase 4 respectively) will no longer be executed.
|
||||
#
|
||||
# Enable the rule 900120 that sets the variable tx.early_blocking to 1 in order
|
||||
# to enable early blocking. The variable tx.early_blocking is set to 0 by
|
||||
# default. Early blocking is thus disabled by default.
|
||||
#
|
||||
# Please note that early blocking will hide potential alerts from you. This
|
||||
# means that a payload that would appear in an alert in phase 2 (or phase 4)
|
||||
# does not get evaluated if the request is being blocked early. So when you
|
||||
# disabled early blocking again at some point in the future, then new alerts
|
||||
# from phase 2 might pop up.
|
||||
SecAction \
|
||||
"id:900120,\
|
||||
phase:1,\
|
||||
pass,\
|
||||
t:none,\
|
||||
nolog,\
|
||||
setvar:tx.early_blocking=1"
|
||||
|
||||
|
||||
#
|
||||
# -- [[ HTTP Policy Settings ]] ------------------------------------------------
|
||||
#
|
||||
# This section defines your policies for the HTTP protocol, such as:
|
||||
# - allowed HTTP versions, HTTP methods, allowed request Content-Types
|
||||
# - forbidden file extensions (e.g. .bak, .sql) and request headers (e.g. Proxy)
|
||||
#
|
||||
# These variables are used in the following rule files:
|
||||
# - REQUEST-911-METHOD-ENFORCEMENT.conf
|
||||
# - REQUEST-920-PROTOCOL-ENFORCEMENT.conf
|
||||
|
||||
# HTTP methods that a client is allowed to use.
|
||||
# Default: GET HEAD POST OPTIONS
|
||||
# Example: for RESTful APIs, add the following methods: PUT PATCH DELETE
|
||||
# Example: for WebDAV, add the following methods: CHECKOUT COPY DELETE LOCK
|
||||
# MERGE MKACTIVITY MKCOL MOVE PROPFIND PROPPATCH PUT UNLOCK
|
||||
# Uncomment this rule to change the default.
|
||||
#SecAction \
|
||||
# "id:900200,\
|
||||
# phase:1,\
|
||||
# pass,\
|
||||
# t:none,\
|
||||
# nolog,\
|
||||
# setvar:'tx.allowed_methods=GET HEAD POST OPTIONS'"
|
||||
|
||||
# Content-Types that a client is allowed to send in a request.
|
||||
# Default: |application/x-www-form-urlencoded| |multipart/form-data| |multipart/related|
|
||||
# |text/xml| |application/xml| |application/soap+xml| |application/json|
|
||||
# |application/cloudevents+json| |application/cloudevents-batch+json|
|
||||
#
|
||||
# Please note, that the rule where CRS uses this variable (920420) evaluates it with operator
|
||||
# `@within`, which is case sensitive, but uses t:lowercase. You must add your whole custom
|
||||
# Content-Type with lowercase.
|
||||
#
|
||||
# Bypass Warning: some applications may not rely on the content-type request header in order
|
||||
# to parse the request body. This could make an attacker able to send malicious URLENCODED/JSON/XML
|
||||
# payloads without being detected by the WAF. Allowing request content-type that doesn't activate any
|
||||
# body processor (for example: "text/plain", "application/x-amf", "application/octet-stream", etc..)
|
||||
# could lead to a WAF bypass. For example, a malicious JSON payload submitted with a "text/plain"
|
||||
# content type may still be interpreted as JSON by a backend application but would not trigger the
|
||||
# JSON body parser at the WAF, leading to a bypass.
|
||||
#
|
||||
# To prevent blocking request with not allowed content-type by default, you can create an exclusion
|
||||
# rule that removes rule 920420. For example:
|
||||
#SecRule REQUEST_HEADERS:Content-Type "@rx ^text/plain" \
|
||||
# "id:1234,\
|
||||
# phase:1,\
|
||||
# pass,\
|
||||
# t:none,\
|
||||
# nolog,\
|
||||
# ctl:ruleRemoveById=920420,\
|
||||
# chain"
|
||||
# SecRule REQUEST_URI "@rx ^/foo/bar" "t:none"
|
||||
#
|
||||
# Uncomment this rule to change the default.
|
||||
#
|
||||
#SecAction \
|
||||
# "id:900220,\
|
||||
# phase:1,\
|
||||
# pass,\
|
||||
# t:none,\
|
||||
# nolog,\
|
||||
# setvar:'tx.allowed_request_content_type=|application/x-www-form-urlencoded| |multipart/form-data| |multipart/related| |text/xml| |application/xml| |application/soap+xml| |application/json| |application/cloudevents+json| |application/cloudevents-batch+json|'"
|
||||
|
||||
# Allowed HTTP versions.
|
||||
# Default: HTTP/1.0 HTTP/1.1 HTTP/2 HTTP/2.0
|
||||
# Example for legacy clients: HTTP/0.9 HTTP/1.0 HTTP/1.1 HTTP/2 HTTP/2.0
|
||||
# Note that some web server versions use 'HTTP/2', some 'HTTP/2.0', so
|
||||
# we include both version strings by default.
|
||||
# Uncomment this rule to change the default.
|
||||
#SecAction \
|
||||
# "id:900230,\
|
||||
# phase:1,\
|
||||
# pass,\
|
||||
# t:none,\
|
||||
# nolog,\
|
||||
# setvar:'tx.allowed_http_versions=HTTP/1.0 HTTP/1.1 HTTP/2 HTTP/2.0'"
|
||||
|
||||
# Forbidden file extensions.
|
||||
# Guards against unintended exposure of development/configuration files.
|
||||
# Default: .asa/ .asax/ .ascx/ .backup/ .bak/ .bat/ .cdx/ .cer/ .cfg/ .cmd/ .com/ .config/ .conf/ .cs/ .csproj/ .csr/ .dat/ .db/ .dbf/ .dll/ .dos/ .htr/ .htw/ .ida/ .idc/ .idq/ .inc/ .ini/ .key/ .licx/ .lnk/ .log/ .mdb/ .old/ .pass/ .pdb/ .pol/ .printer/ .pwd/ .rdb/ .resources/ .resx/ .sql/ .swp/ .sys/ .vb/ .vbs/ .vbproj/ .vsdisco/ .webinfo/ .xsd/ .xsx/
|
||||
# Example: .bak/ .config/ .conf/ .db/ .ini/ .log/ .old/ .pass/ .pdb/ .rdb/ .sql/
|
||||
# Note that .axd was removed due to false positives (see PR 1925).
|
||||
#
|
||||
# To additionally guard against configuration/install archive files from being
|
||||
# accidentally exposed, common archive file extensions can be added to the
|
||||
# restricted extensions list. An example list of common archive file extensions
|
||||
# is presented below:
|
||||
# .7z/ .br/ .bz/ .bz2/ .cab/ .cpio/ .gz/ .img/ .iso/ .jar/ .rar/ .tar/ .tbz2/ .tgz/ .txz/ .xz/ .zip/ .zst/
|
||||
# (Source: https://en.wikipedia.org/wiki/List_of_archive_formats)
|
||||
#
|
||||
# Uncomment this rule to change the default.
|
||||
#SecAction \
|
||||
# "id:900240,\
|
||||
# phase:1,\
|
||||
# pass,\
|
||||
# t:none,\
|
||||
# nolog,\
|
||||
# setvar:'tx.restricted_extensions=.asa/ .asax/ .ascx/ .backup/ .bak/ .bat/ .cdx/ .cer/ .cfg/ .cmd/ .com/ .config/ .conf/ .cs/ .csproj/ .csr/ .dat/ .db/ .dbf/ .dll/ .dos/ .htr/ .htw/ .ida/ .idc/ .idq/ .inc/ .ini/ .key/ .licx/ .lnk/ .log/ .mdb/ .old/ .pass/ .pdb/ .pol/ .printer/ .pwd/ .rdb/ .resources/ .resx/ .sql/ .swp/ .sys/ .vb/ .vbs/ .vbproj/ .vsdisco/ .webinfo/ .xsd/ .xsx/'"
|
||||
|
||||
# Forbidden request headers.
|
||||
# Header names should be lowercase, enclosed by /slashes/ as delimiters.
|
||||
# Default: /accept-charset/ /content-encoding/ /proxy/ /lock-token/ /content-range/ /if/
|
||||
#
|
||||
# Note: Accept-Charset is a deprecated header that should not be used by clients and
|
||||
# ignored by servers. It can be used for a response WAF bypass, by asking for a charset
|
||||
# that the WAF cannot decode.
|
||||
# Reference: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Charset
|
||||
#
|
||||
# Note: Content-Encoding is used to list any encodings that have been applied to the
|
||||
# original payload. It is only used for compression, which isn't supported by CRS by
|
||||
# default since it blocks newlines and null bytes inside the request body. Most
|
||||
# compression algorithms require at least null bytes per RFC. Blocking it shouldn't
|
||||
# break anything and increases security since ModSecurity is incapable of properly
|
||||
# scanning compressed request bodies.
|
||||
#
|
||||
# Note: Blocking Proxy header prevents 'httpoxy' vulnerability: https://httpoxy.org
|
||||
#
|
||||
# Note: Blocking the x-http-method-override,x-http-method and x-method-override headers
|
||||
# prevents attacks as described here: https://www.sidechannel.blog/en/http-method-override-what-it-is-and-how-a-pentester-can-use-it
|
||||
#
|
||||
# Uncomment this rule to change the default.
|
||||
#SecAction \
|
||||
# "id:900250,\
|
||||
# phase:1,\
|
||||
# pass,\
|
||||
# t:none,\
|
||||
# nolog,\
|
||||
# setvar:'tx.restricted_headers=/accept-charset/ /content-encoding/ /proxy/ /lock-token/ /content-range/ /if/ /x-http-method-override/ /x-http-method/ /x-method-override/'"
|
||||
|
||||
# Content-Types charsets that a client is allowed to send in a request.
|
||||
# The content-types are enclosed by |pipes| as delimiters to guarantee exact matches.
|
||||
# Default: |utf-8| |iso-8859-1| |iso-8859-15| |windows-1252|
|
||||
# Uncomment this rule to change the default.
|
||||
#SecAction \
|
||||
# "id:900280,\
|
||||
# phase:1,\
|
||||
# pass,\
|
||||
# t:none,\
|
||||
# nolog,\
|
||||
# setvar:'tx.allowed_request_content_type_charset=|utf-8| |iso-8859-1| |iso-8859-15| |windows-1252|'"
|
||||
|
||||
#
|
||||
# -- [[ HTTP Argument/Upload Limits ]] -----------------------------------------
|
||||
#
|
||||
# Here you can define optional limits on HTTP get/post parameters and uploads.
|
||||
# This can help to prevent application specific DoS attacks.
|
||||
#
|
||||
# These values are checked in REQUEST-920-PROTOCOL-ENFORCEMENT.conf.
|
||||
# Beware of blocking legitimate traffic when enabling these limits.
|
||||
#
|
||||
|
||||
# Block request if number of arguments is too high
|
||||
# Default: unlimited
|
||||
# Example: 255
|
||||
# Uncomment this rule to set a limit.
|
||||
#SecAction \
|
||||
# "id:900300,\
|
||||
# phase:1,\
|
||||
# pass,\
|
||||
# t:none,\
|
||||
# nolog,\
|
||||
# setvar:tx.max_num_args=255"
|
||||
|
||||
# Block request if the length of any argument name is too high
|
||||
# Default: unlimited
|
||||
# Example: 100
|
||||
# Uncomment this rule to set a limit.
|
||||
#SecAction \
|
||||
# "id:900310,\
|
||||
# phase:1,\
|
||||
# pass,\
|
||||
# t:none,\
|
||||
# nolog,\
|
||||
# setvar:tx.arg_name_length=100"
|
||||
|
||||
# Block request if the length of any argument value is too high
|
||||
# Default: unlimited
|
||||
# Example: 400
|
||||
# Uncomment this rule to set a limit.
|
||||
#SecAction \
|
||||
# "id:900320,\
|
||||
# phase:1,\
|
||||
# pass,\
|
||||
# t:none,\
|
||||
# nolog,\
|
||||
# setvar:tx.arg_length=400"
|
||||
|
||||
# Block request if the total length of all combined arguments is too high
|
||||
# Default: unlimited
|
||||
# Example: 64000
|
||||
# Uncomment this rule to set a limit.
|
||||
#SecAction \
|
||||
# "id:900330,\
|
||||
# phase:1,\
|
||||
# pass,\
|
||||
# t:none,\
|
||||
# nolog,\
|
||||
# setvar:tx.total_arg_length=64000"
|
||||
|
||||
# Block request if the file size of any individual uploaded file is too high
|
||||
# Default: unlimited
|
||||
# Example: 1048576
|
||||
# Uncomment this rule to set a limit.
|
||||
#SecAction \
|
||||
# "id:900340,\
|
||||
# phase:1,\
|
||||
# pass,\
|
||||
# t:none,\
|
||||
# nolog,\
|
||||
# setvar:tx.max_file_size=1048576"
|
||||
|
||||
# Block request if the total size of all combined uploaded files is too high
|
||||
# Default: unlimited
|
||||
# Example: 1048576
|
||||
# Uncomment this rule to set a limit.
|
||||
#SecAction \
|
||||
# "id:900350,\
|
||||
# phase:1,\
|
||||
# pass,\
|
||||
# t:none,\
|
||||
# nolog,\
|
||||
# setvar:tx.combined_file_sizes=1048576"
|
||||
|
||||
|
||||
#
|
||||
# -- [[ Easing In / Sampling Percentage ]] -------------------------------------
|
||||
#
|
||||
# Adding the Core Rule Set to an existing productive site can lead to false
|
||||
# positives, unexpected performance issues and other undesired side effects.
|
||||
#
|
||||
# It can be beneficial to test the water first by enabling the CRS for a
|
||||
# limited number of requests only and then, when you have solved the issues (if
|
||||
# any) and you have confidence in the setup, to raise the ratio of requests
|
||||
# being sent into the ruleset.
|
||||
#
|
||||
# Adjust the percentage of requests that are funnelled into the Core Rules by
|
||||
# setting TX.sampling_percentage below. The default is 100, meaning that every
|
||||
# request gets checked by the CRS. The selection of requests, which are going
|
||||
# to be checked, is based on a pseudo random number generated by ModSecurity.
|
||||
#
|
||||
# If a request is allowed to pass without being checked by the CRS, there is no
|
||||
# entry in the audit log (for performance reasons), but an error log entry is
|
||||
# written. If you want to disable the error log entry, then issue the
|
||||
# following directive somewhere after the inclusion of the CRS
|
||||
# (E.g., RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf).
|
||||
#
|
||||
#SecRuleUpdateActionById 901450 "nolog"
|
||||
#
|
||||
# ATTENTION: If this TX.sampling_percentage is below 100, then some of the
|
||||
# requests will bypass the Core Rules completely and you lose the ability to
|
||||
# protect your service with ModSecurity.
|
||||
#
|
||||
# Uncomment this rule to enable this feature:
|
||||
#
|
||||
#SecAction \
|
||||
# "id:900400,\
|
||||
# phase:1,\
|
||||
# pass,\
|
||||
# nolog,\
|
||||
# setvar:tx.sampling_percentage=100"
|
||||
|
||||
|
||||
|
||||
#
|
||||
# -- [[ Check UTF-8 encoding ]] ------------------------------------------------
|
||||
#
|
||||
# The CRS can optionally check request contents for invalid UTF-8 encoding.
|
||||
# We only want to apply this check if UTF-8 encoding is actually used by the
|
||||
# site; otherwise it will result in false positives.
|
||||
#
|
||||
# Uncomment this rule to use this feature:
|
||||
#
|
||||
#SecAction \
|
||||
# "id:900950,\
|
||||
# phase:1,\
|
||||
# pass,\
|
||||
# t:none,\
|
||||
# nolog,\
|
||||
# setvar:tx.crs_validate_utf8_encoding=1"
|
||||
|
||||
|
||||
#
|
||||
# -- [[ Collection timeout ]] --------------------------------------------------
|
||||
#
|
||||
# Set the SecCollectionTimeout directive from the ModSecurity default (1 hour)
|
||||
# to a lower setting which is appropriate to most sites.
|
||||
# This increases performance by cleaning out stale collection (block) entries.
|
||||
#
|
||||
# This value should be greater than or equal to any block durations or timeouts
|
||||
# set by plugins that make use of ModSecurity's persistent collections (e.g. the
|
||||
# DoS protection and IP reputation plugins).
|
||||
#
|
||||
# Ref: https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual-(v2.x)#SecCollectionTimeout
|
||||
|
||||
# Please keep this directive uncommented.
|
||||
# Default: 600 (10 minutes)
|
||||
SecCollectionTimeout 600
|
||||
|
||||
|
||||
#
|
||||
# -- [[ End of setup ]] --------------------------------------------------------
|
||||
#
|
||||
# The CRS checks the tx.crs_setup_version variable to ensure that the setup
|
||||
# has been loaded. If you are not planning to use this setup template,
|
||||
# you must manually set the tx.crs_setup_version variable before including
|
||||
# the CRS rules/* files.
|
||||
#
|
||||
# The variable is a numerical representation of the CRS version number.
|
||||
# E.g., v3.0.0 is represented as 300.
|
||||
#
|
||||
SecAction \
|
||||
"id:900990,\
|
||||
phase:1,\
|
||||
pass,\
|
||||
t:none,\
|
||||
nolog,\
|
||||
setvar:tx.crs_setup_version=400"
|
||||
@@ -0,0 +1,727 @@
|
||||
# ------------------------------------------------------------------------
|
||||
# OWASP ModSecurity Core Rule Set ver.4.0.0-rc1
|
||||
# Copyright (c) 2006-2020 Trustwave and contributors. All rights reserved.
|
||||
# Copyright (c) 2021-2022 Core Rule Set project. All rights reserved.
|
||||
#
|
||||
# The OWASP ModSecurity Core Rule Set is distributed under
|
||||
# Apache Software License (ASL) version 2
|
||||
# Please see the enclosed LICENSE file for full details.
|
||||
# ------------------------------------------------------------------------
|
||||
|
||||
|
||||
#
|
||||
# -- [[ Introduction ]] --------------------------------------------------------
|
||||
#
|
||||
# The OWASP ModSecurity Core Rule Set (CRS) is a set of generic attack
|
||||
# detection rules that provide a base level of protection for any web
|
||||
# application. They are written for the open source, cross-platform
|
||||
# ModSecurity Web Application Firewall.
|
||||
#
|
||||
# See also:
|
||||
# https://coreruleset.org/
|
||||
# https://github.com/coreruleset/coreruleset
|
||||
# https://owasp.org/www-project-modsecurity-core-rule-set/
|
||||
#
|
||||
|
||||
|
||||
#
|
||||
# -- [[ System Requirements ]] -------------------------------------------------
|
||||
#
|
||||
# CRS requires ModSecurity version 2.8.0 or above.
|
||||
# We recommend to always use the newest ModSecurity version.
|
||||
#
|
||||
# The configuration directives/settings in this file are used to control
|
||||
# the OWASP ModSecurity CRS. These settings do **NOT** configure the main
|
||||
# ModSecurity settings (modsecurity.conf) such as SecRuleEngine,
|
||||
# SecRequestBodyAccess, SecAuditEngine, SecDebugLog, and XML processing.
|
||||
#
|
||||
# The CRS assumes that modsecurity.conf has been loaded. It is bundled with
|
||||
# ModSecurity. If you don't have it, you can get it from:
|
||||
# 2.x: https://raw.githubusercontent.com/SpiderLabs/ModSecurity/v2/master/modsecurity.conf-recommended
|
||||
# 3.x: https://raw.githubusercontent.com/SpiderLabs/ModSecurity/v3/master/modsecurity.conf-recommended
|
||||
#
|
||||
# The order of file inclusion in your webserver configuration should always be:
|
||||
# 1. modsecurity.conf
|
||||
# 2. crs-setup.conf (this file)
|
||||
# 3. rules/*.conf (the CRS rule files)
|
||||
#
|
||||
# Please refer to the INSTALL file for detailed installation instructions.
|
||||
#
|
||||
|
||||
|
||||
#
|
||||
# -- [[ Mode of Operation: Anomaly Scoring vs. Self-Contained ]] ---------------
|
||||
#
|
||||
# The CRS can run in two modes:
|
||||
#
|
||||
# -- [[ Anomaly Scoring Mode (default) ]] --
|
||||
# In CRS3, anomaly mode is the default and recommended mode, since it gives the
|
||||
# most accurate log information and offers the most flexibility in setting your
|
||||
# blocking policies. It is also called "collaborative detection mode".
|
||||
# In this mode, each matching rule increases an 'anomaly score'.
|
||||
# At the conclusion of the inbound rules, and again at the conclusion of the
|
||||
# outbound rules, the anomaly score is checked, and the blocking evaluation
|
||||
# rules apply a disruptive action, by default returning an error 403.
|
||||
#
|
||||
# -- [[ Self-Contained Mode ]] --
|
||||
# In this mode, rules apply an action instantly. This was the CRS2 default.
|
||||
# It can lower resource usage, at the cost of less flexibility in blocking policy
|
||||
# and less informative audit logs (only the first detected threat is logged).
|
||||
# Rules inherit the disruptive action that you specify (i.e. deny, drop, etc).
|
||||
# The first rule that matches will execute this action. In most cases this will
|
||||
# cause evaluation to stop after the first rule has matched, similar to how many
|
||||
# IDSs function.
|
||||
#
|
||||
# -- [[ Alert Logging Control ]] --
|
||||
# In the mode configuration, you must also adjust the desired logging options.
|
||||
# There are three common options for dealing with logging. By default CRS enables
|
||||
# logging to the webserver error log (or Event viewer) plus detailed logging to
|
||||
# the ModSecurity audit log (configured under SecAuditLog in modsecurity.conf).
|
||||
#
|
||||
# - To log to both error log and ModSecurity audit log file, use: "log,auditlog"
|
||||
# - To log *only* to the ModSecurity audit log file, use: "nolog,auditlog"
|
||||
# - To log *only* to the error log file, use: "log,noauditlog"
|
||||
#
|
||||
# Examples for the various modes follow.
|
||||
# You must leave one of the following options enabled.
|
||||
# Note that you must specify the same line for phase:1 and phase:2.
|
||||
#
|
||||
|
||||
# Default: Anomaly Scoring mode, log to error log, log to ModSecurity audit log
|
||||
# - By default, offending requests are blocked with an error 403 response.
|
||||
# - To change the disruptive action, see RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf.example
|
||||
# and review section 'Changing the Disruptive Action for Anomaly Mode'.
|
||||
# - In Apache, you can use ErrorDocument to show a friendly error page or
|
||||
# perform a redirect: https://httpd.apache.org/docs/2.4/custom-error.html
|
||||
#
|
||||
SecDefaultAction "phase:1,log,auditlog,pass"
|
||||
SecDefaultAction "phase:2,log,auditlog,pass"
|
||||
|
||||
# Example: Anomaly Scoring mode, log only to ModSecurity audit log
|
||||
# - By default, offending requests are blocked with an error 403 response.
|
||||
# - To change the disruptive action, see RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf.example
|
||||
# and review section 'Changing the Disruptive Action for Anomaly Mode'.
|
||||
# - In Apache, you can use ErrorDocument to show a friendly error page or
|
||||
# perform a redirect: https://httpd.apache.org/docs/2.4/custom-error.html
|
||||
#
|
||||
# SecDefaultAction "phase:1,nolog,auditlog,pass"
|
||||
# SecDefaultAction "phase:2,nolog,auditlog,pass"
|
||||
|
||||
# Example: Self-contained mode, return error 403 on blocking
|
||||
# - In this configuration the default disruptive action becomes 'deny'. After a
|
||||
# rule triggers, it will stop processing the request and return an error 403.
|
||||
# - You can also use a different error status, such as 404, 406, et cetera.
|
||||
# - In Apache, you can use ErrorDocument to show a friendly error page or
|
||||
# perform a redirect: https://httpd.apache.org/docs/2.4/custom-error.html
|
||||
#
|
||||
# SecDefaultAction "phase:1,log,auditlog,deny,status:403"
|
||||
# SecDefaultAction "phase:2,log,auditlog,deny,status:403"
|
||||
|
||||
# Example: Self-contained mode, redirect back to homepage on blocking
|
||||
# - In this configuration the 'tag' action includes the Host header data in the
|
||||
# log. This helps to identify which virtual host triggered the rule (if any).
|
||||
# - Note that this might cause redirect loops in some situations; for example
|
||||
# if a Cookie or User-Agent header is blocked, it will also be blocked when
|
||||
# the client subsequently tries to access the homepage. You can also redirect
|
||||
# to another custom URL.
|
||||
# SecDefaultAction "phase:1,log,auditlog,redirect:'http://%{request_headers.host}/',tag:'Host: %{request_headers.host}'"
|
||||
# SecDefaultAction "phase:2,log,auditlog,redirect:'http://%{request_headers.host}/',tag:'Host: %{request_headers.host}'"
|
||||
|
||||
|
||||
#
|
||||
# -- [[ Paranoia Level Initialization ]] ---------------------------------------
|
||||
#
|
||||
# The Paranoia Level (PL) setting allows you to choose the desired level
|
||||
# of rule checks that will add to your anomaly scores.
|
||||
#
|
||||
# With each paranoia level increase, the CRS enables additional rules
|
||||
# giving you a higher level of security. However, higher paranoia levels
|
||||
# also increase the possibility of blocking some legitimate traffic due to
|
||||
# false alarms (also named false positives or FPs). If you use higher
|
||||
# paranoia levels, it is likely that you will need to add some exclusion
|
||||
# rules for certain requests and applications receiving complex input.
|
||||
#
|
||||
# - A paranoia level of 1 is default. In this level, most core rules
|
||||
# are enabled. PL1 is advised for beginners, installations
|
||||
# covering many different sites and applications, and for setups
|
||||
# with standard security requirements.
|
||||
# At PL1 you should face FPs rarely. If you encounter FPs, please
|
||||
# open an issue on the CRS GitHub site and don't forget to attach your
|
||||
# complete Audit Log record for the request with the issue.
|
||||
# - Paranoia level 2 includes many extra rules, for instance enabling
|
||||
# many regexp-based SQL and XSS injection protections, and adding
|
||||
# extra keywords checked for code injections. PL2 is advised
|
||||
# for moderate to experienced users desiring more complete coverage
|
||||
# and for installations with elevated security requirements.
|
||||
# PL2 comes with some FPs which you need to handle.
|
||||
# - Paranoia level 3 enables more rules and keyword lists, and tweaks
|
||||
# limits on special characters used. PL3 is aimed at users experienced
|
||||
# at the handling of FPs and at installations with a high security
|
||||
# requirement.
|
||||
# - Paranoia level 4 further restricts special characters.
|
||||
# The highest level is advised for experienced users protecting
|
||||
# installations with very high security requirements. Running PL4 will
|
||||
# likely produce a very high number of FPs which have to be
|
||||
# treated before the site can go productive.
|
||||
#
|
||||
# All rules will log their PL to the audit log;
|
||||
# example: [tag "paranoia-level/2"]. This allows you to deduct from the
|
||||
# audit log how the WAF behavior is affected by paranoia level.
|
||||
#
|
||||
# It is important to also look into the variable
|
||||
# tx.enforce_bodyproc_urlencoded (Enforce Body Processor URLENCODED)
|
||||
# defined below. Enabling it closes a possible bypass of CRS.
|
||||
#
|
||||
# Uncomment this rule to change the default:
|
||||
#
|
||||
#SecAction \
|
||||
# "id:900000,\
|
||||
# phase:1,\
|
||||
# pass,\
|
||||
# t:none,\
|
||||
# nolog,\
|
||||
# setvar:tx.blocking_paranoia_level=1"
|
||||
|
||||
|
||||
# It is possible to execute rules from a higher paranoia level but not include
|
||||
# them in the anomaly scoring. This allows you to take a well-tuned system on
|
||||
# paranoia level 1 and add rules from paranoia level 2 without having to fear
|
||||
# the new rules would lead to false positives that raise your score above the
|
||||
# threshold.
|
||||
# This optional feature is enabled by uncommenting the following rule and
|
||||
# setting the tx.detection_paranoia_level.
|
||||
# Technically, rules up to the level defined in tx.detection_paranoia_level
|
||||
# will be executed, but only the rules up to tx.blocking_paranoia_level affect the
|
||||
# anomaly scores.
|
||||
# By default, tx.detection_paranoia_level is set to tx.blocking_paranoia_level.
|
||||
# tx.detection_paranoia_level must not be lower than tx.blocking_paranoia_level.
|
||||
#
|
||||
# Please notice that setting tx.detection_paranoia_level to a higher paranoia
|
||||
# level results in a performance impact that is equally high as setting
|
||||
# tx.blocking_paranoia_level to said level.
|
||||
#
|
||||
#SecAction \
|
||||
# "id:900001,\
|
||||
# phase:1,\
|
||||
# pass,\
|
||||
# t:none,\
|
||||
# nolog,\
|
||||
# setvar:tx.detection_paranoia_level=1"
|
||||
|
||||
|
||||
#
|
||||
# -- [[ Enforce Body Processor URLENCODED ]] -----------------------------------
|
||||
#
|
||||
# ModSecurity selects the body processor based on the Content-Type request
|
||||
# header. But clients are not always setting the Content-Type header for their
|
||||
# request body payloads. This will leave ModSecurity with limited vision into
|
||||
# the payload. The variable tx.enforce_bodyproc_urlencoded lets you force the
|
||||
# URLENCODED body processor in these situations. This is off by default, as it
|
||||
# implies a change of the behaviour of ModSecurity beyond CRS (the body
|
||||
# processor applies to all rules, not only CRS) and because it may lead to
|
||||
# false positives already on paranoia level 1. However, enabling this variable
|
||||
# closes a possible bypass of CRS so it should be considered.
|
||||
#
|
||||
# Uncomment this rule to change the default:
|
||||
#
|
||||
#SecAction \
|
||||
# "id:900010,\
|
||||
# phase:1,\
|
||||
# pass,\
|
||||
# t:none,\
|
||||
# nolog,\
|
||||
# setvar:tx.enforce_bodyproc_urlencoded=1"
|
||||
|
||||
|
||||
#
|
||||
# -- [[ Anomaly Scoring Mode Severity Levels ]] --------------------------------
|
||||
#
|
||||
# Each rule in the CRS has an associated severity level.
|
||||
# These are the default scoring points for each severity level.
|
||||
# These settings will be used to increment the anomaly score if a rule matches.
|
||||
# You may adjust these points to your liking, but this is usually not needed.
|
||||
#
|
||||
# - CRITICAL severity: Anomaly Score of 5.
|
||||
# Mostly generated by the application attack rules (93x and 94x files).
|
||||
# - ERROR severity: Anomaly Score of 4.
|
||||
# Generated mostly from outbound leakage rules (95x files).
|
||||
# - WARNING severity: Anomaly Score of 3.
|
||||
# Generated mostly by malicious client rules (91x files).
|
||||
# - NOTICE severity: Anomaly Score of 2.
|
||||
# Generated mostly by the protocol rules (92x files).
|
||||
#
|
||||
# In anomaly mode, these scores are cumulative.
|
||||
# So it's possible for a request to hit multiple rules.
|
||||
#
|
||||
# (Note: In this file, we use 'phase:1' to set CRS configuration variables.
|
||||
# In general, 'phase:request' is used. However, we want to make absolutely sure
|
||||
# that all configuration variables are set before the CRS rules are processed.)
|
||||
#
|
||||
#SecAction \
|
||||
# "id:900100,\
|
||||
# phase:1,\
|
||||
# pass,\
|
||||
# t:none,\
|
||||
# nolog,\
|
||||
# setvar:tx.critical_anomaly_score=5,\
|
||||
# setvar:tx.error_anomaly_score=4,\
|
||||
# setvar:tx.warning_anomaly_score=3,\
|
||||
# setvar:tx.notice_anomaly_score=2"
|
||||
|
||||
|
||||
#
|
||||
# -- [[ Anomaly Scoring Mode Blocking Threshold Levels ]] ----------------------
|
||||
#
|
||||
# Here, you can specify at which cumulative anomaly score an inbound request,
|
||||
# or outbound response, gets blocked.
|
||||
#
|
||||
# Most detected inbound threats will give a critical score of 5.
|
||||
# Smaller violations, like violations of protocol/standards, carry lower scores.
|
||||
#
|
||||
# [ At default value ]
|
||||
# If you keep the blocking thresholds at the defaults, the CRS will work
|
||||
# similarly to previous CRS versions: a single critical rule match will cause
|
||||
# the request to be blocked and logged.
|
||||
#
|
||||
# [ Using higher values ]
|
||||
# If you want to make the CRS less sensitive, you can increase the blocking
|
||||
# thresholds, for instance to 7 (which would require multiple rule matches
|
||||
# before blocking) or 10 (which would require at least two critical alerts - or
|
||||
# a combination of many lesser alerts), or even higher. However, increasing the
|
||||
# thresholds might cause some attacks to bypass the CRS rules or your policies.
|
||||
#
|
||||
# [ New deployment strategy: Starting high and decreasing ]
|
||||
# It is a common practice to start a fresh CRS installation with elevated
|
||||
# anomaly scoring thresholds (>100) and then lower the limits as your
|
||||
# confidence in the setup grows. You may also look into the Sampling
|
||||
# Percentage section below for a different strategy to ease into a new
|
||||
# CRS installation.
|
||||
#
|
||||
# [ Anomaly Threshold / Paranoia Level Quadrant ]
|
||||
#
|
||||
# High Anomaly Limit | High Anomaly Limit
|
||||
# Low Paranoia Level | High Paranoia Level
|
||||
# -> Fresh Site | -> Experimental Site
|
||||
# ------------------------------------------------------
|
||||
# Low Anomaly Limit | Low Anomaly Limit
|
||||
# Low Paranoia Level | High Paranoia Level
|
||||
# -> Standard Site | -> High Security Site
|
||||
#
|
||||
# Uncomment this rule to change the defaults:
|
||||
#
|
||||
#SecAction \
|
||||
# "id:900110,\
|
||||
# phase:1,\
|
||||
# pass,\
|
||||
# t:none,\
|
||||
# nolog,\
|
||||
# setvar:tx.inbound_anomaly_score_threshold=5,\
|
||||
# setvar:tx.outbound_anomaly_score_threshold=4"
|
||||
|
||||
|
||||
#
|
||||
# -- [[ Application Specific Rule Exclusions ]] --------------------------------
|
||||
#
|
||||
# CRS 3.x contained exclusion packages to tweak the CRS for use with common
|
||||
# web applications, lowering the number of false positives.
|
||||
#
|
||||
# In CRS 4, these are no longer part of the CRS itself, but they are available
|
||||
# as "CRS plugins". Some plugins improve support for web applications, and others
|
||||
# may bring new functionality. Plugins are not installed by default, but can be
|
||||
# downloaded from the plugin registry:
|
||||
# https://github.com/coreruleset/plugin-registry
|
||||
#
|
||||
# For detailed information about using and installing plugins, please see:
|
||||
# https://coreruleset.org/docs/concepts/plugins/
|
||||
|
||||
|
||||
#
|
||||
# -- [[ Anomaly Score Reporting Level ]] ---------------------------------------
|
||||
#
|
||||
# When a request is blocked due to the anomaly score meeting or exceeding the
|
||||
# anomaly threshold then the blocking rule will also report the anomaly score.
|
||||
# This applies to the separate inbound and outbound anomaly scores.
|
||||
#
|
||||
# In phase 5, there are additional rules that can perform additional reporting
|
||||
# of anomaly scores with a verbosity that depends on the reporting level defined
|
||||
# below.
|
||||
#
|
||||
# By setting the reporting level you control whether you want additional
|
||||
# reporting beyond the blocking rule or not and, if yes, which requests should
|
||||
# be covered. The higher the reporting level, the more verbose the reporting is.
|
||||
#
|
||||
# There are 6 reporting levels:
|
||||
#
|
||||
# 0 - Reporting disabled
|
||||
# 1 - Reporting for requests with a blocking anomaly score >= a threshold
|
||||
# 2 - Reporting for requests with a detection anomaly score >= a threshold
|
||||
# 3 - Reporting for requests with a blocking anomaly score greater than 0
|
||||
# 4 - Reporting for requests with a detection anomaly score greater than 0
|
||||
# 5 - Reporting for all requests
|
||||
#
|
||||
# Note: Reporting levels 1 and 2 make it possible to differentiate between
|
||||
# requests that are blocked and requests that are *not* blocked but would have
|
||||
# been blocked if the blocking PL was equal to detection PL. This may be useful
|
||||
# for certain FP tuning methodologies, for example moving to a higher PL.
|
||||
#
|
||||
# A value of 5 can be useful on platforms where you are interested in logging
|
||||
# non-scoring requests, yet it is not possible to report this information in
|
||||
# the request/access log. This applies to Nginx, for example.
|
||||
#
|
||||
#SecAction \
|
||||
# "id:900115,\
|
||||
# phase:1,\
|
||||
# pass,\
|
||||
# t:none,\
|
||||
# nolog,\
|
||||
# setvar:tx.reporting_level=4"
|
||||
|
||||
|
||||
#
|
||||
# -- [[ Early Anomaly Scoring Mode Blocking ]] ------------------------------
|
||||
#
|
||||
# The anomaly scores for the request and the responses are generally summed up
|
||||
# and evaluated at the end of phase:2 and at the end of phase:4 respectively.
|
||||
# However, it is possible to enable an early evaluation of these anomaly scores
|
||||
# at the end of phase:1 and at the end of phase:3.
|
||||
#
|
||||
# If a request (or a response) hits the anomaly threshold in this early
|
||||
# evaluation, then blocking happens immediately (if blocking is enabled) and
|
||||
# the phase 2 (and phase 4 respectively) will no longer be executed.
|
||||
#
|
||||
# Enable the rule 900120 that sets the variable tx.early_blocking to 1 in order
|
||||
# to enable early blocking. The variable tx.early_blocking is set to 0 by
|
||||
# default. Early blocking is thus disabled by default.
|
||||
#
|
||||
# Please note that early blocking will hide potential alerts from you. This
|
||||
# means that a payload that would appear in an alert in phase 2 (or phase 4)
|
||||
# does not get evaluated if the request is being blocked early. So when you
|
||||
# disabled early blocking again at some point in the future, then new alerts
|
||||
# from phase 2 might pop up.
|
||||
SecAction \
|
||||
"id:900120,\
|
||||
phase:1,\
|
||||
pass,\
|
||||
t:none,\
|
||||
nolog,\
|
||||
setvar:tx.early_blocking=1"
|
||||
|
||||
|
||||
#
|
||||
# -- [[ HTTP Policy Settings ]] ------------------------------------------------
|
||||
#
|
||||
# This section defines your policies for the HTTP protocol, such as:
|
||||
# - allowed HTTP versions, HTTP methods, allowed request Content-Types
|
||||
# - forbidden file extensions (e.g. .bak, .sql) and request headers (e.g. Proxy)
|
||||
#
|
||||
# These variables are used in the following rule files:
|
||||
# - REQUEST-911-METHOD-ENFORCEMENT.conf
|
||||
# - REQUEST-920-PROTOCOL-ENFORCEMENT.conf
|
||||
|
||||
# HTTP methods that a client is allowed to use.
|
||||
# Default: GET HEAD POST OPTIONS
|
||||
# Example: for RESTful APIs, add the following methods: PUT PATCH DELETE
|
||||
# Example: for WebDAV, add the following methods: CHECKOUT COPY DELETE LOCK
|
||||
# MERGE MKACTIVITY MKCOL MOVE PROPFIND PROPPATCH PUT UNLOCK
|
||||
# Uncomment this rule to change the default.
|
||||
#SecAction \
|
||||
# "id:900200,\
|
||||
# phase:1,\
|
||||
# pass,\
|
||||
# t:none,\
|
||||
# nolog,\
|
||||
# setvar:'tx.allowed_methods=GET HEAD POST OPTIONS'"
|
||||
|
||||
# Content-Types that a client is allowed to send in a request.
|
||||
# Default: |application/x-www-form-urlencoded| |multipart/form-data| |multipart/related|
|
||||
# |text/xml| |application/xml| |application/soap+xml| |application/json|
|
||||
# |application/cloudevents+json| |application/cloudevents-batch+json|
|
||||
#
|
||||
# Please note, that the rule where CRS uses this variable (920420) evaluates it with operator
|
||||
# `@within`, which is case sensitive, but uses t:lowercase. You must add your whole custom
|
||||
# Content-Type with lowercase.
|
||||
#
|
||||
# Bypass Warning: some applications may not rely on the content-type request header in order
|
||||
# to parse the request body. This could make an attacker able to send malicious URLENCODED/JSON/XML
|
||||
# payloads without being detected by the WAF. Allowing request content-type that doesn't activate any
|
||||
# body processor (for example: "text/plain", "application/x-amf", "application/octet-stream", etc..)
|
||||
# could lead to a WAF bypass. For example, a malicious JSON payload submitted with a "text/plain"
|
||||
# content type may still be interpreted as JSON by a backend application but would not trigger the
|
||||
# JSON body parser at the WAF, leading to a bypass.
|
||||
#
|
||||
# To prevent blocking request with not allowed content-type by default, you can create an exclusion
|
||||
# rule that removes rule 920420. For example:
|
||||
#SecRule REQUEST_HEADERS:Content-Type "@rx ^text/plain" \
|
||||
# "id:1234,\
|
||||
# phase:1,\
|
||||
# pass,\
|
||||
# t:none,\
|
||||
# nolog,\
|
||||
# ctl:ruleRemoveById=920420,\
|
||||
# chain"
|
||||
# SecRule REQUEST_URI "@rx ^/foo/bar" "t:none"
|
||||
#
|
||||
# Uncomment this rule to change the default.
|
||||
#
|
||||
#SecAction \
|
||||
# "id:900220,\
|
||||
# phase:1,\
|
||||
# pass,\
|
||||
# t:none,\
|
||||
# nolog,\
|
||||
# setvar:'tx.allowed_request_content_type=|application/x-www-form-urlencoded| |multipart/form-data| |multipart/related| |text/xml| |application/xml| |application/soap+xml| |application/json| |application/cloudevents+json| |application/cloudevents-batch+json|'"
|
||||
|
||||
# Allowed HTTP versions.
|
||||
# Default: HTTP/1.0 HTTP/1.1 HTTP/2 HTTP/2.0
|
||||
# Example for legacy clients: HTTP/0.9 HTTP/1.0 HTTP/1.1 HTTP/2 HTTP/2.0
|
||||
# Note that some web server versions use 'HTTP/2', some 'HTTP/2.0', so
|
||||
# we include both version strings by default.
|
||||
# Uncomment this rule to change the default.
|
||||
#SecAction \
|
||||
# "id:900230,\
|
||||
# phase:1,\
|
||||
# pass,\
|
||||
# t:none,\
|
||||
# nolog,\
|
||||
# setvar:'tx.allowed_http_versions=HTTP/1.0 HTTP/1.1 HTTP/2 HTTP/2.0'"
|
||||
|
||||
# Forbidden file extensions.
|
||||
# Guards against unintended exposure of development/configuration files.
|
||||
# Default: .asa/ .asax/ .ascx/ .backup/ .bak/ .bat/ .cdx/ .cer/ .cfg/ .cmd/ .com/ .config/ .conf/ .cs/ .csproj/ .csr/ .dat/ .db/ .dbf/ .dll/ .dos/ .htr/ .htw/ .ida/ .idc/ .idq/ .inc/ .ini/ .key/ .licx/ .lnk/ .log/ .mdb/ .old/ .pass/ .pdb/ .pol/ .printer/ .pwd/ .rdb/ .resources/ .resx/ .sql/ .swp/ .sys/ .vb/ .vbs/ .vbproj/ .vsdisco/ .webinfo/ .xsd/ .xsx/
|
||||
# Example: .bak/ .config/ .conf/ .db/ .ini/ .log/ .old/ .pass/ .pdb/ .rdb/ .sql/
|
||||
# Note that .axd was removed due to false positives (see PR 1925).
|
||||
#
|
||||
# To additionally guard against configuration/install archive files from being
|
||||
# accidentally exposed, common archive file extensions can be added to the
|
||||
# restricted extensions list. An example list of common archive file extensions
|
||||
# is presented below:
|
||||
# .7z/ .br/ .bz/ .bz2/ .cab/ .cpio/ .gz/ .img/ .iso/ .jar/ .rar/ .tar/ .tbz2/ .tgz/ .txz/ .xz/ .zip/ .zst/
|
||||
# (Source: https://en.wikipedia.org/wiki/List_of_archive_formats)
|
||||
#
|
||||
# Uncomment this rule to change the default.
|
||||
#SecAction \
|
||||
# "id:900240,\
|
||||
# phase:1,\
|
||||
# pass,\
|
||||
# t:none,\
|
||||
# nolog,\
|
||||
# setvar:'tx.restricted_extensions=.asa/ .asax/ .ascx/ .backup/ .bak/ .bat/ .cdx/ .cer/ .cfg/ .cmd/ .com/ .config/ .conf/ .cs/ .csproj/ .csr/ .dat/ .db/ .dbf/ .dll/ .dos/ .htr/ .htw/ .ida/ .idc/ .idq/ .inc/ .ini/ .key/ .licx/ .lnk/ .log/ .mdb/ .old/ .pass/ .pdb/ .pol/ .printer/ .pwd/ .rdb/ .resources/ .resx/ .sql/ .swp/ .sys/ .vb/ .vbs/ .vbproj/ .vsdisco/ .webinfo/ .xsd/ .xsx/'"
|
||||
|
||||
# Forbidden request headers.
|
||||
# Header names should be lowercase, enclosed by /slashes/ as delimiters.
|
||||
# Default: /accept-charset/ /content-encoding/ /proxy/ /lock-token/ /content-range/ /if/
|
||||
#
|
||||
# Note: Accept-Charset is a deprecated header that should not be used by clients and
|
||||
# ignored by servers. It can be used for a response WAF bypass, by asking for a charset
|
||||
# that the WAF cannot decode.
|
||||
# Reference: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Charset
|
||||
#
|
||||
# Note: Content-Encoding is used to list any encodings that have been applied to the
|
||||
# original payload. It is only used for compression, which isn't supported by CRS by
|
||||
# default since it blocks newlines and null bytes inside the request body. Most
|
||||
# compression algorithms require at least null bytes per RFC. Blocking it shouldn't
|
||||
# break anything and increases security since ModSecurity is incapable of properly
|
||||
# scanning compressed request bodies.
|
||||
#
|
||||
# Note: Blocking Proxy header prevents 'httpoxy' vulnerability: https://httpoxy.org
|
||||
#
|
||||
# Note: Blocking the x-http-method-override,x-http-method and x-method-override headers
|
||||
# prevents attacks as described here: https://www.sidechannel.blog/en/http-method-override-what-it-is-and-how-a-pentester-can-use-it
|
||||
#
|
||||
# Uncomment this rule to change the default.
|
||||
#SecAction \
|
||||
# "id:900250,\
|
||||
# phase:1,\
|
||||
# pass,\
|
||||
# t:none,\
|
||||
# nolog,\
|
||||
# setvar:'tx.restricted_headers=/accept-charset/ /content-encoding/ /proxy/ /lock-token/ /content-range/ /if/ /x-http-method-override/ /x-http-method/ /x-method-override/'"
|
||||
|
||||
# Content-Types charsets that a client is allowed to send in a request.
|
||||
# The content-types are enclosed by |pipes| as delimiters to guarantee exact matches.
|
||||
# Default: |utf-8| |iso-8859-1| |iso-8859-15| |windows-1252|
|
||||
# Uncomment this rule to change the default.
|
||||
#SecAction \
|
||||
# "id:900280,\
|
||||
# phase:1,\
|
||||
# pass,\
|
||||
# t:none,\
|
||||
# nolog,\
|
||||
# setvar:'tx.allowed_request_content_type_charset=|utf-8| |iso-8859-1| |iso-8859-15| |windows-1252|'"
|
||||
|
||||
#
|
||||
# -- [[ HTTP Argument/Upload Limits ]] -----------------------------------------
|
||||
#
|
||||
# Here you can define optional limits on HTTP get/post parameters and uploads.
|
||||
# This can help to prevent application specific DoS attacks.
|
||||
#
|
||||
# These values are checked in REQUEST-920-PROTOCOL-ENFORCEMENT.conf.
|
||||
# Beware of blocking legitimate traffic when enabling these limits.
|
||||
#
|
||||
|
||||
# Block request if number of arguments is too high
|
||||
# Default: unlimited
|
||||
# Example: 255
|
||||
# Uncomment this rule to set a limit.
|
||||
#SecAction \
|
||||
# "id:900300,\
|
||||
# phase:1,\
|
||||
# pass,\
|
||||
# t:none,\
|
||||
# nolog,\
|
||||
# setvar:tx.max_num_args=255"
|
||||
|
||||
# Block request if the length of any argument name is too high
|
||||
# Default: unlimited
|
||||
# Example: 100
|
||||
# Uncomment this rule to set a limit.
|
||||
#SecAction \
|
||||
# "id:900310,\
|
||||
# phase:1,\
|
||||
# pass,\
|
||||
# t:none,\
|
||||
# nolog,\
|
||||
# setvar:tx.arg_name_length=100"
|
||||
|
||||
# Block request if the length of any argument value is too high
|
||||
# Default: unlimited
|
||||
# Example: 400
|
||||
# Uncomment this rule to set a limit.
|
||||
#SecAction \
|
||||
# "id:900320,\
|
||||
# phase:1,\
|
||||
# pass,\
|
||||
# t:none,\
|
||||
# nolog,\
|
||||
# setvar:tx.arg_length=400"
|
||||
|
||||
# Block request if the total length of all combined arguments is too high
|
||||
# Default: unlimited
|
||||
# Example: 64000
|
||||
# Uncomment this rule to set a limit.
|
||||
#SecAction \
|
||||
# "id:900330,\
|
||||
# phase:1,\
|
||||
# pass,\
|
||||
# t:none,\
|
||||
# nolog,\
|
||||
# setvar:tx.total_arg_length=64000"
|
||||
|
||||
# Block request if the file size of any individual uploaded file is too high
|
||||
# Default: unlimited
|
||||
# Example: 1048576
|
||||
# Uncomment this rule to set a limit.
|
||||
#SecAction \
|
||||
# "id:900340,\
|
||||
# phase:1,\
|
||||
# pass,\
|
||||
# t:none,\
|
||||
# nolog,\
|
||||
# setvar:tx.max_file_size=1048576"
|
||||
|
||||
# Block request if the total size of all combined uploaded files is too high
|
||||
# Default: unlimited
|
||||
# Example: 1048576
|
||||
# Uncomment this rule to set a limit.
|
||||
#SecAction \
|
||||
# "id:900350,\
|
||||
# phase:1,\
|
||||
# pass,\
|
||||
# t:none,\
|
||||
# nolog,\
|
||||
# setvar:tx.combined_file_sizes=1048576"
|
||||
|
||||
|
||||
#
|
||||
# -- [[ Easing In / Sampling Percentage ]] -------------------------------------
|
||||
#
|
||||
# Adding the Core Rule Set to an existing productive site can lead to false
|
||||
# positives, unexpected performance issues and other undesired side effects.
|
||||
#
|
||||
# It can be beneficial to test the water first by enabling the CRS for a
|
||||
# limited number of requests only and then, when you have solved the issues (if
|
||||
# any) and you have confidence in the setup, to raise the ratio of requests
|
||||
# being sent into the ruleset.
|
||||
#
|
||||
# Adjust the percentage of requests that are funnelled into the Core Rules by
|
||||
# setting TX.sampling_percentage below. The default is 100, meaning that every
|
||||
# request gets checked by the CRS. The selection of requests, which are going
|
||||
# to be checked, is based on a pseudo random number generated by ModSecurity.
|
||||
#
|
||||
# If a request is allowed to pass without being checked by the CRS, there is no
|
||||
# entry in the audit log (for performance reasons), but an error log entry is
|
||||
# written. If you want to disable the error log entry, then issue the
|
||||
# following directive somewhere after the inclusion of the CRS
|
||||
# (E.g., RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf).
|
||||
#
|
||||
#SecRuleUpdateActionById 901450 "nolog"
|
||||
#
|
||||
# ATTENTION: If this TX.sampling_percentage is below 100, then some of the
|
||||
# requests will bypass the Core Rules completely and you lose the ability to
|
||||
# protect your service with ModSecurity.
|
||||
#
|
||||
# Uncomment this rule to enable this feature:
|
||||
#
|
||||
#SecAction \
|
||||
# "id:900400,\
|
||||
# phase:1,\
|
||||
# pass,\
|
||||
# nolog,\
|
||||
# setvar:tx.sampling_percentage=100"
|
||||
|
||||
|
||||
|
||||
#
|
||||
# -- [[ Check UTF-8 encoding ]] ------------------------------------------------
|
||||
#
|
||||
# The CRS can optionally check request contents for invalid UTF-8 encoding.
|
||||
# We only want to apply this check if UTF-8 encoding is actually used by the
|
||||
# site; otherwise it will result in false positives.
|
||||
#
|
||||
# Uncomment this rule to use this feature:
|
||||
#
|
||||
#SecAction \
|
||||
# "id:900950,\
|
||||
# phase:1,\
|
||||
# pass,\
|
||||
# t:none,\
|
||||
# nolog,\
|
||||
# setvar:tx.crs_validate_utf8_encoding=1"
|
||||
|
||||
|
||||
#
|
||||
# -- [[ Collection timeout ]] --------------------------------------------------
|
||||
#
|
||||
# Set the SecCollectionTimeout directive from the ModSecurity default (1 hour)
|
||||
# to a lower setting which is appropriate to most sites.
|
||||
# This increases performance by cleaning out stale collection (block) entries.
|
||||
#
|
||||
# This value should be greater than or equal to any block durations or timeouts
|
||||
# set by plugins that make use of ModSecurity's persistent collections (e.g. the
|
||||
# DoS protection and IP reputation plugins).
|
||||
#
|
||||
# Ref: https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual-(v2.x)#SecCollectionTimeout
|
||||
|
||||
# Please keep this directive uncommented.
|
||||
# Default: 600 (10 minutes)
|
||||
SecCollectionTimeout 600
|
||||
|
||||
|
||||
#
|
||||
# -- [[ End of setup ]] --------------------------------------------------------
|
||||
#
|
||||
# The CRS checks the tx.crs_setup_version variable to ensure that the setup
|
||||
# has been loaded. If you are not planning to use this setup template,
|
||||
# you must manually set the tx.crs_setup_version variable before including
|
||||
# the CRS rules/* files.
|
||||
#
|
||||
# The variable is a numerical representation of the CRS version number.
|
||||
# E.g., v3.0.0 is represented as 300.
|
||||
#
|
||||
SecAction \
|
||||
"id:900990,\
|
||||
phase:1,\
|
||||
pass,\
|
||||
t:none,\
|
||||
nolog,\
|
||||
setvar:tx.crs_setup_version=400"
|
||||
@@ -0,0 +1,200 @@
|
||||
# ------------------------------------------------------------------------
|
||||
# OWASP ModSecurity Core Rule Set ver.4.0.0-rc1
|
||||
# Copyright (c) 2006-2020 Trustwave and contributors. All rights reserved.
|
||||
# Copyright (c) 2021-2022 Core Rule Set project. All rights reserved.
|
||||
#
|
||||
# The OWASP ModSecurity Core Rule Set is distributed under
|
||||
# Apache Software License (ASL) version 2
|
||||
# Please see the enclosed LICENSE file for full details.
|
||||
# ------------------------------------------------------------------------
|
||||
|
||||
#
|
||||
# The purpose of this file is to hold LOCAL exceptions for your site. The
|
||||
# types of rules that would go into this file are one where you want to
|
||||
# short-circuit inspection and allow certain transactions to pass through
|
||||
# inspection or if you want to alter rules that are applied.
|
||||
#
|
||||
# This file is named REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf.example for a
|
||||
# very specific reason. Files affixed with the .example extension are designed
|
||||
# to contain user created/modified data. The '.example'. extension should be
|
||||
# renamed to end in .conf. The advantage of this is that when OWASP CRS is
|
||||
# updated, the updates will not overwrite a user generated configuration file.
|
||||
#
|
||||
# As a result of this design paradigm users are encouraged NOT to directly
|
||||
# modify rules. Instead they should use this
|
||||
# REQUEST-900-EXCLUSION-RULES-BEFORE-CRS and the
|
||||
# RESPONSE-999-EXCLUSION-RULES-AFTER-CRS file to modify OWASP rules using
|
||||
# methods similar to the examples specified below.
|
||||
#
|
||||
# REQUEST-900-EXCLUSION-RULES-BEFORE-CRS and
|
||||
# RESPONSE-999-EXCLUSION-RULES-AFTER-CRS serve different purposes. ModSecurity
|
||||
# effectively maintains two different context: startup, and per transaction.
|
||||
# As a rule, directives are processed within the startup context. While they
|
||||
# can affect the per transaction context they generally remain fixed during the
|
||||
# execution of ModSecurity.
|
||||
#
|
||||
# As a result if one wanted to disable a rule at bootup the SecRuleRemoveById
|
||||
# directive or one of its siblings would have to be placed AFTER the rule is
|
||||
# listed, otherwise it will not have knowledge of the rules existence (since
|
||||
# these rules are read in at the same time). This means that when using
|
||||
# directives that effect SecRules, these exceptions should be placed AFTER all
|
||||
# the existing rules. This is why RESPONSE-999-EXCLUSION-RULES-AFTER-CRS is
|
||||
# designed such that it loads LAST.
|
||||
#
|
||||
# Conversely, ModSecurity supports several actions that can change the state of
|
||||
# the underlying configuration during the per transaction context, this is when
|
||||
# rules are being processed. Generally, these are accomplished by using the
|
||||
# 'ctl' action. As these are part of a rule, they will be evaluated in the
|
||||
# order rules are applied (by physical location, considering phases). As a
|
||||
# result of this ordering a 'ctl' action should be placed with consideration to
|
||||
# when it will be executed. This is particularly relevant for the 'ctl' options
|
||||
# that involve modifying ID's (such as ruleRemoveById). In these cases it is
|
||||
# important that such rules are placed BEFORE the rule ID they will affect.
|
||||
# Unlike the setup context, by the time we process rules in the per-transaction
|
||||
# context, we are already aware of all the rule ID's. It is by this logic that
|
||||
# we include rules such as this BEFORE all the remaining rules. As a result
|
||||
# REQUEST-900-EXCLUSION-RULES-BEFORE-CRS is designed to load FIRST.
|
||||
#
|
||||
# As a general rule:
|
||||
# ctl:ruleEngine -> place in REQUEST-900-EXCLUSION-RULES-BEFORE-CRS
|
||||
# ctl:ruleRemoveById -> place in REQUEST-900-EXCLUSION-RULES-BEFORE-CRS
|
||||
# ctl:ruleRemoveByMsg -> place in REQUEST-900-EXCLUSION-RULES-BEFORE-CRS
|
||||
# ctl:ruleRemoveByTag -> place in REQUEST-900-EXCLUSION-RULES-BEFORE-CRS
|
||||
# ctl:ruleRemoveTargetById -> place in REQUEST-900-EXCLUSION-RULES-BEFORE-CRS
|
||||
# ctl:ruleRemoveTargetByMsg -> place in REQUEST-900-EXCLUSION-RULES-BEFORE-CRS
|
||||
# ctl:ruleRemoveTargetByTag -> place in REQUEST-900-EXCLUSION-RULES-BEFORE-CRS
|
||||
#
|
||||
# SecRuleRemoveById -> place in RESPONSE-999-EXCLUSION-RULES-AFTER-CRS
|
||||
# SecRuleRemoveByMsg -> place in RESPONSE-999-EXCLUSION-RULES-AFTER-CRS
|
||||
# SecRuleRemoveByTag -> place in RESPONSE-999-EXCLUSION-RULES-AFTER-CRS
|
||||
# SecRuleUpdateActionById -> place in RESPONSE-999-EXCLUSION-RULES-AFTER-CRS
|
||||
# SecRuleUpdateTargetById -> place in RESPONSE-999-EXCLUSION-RULES-AFTER-CRS
|
||||
# SecRuleUpdateTargetByMsg -> place in RESPONSE-999-EXCLUSION-RULES-AFTER-CRS
|
||||
# SecRuleUpdateTargetByTag -> place in RESPONSE-999-EXCLUSION-RULES-AFTER-CRS
|
||||
#
|
||||
#
|
||||
# What follows are a group of examples that show you how to perform rule
|
||||
# exclusions.
|
||||
#
|
||||
#
|
||||
# Example Exclusion Rule: Disable inspection for an authorized client
|
||||
#
|
||||
# This ruleset allows you to control how ModSecurity will handle traffic
|
||||
# originating from Authorized Vulnerability Scanning (AVS) sources. See
|
||||
# related blog post -
|
||||
# https://www.trustwave.com/en-us/resources/blogs/spiderlabs-blog/updated-advanced-topic-of-the-week-handling-authorized-scanning-traffic/
|
||||
#
|
||||
# Allow List ASV network block (no blocking or logging of AVS traffic) Update
|
||||
# IP network block as appropriate for your AVS traffic
|
||||
#
|
||||
# ModSec Rule Exclusion: Disable Rule Engine for known ASV IP
|
||||
# SecRule REMOTE_ADDR "@ipMatch 192.168.1.100" \
|
||||
# "id:1000,\
|
||||
# phase:1,\
|
||||
# pass,\
|
||||
# nolog,\
|
||||
# ctl:ruleEngine=Off"
|
||||
#
|
||||
#
|
||||
# Example Exclusion Rule: Removing a specific ARGS parameter from inspection
|
||||
# for an individual rule
|
||||
#
|
||||
# This rule shows how to conditionally exclude the "password"
|
||||
# parameter for rule 942100 when the REQUEST_URI is /index.php
|
||||
# ModSecurity Rule Exclusion: 942100 SQL Injection Detected via libinjection
|
||||
#
|
||||
# SecRule REQUEST_URI "@beginsWith /index.php" \
|
||||
# "id:1001,\
|
||||
# phase:1,\
|
||||
# pass,\
|
||||
# nolog,\
|
||||
# ctl:ruleRemoveTargetById=942100;ARGS:password"
|
||||
#
|
||||
#
|
||||
# Example Exclusion Rule: Removing a specific ARGS parameter from inspection
|
||||
# for only certain attacks
|
||||
#
|
||||
# Attack rules within the CRS are tagged, with tags such as 'attack-lfi',
|
||||
# 'attack-sqli', 'attack-xss', 'attack-injection-php', et cetera.
|
||||
#
|
||||
# ModSecurity Rule Exclusion: Disable inspection of ARGS:pwd
|
||||
# for all rules tagged attack-sqli
|
||||
# SecRule REQUEST_FILENAME "@endsWith /wp-login.php" \
|
||||
# "id:1002,\
|
||||
# phase:2,\
|
||||
# pass,\
|
||||
# nolog,\
|
||||
# ctl:ruleRemoveTargetByTag=attack-sqli;ARGS:pwd"
|
||||
#
|
||||
|
||||
# Example Exclusion Rule: Removing a specific ARGS parameter from inspection
|
||||
# for all CRS rules
|
||||
#
|
||||
# This rule illustrates that we can use tagging very effectively to allow list a
|
||||
# common false positive across an entire ModSecurity instance. This can be done
|
||||
# because every rule in OWASP_CRS is tagged with OWASP_CRS. This will NOT
|
||||
# affect custom rules.
|
||||
#
|
||||
# ModSecurity Rule Exclusion: Disable inspection of ARGS:pwd
|
||||
# for all CRS rules
|
||||
# SecRule REQUEST_FILENAME "@endsWith /wp-login.php" \
|
||||
# "id:1003,\
|
||||
# phase:2,\
|
||||
# pass,\
|
||||
# nolog,\
|
||||
# ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:pwd"
|
||||
|
||||
#
|
||||
# Example Exclusion Rule: Removing a range of rules
|
||||
#
|
||||
# This rule illustrates that we can remove a rule range via a ctl action.
|
||||
# This uses the fact, that rules are grouped by topic in rule files covering
|
||||
# a certain id range.
|
||||
#
|
||||
# ModSecurity Rule Exclusion: Disable all SQLi and XSS rules
|
||||
# SecRule REQUEST_FILENAME "@beginsWith /admin" \
|
||||
# "id:1004,\
|
||||
# phase:2,\
|
||||
# pass,\
|
||||
# nolog,\
|
||||
# ctl:ruleRemoveById=941000-942999"
|
||||
#
|
||||
#
|
||||
# The application-specific rule exclusion plugins
|
||||
# (see: https://github.com/coreruleset/plugin-registry)
|
||||
# provide additional examples which can be useful then tuning a service.
|
||||
|
||||
|
||||
#
|
||||
# Example Rule: Allow monitoring tools and scripts
|
||||
#
|
||||
# Uncomment this rule to allow all requests from trusted IPs and User-Agent.
|
||||
# This can be useful for monitoring tools like Monit, Nagios, or other agents.
|
||||
# For example, if you're using AWS Load Balancer, you may need to trust all
|
||||
# requests from "10.0.0.0/8" subnet that come with the user-agent
|
||||
# "ELB-HealthChecker/2.0". By doing this, all requests that match these
|
||||
# conditions will not be matched against the following rules:
|
||||
#
|
||||
# - id: 911100 (allowed methods)
|
||||
# - id: 913100,913110,913120,913101,913102 (scan detection)
|
||||
# - id: 920280 (missing/empty host header)
|
||||
# - id: 920350 (IP address in host header)
|
||||
# - tag: attack-disclosure (all RESPONSE-*-DATA-LEAKAGES rules)
|
||||
#
|
||||
# SecRule REMOTE_ADDR "@ipMatch 10.0.0.0/8" \
|
||||
# "id:1005,\
|
||||
# phase:1,\
|
||||
# pass,\
|
||||
# nolog,\
|
||||
# chain"
|
||||
# SecRule REQUEST_METHOD "@pm GET HEAD" "chain"
|
||||
# SecRule REQUEST_HEADERS:User-Agent "@pm ELB-HealthChecker" \
|
||||
# "ctl:ruleRemoveById=911100,\
|
||||
# ctl:ruleRemoveById=913100,\
|
||||
# ctl:ruleRemoveById=913110,\
|
||||
# ctl:ruleRemoveById=913120,\
|
||||
# ctl:ruleRemoveById=913101,\
|
||||
# ctl:ruleRemoveById=913102,\
|
||||
# ctl:ruleRemoveById=920280,\
|
||||
# ctl:ruleRemoveById=920350,\
|
||||
# ctl:ruleRemoveByTag=attack-disclosure"
|
||||
@@ -0,0 +1,424 @@
|
||||
# ------------------------------------------------------------------------
|
||||
# OWASP ModSecurity Core Rule Set ver.4.0.0-rc1
|
||||
# Copyright (c) 2006-2020 Trustwave and contributors. All rights reserved.
|
||||
# Copyright (c) 2021-2022 Core Rule Set project. All rights reserved.
|
||||
#
|
||||
# The OWASP ModSecurity Core Rule Set is distributed under
|
||||
# Apache Software License (ASL) version 2
|
||||
# Please see the enclosed LICENSE file for full details.
|
||||
# ------------------------------------------------------------------------
|
||||
|
||||
#
|
||||
# This file REQUEST-901-INITIALIZATION.conf initializes the Core Rules
|
||||
# and performs preparatory actions. It also fixes errors and omissions
|
||||
# of variable definitions in the file crs-setup.conf.
|
||||
# The crs-setup.conf can and should be edited by the user, this file
|
||||
# is part of the CRS installation and should not be altered.
|
||||
#
|
||||
|
||||
|
||||
#
|
||||
# -=[ Rules Version ]=-
|
||||
#
|
||||
# Rule version data is added to the "Producer" line of Section H of the Audit log:
|
||||
#
|
||||
# - Producer: ModSecurity for Apache/2.9.1 (http://www.modsecurity.org/); OWASP_CRS/3.1.0.
|
||||
#
|
||||
# Ref: https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual#wiki-SecComponentSignature
|
||||
#
|
||||
SecComponentSignature "OWASP_CRS/4.0.0-rc1"
|
||||
|
||||
#
|
||||
# -=[ Default setup values ]=-
|
||||
#
|
||||
# The CRS checks the tx.crs_setup_version variable to ensure that the setup
|
||||
# file is included at the correct time. This detects situations where
|
||||
# necessary settings are not defined, for instance if the file
|
||||
# inclusion order is incorrect, or if the user has forgotten to
|
||||
# include the crs-setup.conf file.
|
||||
#
|
||||
# If you are upgrading from an earlier version of the CRS and you are
|
||||
# getting this error, please make a new copy of the setup template
|
||||
# crs-setup.conf.example to crs-setup.conf, and re-apply your policy
|
||||
# changes. There have been many changes in settings syntax from CRS2
|
||||
# to CRS3, so an old setup file may cause unwanted behavior.
|
||||
#
|
||||
# If you are not planning to use the crs-setup.conf template, you must
|
||||
# manually set the tx.crs_setup_version variable before including
|
||||
# the CRS rules/* files.
|
||||
#
|
||||
# The variable is a numerical representation of the CRS version number.
|
||||
# E.g., v3.0.0 is represented as 300.
|
||||
#
|
||||
|
||||
SecRule &TX:crs_setup_version "@eq 0" \
|
||||
"id:901001,\
|
||||
phase:1,\
|
||||
deny,\
|
||||
status:500,\
|
||||
log,\
|
||||
auditlog,\
|
||||
msg:'ModSecurity Core Rule Set is deployed without configuration! Please copy the crs-setup.conf.example template to crs-setup.conf, and include the crs-setup.conf file in your webserver configuration before including the CRS rules. See the INSTALL file in the CRS directory for detailed instructions',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL'"
|
||||
|
||||
|
||||
#
|
||||
# -=[ Default setup values ]=-
|
||||
#
|
||||
# Some constructs or individual rules will fail if certain parameters
|
||||
# are not set in the crs-setup.conf file. The following rules will catch
|
||||
# these cases and assign sane default values.
|
||||
#
|
||||
|
||||
# Default Inbound Anomaly Threshold Level (rule 900110 in crs-setup.conf)
|
||||
SecRule &TX:inbound_anomaly_score_threshold "@eq 0" \
|
||||
"id:901100,\
|
||||
phase:1,\
|
||||
pass,\
|
||||
nolog,\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
setvar:'tx.inbound_anomaly_score_threshold=5'"
|
||||
|
||||
# Default Outbound Anomaly Threshold Level (rule 900110 in crs-setup.conf)
|
||||
SecRule &TX:outbound_anomaly_score_threshold "@eq 0" \
|
||||
"id:901110,\
|
||||
phase:1,\
|
||||
pass,\
|
||||
nolog,\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
setvar:'tx.outbound_anomaly_score_threshold=4'"
|
||||
|
||||
# Default Reporting Level (rule 900115 in crs-setup.conf)
|
||||
SecRule &TX:reporting_level "@eq 0" \
|
||||
"id:901111,\
|
||||
phase:1,\
|
||||
pass,\
|
||||
nolog,\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
setvar:'tx.reporting_level=4'"
|
||||
|
||||
# Default Early Blocking (rule 900120 in crs-setup.conf)
|
||||
SecRule &TX:early_blocking "@eq 0" \
|
||||
"id:901115,\
|
||||
phase:1,\
|
||||
pass,\
|
||||
nolog,\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
setvar:'tx.early_blocking=0'"
|
||||
|
||||
# Default Blocking Paranoia Level (rule 900000 in crs-setup.conf)
|
||||
SecRule &TX:blocking_paranoia_level "@eq 0" \
|
||||
"id:901120,\
|
||||
phase:1,\
|
||||
pass,\
|
||||
nolog,\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
setvar:'tx.blocking_paranoia_level=1'"
|
||||
|
||||
# Default Detection Paranoia Level (rule 900001 in crs-setup.conf)
|
||||
SecRule &TX:detection_paranoia_level "@eq 0" \
|
||||
"id:901125,\
|
||||
phase:1,\
|
||||
pass,\
|
||||
nolog,\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
setvar:'tx.detection_paranoia_level=%{TX.blocking_paranoia_level}'"
|
||||
|
||||
# Default Sampling Percentage (rule 900400 in crs-setup.conf)
|
||||
SecRule &TX:sampling_percentage "@eq 0" \
|
||||
"id:901130,\
|
||||
phase:1,\
|
||||
pass,\
|
||||
nolog,\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
setvar:'tx.sampling_percentage=100'"
|
||||
|
||||
# Default Anomaly Scores (rule 900100 in crs-setup.conf)
|
||||
SecRule &TX:critical_anomaly_score "@eq 0" \
|
||||
"id:901140,\
|
||||
phase:1,\
|
||||
pass,\
|
||||
nolog,\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
setvar:'tx.critical_anomaly_score=5'"
|
||||
|
||||
SecRule &TX:error_anomaly_score "@eq 0" \
|
||||
"id:901141,\
|
||||
phase:1,\
|
||||
pass,\
|
||||
nolog,\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
setvar:'tx.error_anomaly_score=4'"
|
||||
|
||||
SecRule &TX:warning_anomaly_score "@eq 0" \
|
||||
"id:901142,\
|
||||
phase:1,\
|
||||
pass,\
|
||||
nolog,\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
setvar:'tx.warning_anomaly_score=3'"
|
||||
|
||||
SecRule &TX:notice_anomaly_score "@eq 0" \
|
||||
"id:901143,\
|
||||
phase:1,\
|
||||
pass,\
|
||||
nolog,\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
setvar:'tx.notice_anomaly_score=2'"
|
||||
|
||||
# Default HTTP policy: allowed_methods (rule 900200 in crs-setup.conf)
|
||||
SecRule &TX:allowed_methods "@eq 0" \
|
||||
"id:901160,\
|
||||
phase:1,\
|
||||
pass,\
|
||||
nolog,\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
setvar:'tx.allowed_methods=GET HEAD POST OPTIONS'"
|
||||
|
||||
# Default HTTP policy: allowed_request_content_type (rule 900220 in crs-setup.conf)
|
||||
SecRule &TX:allowed_request_content_type "@eq 0" \
|
||||
"id:901162,\
|
||||
phase:1,\
|
||||
pass,\
|
||||
nolog,\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
setvar:'tx.allowed_request_content_type=|application/x-www-form-urlencoded| |multipart/form-data| |multipart/related| |text/xml| |application/xml| |application/soap+xml| |application/json| |application/cloudevents+json| |application/cloudevents-batch+json|'"
|
||||
|
||||
# Default HTTP policy: allowed_request_content_type_charset (rule 900280 in crs-setup.conf)
|
||||
SecRule &TX:allowed_request_content_type_charset "@eq 0" \
|
||||
"id:901168,\
|
||||
phase:1,\
|
||||
pass,\
|
||||
nolog,\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
setvar:'tx.allowed_request_content_type_charset=|utf-8| |iso-8859-1| |iso-8859-15| |windows-1252|'"
|
||||
|
||||
# Default HTTP policy: allowed_http_versions (rule 900230 in crs-setup.conf)
|
||||
SecRule &TX:allowed_http_versions "@eq 0" \
|
||||
"id:901163,\
|
||||
phase:1,\
|
||||
pass,\
|
||||
nolog,\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
setvar:'tx.allowed_http_versions=HTTP/1.0 HTTP/1.1 HTTP/2 HTTP/2.0'"
|
||||
|
||||
# Default HTTP policy: restricted_extensions (rule 900240 in crs-setup.conf)
|
||||
SecRule &TX:restricted_extensions "@eq 0" \
|
||||
"id:901164,\
|
||||
phase:1,\
|
||||
pass,\
|
||||
nolog,\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
setvar:'tx.restricted_extensions=.asa/ .asax/ .ascx/ .backup/ .bak/ .bat/ .cdx/ .cer/ .cfg/ .cmd/ .com/ .config/ .conf/ .cs/ .csproj/ .csr/ .dat/ .db/ .dbf/ .dll/ .dos/ .htr/ .htw/ .ida/ .idc/ .idq/ .inc/ .ini/ .key/ .licx/ .lnk/ .log/ .mdb/ .old/ .pass/ .pdb/ .pol/ .printer/ .pwd/ .rdb/ .resources/ .resx/ .sql/ .swp/ .sys/ .vb/ .vbs/ .vbproj/ .vsdisco/ .webinfo/ .xsd/ .xsx/'"
|
||||
|
||||
# Default HTTP policy: restricted_headers (rule 900250 in crs-setup.conf)
|
||||
SecRule &TX:restricted_headers "@eq 0" \
|
||||
"id:901165,\
|
||||
phase:1,\
|
||||
pass,\
|
||||
nolog,\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
setvar:'tx.restricted_headers=/accept-charset/ /content-encoding/ /proxy/ /lock-token/ /content-range/ /if/ /x-http-method-override/ /x-http-method/ /x-method-override/'"
|
||||
|
||||
# Default enforcing of body processor URLENCODED (rule 900010 in crs-setup.conf)
|
||||
SecRule &TX:enforce_bodyproc_urlencoded "@eq 0" \
|
||||
"id:901167,\
|
||||
phase:1,\
|
||||
pass,\
|
||||
nolog,\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
setvar:'tx.enforce_bodyproc_urlencoded=0'"
|
||||
|
||||
# Default check for UTF8 encoding validation (rule 900950 in crs-setup.conf)
|
||||
SecRule &TX:crs_validate_utf8_encoding "@eq 0" \
|
||||
"id:901169,\
|
||||
phase:1,\
|
||||
pass,\
|
||||
nolog,\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
setvar:'tx.crs_validate_utf8_encoding=0'"
|
||||
|
||||
#
|
||||
# -=[ Initialize internal variables ]=-
|
||||
#
|
||||
|
||||
# Initialize anomaly scoring variables.
|
||||
# All _score variables start at 0, and are incremented by the various rules
|
||||
# upon detection of a possible attack.
|
||||
|
||||
SecAction \
|
||||
"id:901200,\
|
||||
phase:1,\
|
||||
pass,\
|
||||
t:none,\
|
||||
nolog,\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
setvar:'tx.blocking_inbound_anomaly_score=0',\
|
||||
setvar:'tx.detection_inbound_anomaly_score=0',\
|
||||
setvar:'tx.inbound_anomaly_score_pl1=0',\
|
||||
setvar:'tx.inbound_anomaly_score_pl2=0',\
|
||||
setvar:'tx.inbound_anomaly_score_pl3=0',\
|
||||
setvar:'tx.inbound_anomaly_score_pl4=0',\
|
||||
setvar:'tx.sql_injection_score=0',\
|
||||
setvar:'tx.xss_score=0',\
|
||||
setvar:'tx.rfi_score=0',\
|
||||
setvar:'tx.lfi_score=0',\
|
||||
setvar:'tx.rce_score=0',\
|
||||
setvar:'tx.php_injection_score=0',\
|
||||
setvar:'tx.http_violation_score=0',\
|
||||
setvar:'tx.session_fixation_score=0',\
|
||||
setvar:'tx.blocking_outbound_anomaly_score=0',\
|
||||
setvar:'tx.detection_outbound_anomaly_score=0',\
|
||||
setvar:'tx.outbound_anomaly_score_pl1=0',\
|
||||
setvar:'tx.outbound_anomaly_score_pl2=0',\
|
||||
setvar:'tx.outbound_anomaly_score_pl3=0',\
|
||||
setvar:'tx.outbound_anomaly_score_pl4=0',\
|
||||
setvar:'tx.anomaly_score=0'"
|
||||
|
||||
|
||||
#
|
||||
# -=[ Initialize collections ]=-
|
||||
#
|
||||
# Create both Global and IP collections for rules to use.
|
||||
# There are some CRS rules that assume that these two collections
|
||||
# have already been initiated.
|
||||
#
|
||||
|
||||
SecRule REQUEST_HEADERS:User-Agent "@rx ^.*$" \
|
||||
"id:901318,\
|
||||
phase:1,\
|
||||
pass,\
|
||||
t:none,t:sha1,t:hexEncode,\
|
||||
nolog,\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
setvar:'tx.ua_hash=%{MATCHED_VAR}'"
|
||||
|
||||
SecAction \
|
||||
"id:901321,\
|
||||
phase:1,\
|
||||
pass,\
|
||||
t:none,\
|
||||
nolog,\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
initcol:global=global,\
|
||||
initcol:ip=%{remote_addr}_%{tx.ua_hash}"
|
||||
|
||||
#
|
||||
# -=[ Initialize Correct Body Processing ]=-
|
||||
#
|
||||
# Force request body variable and optionally request body processor
|
||||
#
|
||||
|
||||
# Force body variable
|
||||
SecRule REQBODY_PROCESSOR "!@rx (?:URLENCODED|MULTIPART|XML|JSON)" \
|
||||
"id:901340,\
|
||||
phase:1,\
|
||||
pass,\
|
||||
nolog,\
|
||||
noauditlog,\
|
||||
msg:'Enabling body inspection',\
|
||||
ctl:forceRequestBodyVariable=On,\
|
||||
ver:'OWASP_CRS/4.0.0-rc1'"
|
||||
|
||||
# Force body processor URLENCODED
|
||||
SecRule TX:enforce_bodyproc_urlencoded "@eq 1" \
|
||||
"id:901350,\
|
||||
phase:1,\
|
||||
pass,\
|
||||
t:none,t:urlDecodeUni,\
|
||||
nolog,\
|
||||
noauditlog,\
|
||||
msg:'Enabling forced body inspection for ASCII content',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
chain"
|
||||
SecRule REQBODY_PROCESSOR "!@rx (?:URLENCODED|MULTIPART|XML|JSON)" \
|
||||
"ctl:requestBodyProcessor=URLENCODED"
|
||||
|
||||
|
||||
#
|
||||
# -=[ Easing In / Sampling Percentage ]=-
|
||||
#
|
||||
# This is used to send only a limited percentage of requests into the Core
|
||||
# Rule Set. The selection is based on TX.sampling_percentage and a pseudo
|
||||
# random number calculated below.
|
||||
#
|
||||
# Use this to ease into a new Core Rules installation with an existing
|
||||
# productive service.
|
||||
#
|
||||
# See
|
||||
# https://www.netnea.com/cms/2016/04/26/easing-in-conditional-modsecurity-rule-execution-based-on-pseudo-random-numbers/
|
||||
#
|
||||
|
||||
#
|
||||
# Generate the pseudo random number
|
||||
#
|
||||
# ATTENTION: This is no cryptographically secure random number. It's just
|
||||
# a cheap way to get some random number suitable for sampling.
|
||||
#
|
||||
# We take the entropy contained in the UNIQUE_ID. We hash that variable and
|
||||
# take the first integer numbers out of it. Theoretically, it is possible
|
||||
# but highly improbable that there are no integers in a hexEncoded sha1 hash.
|
||||
# In the very rare event that two integers are not matched (due to only being
|
||||
# a-f in all, or all but one positions) 901450 will not be triggered.
|
||||
# Leading zeros are not removed from the two-digit random number, and are
|
||||
# handled gracefullly by 901450
|
||||
|
||||
SecRule TX:sampling_percentage "@eq 100" \
|
||||
"id:901400,\
|
||||
phase:1,\
|
||||
pass,\
|
||||
nolog,\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
skipAfter:END-SAMPLING"
|
||||
|
||||
SecRule UNIQUE_ID "@rx ^[a-f]*([0-9])[a-f]*([0-9])" \
|
||||
"id:901410,\
|
||||
phase:1,\
|
||||
pass,\
|
||||
capture,\
|
||||
t:sha1,t:hexEncode,\
|
||||
nolog,\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
setvar:'TX.sampling_rnd100=%{TX.1}%{TX.2}'"
|
||||
|
||||
#
|
||||
# Sampling decision
|
||||
#
|
||||
# If a request is allowed to pass without being checked by the CRS, there is no
|
||||
# entry in the audit log (for performance reasons), but an error log entry is
|
||||
# being written. If you want to disable the error log entry, then issue the
|
||||
# following directive somewhere after the inclusion of the CRS
|
||||
# (E.g., RESPONSE-999-EXCEPTIONS.conf).
|
||||
#
|
||||
# SecRuleUpdateActionById 901450 "nolog"
|
||||
#
|
||||
|
||||
|
||||
SecRule TX:sampling_rnd100 "!@lt %{tx.sampling_percentage}" \
|
||||
"id:901450,\
|
||||
phase:1,\
|
||||
pass,\
|
||||
log,\
|
||||
noauditlog,\
|
||||
msg:'Sampling: Disable the rule engine based on sampling_percentage %{TX.sampling_percentage} and random number %{TX.sampling_rnd100}',\
|
||||
ctl:ruleRemoveByTag=OWASP_CRS,\
|
||||
ver:'OWASP_CRS/4.0.0-rc1'"
|
||||
|
||||
SecMarker "END-SAMPLING"
|
||||
|
||||
|
||||
#
|
||||
# Configuration Plausibility Checks
|
||||
#
|
||||
|
||||
# Make sure detection paranoia level is not lower than paranoia level
|
||||
SecRule TX:detection_paranoia_level "@lt %{tx.blocking_paranoia_level}" \
|
||||
"id:901500,\
|
||||
phase:1,\
|
||||
deny,\
|
||||
status:500,\
|
||||
t:none,\
|
||||
log,\
|
||||
msg:'Detection paranoia level configured is lower than the paranoia level itself. This is illegal. Blocking request. Aborting',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1'"
|
||||
@@ -0,0 +1,55 @@
|
||||
# ------------------------------------------------------------------------
|
||||
# OWASP ModSecurity Core Rule Set ver.4.0.0-rc1
|
||||
# Copyright (c) 2006-2020 Trustwave and contributors. All rights reserved.
|
||||
# Copyright (c) 2021-2022 Core Rule Set project. All rights reserved.
|
||||
#
|
||||
# The OWASP ModSecurity Core Rule Set is distributed under
|
||||
# Apache Software License (ASL) version 2
|
||||
# Please see the enclosed LICENSE file for full details.
|
||||
# ------------------------------------------------------------------------
|
||||
|
||||
|
||||
# This file is used as an exception mechanism to remove common false positives
|
||||
# that may be encountered.
|
||||
#
|
||||
# Exception for Apache SSL pinger
|
||||
#
|
||||
SecRule REQUEST_LINE "@streq GET /" \
|
||||
"id:905100,\
|
||||
phase:1,\
|
||||
pass,\
|
||||
t:none,\
|
||||
nolog,\
|
||||
tag:'application-multi',\
|
||||
tag:'language-multi',\
|
||||
tag:'platform-apache',\
|
||||
tag:'attack-generic',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
chain"
|
||||
SecRule REMOTE_ADDR "@ipMatch 127.0.0.1,::1" \
|
||||
"t:none,\
|
||||
ctl:ruleRemoveByTag=OWASP_CRS,\
|
||||
ctl:auditEngine=Off"
|
||||
|
||||
#
|
||||
# Exception for Apache internal dummy connection
|
||||
#
|
||||
SecRule REMOTE_ADDR "@ipMatch 127.0.0.1,::1" \
|
||||
"id:905110,\
|
||||
phase:1,\
|
||||
pass,\
|
||||
t:none,\
|
||||
nolog,\
|
||||
tag:'application-multi',\
|
||||
tag:'language-multi',\
|
||||
tag:'platform-apache',\
|
||||
tag:'attack-generic',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
chain"
|
||||
SecRule REQUEST_HEADERS:User-Agent "@endsWith (internal dummy connection)" \
|
||||
"t:none,\
|
||||
chain"
|
||||
SecRule REQUEST_LINE "@rx ^(?:GET /|OPTIONS \*) HTTP/[12]\.[01]$" \
|
||||
"t:none,\
|
||||
ctl:ruleRemoveByTag=OWASP_CRS,\
|
||||
ctl:auditEngine=Off"
|
||||
@@ -0,0 +1,76 @@
|
||||
# ------------------------------------------------------------------------
|
||||
# OWASP ModSecurity Core Rule Set ver.4.0.0-rc1
|
||||
# Copyright (c) 2006-2020 Trustwave and contributors. All rights reserved.
|
||||
# Copyright (c) 2021-2022 Core Rule Set project. All rights reserved.
|
||||
#
|
||||
# The OWASP ModSecurity Core Rule Set is distributed under
|
||||
# Apache Software License (ASL) version 2
|
||||
# Please see the enclosed LICENSE file for full details.
|
||||
# ------------------------------------------------------------------------
|
||||
|
||||
#
|
||||
# -= Paranoia Level 0 (empty) =- (apply unconditionally)
|
||||
#
|
||||
|
||||
|
||||
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:911011,phase:1,pass,nolog,skipAfter:END-REQUEST-911-METHOD-ENFORCEMENT"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:911012,phase:2,pass,nolog,skipAfter:END-REQUEST-911-METHOD-ENFORCEMENT"
|
||||
#
|
||||
# -= Paranoia Level 1 (default) =- (apply only when tx.detection_paranoia_level is sufficiently high: 1 or higher)
|
||||
#
|
||||
|
||||
#
|
||||
# -=[ Allowed Request Methods ]=-
|
||||
#
|
||||
# tx.allowed_methods is defined in the crs-setup.conf file
|
||||
#
|
||||
SecRule REQUEST_METHOD "!@within %{tx.allowed_methods}" \
|
||||
"id:911100,\
|
||||
phase:1,\
|
||||
block,\
|
||||
msg:'Method is not allowed by policy',\
|
||||
logdata:'%{MATCHED_VAR}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-multi',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-generic',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/210/272/220/274',\
|
||||
tag:'PCI/12.1',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
|
||||
|
||||
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:911013,phase:1,pass,nolog,skipAfter:END-REQUEST-911-METHOD-ENFORCEMENT"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:911014,phase:2,pass,nolog,skipAfter:END-REQUEST-911-METHOD-ENFORCEMENT"
|
||||
#
|
||||
# -= Paranoia Level 2 =- (apply only when tx.detection_paranoia_level is sufficiently high: 2 or higher)
|
||||
#
|
||||
|
||||
|
||||
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:911015,phase:1,pass,nolog,skipAfter:END-REQUEST-911-METHOD-ENFORCEMENT"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:911016,phase:2,pass,nolog,skipAfter:END-REQUEST-911-METHOD-ENFORCEMENT"
|
||||
#
|
||||
# -= Paranoia Level 3 =- (apply only when tx.detection_paranoia_level is sufficiently high: 3 or higher)
|
||||
#
|
||||
|
||||
|
||||
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:911017,phase:1,pass,nolog,skipAfter:END-REQUEST-911-METHOD-ENFORCEMENT"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:911018,phase:2,pass,nolog,skipAfter:END-REQUEST-911-METHOD-ENFORCEMENT"
|
||||
#
|
||||
# -= Paranoia Level 4 =- (apply only when tx.detection_paranoia_level is sufficiently high: 4 or higher)
|
||||
#
|
||||
|
||||
|
||||
|
||||
#
|
||||
# -= Paranoia Levels Finished =-
|
||||
#
|
||||
SecMarker "END-REQUEST-911-METHOD-ENFORCEMENT"
|
||||
@@ -0,0 +1,189 @@
|
||||
# ------------------------------------------------------------------------
|
||||
# OWASP ModSecurity Core Rule Set ver.4.0.0-rc1
|
||||
# Copyright (c) 2006-2020 Trustwave and contributors. All rights reserved.
|
||||
# Copyright (c) 2021-2022 Core Rule Set project. All rights reserved.
|
||||
#
|
||||
# The OWASP ModSecurity Core Rule Set is distributed under
|
||||
# Apache Software License (ASL) version 2
|
||||
# Please see the enclosed LICENSE file for full details.
|
||||
# ------------------------------------------------------------------------
|
||||
|
||||
#
|
||||
# -= Paranoia Level 0 (empty) =- (apply unconditionally)
|
||||
#
|
||||
|
||||
|
||||
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:913011,phase:1,pass,nolog,skipAfter:END-REQUEST-913-SCANNER-DETECTION"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:913012,phase:2,pass,nolog,skipAfter:END-REQUEST-913-SCANNER-DETECTION"
|
||||
#
|
||||
# -= Paranoia Level 1 (default) =- (apply only when tx.detection_paranoia_level is sufficiently high: 1 or higher)
|
||||
#
|
||||
|
||||
#
|
||||
# -=[ Vulnerability Scanner Checks ]=-
|
||||
#
|
||||
# These rules inspect the default User-Agent and Header values sent by
|
||||
# various commercial and open source vuln scanners.
|
||||
#
|
||||
# The following rules contain User-Agent lists:
|
||||
# 913100 - security scanners (data file scanners-user-agents.data)
|
||||
# 913101 - scripting/generic HTTP clients (data file scripting-user-agents.data)
|
||||
# 913102 - web crawlers/bots (data file crawlers-user-agents.data)
|
||||
#
|
||||
# Chained rule is allow listing:
|
||||
# YUM package manager of CentOS / Fedore: User-Agent: urlgrabber/3.10 yum/3.4.3
|
||||
# eCairn service: User-Agent: mozilla/5.0 ecairn-grabber/1.0 (+http://ecairn.com/grabber)
|
||||
SecRule REQUEST_HEADERS:User-Agent "@pmFromFile scanners-user-agents.data" \
|
||||
"id:913100,\
|
||||
phase:1,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,\
|
||||
msg:'Found User-Agent associated with security scanner',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-multi',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-reputation-scanner',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/118/224/541/310',\
|
||||
tag:'PCI/6.5.10',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
chain"
|
||||
SecRule MATCHED_VARS "!@rx ^(?:urlgrabber/[0-9\.]+ yum/[0-9\.]+|mozilla/[0-9\.]+ ecairn-grabber/[0-9\.]+ \(\+http://ecairn.com/grabber\))$" \
|
||||
"setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
SecRule REQUEST_HEADERS_NAMES|REQUEST_HEADERS "@pmFromFile scanners-headers.data" \
|
||||
"id:913110,\
|
||||
phase:1,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,\
|
||||
msg:'Found request header associated with security scanner',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-multi',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-reputation-scanner',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/118/224/541/310',\
|
||||
tag:'PCI/6.5.10',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
|
||||
|
||||
SecRule REQUEST_FILENAME|ARGS "@pmFromFile scanners-urls.data" \
|
||||
"id:913120,\
|
||||
phase:2,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,\
|
||||
msg:'Found request filename/argument associated with security scanner',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-multi',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-reputation-scanner',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/118/224/541/310',\
|
||||
tag:'PCI/6.5.10',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:913013,phase:1,pass,nolog,skipAfter:END-REQUEST-913-SCANNER-DETECTION"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:913014,phase:2,pass,nolog,skipAfter:END-REQUEST-913-SCANNER-DETECTION"
|
||||
#
|
||||
# -= Paranoia Level 2 =- (apply only when tx.detection_paranoia_level is sufficiently high: 2 or higher)
|
||||
#
|
||||
|
||||
|
||||
#
|
||||
# -=[ Scripting/Generic User-Agents ]=-
|
||||
#
|
||||
# This rule detects user-agents associated with various HTTP client libraries
|
||||
# and scripting languages. Detection suggests attempted access by some
|
||||
# automated tool.
|
||||
#
|
||||
# This rule is a sibling of rule 913100.
|
||||
#
|
||||
SecRule REQUEST_HEADERS:User-Agent "@pmFromFile scripting-user-agents.data" \
|
||||
"id:913101,\
|
||||
phase:1,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,\
|
||||
msg:'Found User-Agent associated with scripting/generic HTTP client',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-multi',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-reputation-scripting',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/118/224/541/310',\
|
||||
tag:'PCI/6.5.10',\
|
||||
tag:'paranoia-level/2',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
|
||||
|
||||
#
|
||||
# -=[ Crawler User-Agents ]=-
|
||||
#
|
||||
# This rule detects user-agents associated with various crawlers, SEO tools,
|
||||
# and bots, which have been reported to potentially misbehave.
|
||||
# These crawlers can have legitimate uses when used with authorization.
|
||||
#
|
||||
# This rule is a sibling of rule 913100.
|
||||
#
|
||||
SecRule REQUEST_HEADERS:User-Agent "@pmFromFile crawlers-user-agents.data" \
|
||||
"id:913102,\
|
||||
phase:1,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,\
|
||||
msg:'Found User-Agent associated with web crawler/bot',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-multi',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-reputation-crawler',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/118/116/150',\
|
||||
tag:'PCI/6.5.10',\
|
||||
tag:'paranoia-level/2',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:913015,phase:1,pass,nolog,skipAfter:END-REQUEST-913-SCANNER-DETECTION"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:913016,phase:2,pass,nolog,skipAfter:END-REQUEST-913-SCANNER-DETECTION"
|
||||
#
|
||||
# -= Paranoia Level 3 =- (apply only when tx.detection_paranoia_level is sufficiently high: 3 or higher)
|
||||
#
|
||||
|
||||
|
||||
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:913017,phase:1,pass,nolog,skipAfter:END-REQUEST-913-SCANNER-DETECTION"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:913018,phase:2,pass,nolog,skipAfter:END-REQUEST-913-SCANNER-DETECTION"
|
||||
#
|
||||
# -= Paranoia Level 4 =- (apply only when tx.detection_paranoia_level is sufficiently high: 4 or higher)
|
||||
#
|
||||
|
||||
|
||||
|
||||
#
|
||||
# -= Paranoia Levels Finished =-
|
||||
#
|
||||
SecMarker "END-REQUEST-913-SCANNER-DETECTION"
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,560 @@
|
||||
# ------------------------------------------------------------------------
|
||||
# OWASP ModSecurity Core Rule Set ver.4.0.0-rc1
|
||||
# Copyright (c) 2006-2020 Trustwave and contributors. All rights reserved.
|
||||
# Copyright (c) 2021-2022 Core Rule Set project. All rights reserved.
|
||||
#
|
||||
# The OWASP ModSecurity Core Rule Set is distributed under
|
||||
# Apache Software License (ASL) version 2
|
||||
# Please see the enclosed LICENSE file for full details.
|
||||
# ------------------------------------------------------------------------
|
||||
|
||||
#
|
||||
# -= Paranoia Level 0 (empty) =- (apply unconditionally)
|
||||
#
|
||||
|
||||
|
||||
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:921011,phase:1,pass,nolog,skipAfter:END-REQUEST-921-PROTOCOL-ATTACK"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:921012,phase:2,pass,nolog,skipAfter:END-REQUEST-921-PROTOCOL-ATTACK"
|
||||
#
|
||||
# -= Paranoia Level 1 (default) =- (apply only when tx.detection_paranoia_level is sufficiently high: 1 or higher)
|
||||
#
|
||||
|
||||
#
|
||||
# -=[ HTTP Request Smuggling ]=-
|
||||
#
|
||||
# [ Rule Logic ]
|
||||
# This rule looks for a HTTP / WEBDAV method name in combination with the word http/\d or a CR/LF character.
|
||||
# This would point to an attempt to inject a 2nd request into the request, thus bypassing
|
||||
# tests carried out on the primary request.
|
||||
#
|
||||
# [ References ]
|
||||
# http://projects.webappsec.org/HTTP-Request-Smuggling
|
||||
#
|
||||
SecRule ARGS_NAMES|ARGS|REQUEST_BODY|XML:/* "@rx (?:get|post|head|options|connect|put|delete|trace|track|patch|propfind|propatch|mkcol|copy|move|lock|unlock)\s+[^\s]+\s+http/\d" \
|
||||
"id:921110,\
|
||||
phase:2,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,t:htmlEntityDecode,t:lowercase,\
|
||||
msg:'HTTP Request Smuggling Attack',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-multi',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-protocol',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/210/272/220/33',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.http_violation_score=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
#
|
||||
# -=[ HTTP Response Splitting ]=-
|
||||
#
|
||||
# [ Rule Logic ]
|
||||
# These rules look for Carriage Return (CR) %0d and Linefeed (LF) %0a characters.
|
||||
# These characters may cause problems if the data is returned in a response header and
|
||||
# may be interpreted by an intermediary proxy server and treated as two separate
|
||||
# responses.
|
||||
#
|
||||
# [ References ]
|
||||
# http://projects.webappsec.org/HTTP-Response-Splitting
|
||||
#
|
||||
SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx [\r\n]\W*?(?:content-(?:type|length)|set-cookie|location):\s*\w" \
|
||||
"id:921120,\
|
||||
phase:2,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,t:lowercase,\
|
||||
msg:'HTTP Response Splitting Attack',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-multi',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-protocol',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/210/272/220/34',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.http_violation_score=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
|
||||
SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?:\bhttp/\d|<(?:html|meta)\b)" \
|
||||
"id:921130,\
|
||||
phase:2,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,t:htmlEntityDecode,t:lowercase,\
|
||||
msg:'HTTP Response Splitting Attack',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-multi',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-protocol',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/210/272/220/34',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.http_violation_score=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
#
|
||||
# -=[ HTTP Header Injection ]=-
|
||||
#
|
||||
# [ Rule Logic ]
|
||||
# These rules look for Carriage Return (CR) %0d and Linefeed (LF) %0a characters,
|
||||
# on their own or in combination with header field names.
|
||||
# These characters may cause problems if the data is returned in a response header
|
||||
# and interpreted by the client.
|
||||
# The rules are similar to rules defending against the HTTP Request Splitting and
|
||||
# Request Smuggling rules.
|
||||
#
|
||||
# [ References ]
|
||||
# https://en.wikipedia.org/wiki/HTTP_header_injection
|
||||
#
|
||||
SecRule REQUEST_HEADERS_NAMES|REQUEST_HEADERS "@rx [\n\r]" \
|
||||
"id:921140,\
|
||||
phase:1,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,t:htmlEntityDecode,\
|
||||
msg:'HTTP Header Injection Attack via headers',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-multi',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-protocol',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/210/272/220/273',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.http_violation_score=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
|
||||
# Detect newlines in argument names.
|
||||
# Checking for GET arguments has been moved to paranoia level 2 (921151)
|
||||
# in order to mitigate possible false positives.
|
||||
#
|
||||
# This rule is also triggered by the following exploit(s):
|
||||
# [ SAP CRM Java vulnerability CVE-2018-2380 - Exploit tested: https://www.exploit-db.com/exploits/44292 ]
|
||||
#
|
||||
SecRule ARGS_NAMES "@rx [\n\r]" \
|
||||
"id:921150,\
|
||||
phase:2,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,t:htmlEntityDecode,\
|
||||
msg:'HTTP Header Injection Attack via payload (CR/LF detected)',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-multi',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-protocol',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/210/272/220/33',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.http_violation_score=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
|
||||
SecRule ARGS_GET_NAMES|ARGS_GET "@rx [\n\r]+(?:\s|location|refresh|(?:set-)?cookie|(?:x-)?(?:forwarded-(?:for|host|server)|host|via|remote-ip|remote-addr|originating-IP))\s*:" \
|
||||
"id:921160,\
|
||||
phase:1,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,t:htmlEntityDecode,t:lowercase,\
|
||||
msg:'HTTP Header Injection Attack via payload (CR/LF and header-name detected)',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-multi',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-protocol',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/210/272/220/33',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.http_violation_score=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
|
||||
# -=[ HTTP Splitting ]=-
|
||||
#
|
||||
# This rule detect \n or \r in the REQUEST FILENAME
|
||||
# Reference: https://www.owasp.org/index.php/Testing_for_HTTP_Splitting/Smuggling_(OTG-INPVAL-016)
|
||||
#
|
||||
SecRule REQUEST_FILENAME "@rx [\n\r]" \
|
||||
"id:921190,\
|
||||
phase:1,\
|
||||
block,\
|
||||
t:none,t:urlDecodeUni,\
|
||||
msg:'HTTP Splitting (CR/LF in request filename detected)',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-multi',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-protocol',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/210/272/220/34',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.http_violation_score=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
|
||||
#
|
||||
# -=[ LDAP Injection ]=-
|
||||
#
|
||||
# [ Rule Logic ]
|
||||
#
|
||||
# This is a rule trying to prevent LDAP injection. It is based on a BlackHat presentation by Alonso Parada
|
||||
# and regex writing by Denis Kolegov.
|
||||
#
|
||||
# [ References ]
|
||||
# * https://www.blackhat.com/presentations/bh-europe-08/Alonso-Parada/Whitepaper/bh-eu-08-alonso-parada-WP.pdf
|
||||
# * https://blog.ripstech.com/2017/joomla-takeover-in-20-seconds-with-ldap-injection-cve-2017-14596/
|
||||
# * https://github.com/SpiderLabs/owasp-modsecurity-crs/issues/276#issue-126581660
|
||||
|
||||
SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx ^[^:\(\)\&\|\!\<\>\~]*\)\s*(?:\((?:[^,\(\)\=\&\|\!\<\>\~]+[><~]?=|\s*[&!|]\s*(?:\)|\()?\s*)|\)\s*\(\s*[\&\|\!]\s*|[&!|]\s*\([^\(\)\=\&\|\!\<\>\~]+[><~]?=[^:\(\)\&\|\!\<\>\~]*)" \
|
||||
"id:921200,\
|
||||
phase:2,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,t:htmlEntityDecode,\
|
||||
msg:'LDAP Injection Attack',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-ldap',\
|
||||
tag:'platform-multi',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/152/248/136',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
#
|
||||
# -=[ Body Processor Bypass ]=-
|
||||
#
|
||||
# [ Rule Logic ]
|
||||
#
|
||||
# This rule intends to detect content types in the Content-Type header outside of the actual content type declaration.
|
||||
# This prevents bypasses targeting the Modsecurity recommended rules controlling which body processor is used.
|
||||
#
|
||||
# Regular expression generated from regex-assembly/921421.ra.
|
||||
# To update the regular expression run the following shell script
|
||||
# (consult https://coreruleset.org/docs/development/regex_assembly/ for details):
|
||||
# crs-toolchain regex update 921421
|
||||
#
|
||||
SecRule REQUEST_HEADERS:Content-Type "@rx ^[^\s\v,;]+[\s\v,;].*?(?:application/(?:.+\+)?json|(?:application/(?:soap\+)?|text/)xml)" \
|
||||
"id:921421,\
|
||||
phase:1,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,t:lowercase,\
|
||||
msg:'Content-Type header: Dangerous content type outside the mime type declaration',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-multi',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-protocol',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/255/153',\
|
||||
tag:'PCI/12.1',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
|
||||
#
|
||||
# Rule against CVE-2021-40438:
|
||||
# A crafted request uri-path can cause mod_proxy to forward the request to an origin server choosen by the remote user.
|
||||
# This issue affects Apache HTTP Server 2.4.48 and earlier.
|
||||
# GET /?unix:AAAAAAAAAAAAA|http://coreruleset.org/
|
||||
#
|
||||
SecRule REQUEST_URI "@rx unix:[^|]*\|" \
|
||||
"id:921240,\
|
||||
phase:1,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,t:lowercase,\
|
||||
msg:'mod_proxy attack attempt detected',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-multi',\
|
||||
tag:'platform-apache',\
|
||||
tag:'attack-protocol',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/210/272/220/33',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:921013,phase:1,pass,nolog,skipAfter:END-REQUEST-921-PROTOCOL-ATTACK"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:921014,phase:2,pass,nolog,skipAfter:END-REQUEST-921-PROTOCOL-ATTACK"
|
||||
#
|
||||
# -= Paranoia Level 2 =- (apply only when tx.detection_paranoia_level is sufficiently high: 2 or higher)
|
||||
#
|
||||
|
||||
|
||||
# Detect newlines in GET argument values.
|
||||
# These may point to a HTTP header injection attack, but can also sometimes
|
||||
# occur in benign query parameters.
|
||||
#
|
||||
# See also: rule 921140, 921150
|
||||
#
|
||||
SecRule ARGS_GET "@rx [\n\r]" \
|
||||
"id:921151,\
|
||||
phase:1,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,t:urlDecodeUni,t:htmlEntityDecode,\
|
||||
msg:'HTTP Header Injection Attack via payload (CR/LF detected)',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-multi',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-protocol',\
|
||||
tag:'paranoia-level/2',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/210/272/220/33',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.http_violation_score=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
#
|
||||
# -=[ Body Processor Bypass ]=-
|
||||
#
|
||||
# [ Rule Logic ]
|
||||
#
|
||||
# This rule intends to detect content types in the Content-Type header outside of the actual content type declaration.
|
||||
#
|
||||
# [ References ]
|
||||
# * See rule 921422
|
||||
#
|
||||
# Regular expression generated from regex-assembly/921422.ra.
|
||||
# To update the regular expression run the following shell script
|
||||
# (consult https://coreruleset.org/docs/development/regex_assembly/ for details):
|
||||
# crs-toolchain regex update 921422
|
||||
#
|
||||
SecRule REQUEST_HEADERS:Content-Type "@rx ^[^\s\v,;]+[\s\v,;].*?\b(?:((?:tex|multipar)t|application)|((?:audi|vide)o|image|cs[sv]|(?:vn|relate)d|p(?:df|lain)|json|(?:soa|cs)p|x(?:ml|-www-form-urlencoded)|form-data|x-amf|(?:octe|repor)t|stream)|([\+/]))\b" \
|
||||
"id:921422,\
|
||||
phase:1,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,t:lowercase,\
|
||||
msg:'Content-Type header: Dangerous content type outside the mime type declaration',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-multi',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-protocol',\
|
||||
tag:'paranoia-level/2',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/255/153',\
|
||||
tag:'PCI/12.1',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:921015,phase:1,pass,nolog,skipAfter:END-REQUEST-921-PROTOCOL-ATTACK"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:921016,phase:2,pass,nolog,skipAfter:END-REQUEST-921-PROTOCOL-ATTACK"
|
||||
#
|
||||
# -= Paranoia Level 3 =- (apply only when tx.detection_paranoia_level is sufficiently high: 3 or higher)
|
||||
#
|
||||
#
|
||||
|
||||
# Forbid Request Range Header
|
||||
#
|
||||
# It is possible abuse the HTTP Request Range Header to leak error pages
|
||||
# and other information in very small snippets.
|
||||
# The easiest way to fight this is to deny the use of this header.
|
||||
# This is a viable option since the header is only used in rare circumstances
|
||||
# anymore.
|
||||
# If it is necessary to use it in a certain setup, then it is best to
|
||||
# create a rule exclusion for a given URI and this rule ID as a workaround.
|
||||
#
|
||||
SecRule &REQUEST_HEADERS:Range "@gt 0" \
|
||||
"id:921230,\
|
||||
phase:1,\
|
||||
block,\
|
||||
t:none,\
|
||||
msg:'HTTP Range Header detected',\
|
||||
logdata:'Matched Data: Header %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-multi',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-protocol',\
|
||||
tag:'paranoia-level/3',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/210/272/220',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.inbound_anomaly_score_pl3=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
|
||||
# -=[ HTTP Parameter Pollution ]=-
|
||||
#
|
||||
# [ Rule Logic ]
|
||||
# These rules look for multiple parameters with the same name.
|
||||
# 921170 counts the occurrences of the individual parameters.
|
||||
# 921180 checks if any counter is > 1.
|
||||
#
|
||||
# One HPP attack vector is to try evade signature filters by distributing the
|
||||
# attack payload across multiple parameters with the same name.
|
||||
# This works as many security devices only apply signatures to individual
|
||||
# parameter payloads, however the back-end web application may (in the case
|
||||
# of ASP.NET) consolidate all of the payloads into one thus making the
|
||||
# attack payload active.
|
||||
#
|
||||
# [ References ]
|
||||
# http://tacticalwebappsec.blogspot.com/2009/05/http-parameter-pollution.html
|
||||
# https://capec.mitre.org/data/definitions/460.html
|
||||
#
|
||||
SecRule ARGS_NAMES "@rx ." \
|
||||
"id:921170,\
|
||||
phase:2,\
|
||||
pass,\
|
||||
nolog,\
|
||||
tag:'application-multi',\
|
||||
tag:'language-multi',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-protocol',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/152/137/15/460',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
setvar:'TX.paramcounter_%{MATCHED_VAR_NAME}=+1'"
|
||||
|
||||
SecRule TX:/paramcounter_.*/ "@gt 1" \
|
||||
"id:921180,\
|
||||
phase:2,\
|
||||
pass,\
|
||||
msg:'HTTP Parameter Pollution (%{TX.1})',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-multi',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-protocol',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/152/137/15/460',\
|
||||
tag:'paranoia-level/3',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
chain"
|
||||
SecRule MATCHED_VARS_NAMES "@rx TX:paramcounter_(.*)" \
|
||||
"capture,\
|
||||
setvar:'tx.http_violation_score=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.inbound_anomaly_score_pl3=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
|
||||
# -=[ HTTP Parameter Pollution ]=-
|
||||
#
|
||||
# [ Rule Logic ]
|
||||
# Parameter pollution rule 921180 PL3 can by bypassed when a weak backend parameter
|
||||
# parser is ignoring additional characters in a parameter array name after the
|
||||
# closing of the array.
|
||||
# Rule 921210 PL3 prevents this by disallowing arbitrary strings after an array has
|
||||
# been closed or inbetween the square brackets in multidimensional arrays.
|
||||
# Please note that rule 921120 allows for 2-dimensional, but not for higher dimensional
|
||||
# arrays. If these are flagged as attacks, a rule exclusion will have to be
|
||||
# deployed; ideally for the parameter(s) in question.
|
||||
#
|
||||
# [ References ]
|
||||
# Private bug bounty in Spring 2022, findings Z05OZUCH.
|
||||
#
|
||||
# [ Payloads ]
|
||||
# * foo[1]a=bar&foo[1]b=<evil> - parameter parsers often cut after the closing of
|
||||
# the array. 921180 PL3 takes the full name, though.
|
||||
# This impediance mismatch allows for bypasses.
|
||||
# * foo[1]x[1]=bar&foo[1]x[2]=<evil> - extension of 1; this has the advantage that
|
||||
# the parameter name does end with "]" just like a valid array notation.
|
||||
#
|
||||
SecRule ARGS_NAMES "@rx (][^\]]+$|][^\]]+\[)" \
|
||||
"id:921210,\
|
||||
phase:2,\
|
||||
pass,\
|
||||
log,\
|
||||
msg:'HTTP Parameter Pollution after detecting bogus char after parameter array',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-multi',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-protocol',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/152/137/15/460',\
|
||||
tag:'paranoia-level/3',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.http_violation_score=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.inbound_anomaly_score_pl3=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
|
||||
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:921017,phase:1,pass,nolog,skipAfter:END-REQUEST-921-PROTOCOL-ATTACK"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:921018,phase:2,pass,nolog,skipAfter:END-REQUEST-921-PROTOCOL-ATTACK"
|
||||
#
|
||||
# -= Paranoia Level 4 =- (apply only when tx.detection_paranoia_level is sufficiently high: 4 or higher)
|
||||
#
|
||||
|
||||
# -=[ HTTP Parameter Pollution ]=-
|
||||
#
|
||||
# [ Rule Logic ]
|
||||
# Parameter pollution rule 921180 PL3 and 921210 PL3 can by bypassed if a
|
||||
# weak backend parameter parser ignores parameter array alltogether at
|
||||
# cuts parameter names at the first occurrence of the "[" character.
|
||||
# The rule 921220 PL4 prevents this by disallowing parameter array names.
|
||||
#
|
||||
# If an application needs parameter array names, then this rule should be
|
||||
# disabled, ideally by issueing a rule exclusion for the parameter names
|
||||
# that need it.
|
||||
#
|
||||
# [ References ]
|
||||
# Private bug bounty in Spring 2022, finding 5UXE4RK0.
|
||||
#
|
||||
# [ Payloads ]
|
||||
# * foo[1]=bar&foo[2]=<evil>
|
||||
# * foo=bar&foo[1]=<evil>
|
||||
# * foo[1]=bar&foo[1]acb]=<evil> - this is an edge case that 921210 PL3 is not
|
||||
# able to catch since the parameter name ends with "]".
|
||||
#
|
||||
SecRule ARGS_NAMES "@rx \[" \
|
||||
"id:921220,\
|
||||
phase:2,\
|
||||
pass,\
|
||||
log,\
|
||||
msg:'HTTP Parameter Pollution possible via array notation',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-multi',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-protocol',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/152/137/15/460',\
|
||||
tag:'paranoia-level/4',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.http_violation_score=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.inbound_anomaly_score_pl4=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
|
||||
|
||||
#
|
||||
# -= Paranoia Levels Finished =-
|
||||
#
|
||||
SecMarker "END-REQUEST-921-PROTOCOL-ATTACK"
|
||||
@@ -0,0 +1,92 @@
|
||||
# ------------------------------------------------------------------------
|
||||
# OWASP ModSecurity Core Rule Set ver.4.0.0-rc1
|
||||
# Copyright (c) 2006-2020 Trustwave and contributors. All rights reserved.
|
||||
# Copyright (c) 2021-2022 Core Rule Set project. All rights reserved.
|
||||
#
|
||||
# The OWASP ModSecurity Core Rule Set is distributed under
|
||||
# Apache Software License (ASL) version 2
|
||||
# Please see the enclosed LICENSE file for full details.
|
||||
# ------------------------------------------------------------------------
|
||||
|
||||
#
|
||||
# -= Paranoia Level 0 (empty) =- (apply unconditionally)
|
||||
#
|
||||
|
||||
# This file is to address the 3UWMWA6W vulnerability.
|
||||
# It requires ModSecurity version 2.9.6 or 3.0.8 (or an updated version with backports
|
||||
# of the security fixes in these versions) or a compatible engine supporting these changes.
|
||||
#
|
||||
# If you cannot upgrade ModSecurity, this file will cause ModSecurity to fail to start.
|
||||
# In that case, you can temporarily delete this file. However, you will be missing
|
||||
# protection from these rules. Therefore, we recommend upgrading your engine instead.
|
||||
|
||||
# The rules in this file will be part of the 920 / 921 in the future.
|
||||
|
||||
# Only allow specific charsets when using "_charset_"
|
||||
# Note: this is in phase:2 because these are headers that come in the body
|
||||
SecRule &MULTIPART_PART_HEADERS:_charset_ "!@eq 0" \
|
||||
"id:922100,\
|
||||
phase:2,\
|
||||
block,\
|
||||
t:none,\
|
||||
msg:'Multipart content type global _charset_ definition is not allowed by policy',\
|
||||
logdata:'Matched Data: %{ARGS._charset_}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-multi',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-multipart-header',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/255/153',\
|
||||
tag:'paranoia-level/1',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
chain"
|
||||
SecRule ARGS:_charset_ "!@within |%{tx.allowed_request_content_type_charset}|" \
|
||||
"t:lowercase,\
|
||||
setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
|
||||
# Only allow specific charsets same as Rule 920600
|
||||
# Note: this is in phase:2 because these are headers that come in the body
|
||||
SecRule MULTIPART_PART_HEADERS "@rx ^content-type\s*:\s*(.*)$" \
|
||||
"id:922110,\
|
||||
phase:2,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,t:lowercase,\
|
||||
msg:'Illegal MIME Multipart Header content-type: charset parameter',\
|
||||
logdata:'Matched Data: %{TX.1} found within Content-Type multipart form',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-multi',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-protocol',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/272/220',\
|
||||
tag:'paranoia-level/1',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
chain"
|
||||
SecRule TX:1 "!@rx ^(?:(?:\*|[^!-\"\(-\),/:-\?\[-\]\{\}]+)/(?:\*|[^!-\"\(-\),/:-\?\[-\]\{\}]+)|\*)(?:[\s\v]*;[\s\v]*(?:charset[\s\v]*=[\s\v]*\"?(?:iso-8859-15?|utf-8|windows-1252)\b\"?|(?:[^\s\v -\"\(-\),/:-\?\[-\]c\{\}]|c(?:[^!-\"\(-\),/:-\?\[-\]h\{\}]|h(?:[^!-\"\(-\),/:-\?\[-\]a\{\}]|a(?:[^!-\"\(-\),/:-\?\[-\]r\{\}]|r(?:[^!-\"\(-\),/:-\?\[-\]s\{\}]|s(?:[^!-\"\(-\),/:-\?\[-\]e\{\}]|e[^!-\"\(-\),/:-\?\[-\]t\{\}]))))))[^!-\"\(-\),/:-\?\[-\]\{\}]*[\s\v]*=[\s\v]*[^!\(-\),/:-\?\[-\]\{\}]+);?)*(?:[\s\v]*,[\s\v]*(?:(?:\*|[^!-\"\(-\),/:-\?\[-\]\{\}]+)/(?:\*|[^!-\"\(-\),/:-\?\[-\]\{\}]+)|\*)(?:[\s\v]*;[\s\v]*(?:charset[\s\v]*=[\s\v]*\"?(?:iso-8859-15?|utf-8|windows-1252)\b\"?|(?:[^\s\v -\"\(-\),/:-\?\[-\]c\{\}]|c(?:[^!-\"\(-\),/:-\?\[-\]h\{\}]|h(?:[^!-\"\(-\),/:-\?\[-\]a\{\}]|a(?:[^!-\"\(-\),/:-\?\[-\]r\{\}]|r(?:[^!-\"\(-\),/:-\?\[-\]s\{\}]|s(?:[^!-\"\(-\),/:-\?\[-\]e\{\}]|e[^!-\"\(-\),/:-\?\[-\]t\{\}]))))))[^!-\"\(-\),/:-\?\[-\]\{\}]*[\s\v]*=[\s\v]*[^!\(-\),/:-\?\[-\]\{\}]+);?)*)*$" \
|
||||
"t:lowercase,\
|
||||
setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
# Content-Transfer-Encoding was deprecated by rfc7578 in 2015 and should not be used (see: https://www.rfc-editor.org/rfc/rfc7578#section-4.7)
|
||||
# Note: this is in phase:2 because these are headers that come in the body
|
||||
SecRule MULTIPART_PART_HEADERS "@rx content-transfer-encoding:(.*)" \
|
||||
"id:922120,\
|
||||
phase:2,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,t:lowercase,\
|
||||
msg:'Content-Transfer-Encoding was deprecated by rfc7578 in 2015 and should not be used',\
|
||||
logdata:'Matched Data: %{TX.0}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-multi',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-deprecated-header',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/272/220',\
|
||||
tag:'paranoia-level/1',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
|
||||
@@ -0,0 +1,203 @@
|
||||
# ------------------------------------------------------------------------
|
||||
# OWASP ModSecurity Core Rule Set ver.4.0.0-rc1
|
||||
# Copyright (c) 2006-2020 Trustwave and contributors. All rights reserved.
|
||||
# Copyright (c) 2021-2022 Core Rule Set project. All rights reserved.
|
||||
#
|
||||
# The OWASP ModSecurity Core Rule Set is distributed under
|
||||
# Apache Software License (ASL) version 2
|
||||
# Please see the enclosed LICENSE file for full details.
|
||||
# ------------------------------------------------------------------------
|
||||
|
||||
#
|
||||
# -= Paranoia Level 0 (empty) =- (apply unconditionally)
|
||||
#
|
||||
|
||||
|
||||
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:930011,phase:1,pass,nolog,skipAfter:END-REQUEST-930-APPLICATION-ATTACK-LFI"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:930012,phase:2,pass,nolog,skipAfter:END-REQUEST-930-APPLICATION-ATTACK-LFI"
|
||||
#
|
||||
# -= Paranoia Level 1 (default) =- (apply only when tx.detection_paranoia_level is sufficiently high: 1 or higher)
|
||||
#
|
||||
|
||||
#
|
||||
# -=[ Directory Traversal Attacks ]=-
|
||||
#
|
||||
# Ref: https://github.com/wireghoul/dotdotpwn
|
||||
#
|
||||
# [ Encoded /../ Payloads ]
|
||||
#
|
||||
# Regular expression generated from regex-assembly/930100.ra.
|
||||
# To update the regular expression run the following shell script
|
||||
# (consult https://coreruleset.org/docs/development/regex_assembly/ for details):
|
||||
# crs-toolchain regex update 930100
|
||||
#
|
||||
SecRule REQUEST_URI_RAW|ARGS|REQUEST_HEADERS|!REQUEST_HEADERS:Referer|FILES|XML:/* "@rx (?i)(?:[/\x5c]|%(?:2(?:f|5(?:2f|5c|c(?:1%259c|0%25af))|%46)|5c|c(?:0%(?:[2aq]f|5c|9v)|1%(?:[19p]c|8s|af))|(?:bg%q|(?:e|f(?:8%8)?0%8)0%80%a)f|u(?:221[5-6]|EFC8|F025|002f)|%3(?:2(?:%(?:%6|4)6|F)|5%%63)|1u)|0x(?:2f|5c))(?:\.(?:%0[0-1]|\?)?|\?\.?|%(?:2(?:(?:5(?:2|c0%25a))?e|%45)|c0(?:\.|%[25-6ae-f]e)|u(?:(?:ff0|002)e|2024)|%32(?:%(?:%6|4)5|E)|(?:e|f(?:(?:8|c%80)%8)?0%8)0%80%ae)|0x2e){2,3}(?:[/\x5c]|%(?:2(?:f|5(?:2f|5c|c(?:1%259c|0%25af))|%46)|5c|c(?:0%(?:[2aq]f|5c|9v)|1%(?:[19p]c|8s|af))|(?:bg%q|(?:e|f(?:8%8)?0%8)0%80%a)f|u(?:221[5-6]|EFC8|F025|002f)|%3(?:2(?:%(?:%6|4)6|F)|5%%63)|1u)|0x(?:2f|5c))" \
|
||||
"id:930100,\
|
||||
phase:2,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,\
|
||||
msg:'Path Traversal Attack (/../) or (/.../)',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-multi',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-lfi',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/255/153/126',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.lfi_score=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
#
|
||||
# [ Decoded /../ or /..;/ Payloads ]
|
||||
#
|
||||
# To prevent '..' from triggering, the regexp is split into two parts:
|
||||
# - ../
|
||||
# - /..
|
||||
# OR
|
||||
# - .../
|
||||
# - /...
|
||||
#
|
||||
# Semicolon added to prevent path traversal via reverse proxy mapping '/..;/' (Tomcat)
|
||||
#
|
||||
SecRule REQUEST_URI|ARGS|REQUEST_HEADERS|!REQUEST_HEADERS:Referer|FILES|XML:/* "@rx (?:(?:^|[\x5c/;])\.{2,3}[\x5c/;]|[\x5c/;]\.{2,3}(?:[\x5c/;]|$))" \
|
||||
"id:930110,\
|
||||
phase:2,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,t:utf8toUnicode,t:urlDecodeUni,t:removeNulls,t:cmdLine,\
|
||||
msg:'Path Traversal Attack (/../) or (/.../)',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-multi',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-lfi',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/255/153/126',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
multiMatch,\
|
||||
setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.lfi_score=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
#
|
||||
# -=[ OS File Access ]=-
|
||||
#
|
||||
# We check for OS file access with the help of a local file with OS files data.
|
||||
#
|
||||
# Ref: https://github.com/lightos/Panoptic/blob/master/cases.xml
|
||||
#
|
||||
# If you wonder where support for Google OAuth2 has gone, see:
|
||||
# https://github.com/coreruleset/google-oauth2-plugin
|
||||
SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@pmFromFile lfi-os-files.data" \
|
||||
"id:930120,\
|
||||
phase:2,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,t:utf8toUnicode,t:urlDecodeUni,t:normalizePathWin,\
|
||||
msg:'OS File Access Attempt',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-multi',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-lfi',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/255/153/126',\
|
||||
tag:'PCI/6.5.4',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.lfi_score=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
#
|
||||
# -=[ Restricted File Access ]=-
|
||||
#
|
||||
# Detects attempts to retrieve application source code, metadata,
|
||||
# credentials and version control history possibly reachable in a web root.
|
||||
#
|
||||
SecRule REQUEST_FILENAME "@pmFromFile restricted-files.data" \
|
||||
"id:930130,\
|
||||
phase:1,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,t:utf8toUnicode,t:urlDecodeUni,t:normalizePathWin,\
|
||||
msg:'Restricted File Access Attempt',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-multi',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-lfi',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/255/153/126',\
|
||||
tag:'PCI/6.5.4',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.lfi_score=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
|
||||
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:930013,phase:1,pass,nolog,skipAfter:END-REQUEST-930-APPLICATION-ATTACK-LFI"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:930014,phase:2,pass,nolog,skipAfter:END-REQUEST-930-APPLICATION-ATTACK-LFI"
|
||||
#
|
||||
# -= Paranoia Level 2 =- (apply only when tx.detection_paranoia_level is sufficiently high: 2 or higher)
|
||||
#
|
||||
|
||||
#
|
||||
# -=[ OS File Access ]=-
|
||||
#
|
||||
# This is a stricter sibling of rule 930120.
|
||||
# This stricter sibling checks for OS file data in request headers referer and user-agent.
|
||||
# We check for OS file access with the help of a local file with OS files data.
|
||||
#
|
||||
# Ref: https://github.com/lightos/Panoptic/blob/master/cases.xml
|
||||
#
|
||||
SecRule REQUEST_HEADERS:Referer|REQUEST_HEADERS:User-Agent "@pmFromFile lfi-os-files.data" \
|
||||
"id:930121,\
|
||||
phase:1,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,t:utf8toUnicode,t:urlDecodeUni,t:normalizePathWin,\
|
||||
msg:'OS File Access Attempt in REQUEST_HEADERS',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-multi',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-lfi',\
|
||||
tag:'paranoia-level/2',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/255/153/126',\
|
||||
tag:'PCI/6.5.4',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.lfi_score=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:930015,phase:1,pass,nolog,skipAfter:END-REQUEST-930-APPLICATION-ATTACK-LFI"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:930016,phase:2,pass,nolog,skipAfter:END-REQUEST-930-APPLICATION-ATTACK-LFI"
|
||||
#
|
||||
# -= Paranoia Level 3 =- (apply only when tx.detection_paranoia_level is sufficiently high: 3 or higher)
|
||||
#
|
||||
|
||||
|
||||
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:930017,phase:1,pass,nolog,skipAfter:END-REQUEST-930-APPLICATION-ATTACK-LFI"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:930018,phase:2,pass,nolog,skipAfter:END-REQUEST-930-APPLICATION-ATTACK-LFI"
|
||||
#
|
||||
# -= Paranoia Level 4 =- (apply only when tx.detection_paranoia_level is sufficiently high: 4 or higher)
|
||||
#
|
||||
|
||||
|
||||
|
||||
#
|
||||
# -= Paranoia Levels Finished =-
|
||||
#
|
||||
SecMarker "END-REQUEST-930-APPLICATION-ATTACK-LFI"
|
||||
@@ -0,0 +1,189 @@
|
||||
# ------------------------------------------------------------------------
|
||||
# OWASP ModSecurity Core Rule Set ver.4.0.0-rc1
|
||||
# Copyright (c) 2006-2020 Trustwave and contributors. All rights reserved.
|
||||
# Copyright (c) 2021-2022 Core Rule Set project. All rights reserved.
|
||||
#
|
||||
# The OWASP ModSecurity Core Rule Set is distributed under
|
||||
# Apache Software License (ASL) version 2
|
||||
# Please see the enclosed LICENSE file for full details.
|
||||
# ------------------------------------------------------------------------
|
||||
#
|
||||
# RFI Attacks
|
||||
#
|
||||
|
||||
#
|
||||
# -= Paranoia Level 0 (empty) =- (apply unconditionally)
|
||||
#
|
||||
|
||||
|
||||
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:931011,phase:1,pass,nolog,skipAfter:END-REQUEST-931-APPLICATION-ATTACK-RFI"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:931012,phase:2,pass,nolog,skipAfter:END-REQUEST-931-APPLICATION-ATTACK-RFI"
|
||||
#
|
||||
# -= Paranoia Level 1 (default) =- (apply only when tx.detection_paranoia_level is sufficiently high: 1 or higher)
|
||||
#
|
||||
|
||||
# -=[ Rule Logic ]=-
|
||||
# These rules look for common types of Remote File Inclusion (RFI) attack methods.
|
||||
# - URL Contains an IP Address
|
||||
# - The PHP "include()" Function
|
||||
# - RFI Data Ends with Question Mark(s) (?)
|
||||
# - RFI Host Doesn't Match Local Host
|
||||
#
|
||||
# -=[ References ]=-
|
||||
# http://projects.webappsec.org/Remote-File-Inclusion
|
||||
# http://tacticalwebappsec.blogspot.com/2009/06/generic-remote-file-inclusion-attack.html
|
||||
#
|
||||
SecRule ARGS "@rx ^(?i:file|ftps?|https?)://(?:\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})" \
|
||||
"id:931100,\
|
||||
phase:2,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,\
|
||||
msg:'Possible Remote File Inclusion (RFI) Attack: URL Parameter using IP Address',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-multi',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-rfi',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/152/175/253',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.rfi_score=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
SecRule QUERY_STRING|REQUEST_BODY "@rx (?i)(?:\binclude\s*\([^)]*|mosConfig_absolute_path|_CONF\[path\]|_SERVER\[DOCUMENT_ROOT\]|GALLERY_BASEDIR|path\[docroot\]|appserv_root|config\[root_dir\])=(?:file|ftps?|https?)://" \
|
||||
"id:931110,\
|
||||
phase:2,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,t:urlDecodeUni,\
|
||||
msg:'Possible Remote File Inclusion (RFI) Attack: Common RFI Vulnerable Parameter Name used w/URL Payload',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-multi',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-rfi',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/152/175/253',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.rfi_score=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
SecRule ARGS "@rx ^(?i:file|ftps?|https?).*?\?+$" \
|
||||
"id:931120,\
|
||||
phase:2,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,\
|
||||
msg:'Possible Remote File Inclusion (RFI) Attack: URL Payload Used w/Trailing Question Mark Character (?)',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-multi',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-rfi',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/152/175/253',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.rfi_score=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
|
||||
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:931013,phase:1,pass,nolog,skipAfter:END-REQUEST-931-APPLICATION-ATTACK-RFI"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:931014,phase:2,pass,nolog,skipAfter:END-REQUEST-931-APPLICATION-ATTACK-RFI"
|
||||
#
|
||||
# -= Paranoia Level 2 =- (apply only when tx.detection_paranoia_level is sufficiently high: 2 or higher)
|
||||
#
|
||||
|
||||
# url:file:// can be used by Java applications using
|
||||
# org.apache.commons.io.IOUtils to access internal files, so this has been added
|
||||
#
|
||||
# This rule has one (stricter) sibling: 931131.
|
||||
# That rule applies the same regular expression to the request filename in phase 1.
|
||||
#
|
||||
# Regular expression generated from regex-assembly/931130.ra.
|
||||
# To update the regular expression run the following shell script
|
||||
# (consult https://coreruleset.org/docs/development/regex_assembly/ for details):
|
||||
# crs-toolchain regex update 931130
|
||||
#
|
||||
SecRule ARGS "@rx (?i)(?:(?:url|jar):)?(?:a(?:cap|f[ps]|ttachment)|b(?:eshare|itcoin|lob)|c(?:a(?:llto|p)|id|vs|ompress.(?:zlib|bzip2))|d(?:a(?:v|ta)|ict|n(?:s|tp))|e(?:d2k|xpect)|f(?:(?:ee)?d|i(?:le|nger|sh)|tps?)|g(?:it|o(?:pher)?|lob)|h(?:323|ttps?)|i(?:ax|cap|(?:ma|p)ps?|rc[6s]?)|ja(?:bbe)?r|l(?:dap[is]?|ocal_file)|m(?:a(?:ilto|ven)|ms|umble)|n(?:e(?:tdoc|ws)|fs|ntps?)|ogg|p(?:aparazzi|h(?:ar|p)|op(?:2|3s?)|r(?:es|oxy)|syc)|r(?:mi|sync|tm(?:f?p)?|ar)|s(?:3|ftp|ips?|m(?:[bs]|tps?)|n(?:ews|mp)|sh(?:2(?:.(?:s(?:hell|(?:ft|c)p)|exec|tunnel))?)?|vn(?:\+ssh)?)|t(?:e(?:amspeak|lnet)|ftp|urns?)|u(?:dp|nreal|t2004)|v(?:entrilo|iew-source|nc)|w(?:ebcal|ss?)|x(?:mpp|ri)|zip)://(?:[^@]+@)?([^/]*)" \
|
||||
"id:931130,\
|
||||
phase:2,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,\
|
||||
msg:'Possible Remote File Inclusion (RFI) Attack: Off-Domain Reference/Link',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-multi',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-rfi',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/152/175/253',\
|
||||
tag:'paranoia-level/2',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.rfi_parameter_%{MATCHED_VAR_NAME}=.%{tx.1}',\
|
||||
chain"
|
||||
SecRule TX:/rfi_parameter_.*/ "!@endsWith .%{request_headers.host}" \
|
||||
"setvar:'tx.rfi_score=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
# This is a (stricter) sibling of 931130.
|
||||
#
|
||||
# Regular expression generated from regex-assembly/931131.ra.
|
||||
# To update the regular expression run the following shell script
|
||||
# (consult https://coreruleset.org/docs/development/regex_assembly/ for details):
|
||||
# crs-toolchain regex update 931131
|
||||
#
|
||||
SecRule REQUEST_FILENAME "@rx (?i)(?:(?:url|jar):)?(?:a(?:cap|f[ps]|ttachment)|b(?:eshare|itcoin|lob)|c(?:a(?:llto|p)|id|vs|ompress.(?:zlib|bzip2))|d(?:a(?:v|ta)|ict|n(?:s|tp))|e(?:d2k|xpect)|f(?:(?:ee)?d|i(?:le|nger|sh)|tps?)|g(?:it|o(?:pher)?|lob)|h(?:323|ttps?)|i(?:ax|cap|(?:ma|p)ps?|rc[6s]?)|ja(?:bbe)?r|l(?:dap[is]?|ocal_file)|m(?:a(?:ilto|ven)|ms|umble)|n(?:e(?:tdoc|ws)|fs|ntps?)|ogg|p(?:aparazzi|h(?:ar|p)|op(?:2|3s?)|r(?:es|oxy)|syc)|r(?:mi|sync|tm(?:f?p)?|ar)|s(?:3|ftp|ips?|m(?:[bs]|tps?)|n(?:ews|mp)|sh(?:2(?:.(?:s(?:hell|(?:ft|c)p)|exec|tunnel))?)?|vn(?:\+ssh)?)|t(?:e(?:amspeak|lnet)|ftp|urns?)|u(?:dp|nreal|t2004)|v(?:entrilo|iew-source|nc)|w(?:ebcal|ss?)|x(?:mpp|ri)|zip)://(?:[^@]+@)?([^/]*)" \
|
||||
"id:931131,\
|
||||
phase:1,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,t:urlDecodeUni,\
|
||||
msg:'Possible Remote File Inclusion (RFI) Attack: Off-Domain Reference/Link',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-multi',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-rfi',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/152/175/253',\
|
||||
tag:'paranoia-level/2',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.rfi_parameter_%{MATCHED_VAR_NAME}=.%{tx.1}',\
|
||||
chain"
|
||||
SecRule TX:/rfi_parameter_.*/ "!@endsWith .%{request_headers.host}" \
|
||||
"setvar:'tx.rfi_score=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:931015,phase:1,pass,nolog,skipAfter:END-REQUEST-931-APPLICATION-ATTACK-RFI"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:931016,phase:2,pass,nolog,skipAfter:END-REQUEST-931-APPLICATION-ATTACK-RFI"
|
||||
#
|
||||
# -= Paranoia Level 3 =- (apply only when tx.detection_paranoia_level is sufficiently high: 3 or higher)
|
||||
#
|
||||
|
||||
|
||||
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:931017,phase:1,pass,nolog,skipAfter:END-REQUEST-931-APPLICATION-ATTACK-RFI"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:931018,phase:2,pass,nolog,skipAfter:END-REQUEST-931-APPLICATION-ATTACK-RFI"
|
||||
#
|
||||
# -= Paranoia Level 4 =- (apply only when tx.detection_paranoia_level is sufficiently high: 4 or higher)
|
||||
#
|
||||
|
||||
|
||||
|
||||
#
|
||||
# -= Paranoia Levels Finished =-
|
||||
#
|
||||
SecMarker "END-REQUEST-931-APPLICATION-ATTACK-RFI"
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,768 @@
|
||||
# ------------------------------------------------------------------------
|
||||
# OWASP ModSecurity Core Rule Set ver.4.0.0-rc1
|
||||
# Copyright (c) 2006-2020 Trustwave and contributors. All rights reserved.
|
||||
# Copyright (c) 2021-2022 Core Rule Set project. All rights reserved.
|
||||
#
|
||||
# The OWASP ModSecurity Core Rule Set is distributed under
|
||||
# Apache Software License (ASL) version 2
|
||||
# Please see the enclosed LICENSE file for full details.
|
||||
# ------------------------------------------------------------------------
|
||||
|
||||
#
|
||||
# -= Paranoia Level 0 (empty) =- (apply unconditionally)
|
||||
#
|
||||
|
||||
|
||||
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:933011,phase:1,pass,nolog,skipAfter:END-REQUEST-933-APPLICATION-ATTACK-PHP"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:933012,phase:2,pass,nolog,skipAfter:END-REQUEST-933-APPLICATION-ATTACK-PHP"
|
||||
#
|
||||
# -= Paranoia Level 1 (default) =- (apply only when tx.detection_paranoia_level is sufficiently high: 1 or higher)
|
||||
#
|
||||
|
||||
#
|
||||
# -=[ PHP Injection Attacks ]=-
|
||||
#
|
||||
# [ References ]
|
||||
# http://rips-scanner.sourceforge.net/
|
||||
# https://www.owasp.org/index.php/PHP_Top_5#P1:_Remote_Code_Executionh
|
||||
#
|
||||
|
||||
#
|
||||
# [ PHP Open Tag Found ]
|
||||
#
|
||||
# Detects PHP open tags "<?" and "<?php".
|
||||
# http://www.php.net/manual/en/language.basic-syntax.phptags.php
|
||||
#
|
||||
# Care is taken to avoid false positives in XML declarations "<?xml..."
|
||||
#
|
||||
# Also detects "[php]", "[/php]" and "[\php]" tags used by some applications
|
||||
# to indicate PHP dynamic content.
|
||||
#
|
||||
# Previously, this rule also checked for the PHP close tag '?>', but
|
||||
# this resulted in false positives which were difficult to prevent.
|
||||
# Therefore, that pattern is now checked by rule 933190 in paranoia levels
|
||||
# 3 or higher.
|
||||
#
|
||||
SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?:<\?(?:[^x]|x[^m]|xm[^l]|xml[^\s]|xml$|$)|<\?php|\[(?:/|\x5c)?php\])" \
|
||||
"id:933100,\
|
||||
phase:2,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,t:lowercase,\
|
||||
msg:'PHP Injection Attack: PHP Open Tag Found',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-php',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-injection-php',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/152/242',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.php_injection_score=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
#
|
||||
# [ PHP Script Uploads ]
|
||||
#
|
||||
# Block file uploads with filenames ending in PHP related extensions
|
||||
# (.php, .phps, .phtml, .php5 etc).
|
||||
#
|
||||
# Many application contain Unrestricted File Upload vulnerabilities.
|
||||
# https://owasp.org/www-community/vulnerabilities/Unrestricted_File_Upload
|
||||
#
|
||||
# Attackers may use such a vulnerability to achieve remote code execution
|
||||
# by uploading a .php file. If the upload storage location is predictable
|
||||
# and not adequately protected, the attacker may then request the uploaded
|
||||
# .php file and have the code within it executed on the server.
|
||||
#
|
||||
# Also block files with just dot (.) characters after the extension:
|
||||
# https://community.rapid7.com/community/metasploit/blog/2013/08/15/time-to-patch-joomla
|
||||
#
|
||||
# Some AJAX uploaders use the nonstandard request headers X-Filename,
|
||||
# X_Filename, or X-File-Name to transmit the file name to the server;
|
||||
# scan these request headers as well as multipart/form-data file names.
|
||||
#
|
||||
SecRule FILES|REQUEST_HEADERS:X-Filename|REQUEST_HEADERS:X_Filename|REQUEST_HEADERS:X.Filename|REQUEST_HEADERS:X-File-Name "@rx .*\.ph(?:p\d*|tml|ar|ps|t|pt)\.*$" \
|
||||
"id:933110,\
|
||||
phase:2,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,t:lowercase,\
|
||||
msg:'PHP Injection Attack: PHP Script File Upload Found',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-php',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-injection-php',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/152/242',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.php_injection_score=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
|
||||
#
|
||||
# [ PHP Configuration Directives ]
|
||||
#
|
||||
SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@pmFromFile php-config-directives.data" \
|
||||
"id:933120,\
|
||||
phase:2,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,t:normalisePath,\
|
||||
msg:'PHP Injection Attack: Configuration Directive Found',\
|
||||
logdata:'Matched Data: %{TX.933120_TX_0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-php',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-injection-php',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/152/242',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.933120_tx_0=%{tx.0}',\
|
||||
chain"
|
||||
SecRule MATCHED_VARS "@pm =" \
|
||||
"capture,\
|
||||
setvar:'tx.php_injection_score=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
|
||||
#
|
||||
# [ PHP Variables ]
|
||||
#
|
||||
SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@pmFromFile php-variables.data" \
|
||||
"id:933130,\
|
||||
phase:2,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,t:normalisePath,t:urlDecodeUni,\
|
||||
msg:'PHP Injection Attack: Variables Found',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-php',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-injection-php',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/152/242',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.php_injection_score=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
|
||||
#
|
||||
# [ PHP I/O Streams ]
|
||||
#
|
||||
# The "php://" syntax can be used to refer to various objects, such as local files (for LFI),
|
||||
# remote urls (for RFI), or standard input/request body. Its occurrence indicates a possible attempt
|
||||
# to either inject PHP code or exploit a file inclusion vulnerability in a PHP web app.
|
||||
#
|
||||
# Examples:
|
||||
# php://filter/resource=./../../../wp-config.php
|
||||
# php://filter/resource=http://www.example.com
|
||||
# php://stdin
|
||||
# php://input
|
||||
#
|
||||
# http://php.net/manual/en/wrappers.php.php
|
||||
#
|
||||
SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i)php://(?:std(?:in|out|err)|(?:in|out)put|fd|memory|temp|filter)" \
|
||||
"id:933140,\
|
||||
phase:2,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,\
|
||||
msg:'PHP Injection Attack: I/O Stream Found',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-php',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-injection-php',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/152/242',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.php_injection_score=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
|
||||
#
|
||||
# [ PHP Wrappers ]
|
||||
#
|
||||
# PHP comes with many built-in wrappers for various URL-style protocols for use with the filesystem
|
||||
# functions such as fopen(), copy(), file_exists() and filesize(). Abusing of PHP wrappers like phar://
|
||||
# could lead to RCE as describled by Sam Thomas at BlackHat USA 2018 (https://bit.ly/2yaKV5X), even
|
||||
# wrappers like zlib://, glob://, rar://, zip://, etc... could lead to LFI and expect:// to RCE.
|
||||
#
|
||||
# Valid PHP wrappers can be found in the PHP documentation here:
|
||||
# https://www.php.net/manual/en/wrappers.php
|
||||
#
|
||||
# Regular expression generated from regex-assembly/933200.ra.
|
||||
# To update the regular expression run the following shell script
|
||||
# (consult https://coreruleset.org/docs/development/regex_assembly/ for details):
|
||||
# crs-toolchain regex update 933200
|
||||
#
|
||||
SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?:bzip2|expect|glob|ogg|(?:ph|r)ar|ssh2(?:.(?:s(?:hell|(?:ft|c)p)|exec|tunnel))?|z(?:ip|lib))://" \
|
||||
"id:933200,\
|
||||
phase:2,\
|
||||
block,\
|
||||
t:none,t:utf8toUnicode,t:urlDecodeUni,t:removeNulls,t:cmdLine,\
|
||||
msg:'PHP Injection Attack: Wrapper scheme detected',\
|
||||
logdata:'Matched Data: %{MATCHED_VAR} found within %{MATCHED_VAR_NAME}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-php',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-injection-php',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/152/242',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.php_injection_score=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
|
||||
#
|
||||
# [ PHP Functions ]
|
||||
#
|
||||
# Detecting PHP function names is useful to block PHP code injection attacks.
|
||||
# There are many PHP functions. We have to strike a balance between robust detection
|
||||
# of PHP code in content, and the risk of false positives.
|
||||
#
|
||||
# The list of PHP functions is divided into four groups of varying attack/false positive risk.
|
||||
# Four separate rules are used to detect these groups of functions:
|
||||
#
|
||||
# - Rule 933150: ~40 words highly common to PHP injection payloads and extremely rare in
|
||||
# natural language or other contexts.
|
||||
# Examples: 'base64_decode', 'file_get_contents'.
|
||||
# These words are detected as a match directly using @pmFromFile.
|
||||
# Function names are defined in php-function-names-933150.data
|
||||
#
|
||||
# - Rule 933160: ~220 words which are common in PHP code, but have a higher chance to cause
|
||||
# false positives in natural language or other contexts.
|
||||
# Examples: 'chr', 'eval'.
|
||||
# To mitigate false positives, a regexp looks for PHP function syntax, e.g. 'eval()'.
|
||||
# Regexp is generated from function names in util/regexp-assemble/data/933160.data
|
||||
#
|
||||
# - Rule 933151: ~1300 words of lesser importance. This includes most PHP functions and keywords.
|
||||
# Examples: 'addslashes', 'array_diff'.
|
||||
# For performance reasons, the @pmFromFile operator is used, and many functions from lesser
|
||||
# used PHP extensions are removed.
|
||||
# To mitigate false positives, we only match when the '(' character is also found.
|
||||
# This rule only runs in paranoia level 2 or higher.
|
||||
# Function names are defined in php-function-names-933151.data
|
||||
#
|
||||
# - Rule 933161: ~200 words with short or trivial names, possibly leading to false positives.
|
||||
# Examples: 'abs', 'cos'.
|
||||
# To mitigate false positives, a regexp matches on function syntax, e.g. 'abs()'.
|
||||
# This rule only runs in paranoia level 3 or higher.
|
||||
# Regexp is generated from function names in util/regexp-assemble/data/933161.data
|
||||
#
|
||||
|
||||
|
||||
#
|
||||
# [ PHP Functions: High-Risk PHP Function Names ]
|
||||
#
|
||||
# Rule 933150 contains a small list of function names which are highly indicative of a PHP
|
||||
# injection attack, for example 'base64_decode'.
|
||||
# We block these function names outright, without using a complex regexp or chain.
|
||||
# This could make the detection a bit more robust against possible bypasses.
|
||||
#
|
||||
SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_FILENAME|ARGS_NAMES|ARGS|XML:/* "@pmFromFile php-function-names-933150.data" \
|
||||
"id:933150,\
|
||||
phase:2,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,\
|
||||
msg:'PHP Injection Attack: High-Risk PHP Function Name Found',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-php',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-injection-php',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/152/242',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.php_injection_score=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
|
||||
#
|
||||
# [ PHP Functions: High-Risk PHP Function Calls ]
|
||||
#
|
||||
# Some PHP function names have a certain risk of false positives, due to short
|
||||
# names, full or partial overlap with common natural language terms, uses in
|
||||
# other contexts, et cetera. Some examples are 'eval', 'exec', 'system'.
|
||||
#
|
||||
# For these function names, we apply a regexp to look for PHP function syntax.
|
||||
# The regexp looks for a word boundary and adjoining parentheses.
|
||||
# For instance, we want to block 'eval()', but we want to allow 'medieval()'.
|
||||
#
|
||||
# We have to be careful of possible bypasses using comment syntax. Examples:
|
||||
#
|
||||
# system(...)
|
||||
# system (...)
|
||||
# system\t(...)
|
||||
# system /*comment*/ (...)
|
||||
# system /*multiline \n comment*/ (...)
|
||||
# system //comment \n (...)
|
||||
# system #comment \n (...)
|
||||
#
|
||||
# This rule is also triggered by the following exploit(s):
|
||||
# [ Apache Struts vulnerability CVE-2017-9791 - Exploit tested: https://www.exploit-db.com/exploits/42324 ]
|
||||
# [ Apache Struts vulnerability CVE-2018-11776 - Exploit tested: https://www.exploit-db.com/exploits/45260 ]
|
||||
# [ SAP CRM Java vulnerability CVE-2018-2380 - Exploit tested: https://www.exploit-db.com/exploits/44292 ]
|
||||
#
|
||||
# Regular expression generated from regex-assembly/933160.ra.
|
||||
# To update the regular expression run the following shell script
|
||||
# (consult https://coreruleset.org/docs/development/regex_assembly/ for details):
|
||||
# crs-toolchain regex update 933160
|
||||
#
|
||||
SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_FILENAME|ARGS_NAMES|ARGS|XML:/* "@rx (?i)\b\(?[\"']*(?:a(?:rray_(?:(?:diff|intersect)_u(?:assoc|key)|filter|map|reduce|u(?:diff|intersect)(?:_u?assoc)?)|ssert(?:_options)?)|b(?:(?:ase64_en|son_(?:de|en))code|zopen)|c(?:hr|onvert_uuencode|reate_function|url_(?:exec|file_create|init))|(?:debug_backtrac|json_(?:de|en)cod|tmpfil)e|e(?:rror_reporting|scapeshell(?:arg|cmd)|val|x(?:ec|if_(?:imagetype|read_data|t(?:agname|humbnail))))|f(?:i(?:le(?:(?:_exist|perm)s|(?:[acm]tim|inod)e|group)?|nfo_open)|open|(?:pu|unction_exis)ts|tp_(?:connec|ge|nb_(?:ge|pu)|pu)t|write)|g(?:et(?:_(?:c(?:fg_va|urrent_use)r|meta_tags)|(?:cw|lastmo)d|env|imagesize|my(?:[gpu]id|inode))|lob|z(?:compress|(?:(?:defla|wri)t|encod|fil)e|open|read))|h(?:(?:ash_(?:(?:hmac|update)_)?|ighlight_)file|e(?:ader_register_callback|x2bin)|tml(?:_entity_decode|entities|specialchars(?:_decode)?))|i(?:mage(?:2?wbmp|createfrom(?:gif|(?:jpe|pn)g|wbmp|x[bp]m)|g(?:d2?|if)|(?:jpe|pn)g|xbm)|ni_(?:get(?:_all)?|set)|ptcembed|s_(?:dir|(?:(?:execut|read|write?)ab|fi)le)|terator_apply)|m(?:b_(?:ereg(?:_(?:match|replace(?:_callback)?)|i(?:_replace)?)?|parse_str)|(?:d5|ove_uploaded)_file|ethod_exists|kdir|ysql_query)|o(?:b_(?:clean|end_(?:clean|flush)|flush|get_(?:c(?:lean|ontents)|flush)|start)|dbc_(?:connect|exec(?:ute)?|result(?:_all)?)|pendir)|p(?:a(?:rse_(?:ini_file|str)|ssthru)|g_(?:connect|(?:execut|prepar)e|query)|hp(?:_(?:strip_whitespac|unam)e|info|version)|o(?:pen|six_(?:get(?:(?:e[gu]|g)id|login|pwnam)|kill|mk(?:fifo|nod)|ttyname))|r(?:eg_(?:match(?:_all)?|replace(?:_callback(?:_array)?)?|split)|int_r|oc_(?:(?:clos|nic|terminat)e|get_status|open))|utenv)|r(?:awurl(?:de|en)code|e(?:ad(?:_exif_data|dir|(?:gz)?file)|(?:gister_(?:shutdown|tick)|name)_function)|unkit_(?:constant_(?:add|redefine)|(?:function|method)_(?:add|copy|re(?:defin|nam)e)))|s(?:e(?:ssion_s(?:et_save_handler|tart)|t(?:_(?:e(?:rror|xception)_handler|include_path|magic_quotes_runtime)|defaultstub))|h(?:a1_fil|ow_sourc)e|implexml_load_(?:file|string)|ocket_c(?:onnect|reate)|pl_autoload_register|qlite_(?:(?:(?:array|single|unbuffered)_)?query|create_(?:aggregate|function)|exec|p?open)|tr(?:eam_(?:context_create|socket_client)|ipc?slashes|rev)|ystem)|u(?:[ak]?sort|n(?:pack|serialize)|rl(?:de|en)code)|var_dump)(?:/(?:\*.*\*/|/.*)|#.*[\s\v]|\")*[\"']*\)?[\s\v]*\(.*\)" \
|
||||
"id:933160,\
|
||||
phase:2,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,\
|
||||
msg:'PHP Injection Attack: High-Risk PHP Function Call Found',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-php',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-injection-php',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/152/242',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.php_injection_score=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
|
||||
#
|
||||
# [ PHP Object Injection ]
|
||||
#
|
||||
# PHP Object Injection is an application level vulnerability that could allow
|
||||
# an attacker to perform different kinds of malicious attacks, such as
|
||||
# Code Injection, SQL Injection, Path Traversal and Application Denial of Service,
|
||||
# depending on the context.
|
||||
#
|
||||
# The vulnerability occurs when user-supplied input is not properly sanitized
|
||||
# before being passed to the unserialize() PHP function. Since PHP allows object
|
||||
# serialization, attackers could pass ad-hoc serialized strings to a vulnerable
|
||||
# unserialize() call, resulting in an arbitrary PHP object(s) injection into the
|
||||
# application scope.
|
||||
#
|
||||
# https://www.owasp.org/index.php/PHP_Object_Injection
|
||||
#
|
||||
# In serialized form, PHP objects have the following format:
|
||||
#
|
||||
# O:8:"stdClass":1:{s:1:"a";i:2;}
|
||||
# O:3:"Foo":0:{}
|
||||
#
|
||||
# Also detected are PHP objects with a custom unserializer:
|
||||
# http://www.phpinternalsbook.com/classes_objects/serialization.html
|
||||
# These have the following format:
|
||||
#
|
||||
# C:11:"ArrayObject":37:{x:i:0;a:1:{s:1:"a";s:1:"b";};m:a:0:{}}
|
||||
# C:3:"Foo":23:{s:15:"My private data";}
|
||||
#
|
||||
# HTTP headers are inspected, since PHP object injection vulnerabilities have been
|
||||
# found in applications parsing them:
|
||||
# https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-8562 (User-Agent header)
|
||||
# https://www.exploit-db.com/exploits/39033/ (X-Forwarded-For header)
|
||||
# http://karmainsecurity.com/KIS-2015-10 (Host header)
|
||||
#
|
||||
SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_HEADERS|ARGS_NAMES|ARGS|XML:/* "@rx [oOcC]:\d+:\".+?\":\d+:{.*}" \
|
||||
"id:933170,\
|
||||
phase:2,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,\
|
||||
msg:'PHP Injection Attack: Serialized Object Injection',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-php',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-injection-php',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/152/242',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.php_injection_score=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
|
||||
|
||||
#
|
||||
# [ PHP Functions: Variable Function Calls ]
|
||||
#
|
||||
# PHP 'variable functions' provide an alternate syntax for calling PHP functions.
|
||||
# http://php.net/manual/en/functions.variable-functions.php
|
||||
#
|
||||
# An attacker may use variable function syntax to evade detection of function
|
||||
# names during exploitation of a remote code execution vulnerability.
|
||||
# An example to use the 'file_get_contents' function while evading rule 933150:
|
||||
#
|
||||
# $fn = 'file_' . 'get_' . 'contents';
|
||||
# echo $fn('wp-co' . 'nfig.php');
|
||||
#
|
||||
# Some examples from obfuscated malware:
|
||||
#
|
||||
# $OOO0000O0(...)
|
||||
# @$b374k(...)
|
||||
# $_[@-_]($_[@!+_] )
|
||||
#
|
||||
# A breakdown of the regular expression:
|
||||
#
|
||||
# \$+
|
||||
# The variable's '$' char, or multiple '$' for 'variable variables':
|
||||
# http://php.net/manual/en/language.variables.variable.php
|
||||
# (?:[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*|\s*{.+})
|
||||
# One of the following:
|
||||
# - A variable name; regexp from http://php.net/language.variables.basics
|
||||
# - A nonempty expression for variable variables: ${'fn'} or $ {'fn'}
|
||||
# (?:\s|\[.+\]|{.+}|/\*.*\*/|//.*|#.*)*
|
||||
# Optional whitespace, array access, or comments
|
||||
# \(.*\)
|
||||
# Parentheses optionally containing function parameters
|
||||
#
|
||||
SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_FILENAME|ARGS_NAMES|ARGS|XML:/* "@rx \$+(?:[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*|\s*{.+})(?:\s|\[.+\]|{.+}|/\*.*\*/|//.*|#.*)*\(.*\)" \
|
||||
"id:933180,\
|
||||
phase:2,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,\
|
||||
msg:'PHP Injection Attack: Variable Function Call Found',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-php',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-injection-php',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/152/242',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.php_injection_score=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
# [ PHP Functions: Variable Function Prevent Bypass ]
|
||||
#
|
||||
# Referring to https://www.secjuice.com/php-rce-bypass-filters-sanitization-waf/
|
||||
# Regex test on https://regex101.com/r/x1tfXG/1
|
||||
# the rule 933180 could be bypassed by using the following payloads:
|
||||
#
|
||||
# - (system)('uname');
|
||||
# - (sy.(st).em)('uname');
|
||||
# - (string)"system"('uname');
|
||||
# - define('x', 'sys' . 'tem');(x)/* comment */('uname');
|
||||
# - $y = 'sys'.'tem';($y)('uname');
|
||||
# - define('z', [['sys' .'tem']]);(z)[0][0]('uname');
|
||||
# - (system)(ls);
|
||||
# - (/**/system)(ls/**/);
|
||||
# - (['system'])[0]('uname');
|
||||
# - (++[++system++][++0++])++{/*dsasd*/0}++(++ls++);
|
||||
#
|
||||
# This rule blocks all payloads above and avoids to block values like:
|
||||
#
|
||||
# - [ACME] this is a test (just a test)
|
||||
# - Test (with two) rounded (brackets)
|
||||
#
|
||||
# Regular expression generated from regex-assembly/933210.ra.
|
||||
# To update the regular expression run the following shell script
|
||||
# (consult https://coreruleset.org/docs/development/regex_assembly/ for details):
|
||||
# crs-toolchain regex update 933210
|
||||
#
|
||||
SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_FILENAME|ARGS_NAMES|ARGS|XML:/* "@rx (?:\((?:.+\)(?:[\"'][\-0-9A-Z_a-z]+[\"'])?\(.+|[^\)]*string[^\)]*\)[\s\v\"'\--\.0-9A-\[\]_a-\{\}]+\([^\)]*)|(?:\[[0-9]+\]|\{[0-9]+\}|\$[^\(-\),\.-/;\x5c]+|[\"'][\-0-9A-Z\x5c_a-z]+[\"'])\(.+)\);" \
|
||||
"id:933210,\
|
||||
phase:2,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,t:urlDecode,t:replaceComments,t:removeWhitespace,\
|
||||
msg:'PHP Injection Attack: Variable Function Call Found',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-php',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-injection-php',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/152/242',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.php_injection_score=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:933013,phase:1,pass,nolog,skipAfter:END-REQUEST-933-APPLICATION-ATTACK-PHP"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:933014,phase:2,pass,nolog,skipAfter:END-REQUEST-933-APPLICATION-ATTACK-PHP"
|
||||
#
|
||||
# -= Paranoia Level 2 =- (apply only when tx.detection_paranoia_level is sufficiently high: 2 or higher)
|
||||
#
|
||||
|
||||
#
|
||||
# [ PHP Functions: Medium-Risk PHP Function Names ]
|
||||
#
|
||||
# In paranoia level 2, we add additional checks for most PHP functions.
|
||||
#
|
||||
# The size of the PHP function list is considerable.
|
||||
# Even after excluding the more obscure PHP extensions, 1300+ functions remain.
|
||||
# For performance and maintenance reasons, this rule does not use a regexp,
|
||||
# but uses a phrase file (@pmFromFile), and additionally looks for an '(' character
|
||||
# in the matched variable.
|
||||
#
|
||||
# This approach carries some risk for false positives. Therefore, the function list
|
||||
# has been curated to remove words closely matching natural language and terms often
|
||||
# used in other contexts.
|
||||
#
|
||||
# This rule is a stricter sibling of rule 933150.
|
||||
#
|
||||
SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_FILENAME|ARGS_NAMES|ARGS|XML:/* "@pmFromFile php-function-names-933151.data" \
|
||||
"id:933151,\
|
||||
phase:2,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,\
|
||||
msg:'PHP Injection Attack: Medium-Risk PHP Function Name Found',\
|
||||
logdata:'Matched Data: %{TX.933151_TX_0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-php',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-injection-php',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/152/242',\
|
||||
tag:'paranoia-level/2',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.933151_tx_0=%{tx.0}',\
|
||||
chain"
|
||||
SecRule MATCHED_VARS "@pm (" \
|
||||
"capture,\
|
||||
setvar:'tx.php_injection_score=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
|
||||
|
||||
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:933015,phase:1,pass,nolog,skipAfter:END-REQUEST-933-APPLICATION-ATTACK-PHP"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:933016,phase:2,pass,nolog,skipAfter:END-REQUEST-933-APPLICATION-ATTACK-PHP"
|
||||
#
|
||||
# -= Paranoia Level 3 =- (apply only when tx.detection_paranoia_level is sufficiently high: 3 or higher)
|
||||
#
|
||||
|
||||
#
|
||||
# [ PHP Variables: Common Variable Indexes ]
|
||||
#
|
||||
# In paranoia level 3, we add additional checks for parameters to many PHP variables.
|
||||
#
|
||||
#
|
||||
# One of the more common variables used within attacks on PHP is $_SERVER. Because
|
||||
# of how many different ways PHP has for executing variables (variable variables,
|
||||
# etc) often just looking for $_SERVER will be less effective than looking for the
|
||||
# various indexes within $_SERVER. This rule checks for these indexes.
|
||||
# This rule is located in PL 3 because often developers will use these names as
|
||||
# parameter names or values and this will lead to false positives.
|
||||
# Because this list is not expected to change and it is limited in size we use a
|
||||
# regex in this case to look for these values whereas in its sibling rule we use
|
||||
# @pmFromFile for flexibility and performance.
|
||||
#
|
||||
# Regular expression generated from regex-assembly/933131.ra.
|
||||
# To update the regular expression run the following shell script
|
||||
# (consult https://coreruleset.org/docs/development/regex_assembly/ for details):
|
||||
# crs-toolchain regex update 933131
|
||||
#
|
||||
# This rule is a stricter sibling of rule 933130.
|
||||
SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx AUTH_TYPE|HTTP_(?:ACCEPT(?:_(?:CHARSET|ENCODING|LANGUAGE))?|CONNECTION|(?:HOS|USER_AGEN)T|KEEP_ALIVE|(?:REFERE|X_FORWARDED_FO)R)|ORIG_PATH_INFO|PATH_(?:INFO|TRANSLATED)|QUERY_STRING|REQUEST_URI" \
|
||||
"id:933131,\
|
||||
phase:2,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,t:normalisePath,t:urlDecodeUni,\
|
||||
msg:'PHP Injection Attack: Variables Found',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-php',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-injection-php',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/152/242',\
|
||||
tag:'paranoia-level/3',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.php_injection_score=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.inbound_anomaly_score_pl3=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
|
||||
#
|
||||
# [ PHP Functions: Low-Value PHP Function Calls ]
|
||||
#
|
||||
# In paranoia level 3, we add additional checks for the remaining PHP functions.
|
||||
#
|
||||
# Most of these function names are likely to cause false positives in natural text
|
||||
# or common parameter values, such as 'abs', 'copy', 'date', 'key', 'max', 'min'.
|
||||
# Therefore, these function names are not scanned in lower paranoia levels.
|
||||
#
|
||||
# To mitigate the risk of false positives somewhat, a regexp is used to look for
|
||||
# PHP function syntax. (See rule 933160 for a description.)
|
||||
#
|
||||
# This rule is a stricter sibling of rule 933160.
|
||||
#
|
||||
# This rule is also triggered by the following exploit(s):
|
||||
# [ Apache Struts vulnerability CVE-2018-11776 - Exploit tested: https://www.exploit-db.com/exploits/45262 ]
|
||||
# [ SAP CRM Java vulnerability CVE-2018-2380 - Exploit tested: https://www.exploit-db.com/exploits/44292 ]
|
||||
#
|
||||
# Regular expression generated from regex-assembly/933161.ra.
|
||||
# To update the regular expression run the following shell script
|
||||
# (consult https://coreruleset.org/docs/development/regex_assembly/ for details):
|
||||
# crs-toolchain regex update 933161
|
||||
#
|
||||
SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_FILENAME|ARGS_NAMES|ARGS|XML:/* "@rx (?i)\b(?:a(?:bs|cosh?|r(?:ray|sort)|s(?:inh?|(?:o|se)rt)|tan[2h]?)|b(?:asename|indec)|c(?:eil|h(?:dir|eckdate|mod|o(?:p|wn)|root)|lose(?:dir|log)|o(?:(?:mpac|(?:nsta|u)n)t|py|sh?)|(?:ryp|urren)t)|d(?:ate|e(?:coct|fined?)|i(?:(?:skfreespac)?e|r(?:name)?)|(?:oubleva)?l)|e(?:a(?:ch|ster_da(?:te|ys))|cho|mpty|nd|r(?:egi?|ror_log)|x(?:(?:i|trac)t|p(?:lode)?))|f(?:close|eof|gets|ile(?:owner|pro|(?:siz|typ)e)|l(?:o(?:atval|ck|or)|ush)|(?:mo|rea)d|stat|t(?:ell|ok)|unction)|g(?:et(?:date|t(?:ext|ype))|mdate)|h(?:ash|e(?:ader(?:s_(?:lis|sen)t)?|brev)|ypot)|i(?:conv|(?:dat|mplod)e|n(?:(?:clud|vok)e|t(?:div|val))|s(?:_(?:a(?:rray)?|bool|(?:calla|dou)ble|f(?:inite|loat)|in(?:finite|t(?:eger)?)|l(?:ink|ong)|n(?:an|u(?:ll|meric))|object|re(?:al|source)|s(?:calar|tring))|set))|join|k(?:ey|sort)|l(?:(?:cfirs|sta)t|evenshtein|i(?:nk(?:info)?|st)|o(?:caltime|g(?:1[0p])?)|trim)|m(?:a(?:i[ln]|x)|b(?:ereg|split)|etaphone|hash|i(?:crotime|n)|y?sql)|n(?:atsor|ex)t|o(?:ctdec|penlog|rd)|p(?:a(?:ck|thinfo)|close|i|o[sw]|r(?:ev|intf?))|quotemeta|r(?:an(?:d|ge)|e(?:adlin[ek]|(?:cod|nam|quir)e|set|wind)|ound|sort|trim)|s(?:(?:candi|ubst)r|(?:e(?:rializ|ttyp)|huffl)e|i(?:milar_text|nh?|zeof)|leep|o(?:rt|undex)|p(?:liti?|rintf)|qrt|rand|t(?:at|r(?:coll|(?:le|sp)n))|y(?:mlink|slog))|t(?:a(?:int|nh?)|e(?:mpnam|xtdomain)|ime|ouch|rim)|u(?:cfirst|mask|n(?:iqid|link|(?:se|tain)t)|s(?:leep|ort))|virtual|wordwrap)(?:[\s\v]|/(?:\*.*\*/|/.*)|#.*)*\(.*\)" \
|
||||
"id:933161,\
|
||||
phase:2,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,\
|
||||
msg:'PHP Injection Attack: Low-Value PHP Function Call Found',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-php',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-injection-php',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/152/242',\
|
||||
tag:'paranoia-level/3',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.php_injection_score=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.inbound_anomaly_score_pl3=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
|
||||
#
|
||||
# [ PHP Script Uploads: Superfluous extension ]
|
||||
#
|
||||
# Block file uploads with PHP related extensions (.php, .phps, .phtml,
|
||||
# .php5 etc) anywhere in the name, followed by a dot.
|
||||
#
|
||||
# Example: index.php.tmp
|
||||
#
|
||||
# Uploading of such files can lead to remote code execution if
|
||||
# Apache is configured with AddType and MultiViews, as Apache will
|
||||
# automatically do a filename match when the extension is unknown.
|
||||
# This configuration is fortunately not common in modern installs.
|
||||
#
|
||||
# Blocking these file names might lead to more false positives.
|
||||
#
|
||||
# Some AJAX uploaders use the nonstandard request headers X-Filename,
|
||||
# X_Filename, or X-File-Name to transmit the file name to the server;
|
||||
# scan these request headers as well as multipart/form-data file names.
|
||||
#
|
||||
# This rule is a stricter sibling of rule 933110.
|
||||
#
|
||||
SecRule FILES|REQUEST_HEADERS:X-Filename|REQUEST_HEADERS:X_Filename|REQUEST_HEADERS:X.Filename|REQUEST_HEADERS:X-File-Name "@rx .*\.(?:php\d*|phtml)\..*$" \
|
||||
"id:933111,\
|
||||
phase:2,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,t:lowercase,\
|
||||
msg:'PHP Injection Attack: PHP Script File Upload Found',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-php',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-injection-php',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/152/242',\
|
||||
tag:'paranoia-level/3',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.php_injection_score=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.inbound_anomaly_score_pl3=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
|
||||
# [ PHP Closing Tag Found ]
|
||||
#
|
||||
# http://www.php.net/manual/en/language.basic-syntax.phptags.php
|
||||
#
|
||||
# This check was extracted from 933100 (paranoia level 1), since the
|
||||
# checked sequence '?>' commonly causes false positives.
|
||||
# See issue #654 for discussion.
|
||||
#
|
||||
SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@pm ?>" \
|
||||
"id:933190,\
|
||||
phase:2,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,t:urlDecodeUni,\
|
||||
msg:'PHP Injection Attack: PHP Closing Tag Found',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-php',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-injection-php',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/152/242',\
|
||||
tag:'paranoia-level/3',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.php_injection_score=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.inbound_anomaly_score_pl3=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
|
||||
# [ PHP Functions: Variable Function Prevent Bypass ]
|
||||
#
|
||||
# This rule is a stricter sibling of 933210.
|
||||
# Unlike 933210, this rule will also match "this is a 'dog' (not a cat)", because the semi-colon at the end of the string is optional.
|
||||
# This is useful for PHP evals where the semi-colon is already hardcoded:
|
||||
# <?php eval("($input);") ?>
|
||||
#
|
||||
# Any potential function calls not at the end of a string will require a semi-colon to form valid PHP, which is automatically covered by 933210.
|
||||
#
|
||||
# Regular expression generated from regex-assembly/933211.ra.
|
||||
# To update the regular expression run the following shell script
|
||||
# (consult https://coreruleset.org/docs/development/regex_assembly/ for details):
|
||||
# crs-toolchain regex update 933211
|
||||
#
|
||||
SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_FILENAME|ARGS_NAMES|ARGS|XML:/* "@rx (?:\((?:.+\)(?:[\"'][\-0-9A-Z_a-z]+[\"'])?\(.+|[^\)]*string[^\)]*\)[\s\v\"'\--\.0-9A-\[\]_a-\{\}]+\([^\)]*)|(?:\[[0-9]+\]|\{[0-9]+\}|\$[^\(-\),\.-/;\x5c]+|[\"'][\-0-9A-Z\x5c_a-z]+[\"'])\(.+)\)(?:;|$)?" \
|
||||
"id:933211,\
|
||||
phase:2,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,t:urlDecode,t:replaceComments,t:removeWhitespace,\
|
||||
msg:'PHP Injection Attack: Variable Function Call Found',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-php',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-injection-php',\
|
||||
tag:'paranoia-level/3',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/152/242',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.php_injection_score=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.inbound_anomaly_score_pl3=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:933017,phase:1,pass,nolog,skipAfter:END-REQUEST-933-APPLICATION-ATTACK-PHP"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:933018,phase:2,pass,nolog,skipAfter:END-REQUEST-933-APPLICATION-ATTACK-PHP"
|
||||
#
|
||||
# -= Paranoia Level 4 =- (apply only when tx.detection_paranoia_level is sufficiently high: 4 or higher)
|
||||
#
|
||||
|
||||
|
||||
|
||||
#
|
||||
# -= Paranoia Levels Finished =-
|
||||
#
|
||||
SecMarker "END-REQUEST-933-APPLICATION-ATTACK-PHP"
|
||||
@@ -0,0 +1,388 @@
|
||||
# ------------------------------------------------------------------------
|
||||
# OWASP ModSecurity Core Rule Set ver.4.0.0-rc1
|
||||
# Copyright (c) 2006-2020 Trustwave and contributors. All rights reserved.
|
||||
# Copyright (c) 2021-2022 Core Rule Set project. All rights reserved.
|
||||
#
|
||||
# The OWASP ModSecurity Core Rule Set is distributed under
|
||||
# Apache Software License (ASL) version 2
|
||||
# Please see the enclosed LICENSE file for full details.
|
||||
# ------------------------------------------------------------------------
|
||||
|
||||
#
|
||||
# -= Paranoia Level 0 (empty) =- (apply unconditionally)
|
||||
#
|
||||
|
||||
|
||||
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:934011,phase:1,pass,nolog,skipAfter:END-REQUEST-934-APPLICATION-ATTACK-GENERIC"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:934012,phase:2,pass,nolog,skipAfter:END-REQUEST-934-APPLICATION-ATTACK-GENERIC"
|
||||
#
|
||||
# -= Paranoia Level 1 (default) =- (apply only when tx.detection_paranoia_level is sufficiently high: 1 or higher)
|
||||
#
|
||||
|
||||
|
||||
# [ NodeJS Insecure unserialization / generic RCE signatures ]
|
||||
#
|
||||
# Libraries performing insecure unserialization:
|
||||
# - node-serialize: _$$ND_FUNC$$_ (CVE-2017-5941)
|
||||
# - funcster: __js_function
|
||||
#
|
||||
# See:
|
||||
# https://opsecx.com/index.php/2017/02/08/exploiting-node-js-deserialization-bug-for-remote-code-execution/
|
||||
# https://www.acunetix.com/blog/web-security-zone/deserialization-vulnerabilities-attacking-deserialization-in-js/
|
||||
#
|
||||
# Some generic snippets used:
|
||||
# - function() {
|
||||
# - new Function(
|
||||
# - eval(
|
||||
# - String.fromCharCode(
|
||||
#
|
||||
# Last two are used by nodejsshell.py,
|
||||
# https://github.com/ajinabraham/Node.Js-Security-Course/blob/master/nodejsshell.py
|
||||
#
|
||||
# As base64 is sometimes (but not always) used to encode serialized values,
|
||||
# use multiMatch and t:base64decode.
|
||||
#
|
||||
# Regular expression generated from regex-assembly/934100.ra.
|
||||
# To update the regular expression run the following shell script
|
||||
# (consult https://coreruleset.org/docs/development/regex_assembly/ for details):
|
||||
# crs-toolchain regex update 934100
|
||||
#
|
||||
# Stricter sibling: 934101
|
||||
SecRule REQUEST_FILENAME|REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx _(?:\$\$ND_FUNC\$\$_|_js_function)|(?:\beval|new[\s\v]+Function[\s\v]*)\(|String\.fromCharCode|function\(\)\{|this\.constructor|module\.exports=|\([\s\v]*[^0-9A-Z_a-z]child_process[^0-9A-Z_a-z][\s\v]*\)|process(?:\.(?:(?:a(?:ccess|ppendfile|rgv|vailability)|c(?:aveats|h(?:mod|own)|(?:los|opyfil)e|p|reate(?:read|write)stream)|ex(?:ec(?:file)?|ists)|f(?:ch(?:mod|own)|data(?:sync)?|s(?:tat|ync)|utimes)|inodes|l(?:chmod|ink|stat|utimes)|mkd(?:ir|temp)|open(?:dir)?|r(?:e(?:ad(?:dir|file|link|v)?|name)|m)|s(?:pawn(?:file)?|tat|ymlink)|truncate|u(?:n(?:link|watchfile)|times)|w(?:atchfile|rite(?:file|v)?))(?:sync)?(?:\.call)?\(|binding|constructor|env|global|main(?:Module)?|process|require)|\[[\"'`](?:(?:a(?:ccess|ppendfile|rgv|vailability)|c(?:aveats|h(?:mod|own)|(?:los|opyfil)e|p|reate(?:read|write)stream)|ex(?:ec(?:file)?|ists)|f(?:ch(?:mod|own)|data(?:sync)?|s(?:tat|ync)|utimes)|inodes|l(?:chmod|ink|stat|utimes)|mkd(?:ir|temp)|open(?:dir)?|r(?:e(?:ad(?:dir|file|link|v)?|name)|m)|s(?:pawn(?:file)?|tat|ymlink)|truncate|u(?:n(?:link|watchfile)|times)|w(?:atchfile|rite(?:file|v)?))(?:sync)?|binding|constructor|env|global|main(?:Module)?|process|require)[\"'`]\])|(?:binding|constructor|env|global|main(?:Module)?|process|require)\[|console(?:\.(?:debug|error|info|trace|warn)(?:\.call)?\(|\[[\"'`](?:debug|error|info|trace|warn)[\"'`]\])|require(?:\.(?:resolve(?:\.call)?\(|main|extensions|cache)|\[[\"'`](?:(?:resolv|cach)e|main|extensions)[\"'`]\])" \
|
||||
"id:934100,\
|
||||
phase:2,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,t:urlDecodeUni,t:jsDecode,t:removeWhitespace,t:base64Decode,\
|
||||
msg:'Node.js Injection Attack 1/2',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-javascript',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-rce',\
|
||||
tag:'attack-injection-generic',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/152/242',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
multiMatch,\
|
||||
setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
|
||||
SecRule REQUEST_FILENAME|REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?:close|exists|fork|(?:ope|spaw)n|re(?:ad|quire)|w(?:atch|rite))[\s\v]*\(" \
|
||||
"id:934101,\
|
||||
phase:2,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,t:urlDecodeUni,t:base64Decode,\
|
||||
msg:'Node.js Injection Attack 2/2',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-javascript',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-rce',\
|
||||
tag:'attack-injection-generic',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/152/242',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
multiMatch,\
|
||||
setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
# -=[ SSRF Attacks ]=-
|
||||
#
|
||||
# We provide only partial protection to SSRF. DNS Rebinding attacks needs
|
||||
# to be handled at application level, and even those might be difficult to catch.
|
||||
#
|
||||
# PL1 rules are based on common attacks on cloud providers, based on well-known URLs.
|
||||
#
|
||||
# -=[ References ]=-
|
||||
# https://highon.coffee/blog/ssrf-cheat-sheet/
|
||||
# https://cwe.mitre.org/data/definitions/918.html
|
||||
# https://capec.mitre.org/data/definitions/664.html)
|
||||
#
|
||||
# Preventing: https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html
|
||||
|
||||
SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_FILENAME|ARGS_NAMES|ARGS|XML:/* "@pmFromFile ssrf.data" \
|
||||
"id:934110,\
|
||||
phase:2,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,\
|
||||
msg:'Possible Server Side Request Forgery (SSRF) Attack: Cloud provider metadata URL in Parameter',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-multi',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-ssrf',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/225/664',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
# JavaScript prototype pollution injection attempts
|
||||
#
|
||||
# Example from https://hackerone.com/reports/869574 critical
|
||||
# vulnerability in the TypeORM library:
|
||||
# {"text":"a","title":{"__proto__":{"where":{"name":"sqlinjection","where":null}}}}
|
||||
#
|
||||
# Test cases are based on this list of payloads:
|
||||
# https://github.com/BlackFan/client-side-prototype-pollution/blob/master/README.md
|
||||
#
|
||||
# See also: https://cwe.mitre.org/data/definitions/1321.html
|
||||
#
|
||||
# Note: only server-based (not DOM-based) attacks are covered here.
|
||||
# Stricter sibling: 934131
|
||||
|
||||
SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?:__proto__|constructor\s*(?:\.|\[)\s*prototype)" \
|
||||
"id:934130,\
|
||||
phase:2,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,t:urlDecodeUni,t:base64Decode,\
|
||||
msg:'JavaScript Prototype Pollution',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-javascript',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-rce',\
|
||||
tag:'attack-injection-generic',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1/180/77',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
multiMatch,\
|
||||
setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
# [ Ruby generic RCE signatures ]
|
||||
#
|
||||
# Detects Ruby-based injection attacks.
|
||||
# Example: Process.spawn("id")
|
||||
#
|
||||
# Regular expression generated from regex-assembly/934150.ra.
|
||||
# To update the regular expression run the following shell script
|
||||
# (consult https://coreruleset.org/docs/development/regex_assembly/ for details):
|
||||
# crs-toolchain regex update 934150
|
||||
#
|
||||
SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx Process[\s\v]*\.[\s\v]*spawn[\s\v]*\(" \
|
||||
"id:934150,\
|
||||
phase:2,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,\
|
||||
msg:'Ruby Injection Attack',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-ruby',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-rce',\
|
||||
tag:'attack-injection-generic',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/152/242',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
# [ NodeJS DoS signatures ]
|
||||
#
|
||||
# NodeJS runs in a single thread, so any evaluated payloads that block execution can cause an easy DoS.
|
||||
# This rule attempts to block e.g. while(true).
|
||||
#
|
||||
# Regular expression generated from regex-assembly/934160.ra.
|
||||
# To update the regular expression run the following shell script
|
||||
# (consult https://coreruleset.org/docs/development/regex_assembly/ for details):
|
||||
# crs-toolchain regex update 934160
|
||||
#
|
||||
SecRule REQUEST_FILENAME|REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx while[\s\v]*\([\s\v\(]*(?:!+(?:false|null|undefined|NaN|[\+\-]?0|\"{2}|'{2}|`{2})|(?:!!)*(?:(?:t(?:rue|his)|[\+\-]?(?:Infinity|[1-9][0-9]*)|new [A-Za-z][0-9A-Z_a-z]*|window|String|(?:Boolea|Functio)n|Object|Array)\b|\{.*\}|\[.*\]|\"[^\"]+\"|'[^']+'|`[^`]+`)).*\)" \
|
||||
"id:934160,\
|
||||
phase:2,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,t:urlDecodeUni,t:base64Decode,t:replaceComments,\
|
||||
msg:'Node.js DoS attack',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-javascript',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-rce',\
|
||||
tag:'attack-injection-generic',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/152/242',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
multiMatch,\
|
||||
setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
# [ PHP data: scheme ]
|
||||
#
|
||||
# PHP supports the `data:` scheme without using `//` before the content-type.
|
||||
#
|
||||
# Regular expression generated from regex-assembly/934170.ra.
|
||||
# To update the regular expression run the following shell script
|
||||
# (consult https://coreruleset.org/docs/development/regex_assembly/ for details):
|
||||
# crs-toolchain regex update 934170
|
||||
#
|
||||
SecRule REQUEST_FILENAME|REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx ^data:(?:(?:\*|[^!-\"\(-\),/:-\?\[-\]\{\}]+)/(?:\*|[^!-\"\(-\),/:-\?\[-\]\{\}]+)|\*)(?:[\s\v]*;[\s\v]*(?:charset[\s\v]*=[\s\v]*\"?(?:iso-8859-15?|utf-8|windows-1252)\b\"?|(?:[^\s\v -\"\(-\),/:-\?\[-\]c\{\}]|c(?:[^!-\"\(-\),/:-\?\[-\]h\{\}]|h(?:[^!-\"\(-\),/:-\?\[-\]a\{\}]|a(?:[^!-\"\(-\),/:-\?\[-\]r\{\}]|r(?:[^!-\"\(-\),/:-\?\[-\]s\{\}]|s(?:[^!-\"\(-\),/:-\?\[-\]e\{\}]|e[^!-\"\(-\),/:-\?\[-\]t\{\}]))))))[^!-\"\(-\),/:-\?\[-\]\{\}]*[\s\v]*=[\s\v]*[^!\(-\),/:-\?\[-\]\{\}]+);?)*(?:[\s\v]*,[\s\v]*(?:(?:\*|[^!-\"\(-\),/:-\?\[-\]\{\}]+)/(?:\*|[^!-\"\(-\),/:-\?\[-\]\{\}]+)|\*)(?:[\s\v]*;[\s\v]*(?:charset[\s\v]*=[\s\v]*\"?(?:iso-8859-15?|utf-8|windows-1252)\b\"?|(?:[^\s\v -\"\(-\),/:-\?\[-\]c\{\}]|c(?:[^!-\"\(-\),/:-\?\[-\]h\{\}]|h(?:[^!-\"\(-\),/:-\?\[-\]a\{\}]|a(?:[^!-\"\(-\),/:-\?\[-\]r\{\}]|r(?:[^!-\"\(-\),/:-\?\[-\]s\{\}]|s(?:[^!-\"\(-\),/:-\?\[-\]e\{\}]|e[^!-\"\(-\),/:-\?\[-\]t\{\}]))))))[^!-\"\(-\),/:-\?\[-\]\{\}]*[\s\v]*=[\s\v]*[^!\(-\),/:-\?\[-\]\{\}]+);?)*)*" \
|
||||
"id:934170,\
|
||||
phase:2,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,t:urlDecodeUni,\
|
||||
msg:'PHP data scheme attack',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-php',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-ssrf',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/152/242',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:934013,phase:1,pass,nolog,skipAfter:END-REQUEST-934-APPLICATION-ATTACK-GENERIC"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:934014,phase:2,pass,nolog,skipAfter:END-REQUEST-934-APPLICATION-ATTACK-GENERIC"
|
||||
#
|
||||
# -= Paranoia Level 2 =- (apply only when tx.detection_paranoia_level is sufficiently high: 2 or higher)
|
||||
#
|
||||
|
||||
# -=[ SSRF Attacks ]=-
|
||||
#
|
||||
# PL2 rules adds SSRF capture for common evasion techniques.
|
||||
#
|
||||
# We add captures for these evasion techniques: (see source in util/regexp-assemble/data/regexp-934120.data)
|
||||
# http://425.510.425.510/ Dotted decimal with overflow (already covered by RFI rule 931100)
|
||||
# http://2852039166/ Dotless decimal - \d{10}
|
||||
# http://7147006462/ Dotless decimal with overflow - \d{10}
|
||||
# http://0xA9.0xFE.0xA9.0xFE/ Dotted hexadecimal - (?:0x[a-f0-9]{2}\.){3}0x[a-f0-9]{2}
|
||||
# http://0xA9FEA9FE/ Dotless hexadecimal - 0x[a-f0-9]{8}
|
||||
# http://0x41414141A9FEA9FE/ Dotless hexadecimal with overflow - 0x[a-f0-9]{16}
|
||||
# http://0251.0376.0251.0376/ Dotted octal - Covered by the same below
|
||||
# http://0251.00376.000251.0000376/ Dotted octal with padding - (?:0{1,4}\d{3}\.){3}0{1,4}\d{3})
|
||||
# http://169.254.43518/ - (?:\d{1,3}\.){2}\.\d{5}
|
||||
# http://169.16689662/ - \d{1,3}\.\d{8}
|
||||
# http://[::ffff:a9fe:a9fe] IPV6 Compressed - IPv6 regex from https://ihateregex.io/expr/ipv6/, with [0-9] converted to \d and with non-capturing groups (below)
|
||||
# http://[0:0:0:0:0:ffff:a9fe:a9fe] IPV6 Expanded - (?:(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|(?:[0-9a-fA-F]{1,4}:){1,7}:|(?:[0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|(?:[0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|(?:[0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|(?:[0-9a-fA-F]{1,4}:){1,3}(?::[0-9a-fA-F]{1,4}){1,4}|(?:[0-9a-fA-F]{1,4}:){1,2}(?::[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:(?:(?::[0-9a-fA-F]{1,4}){1,6})|:(?:(?::[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(?::[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(?::0{1,4}){0,1}:){0,1}(?:(?:25[0-5]|(?:2[0-4]|1{0,1}\d){0,1}\d)\.){3,3}(?:25[0-5]|(?:2[0-4]|1{0,1}\d){0,1}\d)|(?:[0-9a-fA-F]{1,4}:){1,4}:(?:(?:25[0-5]|(2[0-4]|1{0,1}\d){0,1}\d)\.){3,3}(?:25[0-5]|(?:2[0-4]|1{0,1}\d){0,1}\d))
|
||||
# http://[0:0:0:0:0:ffff:169.254.169.254] IPV6/IPV4 - ((?:[0-9a-fA-F]{1,4}:){6}(?:(25[0-5]|(?:2[0-4]|1{0,1}\d){0,1}\d)\.){3,3}(?:25[0-5]|(?:2[0-4]|1{0,1}\d){0,1}\d))
|
||||
# http://[::]
|
||||
# http://127.88.23.245:22/+&@google.com:80#+@google.com:80/ (already covered by RFI rule 931100)
|
||||
# http://127.88.23.245:22/?@google.com:80/ (already covered by RFI rule 931100)
|
||||
# http://127.88.23.245:22/#@www.google.com:80/ (already covered by RFI rule 931100)
|
||||
# http://google.com:80\\@127.88.23.245:22/ (already covered by RFI rule 931100)
|
||||
# http://google.com:80+&@127.88.23.245:22/#+@google.com:80/
|
||||
# http://google.com:80+&@google.com:80#+@127.88.23.245:22/
|
||||
#
|
||||
# Regular expression generated from regex-assembly/934120.ra.
|
||||
# To update the regular expression run the following shell script
|
||||
# (consult https://coreruleset.org/docs/development/regex_assembly/ for details):
|
||||
# crs-toolchain regex update 934120
|
||||
#
|
||||
SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_FILENAME|ARGS_NAMES|ARGS|XML:/* "@rx (?i)((?:a(?:cap|f[ps]|ttachment)|b(?:eshare|itcoin|lob)|c(?:a(?:llto|p)|id|vs|ompress.(?:zlib|bzip2))|d(?:a(?:v|ta)|ict|n(?:s|tp))|e(?:d2k|xpect)|f(?:(?:ee)?d|i(?:le|nger|sh)|tps?)|g(?:it|o(?:pher)?|lob)|h(?:323|ttps?)|i(?:ax|cap|(?:ma|p)ps?|rc[6s]?)|ja(?:bbe)?r|l(?:dap[is]?|ocal_file)|m(?:a(?:ilto|ven)|ms|umble)|n(?:e(?:tdoc|ws)|fs|ntps?)|ogg|p(?:aparazzi|h(?:ar|p)|op(?:2|3s?)|r(?:es|oxy)|syc)|r(?:mi|sync|tm(?:f?p)?|ar)|s(?:3|ftp|ips?|m(?:[bs]|tps?)|n(?:ews|mp)|sh(?:2(?:.(?:s(?:hell|(?:ft|c)p)|exec|tunnel))?)?|vn(?:\+ssh)?)|t(?:e(?:amspeak|lnet)|ftp|urns?)|u(?:dp|nreal|t2004)|v(?:entrilo|iew-source|nc)|w(?:ebcal|ss?)|x(?:mpp|ri)|zip)://(?:[0-9]{10}|(?:0x[0-9a-f]{2}\.){3}0x[0-9a-f]{2}|0x(?:[0-9a-f]{8}|[0-9a-f]{16})|(?:0{1,4}[0-9]{1,3}\.){3}0{1,4}[0-9]{1,3}|[0-9]{1,3}\.(?:[0-9]{1,3}\.[0-9]{5}|[0-9]{8})|(?:\x5c\x5c[\-0-9a-z]\.?_?)+|\[[0-:a-f]+(?:[\.0-9]+|%[0-9A-Z_a-z]+)?\]|[a-z][\--\.0-9A-Z_a-z]{1,255}:[0-9]{1,5}(?:#?[\s\v]*&?@(?:(?:[0-9]{1,3}\.){3}[0-9]{1,3}|[a-z][\--\.0-9A-Z_a-z]{1,255}):[0-9]{1,5}/?)+|[\.0-9]{0,11}(?:\xe2(?:\x91[\xa0-\xbf]|\x92[\x80-\xbf]|\x93[\x80-\xa9\xab-\xbf])|\xe3\x80\x82)+))" \
|
||||
"id:934120,\
|
||||
phase:2,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,\
|
||||
msg:'Possible Server Side Request Forgery (SSRF) Attack: URL Parameter using IP Address',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-multi',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-ssrf',\
|
||||
tag:'paranoia-level/2',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/225/664',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx \[\s*constructor\s*\]" \
|
||||
"id:934131,\
|
||||
phase:2,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,t:urlDecodeUni,t:base64Decode,\
|
||||
msg:'JavaScript Prototype Pollution',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-javascript',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-rce',\
|
||||
tag:'attack-injection-generic',\
|
||||
tag:'paranoia-level/2',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/152/242',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
multiMatch,\
|
||||
setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
|
||||
# [ Perl generic RCE signatures ]
|
||||
#
|
||||
# Detects Perl-based injection attacks.
|
||||
# Example: @{[system whoami]}
|
||||
#
|
||||
# Regular expression generated from regex-assembly/934140.ra.
|
||||
# To update the regular expression run the following shell script
|
||||
# (consult https://coreruleset.org/docs/development/regex_assembly/ for details):
|
||||
# crs-toolchain regex update 934140
|
||||
#
|
||||
SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx @\{.*\}" \
|
||||
"id:934140,\
|
||||
phase:2,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,\
|
||||
msg:'Perl Injection Attack',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-perl',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-rce',\
|
||||
tag:'attack-injection-generic',\
|
||||
tag:'paranoia-level/2',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/152/242',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:934015,phase:1,pass,nolog,skipAfter:END-REQUEST-934-APPLICATION-ATTACK-GENERIC"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:934016,phase:2,pass,nolog,skipAfter:END-REQUEST-934-APPLICATION-ATTACK-GENERIC"
|
||||
#
|
||||
# -= Paranoia Level 3 =- (apply only when tx.detection_paranoia_level is sufficiently high: 3 or higher)
|
||||
#
|
||||
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:934017,phase:1,pass,nolog,skipAfter:END-REQUEST-934-APPLICATION-ATTACK-GENERIC"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:934018,phase:2,pass,nolog,skipAfter:END-REQUEST-934-APPLICATION-ATTACK-GENERIC"
|
||||
#
|
||||
# -= Paranoia Level 4 =- (apply only when tx.detection_paranoia_level is sufficiently high: 4 or higher)
|
||||
#
|
||||
|
||||
|
||||
|
||||
#
|
||||
# -= Paranoia Levels Finished =-
|
||||
#
|
||||
SecMarker "END-REQUEST-934-APPLICATION-ATTACK-GENERIC"
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,130 @@
|
||||
# ------------------------------------------------------------------------
|
||||
# OWASP ModSecurity Core Rule Set ver.4.0.0-rc1
|
||||
# Copyright (c) 2006-2020 Trustwave and contributors. All rights reserved.
|
||||
# Copyright (c) 2021-2022 Core Rule Set project. All rights reserved.
|
||||
#
|
||||
# The OWASP ModSecurity Core Rule Set is distributed under
|
||||
# Apache Software License (ASL) version 2
|
||||
# Please see the enclosed LICENSE file for full details.
|
||||
# ------------------------------------------------------------------------
|
||||
|
||||
#
|
||||
# -= Paranoia Level 0 (empty) =- (apply unconditionally)
|
||||
#
|
||||
|
||||
|
||||
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:943011,phase:1,pass,nolog,skipAfter:END-REQUEST-943-APPLICATION-ATTACK-SESSION-FIXATION"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:943012,phase:2,pass,nolog,skipAfter:END-REQUEST-943-APPLICATION-ATTACK-SESSION-FIXATION"
|
||||
#
|
||||
# -= Paranoia Level 1 (default) =- (apply only when tx.detection_paranoia_level is sufficiently high: 1 or higher)
|
||||
#
|
||||
|
||||
#
|
||||
# Session fixation
|
||||
#
|
||||
# -=[ References ]=-
|
||||
# http://projects.webappsec.org/Session-Fixation
|
||||
# http://projects.webappsec.org/w/page/13246960/Session%20Fixation
|
||||
# http://capec.mitre.org/data/definitions/61.html
|
||||
#
|
||||
SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i:\.cookie\b.*?;\W*?(?:expires|domain)\W*?=|\bhttp-equiv\W+set-cookie\b)" \
|
||||
"id:943100,\
|
||||
phase:2,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,t:urlDecodeUni,\
|
||||
msg:'Possible Session Fixation Attack: Setting Cookie Values in HTML',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-multi',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-fixation',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/225/21/593/61',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.session_fixation_score=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
|
||||
SecRule ARGS_NAMES "@rx ^(?:jsessionid|aspsessionid|asp\.net_sessionid|phpsession|phpsessid|weblogicsession|session_id|session-id|cfid|cftoken|cfsid|jservsession|jwsession)$" \
|
||||
"id:943110,\
|
||||
phase:2,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,t:lowercase,\
|
||||
msg:'Possible Session Fixation Attack: SessionID Parameter Name with Off-Domain Referer',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-multi',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-fixation',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/225/21/593/61',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
chain"
|
||||
SecRule REQUEST_HEADERS:Referer "@rx ^(?:ht|f)tps?://(.*?)/" \
|
||||
"capture,\
|
||||
chain"
|
||||
SecRule TX:1 "!@endsWith %{request_headers.host}" \
|
||||
"setvar:'tx.session_fixation_score=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
|
||||
SecRule ARGS_NAMES "@rx ^(?:jsessionid|aspsessionid|asp\.net_sessionid|phpsession|phpsessid|weblogicsession|session_id|session-id|cfid|cftoken|cfsid|jservsession|jwsession)$" \
|
||||
"id:943120,\
|
||||
phase:2,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,t:lowercase,\
|
||||
msg:'Possible Session Fixation Attack: SessionID Parameter Name with No Referer',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-multi',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-fixation',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/225/21/593/61',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
chain"
|
||||
SecRule &REQUEST_HEADERS:Referer "@eq 0" \
|
||||
"setvar:'tx.session_fixation_score=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
|
||||
|
||||
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:943013,phase:1,pass,nolog,skipAfter:END-REQUEST-943-APPLICATION-ATTACK-SESSION-FIXATION"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:943014,phase:2,pass,nolog,skipAfter:END-REQUEST-943-APPLICATION-ATTACK-SESSION-FIXATION"
|
||||
#
|
||||
# -= Paranoia Level 2 =- (apply only when tx.detection_paranoia_level is sufficiently high: 2 or higher)
|
||||
#
|
||||
|
||||
|
||||
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:943015,phase:1,pass,nolog,skipAfter:END-REQUEST-943-APPLICATION-ATTACK-SESSION-FIXATION"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:943016,phase:2,pass,nolog,skipAfter:END-REQUEST-943-APPLICATION-ATTACK-SESSION-FIXATION"
|
||||
#
|
||||
# -= Paranoia Level 3 =- (apply only when tx.detection_paranoia_level is sufficiently high: 3 or higher)
|
||||
#
|
||||
|
||||
|
||||
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:943017,phase:1,pass,nolog,skipAfter:END-REQUEST-943-APPLICATION-ATTACK-SESSION-FIXATION"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:943018,phase:2,pass,nolog,skipAfter:END-REQUEST-943-APPLICATION-ATTACK-SESSION-FIXATION"
|
||||
#
|
||||
# -= Paranoia Level 4 =- (apply only when tx.detection_paranoia_level is sufficiently high: 4 or higher)
|
||||
#
|
||||
|
||||
|
||||
|
||||
#
|
||||
# -= Paranoia Levels Finished =-
|
||||
#
|
||||
SecMarker "END-REQUEST-943-APPLICATION-ATTACK-SESSION-FIXATION"
|
||||
@@ -0,0 +1,465 @@
|
||||
# ------------------------------------------------------------------------
|
||||
# OWASP ModSecurity Core Rule Set ver.4.0.0-rc1
|
||||
# Copyright (c) 2006-2020 Trustwave and contributors. All rights reserved.
|
||||
# Copyright (c) 2021-2022 Core Rule Set project. All rights reserved.
|
||||
#
|
||||
# The OWASP ModSecurity Core Rule Set is distributed under
|
||||
# Apache Software License (ASL) version 2
|
||||
# Please see the enclosed LICENSE file for full details.
|
||||
# ------------------------------------------------------------------------
|
||||
|
||||
#
|
||||
# -= Paranoia Level 0 (empty) =- (apply unconditionally)
|
||||
#
|
||||
# Many rules check request bodies, use "SecRequestBodyAccess On" to enable it on main modsecurity configuration file.
|
||||
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:944011,phase:1,pass,nolog,skipAfter:END-REQUEST-944-APPLICATION-ATTACK-JAVA"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:944012,phase:2,pass,nolog,skipAfter:END-REQUEST-944-APPLICATION-ATTACK-JAVA"
|
||||
#
|
||||
# -= Paranoia Level 1 (default) =- (apply only when tx.detection_paranoia_level is sufficiently high: 1 or higher)
|
||||
#
|
||||
# This rule is also triggered by an Apache Struts exploit:
|
||||
# [ Apache Struts vulnerability CVE-2017-5638 - Exploit tested: https://github.com/xsscx/cve-2017-5638 ]
|
||||
#
|
||||
# This rule is also triggered by an Apache Struts Remote Code Execution exploit:
|
||||
# [ Apache Struts vulnerability CVE-2017-9791 - Exploit tested: https://www.exploit-db.com/exploits/42324 ]
|
||||
#
|
||||
# This rule is also triggered by an Apache Struts Remote Code Execution exploit:
|
||||
# [ Apache Struts vulnerability CVE-2017-9805 - Exploit tested: https://www.exploit-db.com/exploits/42627 ]
|
||||
#
|
||||
# This rule is also triggered by an Oracle WebLogic Remote Command Execution exploit:
|
||||
# [ Oracle WebLogic vulnerability CVE-2017-10271 - Exploit tested: https://www.exploit-db.com/exploits/43458 ]
|
||||
#
|
||||
SecRule ARGS|ARGS_NAMES|REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_BODY|REQUEST_HEADERS|XML:/*|XML://@* \
|
||||
"@rx java\.lang\.(?:runtime|processbuilder)" \
|
||||
"id:944100,\
|
||||
phase:2,\
|
||||
block,\
|
||||
t:none,t:lowercase,\
|
||||
msg:'Remote Command Execution: Suspicious Java class detected',\
|
||||
logdata:'Matched Data: %{MATCHED_VAR} found within %{MATCHED_VAR_NAME}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-java',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-rce',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/152/137/6',\
|
||||
tag:'PCI/6.5.2',\
|
||||
tag:'paranoia-level/1',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
# This rule is also triggered by the following exploit(s):
|
||||
# [ Apache Struts vulnerability CVE-2017-5638 - Exploit tested: https://github.com/xsscx/cve-2017-5638 ]
|
||||
# [ Apache Struts vulnerability CVE-2017-9791 - Exploit tested: https://www.exploit-db.com/exploits/42324 ]
|
||||
# [ Apache Struts vulnerability CVE-2017-9805 - Exploit tested: https://www.exploit-db.com/exploits/42627 ]
|
||||
# [ Java deserialization vulnerability/Apache Struts (CVE-2017-9805) ]
|
||||
# [ Java deserialization vulnerability/Oracle Weblogic (CVE-2017-10271) ]
|
||||
# [ SAP CRM Java vulnerability CVE-2018-2380 - Exploit tested: https://www.exploit-db.com/exploits/44292 ]
|
||||
#
|
||||
# Generic rule to detect processbuilder or runtime calls, if any of those is found and the same target contains
|
||||
# java. unmarshaller or base64data to trigger a potential payload execution
|
||||
# tested with https://www.exploit-db.com/exploits/42627/ and https://www.exploit-db.com/exploits/43458/
|
||||
|
||||
SecRule ARGS|ARGS_NAMES|REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_BODY|REQUEST_HEADERS|XML:/*|XML://@* \
|
||||
"@rx (?:runtime|processbuilder)" \
|
||||
"id:944110,\
|
||||
phase:2,\
|
||||
block,\
|
||||
t:none,t:lowercase,\
|
||||
msg:'Remote Command Execution: Java process spawn (CVE-2017-9805)',\
|
||||
logdata:'Matched Data: %{MATCHED_VAR} found within %{MATCHED_VAR_NAME}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-java',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-rce',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/152/248',\
|
||||
tag:'PCI/6.5.2',\
|
||||
tag:'paranoia-level/1',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
chain"
|
||||
SecRule ARGS|ARGS_NAMES|REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_BODY|REQUEST_HEADERS|XML:/*|XML://@* "@rx (?:unmarshaller|base64data|java\.)" \
|
||||
"setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
# Magic bytes detected and payload included possibly RCE vulnerable classes detected and process execution methods detected
|
||||
# anomaly score set to critical as all conditions indicate the request try to perform RCE.
|
||||
SecRule ARGS|ARGS_NAMES|REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_BODY|REQUEST_HEADERS|XML:/*|XML://@* \
|
||||
"@rx (?:clonetransformer|forclosure|instantiatefactory|instantiatetransformer|invokertransformer|prototypeclonefactory|prototypeserializationfactory|whileclosure|getproperty|filewriter|xmldecoder)" \
|
||||
"id:944120,\
|
||||
phase:2,\
|
||||
block,\
|
||||
t:none,t:lowercase,\
|
||||
msg:'Remote Command Execution: Java serialization (CVE-2015-4852)',\
|
||||
logdata:'Matched Data: %{MATCHED_VAR} found within %{MATCHED_VAR_NAME}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-java',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-rce',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/152/248',\
|
||||
tag:'PCI/6.5.2',\
|
||||
tag:'paranoia-level/1',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
chain"
|
||||
SecRule MATCHED_VARS "@rx (?:runtime|processbuilder)" \
|
||||
"setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
# This rule is also triggered by the following exploit(s):
|
||||
# [ Apache Struts vulnerability CVE-2017-5638 - Exploit tested: https://github.com/mazen160/struts-pwn ]
|
||||
# [ Apache Struts vulnerability CVE-2017-5638 - Exploit tested: https://github.com/xsscx/cve-2017-5638 ]
|
||||
# [ Apache Struts vulnerability CVE-2017-9791 - Exploit tested: https://www.exploit-db.com/exploits/42324 ]
|
||||
# [ Apache Struts vulnerability CVE-2017-9805 - Exploit tested: https://www.exploit-db.com/exploits/42627 ]
|
||||
# [ Oracle WebLogic vulnerability CVE-2017-10271 - Exploit tested: https://www.exploit-db.com/exploits/43458 ]
|
||||
# [ Apache Struts vulnerability CVE-2018-11776 - Exploit tested: https://www.exploit-db.com/exploits/45262 ]
|
||||
# [ Apache Struts vulnerability CVE-2018-11776 - Exploit tested: https://www.exploit-db.com/exploits/45260 ]
|
||||
#
|
||||
SecRule ARGS|ARGS_NAMES|REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_BODY|REQUEST_FILENAME|REQUEST_HEADERS|XML:/*|XML://@* \
|
||||
"@pmFromFile java-classes.data" \
|
||||
"id:944130,\
|
||||
phase:2,\
|
||||
block,\
|
||||
t:none,\
|
||||
msg:'Suspicious Java class detected',\
|
||||
logdata:'Matched Data: %{MATCHED_VAR} found within %{MATCHED_VAR_NAME}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-java',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-rce',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/152/248',\
|
||||
tag:'PCI/6.5.2',\
|
||||
tag:'paranoia-level/1',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
|
||||
#
|
||||
# [ Java Script Uploads ]
|
||||
#
|
||||
# Block file uploads with filenames ending in Java scripts (.jsp, .jspx)
|
||||
#
|
||||
# Many application contain Unrestricted File Upload vulnerabilities.
|
||||
# https://owasp.org/www-community/vulnerabilities/Unrestricted_File_Upload
|
||||
#
|
||||
# Attackers may use such a vulnerability to achieve remote code execution
|
||||
# by uploading a script file. If the upload storage location is predictable
|
||||
# and not adequately protected, the attacker may then request the uploaded
|
||||
# file and have the code within it executed on the server.
|
||||
#
|
||||
# Some AJAX uploaders use the nonstandard request headers X-Filename,
|
||||
# X_Filename, or X-File-Name to transmit the file name to the server;
|
||||
# scan these request headers as well as multipart/form-data file names.
|
||||
#
|
||||
SecRule FILES|REQUEST_HEADERS:X-Filename|REQUEST_HEADERS:X_Filename|REQUEST_HEADERS:X.Filename|REQUEST_HEADERS:X-File-Name "@rx .*\.(?:jsp|jspx)\.*$" \
|
||||
"id:944140,\
|
||||
phase:2,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,t:lowercase,\
|
||||
msg:'Java Injection Attack: Java Script File Upload Found',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-java',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-injection-java',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/152/242',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
|
||||
# Log4J / Log4Shell Defense
|
||||
#
|
||||
# This addresses exploits against the Log4J library described in several CVEs:
|
||||
# * CVE-2021-44228
|
||||
# * CVE-2021-44832
|
||||
# * CVE-2021-45046
|
||||
# * CVE-2021-45105
|
||||
#
|
||||
# See https://coreruleset.org/20211213/crs-and-log4j-log4shell-cve-2021-44228/
|
||||
#
|
||||
# This rule attempts to detect two things:
|
||||
# * Nested use of ${
|
||||
# * use of ${jndi:... without the closing bracket
|
||||
#
|
||||
# Rule 932130 is also essential for defense since there are certain
|
||||
# bypasses of the log4j rules that can be caught by 932130.
|
||||
#
|
||||
# The payload is not displayed in the alert message since log4j could
|
||||
# potentially be executed on the logviewer.
|
||||
#
|
||||
# This rule has stricter siblings: 944151 (PL2), 944152 (PL4)
|
||||
#
|
||||
# Regular expression generated from regex-assembly/944150.ra.
|
||||
# To update the regular expression run the following shell script
|
||||
# (consult https://coreruleset.org/docs/development/regex_assembly/ for details):
|
||||
# crs-toolchain regex update 944150
|
||||
#
|
||||
SecRule REQUEST_LINE|ARGS|ARGS_NAMES|REQUEST_COOKIES|REQUEST_COOKIES_NAMES|REQUEST_HEADERS|XML:/*|XML://@* "@rx (?i)(?:\$|$?)(?:\{|&l(?:brace|cub);?)(?:[^\}]{0,15}(?:\$|$?)(?:\{|&l(?:brace|cub);?)|jndi|ctx)" \
|
||||
"id:944150,\
|
||||
phase:2,\
|
||||
block,\
|
||||
t:none,t:urlDecodeUni,t:jsDecode,t:htmlEntityDecode,\
|
||||
log,\
|
||||
msg:'Potential Remote Command Execution: Log4j / Log4shell',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-java',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-rce',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/152/137/6',\
|
||||
tag:'PCI/6.5.2',\
|
||||
tag:'paranoia-level/1',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:944013,phase:1,pass,nolog,skipAfter:END-REQUEST-944-APPLICATION-ATTACK-JAVA"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:944014,phase:2,pass,nolog,skipAfter:END-REQUEST-944-APPLICATION-ATTACK-JAVA"
|
||||
#
|
||||
# -= Paranoia Level 2 =- (apply only when tx.detection_paranoia_level is sufficiently high: 2 or higher)
|
||||
#
|
||||
|
||||
# This is a stricter sibling of 944150.
|
||||
# It is a re-iteration of said rule without the curly bracket distance limiter
|
||||
# between the nested "${". This is prone to backtracking and therefore a potential
|
||||
# DoS problem for backtracking regular expression engines (e.g. PCRE2), but it also avoids evasions that fill the space between the nested
|
||||
# elements with arbitrary data.
|
||||
#
|
||||
# Regular expression generated from regex-assembly/944151.ra.
|
||||
# To update the regular expression run the following shell script
|
||||
# (consult https://coreruleset.org/docs/development/regex_assembly/ for details):
|
||||
# crs-toolchain regex update 944151
|
||||
#
|
||||
SecRule REQUEST_LINE|ARGS|ARGS_NAMES|REQUEST_COOKIES|REQUEST_COOKIES_NAMES|REQUEST_HEADERS|XML:/*|XML://@* "@rx (?i)(?:\$|$?)(?:\{|&l(?:brace|cub);?)(?:[^\}]*(?:\$|$?)(?:\{|&l(?:brace|cub);?)|jndi|ctx)" \
|
||||
"id:944151,\
|
||||
phase:2,\
|
||||
block,\
|
||||
t:none,t:urlDecodeUni,t:jsDecode,t:htmlEntityDecode,\
|
||||
log,\
|
||||
msg:'Potential Remote Command Execution: Log4j / Log4shell',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-java',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-rce',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/152/137/6',\
|
||||
tag:'PCI/6.5.2',\
|
||||
tag:'paranoia-level/2',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
# [ Java deserialization vulnerability/Apache Commons (CVE-2015-4852) ]
|
||||
#
|
||||
# Detect exploitation of "Java deserialization" Apache Commons.
|
||||
#
|
||||
# Based on rules by @spartantri.
|
||||
# https://spartantri.com/ModSecurity/?p=44
|
||||
#
|
||||
# Interesting references about the vulnerability
|
||||
# https://foxglovesecurity.com/2015/11/06/what-do-weblogic-websphere-jboss-jenkins-opennms-and-your-application-have-in-common-this-vulnerability/
|
||||
# https://github.com/GrrrDog/Java-Deserialization-Cheat-Sheet
|
||||
#
|
||||
# Potential false positives with random fields, the anomaly level is set low to avoid blocking request
|
||||
SecRule ARGS|ARGS_NAMES|REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_BODY|REQUEST_HEADERS|XML:/*|XML://@* \
|
||||
"@rx \xac\xed\x00\x05" \
|
||||
"id:944200,\
|
||||
phase:2,\
|
||||
block,\
|
||||
msg:'Magic bytes Detected, probable java serialization in use',\
|
||||
logdata:'Matched Data: %{MATCHED_VAR} found within %{MATCHED_VAR_NAME}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-java',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-rce',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/152/248',\
|
||||
tag:'PCI/6.5.2',\
|
||||
tag:'paranoia-level/2',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
# Detecting possible base64 text to match encoded magic bytes \xac\xed\x00\x05 with padding encoded in base64 strings are rO0ABQ KztAAU Cs7QAF
|
||||
SecRule ARGS|ARGS_NAMES|REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_BODY|REQUEST_HEADERS|XML:/*|XML://@* \
|
||||
"@rx (?:rO0ABQ|KztAAU|Cs7QAF)" \
|
||||
"id:944210,\
|
||||
phase:2,\
|
||||
block,\
|
||||
msg:'Magic bytes Detected Base64 Encoded, probable java serialization in use',\
|
||||
logdata:'Matched Data: %{MATCHED_VAR} found within %{MATCHED_VAR_NAME}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-java',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-rce',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/152/248',\
|
||||
tag:'PCI/6.5.2',\
|
||||
tag:'paranoia-level/2',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
SecRule ARGS|ARGS_NAMES|REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_BODY|REQUEST_HEADERS|XML:/*|XML://@* \
|
||||
"@rx (?:clonetransformer|forclosure|instantiatefactory|instantiatetransformer|invokertransformer|prototypeclonefactory|prototypeserializationfactory|whileclosure|getproperty|filewriter|xmldecoder)" \
|
||||
"id:944240,\
|
||||
phase:2,\
|
||||
block,\
|
||||
t:none,t:lowercase,\
|
||||
msg:'Remote Command Execution: Java serialization (CVE-2015-4852)',\
|
||||
logdata:'Matched Data: %{MATCHED_VAR} found within %{MATCHED_VAR_NAME}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-java',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-rce',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/152/248',\
|
||||
tag:'PCI/6.5.2',\
|
||||
tag:'paranoia-level/2',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
# This rule is also triggered by the following exploit(s):
|
||||
# [ SAP CRM Java vulnerability CVE-2018-2380 - Exploit tested: https://www.exploit-db.com/exploits/44292 ]
|
||||
#
|
||||
SecRule ARGS|ARGS_NAMES|REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_BODY|REQUEST_HEADERS|XML:/*|XML://@* \
|
||||
"@rx java\b.+(?:runtime|processbuilder)" \
|
||||
"id:944250,\
|
||||
phase:2,\
|
||||
block,\
|
||||
t:lowercase,\
|
||||
msg:'Remote Command Execution: Suspicious Java method detected',\
|
||||
logdata:'Matched Data: %{MATCHED_VAR} found within %{MATCHED_VAR_NAME}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-java',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-rce',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/152/248',\
|
||||
tag:'PCI/6.5.2',\
|
||||
tag:'paranoia-level/2',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
|
||||
# This rule is also triggered by the following exploit(s):
|
||||
# - https://www.rapid7.com/blog/post/2022/03/30/spring4shell-zero-day-vulnerability-in-spring-framework/
|
||||
# - https://www.ironcastle.net/possible-new-java-spring-framework-vulnerability-wed-mar-30th/
|
||||
#
|
||||
SecRule ARGS|ARGS_NAMES|REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_BODY|REQUEST_HEADERS|XML:/*|XML://@* \
|
||||
"@rx (?:class\.module\.classLoader\.resources\.context\.parent\.pipeline|springframework\.context\.support\.FileSystemXmlApplicationContext)" \
|
||||
"id:944260,\
|
||||
phase:2,\
|
||||
block,\
|
||||
t:urlDecodeUni,\
|
||||
msg:'Remote Command Execution: Malicious class-loading payload',\
|
||||
logdata:'Matched Data: %{MATCHED_VAR} found within %{MATCHED_VAR_NAME}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-java',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-rce',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/152/248',\
|
||||
tag:'PCI/6.5.2',\
|
||||
tag:'paranoia-level/2',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:944015,phase:1,pass,nolog,skipAfter:END-REQUEST-944-APPLICATION-ATTACK-JAVA"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:944016,phase:2,pass,nolog,skipAfter:END-REQUEST-944-APPLICATION-ATTACK-JAVA"
|
||||
#
|
||||
# -= Paranoia Level 3 =- (apply only when tx.detection_paranoia_level is sufficiently high: 3 or higher)
|
||||
#
|
||||
# Interesting keywords for possibly RCE on vulnerable classes and methods base64 encoded
|
||||
# Keywords = ['runtime', 'processbuilder', 'clonetransformer', 'forclosure', 'instantiatefactory', 'instantiatetransformer', 'invokertransformer', 'prototypeclonefactory', 'prototypeserializationfactory', 'whileclosure']
|
||||
#for item in keywords:
|
||||
# pad='\x00'
|
||||
# for padding in xrange(3):
|
||||
# print base64.b64encode(''.join([pad*padding,item])).replace('=','')[padding:],
|
||||
#cnVudGltZQ HJ1bnRpbWU BydW50aW1l cHJvY2Vzc2J1aWxkZXI HByb2Nlc3NidWlsZGVy Bwcm9jZXNzYnVpbGRlcg Y2xvbmV0cmFuc2Zvcm1lcg GNsb25ldHJhbnNmb3JtZXI BjbG9uZXRyYW5zZm9ybWVy Zm9yY2xvc3VyZQ GZvcmNsb3N1cmU Bmb3JjbG9zdXJl aW5zdGFudGlhdGVmYWN0b3J5 Gluc3RhbnRpYXRlZmFjdG9yeQ BpbnN0YW50aWF0ZWZhY3Rvcnk aW5zdGFudGlhdGV0cmFuc2Zvcm1lcg Gluc3RhbnRpYXRldHJhbnNmb3JtZXI BpbnN0YW50aWF0ZXRyYW5zZm9ybWVy aW52b2tlcnRyYW5zZm9ybWVy Gludm9rZXJ0cmFuc2Zvcm1lcg BpbnZva2VydHJhbnNmb3JtZXI cHJvdG90eXBlY2xvbmVmYWN0b3J5 HByb3RvdHlwZWNsb25lZmFjdG9yeQ Bwcm90b3R5cGVjbG9uZWZhY3Rvcnk cHJvdG90eXBlc2VyaWFsaXphdGlvbmZhY3Rvcnk HByb3RvdHlwZXNlcmlhbGl6YXRpb25mYWN0b3J5 Bwcm90b3R5cGVzZXJpYWxpemF0aW9uZmFjdG9yeQ d2hpbGVjbG9zdXJl HdoaWxlY2xvc3VyZQ B3aGlsZWNsb3N1cmU
|
||||
SecRule ARGS|ARGS_NAMES|REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_BODY|REQUEST_HEADERS|XML:/*|XML://@* \
|
||||
"@rx (?:cnVudGltZQ|HJ1bnRpbWU|BydW50aW1l|cHJvY2Vzc2J1aWxkZXI|HByb2Nlc3NidWlsZGVy|Bwcm9jZXNzYnVpbGRlcg|Y2xvbmV0cmFuc2Zvcm1lcg|GNsb25ldHJhbnNmb3JtZXI|BjbG9uZXRyYW5zZm9ybWVy|Zm9yY2xvc3VyZQ|GZvcmNsb3N1cmU|Bmb3JjbG9zdXJl|aW5zdGFudGlhdGVmYWN0b3J5|Gluc3RhbnRpYXRlZmFjdG9yeQ|BpbnN0YW50aWF0ZWZhY3Rvcnk|aW5zdGFudGlhdGV0cmFuc2Zvcm1lcg|Gluc3RhbnRpYXRldHJhbnNmb3JtZXI|BpbnN0YW50aWF0ZXRyYW5zZm9ybWVy|aW52b2tlcnRyYW5zZm9ybWVy|Gludm9rZXJ0cmFuc2Zvcm1lcg|BpbnZva2VydHJhbnNmb3JtZXI|cHJvdG90eXBlY2xvbmVmYWN0b3J5|HByb3RvdHlwZWNsb25lZmFjdG9yeQ|Bwcm90b3R5cGVjbG9uZWZhY3Rvcnk|cHJvdG90eXBlc2VyaWFsaXphdGlvbmZhY3Rvcnk|HByb3RvdHlwZXNlcmlhbGl6YXRpb25mYWN0b3J5|Bwcm90b3R5cGVzZXJpYWxpemF0aW9uZmFjdG9yeQ|d2hpbGVjbG9zdXJl|HdoaWxlY2xvc3VyZQ|B3aGlsZWNsb3N1cmU)" \
|
||||
"id:944300,\
|
||||
phase:2,\
|
||||
block,\
|
||||
t:none,\
|
||||
msg:'Base64 encoded string matched suspicious keyword',\
|
||||
logdata:'Matched Data: %{MATCHED_VAR} found within %{MATCHED_VAR_NAME}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-java',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-rce',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/152/248',\
|
||||
tag:'PCI/6.5.2',\
|
||||
tag:'paranoia-level/3',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.inbound_anomaly_score_pl3=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:944017,phase:1,pass,nolog,skipAfter:END-REQUEST-944-APPLICATION-ATTACK-JAVA"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:944018,phase:2,pass,nolog,skipAfter:END-REQUEST-944-APPLICATION-ATTACK-JAVA"
|
||||
#
|
||||
# -= Paranoia Level 4 =- (apply only when tx.detection_paranoia_level is sufficiently high: 4 or higher)
|
||||
#
|
||||
|
||||
# This is a stricter sibling of 944150.
|
||||
# It simply checks for the existence of `${`, taking into account the same encoding evasions
|
||||
# as 944150.
|
||||
#
|
||||
# Regular expression generated from regex-assembly/944152.ra.
|
||||
# To update the regular expression run the following shell script
|
||||
# (consult https://coreruleset.org/docs/development/regex_assembly/ for details):
|
||||
# crs-toolchain regex update 944152
|
||||
#
|
||||
SecRule REQUEST_LINE|ARGS|ARGS_NAMES|REQUEST_COOKIES|REQUEST_COOKIES_NAMES|REQUEST_HEADERS|XML:/*|XML://@* "@rx (?i)(?:\$|$?)(?:\{|&l(?:brace|cub);?)" \
|
||||
"id:944152,\
|
||||
phase:2,\
|
||||
block,\
|
||||
t:none,t:urlDecodeUni,t:jsDecode,t:htmlEntityDecode,\
|
||||
log,\
|
||||
msg:'Potential Remote Command Execution: Log4j / Log4shell',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-java',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-rce',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/152/137/6',\
|
||||
tag:'PCI/6.5.2',\
|
||||
tag:'paranoia-level/4',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.inbound_anomaly_score_pl4=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
#
|
||||
# -= Paranoia Levels Finished =-
|
||||
#
|
||||
SecMarker "END-REQUEST-944-APPLICATION-ATTACK-JAVA"
|
||||
@@ -0,0 +1,221 @@
|
||||
# ------------------------------------------------------------------------
|
||||
# OWASP ModSecurity Core Rule Set ver.4.0.0-rc1
|
||||
# Copyright (c) 2006-2020 Trustwave and contributors. All rights reserved.
|
||||
# Copyright (c) 2021-2022 Core Rule Set project. All rights reserved.
|
||||
#
|
||||
# The OWASP ModSecurity Core Rule Set is distributed under
|
||||
# Apache Software License (ASL) version 2
|
||||
# Please see the enclosed LICENSE file for full details.
|
||||
# ------------------------------------------------------------------------
|
||||
|
||||
#
|
||||
# -= Paranoia Level 0 (empty) =- (apply unconditionally)
|
||||
#
|
||||
|
||||
# Summing up the blocking and detection anomaly scores in phase 1
|
||||
# even when early blocking is disabled, we need to sum up the scores in phase 1
|
||||
# this prevents bugs in phase 5 if Apache skips phases because of error handling
|
||||
# See: https://github.com/coreruleset/coreruleset/issues/2319#issuecomment-1047503932
|
||||
|
||||
SecRule TX:BLOCKING_PARANOIA_LEVEL "@ge 1" \
|
||||
"id:949052,\
|
||||
phase:1,\
|
||||
pass,\
|
||||
t:none,\
|
||||
nolog,\
|
||||
setvar:'tx.blocking_inbound_anomaly_score=+%{tx.inbound_anomaly_score_pl1}'"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@ge 1" \
|
||||
"id:949152,\
|
||||
phase:1,\
|
||||
pass,\
|
||||
t:none,\
|
||||
nolog,\
|
||||
setvar:'tx.detection_inbound_anomaly_score=+%{tx.inbound_anomaly_score_pl1}'"
|
||||
|
||||
SecRule TX:BLOCKING_PARANOIA_LEVEL "@ge 2" \
|
||||
"id:949053,\
|
||||
phase:1,\
|
||||
pass,\
|
||||
t:none,\
|
||||
nolog,\
|
||||
setvar:'tx.blocking_inbound_anomaly_score=+%{tx.inbound_anomaly_score_pl2}'"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@ge 2" \
|
||||
"id:949153,\
|
||||
phase:1,\
|
||||
pass,\
|
||||
t:none,\
|
||||
nolog,\
|
||||
setvar:'tx.detection_inbound_anomaly_score=+%{tx.inbound_anomaly_score_pl2}'"
|
||||
|
||||
SecRule TX:BLOCKING_PARANOIA_LEVEL "@ge 3" \
|
||||
"id:949054,\
|
||||
phase:1,\
|
||||
pass,\
|
||||
t:none,\
|
||||
nolog,\
|
||||
setvar:'tx.blocking_inbound_anomaly_score=+%{tx.inbound_anomaly_score_pl3}'"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@ge 3" \
|
||||
"id:949154,\
|
||||
phase:1,\
|
||||
pass,\
|
||||
t:none,\
|
||||
nolog,\
|
||||
setvar:'tx.detection_inbound_anomaly_score=+%{tx.inbound_anomaly_score_pl3}'"
|
||||
|
||||
SecRule TX:BLOCKING_PARANOIA_LEVEL "@ge 4" \
|
||||
"id:949055,\
|
||||
phase:1,\
|
||||
pass,\
|
||||
t:none,\
|
||||
nolog,\
|
||||
setvar:'tx.blocking_inbound_anomaly_score=+%{tx.inbound_anomaly_score_pl4}'"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@ge 4" \
|
||||
"id:949155,\
|
||||
phase:1,\
|
||||
pass,\
|
||||
t:none,\
|
||||
nolog,\
|
||||
setvar:'tx.detection_inbound_anomaly_score=+%{tx.inbound_anomaly_score_pl4}'"
|
||||
|
||||
# at start of phase 2, we reset the aggregate scores to 0 to prevent duplicate counting of per-PL scores
|
||||
# this is necessary because the per-PL scores are counted across phases
|
||||
SecAction "id:949059,\
|
||||
phase:2,\
|
||||
pass,\
|
||||
t:none,\
|
||||
nolog,\
|
||||
setvar:'tx.blocking_inbound_anomaly_score=0'"
|
||||
SecAction "id:949159,\
|
||||
phase:2,\
|
||||
pass,\
|
||||
t:none,\
|
||||
nolog,\
|
||||
setvar:'tx.detection_inbound_anomaly_score=0'"
|
||||
|
||||
# Summing up the blocking and detection anomaly scores in phase 2
|
||||
|
||||
SecRule TX:BLOCKING_PARANOIA_LEVEL "@ge 1" \
|
||||
"id:949060,\
|
||||
phase:2,\
|
||||
pass,\
|
||||
t:none,\
|
||||
nolog,\
|
||||
setvar:'tx.blocking_inbound_anomaly_score=+%{tx.inbound_anomaly_score_pl1}'"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@ge 1" \
|
||||
"id:949160,\
|
||||
phase:2,\
|
||||
pass,\
|
||||
t:none,\
|
||||
nolog,\
|
||||
setvar:'tx.detection_inbound_anomaly_score=+%{tx.inbound_anomaly_score_pl1}'"
|
||||
|
||||
SecRule TX:BLOCKING_PARANOIA_LEVEL "@ge 2" \
|
||||
"id:949061,\
|
||||
phase:2,\
|
||||
pass,\
|
||||
t:none,\
|
||||
nolog,\
|
||||
setvar:'tx.blocking_inbound_anomaly_score=+%{tx.inbound_anomaly_score_pl2}'"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@ge 2" \
|
||||
"id:949161,\
|
||||
phase:2,\
|
||||
pass,\
|
||||
t:none,\
|
||||
nolog,\
|
||||
setvar:'tx.detection_inbound_anomaly_score=+%{tx.inbound_anomaly_score_pl2}'"
|
||||
|
||||
SecRule TX:BLOCKING_PARANOIA_LEVEL "@ge 3" \
|
||||
"id:949062,\
|
||||
phase:2,\
|
||||
pass,\
|
||||
t:none,\
|
||||
nolog,\
|
||||
setvar:'tx.blocking_inbound_anomaly_score=+%{tx.inbound_anomaly_score_pl3}'"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@ge 3" \
|
||||
"id:949162,\
|
||||
phase:2,\
|
||||
pass,\
|
||||
t:none,\
|
||||
nolog,\
|
||||
setvar:'tx.detection_inbound_anomaly_score=+%{tx.inbound_anomaly_score_pl3}'"
|
||||
|
||||
SecRule TX:BLOCKING_PARANOIA_LEVEL "@ge 4" \
|
||||
"id:949063,\
|
||||
phase:2,\
|
||||
pass,\
|
||||
t:none,\
|
||||
nolog,\
|
||||
setvar:'tx.blocking_inbound_anomaly_score=+%{tx.inbound_anomaly_score_pl4}'"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@ge 4" \
|
||||
"id:949163,\
|
||||
phase:2,\
|
||||
pass,\
|
||||
t:none,\
|
||||
nolog,\
|
||||
setvar:'tx.detection_inbound_anomaly_score=+%{tx.inbound_anomaly_score_pl4}'"
|
||||
|
||||
|
||||
SecMarker "BEGIN-REQUEST-BLOCKING-EVAL"
|
||||
|
||||
#
|
||||
# -=[ Anomaly Mode: Overall Transaction Anomaly Score ]=-
|
||||
#
|
||||
|
||||
# if early blocking is active, check threshold in phase 1
|
||||
SecRule TX:BLOCKING_INBOUND_ANOMALY_SCORE "@ge %{tx.inbound_anomaly_score_threshold}" \
|
||||
"id:949111,\
|
||||
phase:1,\
|
||||
deny,\
|
||||
t:none,\
|
||||
msg:'Inbound Anomaly Score Exceeded in phase 1 (Total Score: %{TX.BLOCKING_INBOUND_ANOMALY_SCORE})',\
|
||||
tag:'anomaly-evaluation',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
chain"
|
||||
SecRule TX:EARLY_BLOCKING "@eq 1"
|
||||
|
||||
# always check threshold in phase 2
|
||||
SecRule TX:BLOCKING_INBOUND_ANOMALY_SCORE "@ge %{tx.inbound_anomaly_score_threshold}" \
|
||||
"id:949110,\
|
||||
phase:2,\
|
||||
deny,\
|
||||
t:none,\
|
||||
msg:'Inbound Anomaly Score Exceeded (Total Score: %{TX.BLOCKING_INBOUND_ANOMALY_SCORE})',\
|
||||
tag:'anomaly-evaluation',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1'"
|
||||
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:949011,phase:1,pass,nolog,skipAfter:END-REQUEST-949-BLOCKING-EVALUATION"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:949012,phase:2,pass,nolog,skipAfter:END-REQUEST-949-BLOCKING-EVALUATION"
|
||||
#
|
||||
# -= Paranoia Level 1 (default) =- (apply only when tx.detection_paranoia_level is sufficiently high: 1 or higher)
|
||||
#
|
||||
|
||||
|
||||
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:949013,phase:1,pass,nolog,skipAfter:END-REQUEST-949-BLOCKING-EVALUATION"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:949014,phase:2,pass,nolog,skipAfter:END-REQUEST-949-BLOCKING-EVALUATION"
|
||||
#
|
||||
# -= Paranoia Level 2 =- (apply only when tx.detection_paranoia_level is sufficiently high: 2 or higher)
|
||||
#
|
||||
|
||||
|
||||
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:949015,phase:1,pass,nolog,skipAfter:END-REQUEST-949-BLOCKING-EVALUATION"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:949016,phase:2,pass,nolog,skipAfter:END-REQUEST-949-BLOCKING-EVALUATION"
|
||||
#
|
||||
# -= Paranoia Level 3 =- (apply only when tx.detection_paranoia_level is sufficiently high: 3 or higher)
|
||||
#
|
||||
|
||||
|
||||
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:949017,phase:1,pass,nolog,skipAfter:END-REQUEST-949-BLOCKING-EVALUATION"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:949018,phase:2,pass,nolog,skipAfter:END-REQUEST-949-BLOCKING-EVALUATION"
|
||||
#
|
||||
# -= Paranoia Level 4 =- (apply only when tx.detection_paranoia_level is sufficiently high: 4 or higher)
|
||||
#
|
||||
|
||||
|
||||
|
||||
#
|
||||
# -= Paranoia Levels Finished =-
|
||||
#
|
||||
SecMarker "END-REQUEST-949-BLOCKING-EVALUATION"
|
||||
@@ -0,0 +1,134 @@
|
||||
# ------------------------------------------------------------------------
|
||||
# OWASP ModSecurity Core Rule Set ver.4.0.0-rc1
|
||||
# Copyright (c) 2006-2020 Trustwave and contributors. All rights reserved.
|
||||
# Copyright (c) 2021-2022 Core Rule Set project. All rights reserved.
|
||||
#
|
||||
# The OWASP ModSecurity Core Rule Set is distributed under
|
||||
# Apache Software License (ASL) version 2
|
||||
# Please see the enclosed LICENSE file for full details.
|
||||
# ------------------------------------------------------------------------
|
||||
|
||||
# The paranoia level skip rules 950020, 950021 and 950022 have odd
|
||||
# numbers not in sync with other paranoia level skip rules in other
|
||||
# files. This is done to avoid rule id collisions with CRSv2.
|
||||
# This is also true for rule 950130.
|
||||
|
||||
#
|
||||
# -= Paranoia Level 0 (empty) =- (apply unconditionally)
|
||||
#
|
||||
|
||||
|
||||
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:950020,phase:3,pass,nolog,skipAfter:END-RESPONSE-950-DATA-LEAKAGES"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:950021,phase:4,pass,nolog,skipAfter:END-RESPONSE-950-DATA-LEAKAGES"
|
||||
#
|
||||
# -= Paranoia Level 1 (default) =- (apply only when tx.detection_paranoia_level is sufficiently high: 1 or higher)
|
||||
#
|
||||
|
||||
#
|
||||
# -=[ Directory Listing ]=-
|
||||
#
|
||||
SecRule RESPONSE_BODY "@rx (?:<(?:TITLE>Index of.*?<H|title>Index of.*?<h)1>Index of|>\[To Parent Directory\]</[Aa]><br>)" \
|
||||
"id:950130,\
|
||||
phase:4,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,\
|
||||
msg:'Directory Listing',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-multi',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-disclosure',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/118/116/54/127',\
|
||||
tag:'PCI/6.5.6',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'ERROR',\
|
||||
setvar:'tx.outbound_anomaly_score_pl1=+%{tx.error_anomaly_score}'"
|
||||
|
||||
#
|
||||
# -=[ CGI Source Code Leakage ]=-
|
||||
#
|
||||
# A CGI script begins normally with #! and the interpreter,
|
||||
# for example:
|
||||
#
|
||||
# #!/usr/bin/perl
|
||||
# #!/usr/bin/python
|
||||
# #!/usr/bin/ruby
|
||||
#
|
||||
# If the CGI script processors or MIME type handlers are misconfigured,
|
||||
# the script's source code could be erroneously returned to the client.
|
||||
SecRule RESPONSE_BODY "@rx ^#\!\s?/" \
|
||||
"id:950140,\
|
||||
phase:4,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,\
|
||||
msg:'CGI source code leakage',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-multi',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-disclosure',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/118/116',\
|
||||
tag:'PCI/6.5.6',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'ERROR',\
|
||||
setvar:'tx.outbound_anomaly_score_pl1=+%{tx.error_anomaly_score}'"
|
||||
|
||||
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:950013,phase:3,pass,nolog,skipAfter:END-RESPONSE-950-DATA-LEAKAGES"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:950014,phase:4,pass,nolog,skipAfter:END-RESPONSE-950-DATA-LEAKAGES"
|
||||
#
|
||||
# -= Paranoia Level 2 =- (apply only when tx.detection_paranoia_level is sufficiently high: 2 or higher)
|
||||
#
|
||||
|
||||
#
|
||||
# -=[ The application is not available - 5xx level status code ]=-
|
||||
#
|
||||
SecRule RESPONSE_STATUS "@rx ^5\d{2}$" \
|
||||
"id:950100,\
|
||||
phase:3,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,\
|
||||
msg:'The Application Returned a 500-Level Status Code',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-multi',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-disclosure',\
|
||||
tag:'PCI/6.5.6',\
|
||||
tag:'paranoia-level/2',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/152',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'ERROR',\
|
||||
setvar:'tx.outbound_anomaly_score_pl2=+%{tx.error_anomaly_score}'"
|
||||
|
||||
|
||||
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:950015,phase:3,pass,nolog,skipAfter:END-RESPONSE-950-DATA-LEAKAGES"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:950016,phase:4,pass,nolog,skipAfter:END-RESPONSE-950-DATA-LEAKAGES"
|
||||
#
|
||||
# -= Paranoia Level 3 =- (apply only when tx.detection_paranoia_level is sufficiently high: 3 or higher)
|
||||
#
|
||||
|
||||
|
||||
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:950017,phase:3,pass,nolog,skipAfter:END-RESPONSE-950-DATA-LEAKAGES"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:950022,phase:4,pass,nolog,skipAfter:END-RESPONSE-950-DATA-LEAKAGES"
|
||||
#
|
||||
# -= Paranoia Level 4 =- (apply only when tx.detection_paranoia_level is sufficiently high: 4 or higher)
|
||||
#
|
||||
|
||||
|
||||
|
||||
#
|
||||
# -= Paranoia Levels Finished =-
|
||||
#
|
||||
SecMarker "END-RESPONSE-950-DATA-LEAKAGES"
|
||||
@@ -0,0 +1,404 @@
|
||||
# ------------------------------------------------------------------------
|
||||
# OWASP ModSecurity Core Rule Set ver.4.0.0-rc1
|
||||
# Copyright (c) 2006-2020 Trustwave and contributors. All rights reserved.
|
||||
# Copyright (c) 2021-2022 Core Rule Set project. All rights reserved.
|
||||
#
|
||||
# The OWASP ModSecurity Core Rule Set is distributed under
|
||||
# Apache Software License (ASL) version 2
|
||||
# Please see the enclosed LICENSE file for full details.
|
||||
# ------------------------------------------------------------------------
|
||||
|
||||
#
|
||||
# -= Paranoia Level 0 (empty) =- (apply unconditionally)
|
||||
#
|
||||
|
||||
|
||||
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:951011,phase:3,pass,nolog,skipAfter:END-RESPONSE-951-DATA-LEAKAGES-SQL"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:951012,phase:4,pass,nolog,skipAfter:END-RESPONSE-951-DATA-LEAKAGES-SQL"
|
||||
#
|
||||
# -= Paranoia Level 1 (default) =- (apply only when tx.detection_paranoia_level is sufficiently high: 1 or higher)
|
||||
#
|
||||
|
||||
#
|
||||
# -=[ SQL Error Leakages ]=-
|
||||
#
|
||||
# Ref: https://raw.github.com/sqlmapproject/sqlmap/master/xml/errors.xml
|
||||
# Ref: https://github.com/Arachni/arachni/tree/master/components/checks/active/sql_injection/regexps
|
||||
#
|
||||
SecRule RESPONSE_BODY "!@pmFromFile sql-errors.data" \
|
||||
"id:951100,\
|
||||
phase:4,\
|
||||
pass,\
|
||||
t:none,\
|
||||
nolog,\
|
||||
tag:'application-multi',\
|
||||
tag:'language-multi',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-disclosure',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/118/116/54',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
skipAfter:END-SQL-ERROR-MATCH-PL1"
|
||||
|
||||
SecRule RESPONSE_BODY "@rx (?i:JET Database Engine|Access Database Engine|\[Microsoft\]\[ODBC Microsoft Access Driver\])" \
|
||||
"id:951110,\
|
||||
phase:4,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,\
|
||||
msg:'Microsoft Access SQL Information Leakage',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-multi',\
|
||||
tag:'platform-msaccess',\
|
||||
tag:'attack-disclosure',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/118/116/54',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
SecRule RESPONSE_BODY "@rx (?i:ORA-[0-9][0-9][0-9][0-9]|java\.sql\.SQLException|Oracle error|Oracle.*Driver|Warning.*oci_.*|Warning.*ora_.*)" \
|
||||
"id:951120,\
|
||||
phase:4,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,\
|
||||
msg:'Oracle SQL Information Leakage',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-multi',\
|
||||
tag:'platform-oracle',\
|
||||
tag:'attack-disclosure',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/118/116/54',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
SecRule RESPONSE_BODY "@rx (?i:DB2 SQL error:|\[IBM\]\[CLI Driver\]\[DB2/6000\]|CLI Driver.*DB2|DB2 SQL error|db2_\w+\()" \
|
||||
"id:951130,\
|
||||
phase:4,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,\
|
||||
msg:'DB2 SQL Information Leakage',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-multi',\
|
||||
tag:'platform-db2',\
|
||||
tag:'attack-disclosure',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/118/116/54',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
SecRule RESPONSE_BODY "@rx (?i:\[DM_QUERY_E_SYNTAX\]|has occurred in the vicinity of:)" \
|
||||
"id:951140,\
|
||||
phase:4,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,\
|
||||
msg:'EMC SQL Information Leakage',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-multi',\
|
||||
tag:'platform-emc',\
|
||||
tag:'attack-disclosure',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/118/116/54',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
SecRule RESPONSE_BODY "@rx (?i)Dynamic SQL Error" \
|
||||
"id:951150,\
|
||||
phase:4,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,\
|
||||
msg:'firebird SQL Information Leakage',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-multi',\
|
||||
tag:'platform-firebird',\
|
||||
tag:'attack-disclosure',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/118/116/54',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
SecRule RESPONSE_BODY "@rx (?i)Exception (?:condition )?\d+\. Transaction rollback\." \
|
||||
"id:951160,\
|
||||
phase:4,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,\
|
||||
msg:'Frontbase SQL Information Leakage',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-multi',\
|
||||
tag:'platform-frontbase',\
|
||||
tag:'attack-disclosure',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/118/116/54',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
SecRule RESPONSE_BODY "@rx (?i)org\.hsqldb\.jdbc" \
|
||||
"id:951170,\
|
||||
phase:4,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,\
|
||||
msg:'hsqldb SQL Information Leakage',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-multi',\
|
||||
tag:'platform-hsqldb',\
|
||||
tag:'attack-disclosure',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/118/116/54',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
SecRule RESPONSE_BODY "@rx (?i:An illegal character has been found in the statement|com\.informix\.jdbc|Exception.*Informix)" \
|
||||
"id:951180,\
|
||||
phase:4,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,\
|
||||
msg:'informix SQL Information Leakage',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-multi',\
|
||||
tag:'platform-informix',\
|
||||
tag:'attack-disclosure',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/118/116/54',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
SecRule RESPONSE_BODY "@rx (?i:Warning.*ingres_|Ingres SQLSTATE|Ingres\W.*Driver)" \
|
||||
"id:951190,\
|
||||
phase:4,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,\
|
||||
msg:'ingres SQL Information Leakage',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-multi',\
|
||||
tag:'platform-ingres',\
|
||||
tag:'attack-disclosure',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/118/116/54',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
SecRule RESPONSE_BODY "@rx (?i:<b>Warning</b>: ibase_|Unexpected end of command in statement)" \
|
||||
"id:951200,\
|
||||
phase:4,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,\
|
||||
msg:'interbase SQL Information Leakage',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-multi',\
|
||||
tag:'platform-interbase',\
|
||||
tag:'attack-disclosure',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/118/116/54',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
SecRule RESPONSE_BODY "@rx (?i:SQL error.*POS[0-9]+.*|Warning.*maxdb.*)" \
|
||||
"id:951210,\
|
||||
phase:4,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,\
|
||||
msg:'maxDB SQL Information Leakage',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-multi',\
|
||||
tag:'platform-maxdb',\
|
||||
tag:'attack-disclosure',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/118/116/54',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
SecRule RESPONSE_BODY "@rx (?i)(?:System\.Data\.OleDb\.OleDbException|\[Microsoft\]\[ODBC SQL Server Driver\]|\[Macromedia\]\[SQLServer JDBC Driver\]|\[SqlException|System\.Data\.SqlClient\.SqlException|Unclosed quotation mark after the character string|'80040e14'|mssql_query\(\)|Microsoft OLE DB Provider for ODBC Drivers|Microsoft OLE DB Provider for SQL Server|Incorrect syntax near|Sintaxis incorrecta cerca de|Syntax error in string in query expression|Procedure or function .* expects parameter|Unclosed quotation mark before the character string|Syntax error .* in query expression|Data type mismatch in criteria expression\.|ADODB\.Field \(0x800A0BCD\)|the used select statements have different number of columns|OLE DB.*SQL Server|Warning.*mssql_.*|Driver.*SQL[ _-]*Server|SQL Server.*Driver|SQL Server.*[0-9a-fA-F]{8}|Exception.*\WSystem\.Data\.SqlClient\.)" \
|
||||
"id:951220,\
|
||||
phase:4,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,\
|
||||
msg:'mssql SQL Information Leakage',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-multi',\
|
||||
tag:'platform-mssql',\
|
||||
tag:'attack-disclosure',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/118/116/54',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
# Regular expression generated from regex-assembly/951230.ra.
|
||||
# To update the regular expression run the following shell script
|
||||
# (consult https://coreruleset.org/docs/development/regex_assembly/ for details):
|
||||
# crs-toolchain regex update 951230
|
||||
#
|
||||
SecRule RESPONSE_BODY "@rx (?i)(?:supplied argument is not a valid |SQL syntax.*)MySQL|Column count doesn't match(?: value count at row)?|mysql_fetch_array\(\)|on MySQL result index|You have an error in your SQL syntax(?:;| near)|MyS(?:QL server version for the right syntax to use|qlClient\.)|\[MySQL\]\[ODBC|(?:Table '[^']+' doesn't exis|valid MySQL resul)t|Warning.{1,10}mysql_(?:[\(-\)_a-z]{1,26})?|ERROR [0-9]{4} \([0-9a-z]{5}\):" \
|
||||
"id:951230,\
|
||||
phase:4,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,\
|
||||
msg:'mysql SQL Information Leakage',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-multi',\
|
||||
tag:'platform-mysql',\
|
||||
tag:'attack-disclosure',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/118/116/54',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
# Regular expression generated from regex-assembly/951240.ra.
|
||||
# To update the regular expression run the following shell script
|
||||
# (consult https://coreruleset.org/docs/development/regex_assembly/ for details):
|
||||
# crs-toolchain regex update 951240
|
||||
#
|
||||
SecRule RESPONSE_BODY "@rx (?i)P(?:ostgreSQL(?: query failed:|.{1,20}ERROR)|G::[a-z]*Error)|pg_(?:query|exec)\(\) \[:|Warning.{1,20}\bpg_.*|valid PostgreSQL result|Npgsql\.|Supplied argument is not a valid PostgreSQL .*? resource|Unable to connect to PostgreSQL server" \
|
||||
"id:951240,\
|
||||
phase:4,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,\
|
||||
msg:'postgres SQL Information Leakage',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-multi',\
|
||||
tag:'platform-pgsql',\
|
||||
tag:'attack-disclosure',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/118/116/54',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
SecRule RESPONSE_BODY "@rx (?i)(?:Warning.*sqlite_.*|Warning.*SQLite3::|SQLite/JDBCDriver|SQLite\.Exception|System\.Data\.SQLite\.SQLiteException)" \
|
||||
"id:951250,\
|
||||
phase:4,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,\
|
||||
msg:'sqlite SQL Information Leakage',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-multi',\
|
||||
tag:'platform-sqlite',\
|
||||
tag:'attack-disclosure',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/118/116/54',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
SecRule RESPONSE_BODY "@rx (?i)(?:Sybase message:|Warning.{2,20}sybase|Sybase.*Server message.*)" \
|
||||
"id:951260,\
|
||||
phase:4,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,\
|
||||
msg:'Sybase SQL Information Leakage',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-multi',\
|
||||
tag:'platform-sybase',\
|
||||
tag:'attack-disclosure',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/118/116/54',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}',\
|
||||
setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
SecMarker "END-SQL-ERROR-MATCH-PL1"
|
||||
|
||||
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:951013,phase:3,pass,nolog,skipAfter:END-RESPONSE-951-DATA-LEAKAGES-SQL"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:951014,phase:4,pass,nolog,skipAfter:END-RESPONSE-951-DATA-LEAKAGES-SQL"
|
||||
#
|
||||
# -= Paranoia Level 2 =- (apply only when tx.detection_paranoia_level is sufficiently high: 2 or higher)
|
||||
#
|
||||
|
||||
|
||||
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:951015,phase:3,pass,nolog,skipAfter:END-RESPONSE-951-DATA-LEAKAGES-SQL"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:951016,phase:4,pass,nolog,skipAfter:END-RESPONSE-951-DATA-LEAKAGES-SQL"
|
||||
#
|
||||
# -= Paranoia Level 3 =- (apply only when tx.detection_paranoia_level is sufficiently high: 3 or higher)
|
||||
#
|
||||
|
||||
|
||||
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:951017,phase:3,pass,nolog,skipAfter:END-RESPONSE-951-DATA-LEAKAGES-SQL"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:951018,phase:4,pass,nolog,skipAfter:END-RESPONSE-951-DATA-LEAKAGES-SQL"
|
||||
#
|
||||
# -= Paranoia Level 4 =- (apply only when tx.detection_paranoia_level is sufficiently high: 4 or higher)
|
||||
#
|
||||
|
||||
|
||||
|
||||
#
|
||||
# -= Paranoia Levels Finished =-
|
||||
#
|
||||
SecMarker "END-RESPONSE-951-DATA-LEAKAGES-SQL"
|
||||
@@ -0,0 +1,100 @@
|
||||
# ------------------------------------------------------------------------
|
||||
# OWASP ModSecurity Core Rule Set ver.4.0.0-rc1
|
||||
# Copyright (c) 2006-2020 Trustwave and contributors. All rights reserved.
|
||||
# Copyright (c) 2021-2022 Core Rule Set project. All rights reserved.
|
||||
#
|
||||
# The OWASP ModSecurity Core Rule Set is distributed under
|
||||
# Apache Software License (ASL) version 2
|
||||
# Please see the enclosed LICENSE file for full details.
|
||||
# ------------------------------------------------------------------------
|
||||
|
||||
#
|
||||
# -= Paranoia Level 0 (empty) =- (apply unconditionally)
|
||||
#
|
||||
|
||||
|
||||
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:952011,phase:3,pass,nolog,skipAfter:END-RESPONSE-952-DATA-LEAKAGES-JAVA"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:952012,phase:4,pass,nolog,skipAfter:END-RESPONSE-952-DATA-LEAKAGES-JAVA"
|
||||
#
|
||||
# -= Paranoia Level 1 (default) =- (apply only when tx.detection_paranoia_level is sufficiently high: 1 or higher)
|
||||
#
|
||||
|
||||
#
|
||||
# -=[ Java Source Code Leakages ]=-
|
||||
#
|
||||
SecRule RESPONSE_BODY "@pmFromFile java-code-leakages.data" \
|
||||
"id:952100,\
|
||||
phase:4,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,\
|
||||
msg:'Java Source Code Leakage',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-java',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-disclosure',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/118/116',\
|
||||
tag:'PCI/6.5.6',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'ERROR',\
|
||||
setvar:'tx.outbound_anomaly_score_pl1=+%{tx.error_anomaly_score}'"
|
||||
|
||||
#
|
||||
# -=[ Java Errors ]=-
|
||||
#
|
||||
# Ref: https://github.com/andresriancho/w3af/blob/master/w3af/plugins/grep/error_pages.py
|
||||
#
|
||||
SecRule RESPONSE_BODY "@pmFromFile java-errors.data" \
|
||||
"id:952110,\
|
||||
phase:4,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,\
|
||||
msg:'Java Errors',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-java',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-disclosure',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/118/116',\
|
||||
tag:'PCI/6.5.6',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'ERROR',\
|
||||
setvar:'tx.outbound_anomaly_score_pl1=+%{tx.error_anomaly_score}'"
|
||||
|
||||
|
||||
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:952013,phase:3,pass,nolog,skipAfter:END-RESPONSE-952-DATA-LEAKAGES-JAVA"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:952014,phase:4,pass,nolog,skipAfter:END-RESPONSE-952-DATA-LEAKAGES-JAVA"
|
||||
#
|
||||
# -= Paranoia Level 2 =- (apply only when tx.detection_paranoia_level is sufficiently high: 2 or higher)
|
||||
#
|
||||
|
||||
|
||||
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:952015,phase:3,pass,nolog,skipAfter:END-RESPONSE-952-DATA-LEAKAGES-JAVA"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:952016,phase:4,pass,nolog,skipAfter:END-RESPONSE-952-DATA-LEAKAGES-JAVA"
|
||||
#
|
||||
# -= Paranoia Level 3 =- (apply only when tx.detection_paranoia_level is sufficiently high: 3 or higher)
|
||||
#
|
||||
|
||||
|
||||
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:952017,phase:3,pass,nolog,skipAfter:END-RESPONSE-952-DATA-LEAKAGES-JAVA"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:952018,phase:4,pass,nolog,skipAfter:END-RESPONSE-952-DATA-LEAKAGES-JAVA"
|
||||
#
|
||||
# -= Paranoia Level 4 =- (apply only when tx.detection_paranoia_level is sufficiently high: 4 or higher)
|
||||
#
|
||||
|
||||
|
||||
|
||||
#
|
||||
# -= Paranoia Levels Finished =-
|
||||
#
|
||||
SecMarker "END-RESPONSE-952-DATA-LEAKAGES-JAVA"
|
||||
@@ -0,0 +1,150 @@
|
||||
# ------------------------------------------------------------------------
|
||||
# OWASP ModSecurity Core Rule Set ver.4.0.0-rc1
|
||||
# Copyright (c) 2006-2020 Trustwave and contributors. All rights reserved.
|
||||
# Copyright (c) 2021-2022 Core Rule Set project. All rights reserved.
|
||||
#
|
||||
# The OWASP ModSecurity Core Rule Set is distributed under
|
||||
# Apache Software License (ASL) version 2
|
||||
# Please see the enclosed LICENSE file for full details.
|
||||
# ------------------------------------------------------------------------
|
||||
|
||||
#
|
||||
# -= Paranoia Level 0 (empty) =- (apply unconditionally)
|
||||
#
|
||||
|
||||
|
||||
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:953011,phase:3,pass,nolog,skipAfter:END-RESPONSE-953-DATA-LEAKAGES-PHP"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:953012,phase:4,pass,nolog,skipAfter:END-RESPONSE-953-DATA-LEAKAGES-PHP"
|
||||
#
|
||||
# -= Paranoia Level 1 (default) =- (apply only when tx.detection_paranoia_level is sufficiently high: 1 or higher)
|
||||
#
|
||||
|
||||
#
|
||||
# -=[ PHP Error Message Leakage ]=-
|
||||
#
|
||||
SecRule RESPONSE_BODY "@pmFromFile php-errors.data" \
|
||||
"id:953100,\
|
||||
phase:4,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,\
|
||||
msg:'PHP Information Leakage',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-php',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-disclosure',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/118/116',\
|
||||
tag:'PCI/6.5.6',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'ERROR',\
|
||||
setvar:'tx.outbound_anomaly_score_pl1=+%{tx.error_anomaly_score}'"
|
||||
|
||||
#
|
||||
# -=[ PHP source code leakage ]=-
|
||||
#
|
||||
# Detect some common PHP keywords in output.
|
||||
#
|
||||
SecRule RESPONSE_BODY "@rx (?:\b(?:f(?:tp_(?:nb_)?f?(?:ge|pu)t|get(?:s?s|c)|scanf|write|open|read)|gz(?:(?:encod|writ)e|compress|open|read)|s(?:ession_start|candir)|read(?:(?:gz)?file|dir)|move_uploaded_file|(?:proc_|bz)open|call_user_func)|\$_(?:(?:pos|ge)t|session))\b" \
|
||||
"id:953110,\
|
||||
phase:4,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,\
|
||||
msg:'PHP source code leakage',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-php',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-disclosure',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/118/116',\
|
||||
tag:'PCI/6.5.6',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'ERROR',\
|
||||
setvar:'tx.outbound_anomaly_score_pl1=+%{tx.error_anomaly_score}'"
|
||||
|
||||
# Detect the presence of the PHP open tag "<? ", "<?= " or "<?php " in output.
|
||||
#
|
||||
# To prevent false positives (due to the short "<?" sequences), we also include,
|
||||
# the space after it in an attempt to stop alerts in binary output.
|
||||
# And we make it case insensitive.
|
||||
#
|
||||
SecRule RESPONSE_BODY "@rx (?i)<\?(?:=|php)?\s+" \
|
||||
"id:953120,\
|
||||
phase:4,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,\
|
||||
msg:'PHP source code leakage',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-php',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-disclosure',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/118/116',\
|
||||
tag:'PCI/6.5.6',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'ERROR',\
|
||||
setvar:'tx.outbound_anomaly_score_pl1=+%{tx.error_anomaly_score}'"
|
||||
|
||||
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:953013,phase:3,pass,nolog,skipAfter:END-RESPONSE-953-DATA-LEAKAGES-PHP"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:953014,phase:4,pass,nolog,skipAfter:END-RESPONSE-953-DATA-LEAKAGES-PHP"
|
||||
#
|
||||
# -= Paranoia Level 2 =- (apply only when tx.detection_paranoia_level is sufficiently high: 2 or higher)
|
||||
#
|
||||
|
||||
#
|
||||
# -=[ PHP Error Message Leakage ]=-
|
||||
#
|
||||
# This is a stricter sibling of rule 953100.
|
||||
# This stricter sibling checks for additional error messages which has a higher chance to appear in common language.
|
||||
#
|
||||
SecRule RESPONSE_BODY "@pmFromFile php-errors-pl2.data" \
|
||||
"id:953101,\
|
||||
phase:4,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,\
|
||||
msg:'PHP Information Leakage',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-php',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-disclosure',\
|
||||
tag:'paranoia-level/2',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/118/116',\
|
||||
tag:'PCI/6.5.6',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'ERROR',\
|
||||
setvar:'tx.outbound_anomaly_score_pl2=+%{tx.error_anomaly_score}'"
|
||||
|
||||
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:953015,phase:3,pass,nolog,skipAfter:END-RESPONSE-953-DATA-LEAKAGES-PHP"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:953016,phase:4,pass,nolog,skipAfter:END-RESPONSE-953-DATA-LEAKAGES-PHP"
|
||||
#
|
||||
# -= Paranoia Level 3 =- (apply only when tx.detection_paranoia_level is sufficiently high: 3 or higher)
|
||||
#
|
||||
|
||||
|
||||
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:953017,phase:3,pass,nolog,skipAfter:END-RESPONSE-953-DATA-LEAKAGES-PHP"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:953018,phase:4,pass,nolog,skipAfter:END-RESPONSE-953-DATA-LEAKAGES-PHP"
|
||||
#
|
||||
# -= Paranoia Level 4 =- (apply only when tx.detection_paranoia_level is sufficiently high: 4 or higher)
|
||||
#
|
||||
|
||||
|
||||
|
||||
#
|
||||
# -= Paranoia Levels Finished =-
|
||||
#
|
||||
SecMarker "END-RESPONSE-953-DATA-LEAKAGES-PHP"
|
||||
@@ -0,0 +1,144 @@
|
||||
# ------------------------------------------------------------------------
|
||||
# OWASP ModSecurity Core Rule Set ver.4.0.0-rc1
|
||||
# Copyright (c) 2006-2020 Trustwave and contributors. All rights reserved.
|
||||
# Copyright (c) 2021-2022 Core Rule Set project. All rights reserved.
|
||||
#
|
||||
# The OWASP ModSecurity Core Rule Set is distributed under
|
||||
# Apache Software License (ASL) version 2
|
||||
# Please see the enclosed LICENSE file for full details.
|
||||
# ------------------------------------------------------------------------
|
||||
|
||||
#
|
||||
# -= Paranoia Level 0 (empty) =- (apply unconditionally)
|
||||
#
|
||||
|
||||
|
||||
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:954011,phase:3,pass,nolog,skipAfter:END-RESPONSE-954-DATA-LEAKAGES-IIS"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:954012,phase:4,pass,nolog,skipAfter:END-RESPONSE-954-DATA-LEAKAGES-IIS"
|
||||
#
|
||||
# -= Paranoia Level 1 (default) =- (apply only when tx.detection_paranoia_level is sufficiently high: 1 or higher)
|
||||
#
|
||||
|
||||
# IIS default location
|
||||
SecRule RESPONSE_BODY "@rx [a-z]:\x5cinetpub\b" \
|
||||
"id:954100,\
|
||||
phase:4,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,t:lowercase,\
|
||||
msg:'Disclosure of IIS install location',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-multi',\
|
||||
tag:'platform-iis',\
|
||||
tag:'platform-windows',\
|
||||
tag:'attack-disclosure',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/118/116',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'ERROR',\
|
||||
setvar:'tx.outbound_anomaly_score_pl1=+%{tx.error_anomaly_score}'"
|
||||
|
||||
SecRule RESPONSE_BODY "@rx (?:Microsoft OLE DB Provider for SQL Server(?:</font>.{1,20}?error '800(?:04005|40e31)'.{1,40}?Timeout expired| \(0x80040e31\)<br>Timeout expired<br>)|<h1>internal server error</h1>.*?<h2>part of the server has crashed or it has a configuration error\.</h2>|cannot connect to the server: timed out)" \
|
||||
"id:954110,\
|
||||
phase:4,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,\
|
||||
msg:'Application Availability Error',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-multi',\
|
||||
tag:'platform-iis',\
|
||||
tag:'platform-windows',\
|
||||
tag:'attack-disclosure',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'PCI/6.5.6',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/118/116',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'ERROR',\
|
||||
setvar:'tx.outbound_anomaly_score_pl1=+%{tx.error_anomaly_score}'"
|
||||
|
||||
#
|
||||
# IIS Errors leakage
|
||||
#
|
||||
SecRule RESPONSE_BODY "@pmFromFile iis-errors.data" \
|
||||
"id:954120,\
|
||||
phase:4,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,\
|
||||
msg:'IIS Information Leakage',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-multi',\
|
||||
tag:'platform-iis',\
|
||||
tag:'platform-windows',\
|
||||
tag:'attack-disclosure',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/118/116',\
|
||||
tag:'PCI/6.5.6',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'ERROR',\
|
||||
setvar:'tx.outbound_anomaly_score_pl1=+%{tx.error_anomaly_score}'"
|
||||
|
||||
|
||||
SecRule RESPONSE_STATUS "!@rx ^404$" \
|
||||
"id:954130,\
|
||||
phase:4,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,\
|
||||
msg:'IIS Information Leakage',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\
|
||||
tag:'application-multi',\
|
||||
tag:'language-multi',\
|
||||
tag:'platform-iis',\
|
||||
tag:'platform-windows',\
|
||||
tag:'attack-disclosure',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/118/116',\
|
||||
tag:'PCI/6.5.6',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'ERROR',\
|
||||
chain"
|
||||
SecRule RESPONSE_BODY "@rx \bServer Error in.{0,50}?\bApplication\b" \
|
||||
"capture,\
|
||||
t:none,\
|
||||
setvar:'tx.outbound_anomaly_score_pl1=+%{tx.error_anomaly_score}'"
|
||||
|
||||
|
||||
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:954013,phase:3,pass,nolog,skipAfter:END-RESPONSE-954-DATA-LEAKAGES-IIS"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:954014,phase:4,pass,nolog,skipAfter:END-RESPONSE-954-DATA-LEAKAGES-IIS"
|
||||
#
|
||||
# -= Paranoia Level 2 =- (apply only when tx.detection_paranoia_level is sufficiently high: 2 or higher)
|
||||
#
|
||||
|
||||
|
||||
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:954015,phase:3,pass,nolog,skipAfter:END-RESPONSE-954-DATA-LEAKAGES-IIS"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:954016,phase:4,pass,nolog,skipAfter:END-RESPONSE-954-DATA-LEAKAGES-IIS"
|
||||
#
|
||||
# -= Paranoia Level 3 =- (apply only when tx.detection_paranoia_level is sufficiently high: 3 or higher)
|
||||
#
|
||||
|
||||
|
||||
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:954017,phase:3,pass,nolog,skipAfter:END-RESPONSE-954-DATA-LEAKAGES-IIS"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:954018,phase:4,pass,nolog,skipAfter:END-RESPONSE-954-DATA-LEAKAGES-IIS"
|
||||
#
|
||||
# -= Paranoia Level 4 =- (apply only when tx.detection_paranoia_level is sufficiently high: 4 or higher)
|
||||
#
|
||||
|
||||
|
||||
|
||||
#
|
||||
# -= Paranoia Levels Finished =-
|
||||
#
|
||||
SecMarker "END-RESPONSE-954-DATA-LEAKAGES-IIS"
|
||||
@@ -0,0 +1,548 @@
|
||||
# ------------------------------------------------------------------------
|
||||
# OWASP ModSecurity Core Rule Set ver.4.0.0-rc1
|
||||
# Copyright (c) 2006-2020 Trustwave and contributors. (not) All rights reserved.
|
||||
# Copyright (c) 2021-2022 Core Rule Set project. All rights reserved.
|
||||
#
|
||||
# The OWASP ModSecurity Core Rule Set is distributed under
|
||||
# Apache Software License (ASL) version 2
|
||||
# Please see the enclosed LICENSE file for full details.
|
||||
# ------------------------------------------------------------------------
|
||||
|
||||
#
|
||||
# -= Paranoia Level 0 (empty) =- (apply unconditionally)
|
||||
#
|
||||
|
||||
|
||||
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:955011,phase:3,pass,nolog,skipAfter:END-RESPONSE-955-WEB-SHELLS"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:955012,phase:4,pass,nolog,skipAfter:END-RESPONSE-955-WEB-SHELLS"
|
||||
#
|
||||
# -= Paranoia Level 1 (default) =- (apply only when tx.detection_paranoia_level is sufficiently high: 1 or higher)
|
||||
#
|
||||
|
||||
# For performance reasons, most of the shells are matched using this rule.
|
||||
# This rule is intended for PHP web shells.
|
||||
SecRule RESPONSE_BODY "@pmFromFile web-shells-php.data" \
|
||||
"id:955100,\
|
||||
phase:4,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,\
|
||||
msg:'Web shell detected',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\
|
||||
tag:'language-php',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-rce',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/225/122/17/650',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
# r57 web shell
|
||||
SecRule RESPONSE_BODY "@rx (<title>r57 Shell Version [0-9.]+</title>|<title>r57 shell</title>)" \
|
||||
"id:955110,\
|
||||
phase:4,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,\
|
||||
msg:'r57 web shell',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\
|
||||
tag:'language-php',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-rce',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/225/122/17/650',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
# WSO web shell
|
||||
SecRule RESPONSE_BODY "@rx ^<html><head><meta http-equiv='Content-Type' content='text/html; charset=Windows-1251'><title>.*? - WSO [0-9.]+</title>" \
|
||||
"id:955120,\
|
||||
phase:4,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,\
|
||||
msg:'WSO web shell',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\
|
||||
tag:'language-php',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-rce',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/225/122/17/650',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
# b4tm4n web shell (https://github.com/k4mpr3t/b4tm4n)
|
||||
SecRule RESPONSE_BODY "@rx B4TM4N SH3LL</title>.*<meta name='author' content='k4mpr3t'/>" \
|
||||
"id:955130,\
|
||||
phase:4,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,\
|
||||
msg:'b4tm4n web shell',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\
|
||||
tag:'language-php',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-rce',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/225/122/17/650',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
# Mini Shell web shell
|
||||
SecRule RESPONSE_BODY "@rx <title>Mini Shell</title>.*Developed By LameHacker" \
|
||||
"id:955140,\
|
||||
phase:4,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,\
|
||||
msg:'Mini Shell web shell',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\
|
||||
tag:'language-php',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-rce',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/225/122/17/650',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
# Ashiyane web shell
|
||||
SecRule RESPONSE_BODY "@rx <title>\.:: .* ~ Ashiyane V [0-9.]+ ::\.</title>" \
|
||||
"id:955150,\
|
||||
phase:4,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,\
|
||||
msg:'Ashiyane web shell',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\
|
||||
tag:'language-php',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-rce',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/225/122/17/650',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
# Symlink_Sa web shell
|
||||
SecRule RESPONSE_BODY "@rx <title>Symlink_Sa [0-9.]+</title>" \
|
||||
"id:955160,\
|
||||
phase:4,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,\
|
||||
msg:'Symlink_Sa web shell',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\
|
||||
tag:'language-php',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-rce',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/225/122/17/650',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
# CasuS web shell
|
||||
SecRule RESPONSE_BODY "@rx <title>CasuS [0-9.]+ by MafiABoY</title>" \
|
||||
"id:955170,\
|
||||
phase:4,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,\
|
||||
msg:'CasuS web shell',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\
|
||||
tag:'language-php',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-rce',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/225/122/17/650',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
# GRP WebShell
|
||||
SecRule RESPONSE_BODY "@rx ^<html>\r\n<head>\r\n<title>GRP WebShell [0-9.]+ " \
|
||||
"id:955180,\
|
||||
phase:4,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,\
|
||||
msg:'GRP WebShell',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\
|
||||
tag:'language-php',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-rce',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/225/122/17/650',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
# NGHshell web shell
|
||||
SecRule RESPONSE_BODY "@rx <small>NGHshell [0-9.]+ by Cr4sh</body></html>\n$" \
|
||||
"id:955190,\
|
||||
phase:4,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,\
|
||||
msg:'NGHshell web shell',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\
|
||||
tag:'language-php',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-rce',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/225/122/17/650',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
# SimAttacker web shell
|
||||
SecRule RESPONSE_BODY "@rx <title>SimAttacker - (?:Version|Vrsion) : [0-9.]+ - " \
|
||||
"id:955200,\
|
||||
phase:4,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,\
|
||||
msg:'SimAttacker web shell',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\
|
||||
tag:'language-php',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-rce',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/225/122/17/650',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
# Unknown web shell
|
||||
SecRule RESPONSE_BODY "@rx ^<!DOCTYPE html>\n<html>\n<!-- By Artyum .*<title>Web Shell</title>" \
|
||||
"id:955210,\
|
||||
phase:4,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,\
|
||||
msg:'Unknown web shell',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\
|
||||
tag:'language-php',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-rce',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/225/122/17/650',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
# lama's'hell web shell
|
||||
SecRule RESPONSE_BODY "@rx <title>lama's'hell v. [0-9.]+</title>" \
|
||||
"id:955220,\
|
||||
phase:4,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,\
|
||||
msg:'lama\'s\'hell web shell',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\
|
||||
tag:'language-php',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-rce',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/225/122/17/650',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
# lostDC web shell
|
||||
SecRule RESPONSE_BODY "@rx ^ *<html>\n[ ]+<head>\n[ ]+<title>lostDC - " \
|
||||
"id:955230,\
|
||||
phase:4,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,\
|
||||
msg:'lostDC web shell',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\
|
||||
tag:'language-php',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-rce',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/225/122/17/650',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
# Unknown web shell
|
||||
SecRule RESPONSE_BODY "@rx ^<title>PHP Web Shell</title>\r\n<html>\r\n<body>\r\n <!-- Replaces command with Base64-encoded Data -->" \
|
||||
"id:955240,\
|
||||
phase:4,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,\
|
||||
msg:'Unknown web shell',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\
|
||||
tag:'language-php',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-rce',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/225/122/17/650',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
# Unknown web shell
|
||||
SecRule RESPONSE_BODY "@rx ^<html>\n<head>\n<div align=\"left\"><font size=\"1\">Input command :</font></div>\n<form name=\"cmd\" method=\"POST\" enctype=\"multipart/form-data\">" \
|
||||
"id:955250,\
|
||||
phase:4,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,\
|
||||
msg:'Unknown web shell',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\
|
||||
tag:'language-php',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-rce',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/225/122/17/650',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
# Ru24PostWebShell web shell
|
||||
SecRule RESPONSE_BODY "@rx ^<html>\n<head>\n<title>Ru24PostWebShell - " \
|
||||
"id:955260,\
|
||||
phase:4,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,\
|
||||
msg:'Ru24PostWebShell web shell',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\
|
||||
tag:'language-php',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-rce',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/225/122/17/650',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
# s72 Shell web shell
|
||||
SecRule RESPONSE_BODY "@rx <title>s72 Shell v[0-9.]+ Codinf by Cr@zy_King</title>" \
|
||||
"id:955270,\
|
||||
phase:4,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,\
|
||||
msg:'s72 Shell web shell',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\
|
||||
tag:'language-php',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-rce',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/225/122/17/650',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
# PhpSpy web shell
|
||||
SecRule RESPONSE_BODY "@rx ^<html>\r\n<head>\r\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=gb2312\">\r\n<title>PhpSpy Ver [0-9]+</title>" \
|
||||
"id:955280,\
|
||||
phase:4,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,\
|
||||
msg:'PhpSpy web shell',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\
|
||||
tag:'language-php',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-rce',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/225/122/17/650',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
# g00nshell web shell
|
||||
SecRule RESPONSE_BODY "@rx ^ <html>\n\n<head>\n\n<title>g00nshell v[0-9.]+ " \
|
||||
"id:955290,\
|
||||
phase:4,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,\
|
||||
msg:'g00nshell web shell',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\
|
||||
tag:'language-php',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-rce',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/225/122/17/650',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
# PuNkHoLic shell web shell
|
||||
# Various versions has this text written little differently so we need to do
|
||||
# t:removeWhitespace and t:lowercase.
|
||||
SecRule RESPONSE_BODY "@contains <title>punkholicshell</title>" \
|
||||
"id:955300,\
|
||||
phase:4,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,t:removeWhitespace,t:lowercase,\
|
||||
msg:'PuNkHoLic shell web shell',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\
|
||||
tag:'language-php',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-rce',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/225/122/17/650',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
# azrail web shell
|
||||
SecRule RESPONSE_BODY "@rx ^<html>\n <head>\n <title>azrail [0-9.]+ by C-W-M</title>" \
|
||||
"id:955310,\
|
||||
phase:4,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,\
|
||||
msg:'azrail web shell',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\
|
||||
tag:'language-php',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-rce',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/225/122/17/650',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
# SmEvK_PaThAn Shell web shell
|
||||
SecRule RESPONSE_BODY "@rx >SmEvK_PaThAn Shell v[0-9]+ coded by <a href=" \
|
||||
"id:955320,\
|
||||
phase:4,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,\
|
||||
msg:'SmEvK_PaThAn Shell web shell',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\
|
||||
tag:'language-php',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-rce',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/225/122/17/650',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
# Shell I web shell
|
||||
SecRule RESPONSE_BODY "@rx ^<html>\n<title>.*? ~ Shell I</title>\n<head>\n<style>" \
|
||||
"id:955330,\
|
||||
phase:4,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,\
|
||||
msg:'Shell I web shell',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\
|
||||
tag:'language-php',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-rce',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/225/122/17/650',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
# b374k m1n1 web shell
|
||||
SecRule RESPONSE_BODY "@rx ^ <html><head><title>:: b374k m1n1 [0-9.]+ ::</title>" \
|
||||
"id:955340,\
|
||||
phase:4,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,\
|
||||
msg:'b374k m1n1 web shell',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\
|
||||
tag:'language-php',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-rce',\
|
||||
tag:'paranoia-level/1',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/225/122/17/650',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
|
||||
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:955013,phase:3,pass,nolog,skipAfter:END-RESPONSE-955-WEB-SHELLS"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:955014,phase:4,pass,nolog,skipAfter:END-RESPONSE-955-WEB-SHELLS"
|
||||
#
|
||||
# -= Paranoia Level 2 =- (apply only when tx.detection_paranoia_level is sufficiently high: 2 or higher)
|
||||
#
|
||||
|
||||
# webadmin.php file manager
|
||||
# This is placed in PL2 because of too generic pattern.
|
||||
SecRule RESPONSE_BODY "@contains <h1 style=\"margin-bottom: 0\">webadmin.php</h1>" \
|
||||
"id:955350,\
|
||||
phase:4,\
|
||||
block,\
|
||||
capture,\
|
||||
t:none,\
|
||||
msg:'webadmin.php file manager',\
|
||||
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\
|
||||
tag:'language-php',\
|
||||
tag:'platform-multi',\
|
||||
tag:'attack-rce',\
|
||||
tag:'paranoia-level/2',\
|
||||
tag:'OWASP_CRS',\
|
||||
tag:'capec/1000/225/122/17/650',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
severity:'CRITICAL',\
|
||||
setvar:'tx.outbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'"
|
||||
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:955015,phase:3,pass,nolog,skipAfter:END-RESPONSE-955-WEB-SHELLS"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:955016,phase:4,pass,nolog,skipAfter:END-RESPONSE-955-WEB-SHELLS"
|
||||
#
|
||||
# -= Paranoia Level 3 =- (apply only when tx.detection_paranoia_level is sufficiently high: 3 or higher)
|
||||
#
|
||||
|
||||
|
||||
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:955017,phase:3,pass,nolog,skipAfter:END-RESPONSE-955-WEB-SHELLS"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:955018,phase:4,pass,nolog,skipAfter:END-RESPONSE-955-WEB-SHELLS"
|
||||
#
|
||||
# -= Paranoia Level 4 =- (apply only when tx.detection_paranoia_level is sufficiently high: 4 or higher)
|
||||
#
|
||||
|
||||
|
||||
|
||||
#
|
||||
# -= Paranoia Levels Finished =-
|
||||
#
|
||||
SecMarker "END-RESPONSE-955-WEB-SHELLS"
|
||||
@@ -0,0 +1,231 @@
|
||||
# ------------------------------------------------------------------------
|
||||
# OWASP ModSecurity Core Rule Set ver.4.0.0-rc1
|
||||
# Copyright (c) 2006-2020 Trustwave and contributors. All rights reserved.
|
||||
# Copyright (c) 2021-2022 Core Rule Set project. All rights reserved.
|
||||
#
|
||||
# The OWASP ModSecurity Core Rule Set is distributed under
|
||||
# Apache Software License (ASL) version 2
|
||||
# Please see the enclosed LICENSE file for full details.
|
||||
# ------------------------------------------------------------------------
|
||||
|
||||
# You should set the score to the proper threshold you would prefer. If kept at "@gt 0"
|
||||
# it will work similarly to previous Mod CRS rules and will create an event in the error_log
|
||||
# file if there are any rules that match. If you would like to lessen the number of events
|
||||
# generated in the error_log file, you should increase the anomaly score threshold to
|
||||
# something like "@gt 20". This would only generate an event in the error_log file if
|
||||
# there are multiple lower severity rule matches or if any 1 higher severity item matches.
|
||||
#
|
||||
# You should also set the desired disruptive action (deny, redirect, etc...).
|
||||
#
|
||||
|
||||
#
|
||||
# -= Paranoia Level 0 (empty) =- (apply unconditionally)
|
||||
#
|
||||
|
||||
|
||||
# Summing up the blocking and detection anomaly scores in phase 3
|
||||
# even when early blocking is disabled, we need to sum up the scores in phase 3
|
||||
# this prevents bugs in phase 5 if Apache skips phases because of error handling
|
||||
# See: https://github.com/coreruleset/coreruleset/issues/2319#issuecomment-1047503932
|
||||
|
||||
SecRule TX:BLOCKING_PARANOIA_LEVEL "@ge 1" \
|
||||
"id:959052,\
|
||||
phase:3,\
|
||||
pass,\
|
||||
t:none,\
|
||||
nolog,\
|
||||
setvar:'tx.blocking_outbound_anomaly_score=+%{tx.outbound_anomaly_score_pl1}'"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@ge 1" \
|
||||
"id:959152,\
|
||||
phase:3,\
|
||||
pass,\
|
||||
t:none,\
|
||||
nolog,\
|
||||
setvar:'tx.detection_outbound_anomaly_score=+%{tx.outbound_anomaly_score_pl1}'"
|
||||
|
||||
SecRule TX:BLOCKING_PARANOIA_LEVEL "@ge 2" \
|
||||
"id:959053,\
|
||||
phase:3,\
|
||||
pass,\
|
||||
t:none,\
|
||||
nolog,\
|
||||
setvar:'tx.blocking_outbound_anomaly_score=+%{tx.outbound_anomaly_score_pl2}'"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@ge 2" \
|
||||
"id:959153,\
|
||||
phase:3,\
|
||||
pass,\
|
||||
t:none,\
|
||||
nolog,\
|
||||
setvar:'tx.detection_outbound_anomaly_score=+%{tx.outbound_anomaly_score_pl2}'"
|
||||
|
||||
SecRule TX:BLOCKING_PARANOIA_LEVEL "@ge 3" \
|
||||
"id:959054,\
|
||||
phase:3,\
|
||||
pass,\
|
||||
t:none,\
|
||||
nolog,\
|
||||
setvar:'tx.blocking_outbound_anomaly_score=+%{tx.outbound_anomaly_score_pl3}'"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@ge 3" \
|
||||
"id:959154,\
|
||||
phase:3,\
|
||||
pass,\
|
||||
t:none,\
|
||||
nolog,\
|
||||
setvar:'tx.detection_outbound_anomaly_score=+%{tx.outbound_anomaly_score_pl3}'"
|
||||
|
||||
SecRule TX:BLOCKING_PARANOIA_LEVEL "@ge 4" \
|
||||
"id:959055,\
|
||||
phase:3,\
|
||||
pass,\
|
||||
t:none,\
|
||||
nolog,\
|
||||
setvar:'tx.blocking_outbound_anomaly_score=+%{tx.outbound_anomaly_score_pl4}'"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@ge 4" \
|
||||
"id:959155,\
|
||||
phase:3,\
|
||||
pass,\
|
||||
t:none,\
|
||||
nolog,\
|
||||
setvar:'tx.detection_outbound_anomaly_score=+%{tx.outbound_anomaly_score_pl4}'"
|
||||
|
||||
# at start of phase 4, we reset the aggregate scores to 0 to prevent duplicate counting of per-PL scores
|
||||
# this is necessary because the per-PL scores are counted across phases
|
||||
SecAction "id:959059,\
|
||||
phase:4,\
|
||||
pass,\
|
||||
t:none,\
|
||||
nolog,\
|
||||
setvar:'tx.blocking_outbound_anomaly_score=0'"
|
||||
SecAction "id:959159,\
|
||||
phase:4,\
|
||||
pass,\
|
||||
t:none,\
|
||||
nolog,\
|
||||
setvar:'tx.detection_outbound_anomaly_score=0'"
|
||||
|
||||
SecMarker "EARLY_BLOCKING_ANOMALY_SCORING"
|
||||
|
||||
# Summing up the blocking and detection anomaly scores in phase 4
|
||||
|
||||
SecRule TX:BLOCKING_PARANOIA_LEVEL "@ge 1" \
|
||||
"id:959060,\
|
||||
phase:4,\
|
||||
pass,\
|
||||
t:none,\
|
||||
nolog,\
|
||||
setvar:'tx.blocking_outbound_anomaly_score=+%{tx.outbound_anomaly_score_pl1}'"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@ge 1" \
|
||||
"id:959160,\
|
||||
phase:4,\
|
||||
pass,\
|
||||
t:none,\
|
||||
nolog,\
|
||||
setvar:'tx.detection_outbound_anomaly_score=+%{tx.outbound_anomaly_score_pl1}'"
|
||||
|
||||
SecRule TX:BLOCKING_PARANOIA_LEVEL "@ge 2" \
|
||||
"id:959061,\
|
||||
phase:4,\
|
||||
pass,\
|
||||
t:none,\
|
||||
nolog,\
|
||||
setvar:'tx.blocking_outbound_anomaly_score=+%{tx.outbound_anomaly_score_pl2}'"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@ge 2" \
|
||||
"id:959161,\
|
||||
phase:4,\
|
||||
pass,\
|
||||
t:none,\
|
||||
nolog,\
|
||||
setvar:'tx.detection_outbound_anomaly_score=+%{tx.outbound_anomaly_score_pl2}'"
|
||||
|
||||
SecRule TX:BLOCKING_PARANOIA_LEVEL "@ge 3" \
|
||||
"id:959062,\
|
||||
phase:4,\
|
||||
pass,\
|
||||
t:none,\
|
||||
nolog,\
|
||||
setvar:'tx.blocking_outbound_anomaly_score=+%{tx.outbound_anomaly_score_pl3}'"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@ge 3" \
|
||||
"id:959162,\
|
||||
phase:4,\
|
||||
pass,\
|
||||
t:none,\
|
||||
nolog,\
|
||||
setvar:'tx.detection_outbound_anomaly_score=+%{tx.outbound_anomaly_score_pl3}'"
|
||||
|
||||
SecRule TX:BLOCKING_PARANOIA_LEVEL "@ge 4" \
|
||||
"id:959063,\
|
||||
phase:4,\
|
||||
pass,\
|
||||
t:none,\
|
||||
nolog,\
|
||||
setvar:'tx.blocking_outbound_anomaly_score=+%{tx.outbound_anomaly_score_pl4}'"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@ge 4" \
|
||||
"id:959163,\
|
||||
phase:4,\
|
||||
pass,\
|
||||
t:none,\
|
||||
nolog,\
|
||||
setvar:'tx.detection_outbound_anomaly_score=+%{tx.outbound_anomaly_score_pl4}'"
|
||||
|
||||
#
|
||||
# -=[ Anomaly Mode: Overall Transaction Anomaly Score ]=-
|
||||
#
|
||||
|
||||
# if early blocking is active, check threshold in phase 3
|
||||
SecRule TX:BLOCKING_OUTBOUND_ANOMALY_SCORE "@ge %{tx.outbound_anomaly_score_threshold}" \
|
||||
"id:959101,\
|
||||
phase:3,\
|
||||
deny,\
|
||||
t:none,\
|
||||
msg:'Outbound Anomaly Score Exceeded in phase 3 (Total Score: %{tx.blocking_outbound_anomaly_score})',\
|
||||
tag:'anomaly-evaluation',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
chain"
|
||||
SecRule TX:EARLY_BLOCKING "@eq 1"
|
||||
|
||||
# always check threshold in phase 4
|
||||
SecRule TX:BLOCKING_OUTBOUND_ANOMALY_SCORE "@ge %{tx.outbound_anomaly_score_threshold}" \
|
||||
"id:959100,\
|
||||
phase:4,\
|
||||
deny,\
|
||||
t:none,\
|
||||
msg:'Outbound Anomaly Score Exceeded (Total Score: %{tx.blocking_outbound_anomaly_score})',\
|
||||
tag:'anomaly-evaluation',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1'"
|
||||
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:959011,phase:3,pass,nolog,skipAfter:END-RESPONSE-959-BLOCKING-EVALUATION"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:959012,phase:4,pass,nolog,skipAfter:END-RESPONSE-959-BLOCKING-EVALUATION"
|
||||
#
|
||||
# -= Paranoia Level 1 (default) =- (apply only when tx.detection_paranoia_level is sufficiently high: 1 or higher)
|
||||
#
|
||||
|
||||
|
||||
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:959013,phase:3,pass,nolog,skipAfter:END-RESPONSE-959-BLOCKING-EVALUATION"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:959014,phase:4,pass,nolog,skipAfter:END-RESPONSE-959-BLOCKING-EVALUATION"
|
||||
#
|
||||
# -= Paranoia Level 2 =- (apply only when tx.detection_paranoia_level is sufficiently high: 2 or higher)
|
||||
#
|
||||
|
||||
|
||||
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:959015,phase:3,pass,nolog,skipAfter:END-RESPONSE-959-BLOCKING-EVALUATION"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:959016,phase:4,pass,nolog,skipAfter:END-RESPONSE-959-BLOCKING-EVALUATION"
|
||||
#
|
||||
# -= Paranoia Level 3 =- (apply only when tx.detection_paranoia_level is sufficiently high: 3 or higher)
|
||||
#
|
||||
|
||||
|
||||
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:959017,phase:3,pass,nolog,skipAfter:END-RESPONSE-959-BLOCKING-EVALUATION"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:959018,phase:4,pass,nolog,skipAfter:END-RESPONSE-959-BLOCKING-EVALUATION"
|
||||
#
|
||||
# -= Paranoia Level 4 =- (apply only when tx.detection_paranoia_level is sufficiently high: 4 or higher)
|
||||
#
|
||||
|
||||
|
||||
|
||||
#
|
||||
# -= Paranoia Levels Finished =-
|
||||
#
|
||||
SecMarker "END-RESPONSE-959-BLOCKING-EVALUATION"
|
||||
@@ -0,0 +1,136 @@
|
||||
# ------------------------------------------------------------------------
|
||||
# OWASP ModSecurity Core Rule Set ver.4.0.0-rc1
|
||||
# Copyright (c) 2006-2020 Trustwave and contributors. All rights reserved.
|
||||
# Copyright (c) 2021-2022 Core Rule Set project. All rights reserved.
|
||||
#
|
||||
# The OWASP ModSecurity Core Rule Set is distributed under
|
||||
# Apache Software License (ASL) version 2
|
||||
# Please see the enclosed LICENSE file for full details.
|
||||
# ------------------------------------------------------------------------
|
||||
|
||||
#
|
||||
# This file is used in post processing after the response has been sent to
|
||||
# the client (in the logging phase). Its purpose is to provide inbound+outbound
|
||||
# correlation of events to provide a more intelligent designation as to the outcome
|
||||
# or result of the transaction - meaning, was this a successful attack?
|
||||
#
|
||||
|
||||
#
|
||||
# -= Paranoia Level 0 (empty) =- (apply unconditionally)
|
||||
#
|
||||
|
||||
# Combine inbound and outbound scores
|
||||
SecAction \
|
||||
"id:980099,\
|
||||
phase:5,\
|
||||
pass,\
|
||||
t:none,\
|
||||
nolog,\
|
||||
noauditlog,\
|
||||
ver:'OWASP_CRS/4.0.0-rc1',\
|
||||
setvar:'tx.blocking_anomaly_score=%{tx.blocking_inbound_anomaly_score}',\
|
||||
setvar:'tx.blocking_anomaly_score=+%{tx.blocking_outbound_anomaly_score}',\
|
||||
setvar:'tx.detection_anomaly_score=%{tx.detection_inbound_anomaly_score}',\
|
||||
setvar:'tx.detection_anomaly_score=+%{tx.detection_outbound_anomaly_score}',\
|
||||
setvar:'tx.anomaly_score=%{tx.blocking_inbound_anomaly_score}',\
|
||||
setvar:'tx.anomaly_score=+%{tx.blocking_outbound_anomaly_score}'"
|
||||
|
||||
#
|
||||
# -=[ Anomaly Score Reporting ]=-
|
||||
#
|
||||
|
||||
# -= Reporting Level 0 =- (Skip over reporting when tx.reporting_level is 0)
|
||||
SecRule TX:REPORTING_LEVEL "@eq 0" "id:980041,phase:5,pass,nolog,skipAfter:END-REPORTING"
|
||||
|
||||
# -= Reporting Level 5 =- (Jump to reporting rule immediately when tx.reporting_level is 5 or greater)
|
||||
SecRule TX:REPORTING_LEVEL "@ge 5" "id:980042,phase:5,pass,nolog,skipAfter:LOG-REPORTING"
|
||||
|
||||
# -= Zero detection score =- (Skip over reporting when sum of inbound and outbound detection score is equal to 0)
|
||||
SecRule TX:DETECTION_ANOMALY_SCORE "@eq 0" "id:980043,phase:5,pass,nolog,skipAfter:END-REPORTING"
|
||||
|
||||
# -= Blocking score exceeds threshold =- (Jump to reporting rule immediately if a blocking score exceeds a threshold)
|
||||
SecRule TX:BLOCKING_INBOUND_ANOMALY_SCORE "@ge %{tx.inbound_anomaly_score_threshold}" "id:980044,phase:5,pass,nolog,skipAfter:LOG-REPORTING"
|
||||
SecRule TX:BLOCKING_OUTBOUND_ANOMALY_SCORE "@ge %{tx.outbound_anomaly_score_threshold}" "id:980045,phase:5,pass,nolog,skipAfter:LOG-REPORTING"
|
||||
|
||||
# -= Reporting Level 2 =- (Skip over reporting when tx.reporting_level is less than 2)
|
||||
SecRule TX:REPORTING_LEVEL "@lt 2" "id:980046,phase:5,pass,nolog,skipAfter:END-REPORTING"
|
||||
|
||||
# -= Detection score exceeds threshold =- (Jump to reporting rule immediately if a detection score exceeds a threshold)
|
||||
SecRule TX:DETECTION_INBOUND_ANOMALY_SCORE "@ge %{tx.inbound_anomaly_score_threshold}" "id:980047,phase:5,pass,nolog,skipAfter:LOG-REPORTING"
|
||||
SecRule TX:DETECTION_OUTBOUND_ANOMALY_SCORE "@ge %{tx.outbound_anomaly_score_threshold}" "id:980048,phase:5,pass,nolog,skipAfter:LOG-REPORTING"
|
||||
|
||||
# -= Reporting Level 3 =- (Skip over reporting when tx.reporting_level is less than 3)
|
||||
SecRule TX:REPORTING_LEVEL "@lt 3" "id:980049,phase:5,pass,nolog,skipAfter:END-REPORTING"
|
||||
|
||||
# -= Blocking score greater than zero =- (Jump to reporting rule immediately when sum of inbound and outbound blocking score is greater than zero)
|
||||
SecRule TX:BLOCKING_ANOMALY_SCORE "@gt 0" "id:980050,phase:5,pass,nolog,skipAfter:LOG-REPORTING"
|
||||
|
||||
# -= Reporting Level 4 =- (Skip over reporting when tx.reporting_level is less than 4)
|
||||
SecRule TX:REPORTING_LEVEL "@lt 4" "id:980051,phase:5,pass,nolog,skipAfter:END-REPORTING"
|
||||
|
||||
# At this point, the reporting level is 4 and there's a non-zero detection
|
||||
# score (already established by rule 980043) so fall through to the reporting
|
||||
# rule.
|
||||
|
||||
|
||||
# Requests that land on the following SecMarker:
|
||||
# - At reporting level 5 (unconditional reporting)
|
||||
# - At reporting levels 1-4 when a blocking score exceeds a threshold
|
||||
# - At reporting levels 2-4 when a detection score exceeds a threshold
|
||||
# - At reporting levels 3-4 when the total blocking score is greater than zero
|
||||
# - At reporting level 4 when the total detection score is greater than zero
|
||||
SecMarker "LOG-REPORTING"
|
||||
|
||||
# Inbound and outbound - all requests
|
||||
SecAction \
|
||||
"id:980170,\
|
||||
phase:5,\
|
||||
pass,\
|
||||
t:none,\
|
||||
noauditlog,\
|
||||
msg:'Anomaly Scores: \
|
||||
(Inbound Scores: blocking=%{tx.blocking_inbound_anomaly_score}, detection=%{tx.detection_inbound_anomaly_score}, per_pl=%{tx.inbound_anomaly_score_pl1}-%{tx.inbound_anomaly_score_pl2}-%{tx.inbound_anomaly_score_pl3}-%{tx.inbound_anomaly_score_pl4}, threshold=%{tx.inbound_anomaly_score_threshold}) - \
|
||||
(Outbound Scores: blocking=%{tx.blocking_outbound_anomaly_score}, detection=%{tx.detection_outbound_anomaly_score}, per_pl=%{tx.outbound_anomaly_score_pl1}-%{tx.outbound_anomaly_score_pl2}-%{tx.outbound_anomaly_score_pl3}-%{tx.outbound_anomaly_score_pl4}, threshold=%{tx.outbound_anomaly_score_threshold}) - \
|
||||
(SQLI=%{tx.sql_injection_score}, XSS=%{tx.xss_score}, RFI=%{tx.rfi_score}, LFI=%{tx.lfi_score}, RCE=%{tx.rce_score}, PHPI=%{tx.php_injection_score}, HTTP=%{tx.http_violation_score}, SESS=%{tx.session_fixation_score}, COMBINED_SCORE=%{tx.anomaly_score})',\
|
||||
tag:'reporting',\
|
||||
ver:'OWASP_CRS/4.0.0-rc1'"
|
||||
|
||||
SecMarker "END-REPORTING"
|
||||
|
||||
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:980011,phase:1,pass,nolog,skipAfter:END-RESPONSE-980-CORRELATION"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:980012,phase:2,pass,nolog,skipAfter:END-RESPONSE-980-CORRELATION"
|
||||
#
|
||||
# -= Paranoia Level 1 (default) =- (apply only when tx.detection_paranoia_level is sufficiently high: 1 or higher)
|
||||
#
|
||||
|
||||
|
||||
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:980013,phase:1,pass,nolog,skipAfter:END-RESPONSE-980-CORRELATION"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:980014,phase:2,pass,nolog,skipAfter:END-RESPONSE-980-CORRELATION"
|
||||
#
|
||||
# -= Paranoia Level 2 =- (apply only when tx.detection_paranoia_level is sufficiently high: 2 or higher)
|
||||
#
|
||||
|
||||
|
||||
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:980015,phase:1,pass,nolog,skipAfter:END-RESPONSE-980-CORRELATION"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:980016,phase:2,pass,nolog,skipAfter:END-RESPONSE-980-CORRELATION"
|
||||
#
|
||||
# -= Paranoia Level 3 =- (apply only when tx.detection_paranoia_level is sufficiently high: 3 or higher)
|
||||
#
|
||||
|
||||
|
||||
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:980017,phase:1,pass,nolog,skipAfter:END-RESPONSE-980-CORRELATION"
|
||||
SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:980018,phase:2,pass,nolog,skipAfter:END-RESPONSE-980-CORRELATION"
|
||||
#
|
||||
# -= Paranoia Level 4 =- (apply only when tx.detection_paranoia_level is sufficiently high: 4 or higher)
|
||||
#
|
||||
|
||||
|
||||
|
||||
#
|
||||
# -= Paranoia Levels Finished =-
|
||||
#
|
||||
SecMarker "END-RESPONSE-980-CORRELATION"
|
||||
@@ -0,0 +1,76 @@
|
||||
# ------------------------------------------------------------------------
|
||||
# OWASP ModSecurity Core Rule Set ver.4.0.0-rc1
|
||||
# Copyright (c) 2006-2020 Trustwave and contributors. All rights reserved.
|
||||
# Copyright (c) 2021-2022 Core Rule Set project. All rights reserved.
|
||||
#
|
||||
# The OWASP ModSecurity Core Rule Set is distributed under
|
||||
# Apache Software License (ASL) version 2
|
||||
# Please see the enclosed LICENSE file for full details.
|
||||
# ------------------------------------------------------------------------
|
||||
|
||||
#
|
||||
# The purpose of this file is to hold LOCAL exceptions for your site.
|
||||
# The types of rules that would go into this file are one where you want
|
||||
# to unconditionally disable rules or modify their actions during startup.
|
||||
#
|
||||
# Please see the file REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf.example
|
||||
# for a description of the rule exclusions mechanism and the correct
|
||||
# use of this file.
|
||||
#
|
||||
|
||||
#
|
||||
# Example Exclusion Rule: To unconditionally disable a rule ID
|
||||
#
|
||||
# ModSecurity Rule Exclusion: 942100 SQL Injection Detected via libinjection
|
||||
# SecRuleRemoveById 942100
|
||||
|
||||
# Example Exclusion Rule: Remove a group of rules
|
||||
#
|
||||
# ModSecurity Rule Exclusion: Disable PHP injection rules
|
||||
# SecRuleRemoveByTag "attack-injection-php"
|
||||
|
||||
#
|
||||
# Example Exclusion Rule: To unconditionally remove parameter "foo" from
|
||||
# inspection for SQLi rules
|
||||
#
|
||||
# ModSecurity Rule Exclusion: disable sqli rules for parameter foo.
|
||||
# SecRuleUpdateTargetByTag "attack-sqli" "!ARGS:foo"
|
||||
|
||||
|
||||
# -- [[ Changing the Disruptive Action for Anomaly Mode ]] --
|
||||
#
|
||||
# In Anomaly Mode (default in CRS3), the rules in REQUEST-949-BLOCKING-EVALUATION.conf
|
||||
# and RESPONSE-959-BLOCKING-EVALUATION.conf check the accumulated attack scores
|
||||
# against your policy. To apply a disruptive action, they overwrite the default
|
||||
# actions specified in SecDefaultAction (setup.conf) with a 'deny' action.
|
||||
# This 'deny' is by default paired with a 'status:403' action.
|
||||
#
|
||||
# In order to change the disruptive action from 'deny' to something else,
|
||||
# you must use SecRuleUpdateActionByID directives AFTER the CRS rules
|
||||
# are configured, for instance in the RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf file.
|
||||
#
|
||||
# These actions only apply when using Anomaly Mode.
|
||||
#
|
||||
# Default action: block with error 403
|
||||
# (No configuration needed in this file if you want the default behavior.)
|
||||
#
|
||||
|
||||
# Example: redirect back to the homepage on blocking
|
||||
#
|
||||
# SecRuleUpdateActionById 949110 "t:none,redirect:'http://%{request_headers.host}/'"
|
||||
# SecRuleUpdateActionById 959100 "t:none,redirect:'http://%{request_headers.host}/'"
|
||||
|
||||
# Example: redirect to another URL on blocking
|
||||
#
|
||||
# SecRuleUpdateActionById 949110 "t:none,redirect:'http://example.com/report_problem'"
|
||||
# SecRuleUpdateActionById 959100 "t:none,redirect:'http://example.com/report_problem'"
|
||||
|
||||
# Example: send an error 404
|
||||
#
|
||||
# SecRuleUpdateActionById 949110 "t:none,deny,status:404"
|
||||
# SecRuleUpdateActionById 959100 "t:none,deny,status:404"
|
||||
|
||||
# Example: drop the connection (best for DoS attacks)
|
||||
#
|
||||
# SecRuleUpdateActionById 949110 "t:none,drop"
|
||||
# SecRuleUpdateActionById 959100 "t:none,drop"
|
||||
@@ -0,0 +1,82 @@
|
||||
# Search engine crawlers and other bots
|
||||
# crawler
|
||||
# https://80legs.com/
|
||||
80legs
|
||||
# scraping framework
|
||||
# https://ache.readthedocs.io/en/latest/
|
||||
# User-Agent: (Mozilla/5.0 (compatible; ACME/VERSION; +OPERATOR_CONTACT_URL; +OPERATOR_CONTACT_EMAIL)
|
||||
ACHE/
|
||||
# SEO
|
||||
# https://ahrefs.com/robot
|
||||
AhrefsBot
|
||||
# site ripper
|
||||
# http://www.softbytelabs.com/en/BlackWidow/
|
||||
black widow
|
||||
blackwidow
|
||||
# security crawler
|
||||
# User-Agent: Censys: Mozilla/5.0 (compatible; CensysInspect/1.1; +https://about.censys.io/)
|
||||
CensysInspect
|
||||
# scraping framework
|
||||
# http://go-colly.org/
|
||||
# User-Agent: colly - https://github.com/gocolly/colly/v2
|
||||
colly -
|
||||
# scraping framework
|
||||
# https://github.com/yasserg/crawler4j
|
||||
# User-Agent: crawler4j (https://github.com/yasserg/crawler4j/)
|
||||
crawler4j
|
||||
# SEO
|
||||
# advertising targeting
|
||||
# https://www.grapeshot.com/crawler/
|
||||
grapeFX
|
||||
GrapeshotCrawler/2.0
|
||||
# scraping framework
|
||||
# https://github.com/internetarchive/heritrix3
|
||||
# User-Agent: "Mozilla/5.0 (compatible; heritrix/VERSION +OPERATOR_CONTACT_URL)
|
||||
heritrix/
|
||||
# User-Agent: Krzana bot
|
||||
# https://krzana.com/
|
||||
Krzana bot
|
||||
# misbehaving spider
|
||||
Lingewoud-550-Spyder
|
||||
# scraping framework
|
||||
# http://docs.seattlerb.org/mechanize/Mechanize.html
|
||||
Mechanize
|
||||
# SEO
|
||||
# http://www.majestic12.co.uk/projects/dsearch/mj12bot.php
|
||||
MJ12bot
|
||||
# scraping framework
|
||||
# https://nutch.apache.org/
|
||||
# User-Agent: NutchCVS/VERSION (Nutch; http://lucene.apache.org/nutch/bot.html; nutch-agent@lucene.apache.org)
|
||||
NutchCVS/
|
||||
# news service
|
||||
Owlin bot
|
||||
# people database
|
||||
# https://pipl.com/bot/
|
||||
PiplBot
|
||||
# crawler
|
||||
# 2006
|
||||
prowebwalker
|
||||
# generic crawler
|
||||
pymills-spider/
|
||||
# scraping framework
|
||||
# https://docs.pyspider.org/en/latest/
|
||||
# User-Agent: pyspider/VERSION (+http://pyspider.org/)
|
||||
pyspider/
|
||||
# SEO
|
||||
# https://moz.com/help/guides/moz-procedures/what-is-rogerbot
|
||||
rogerbot
|
||||
# SEO
|
||||
# http://www.searchmetrics.com/searchmetricsbot/
|
||||
SearchmetricsBot
|
||||
# SEO
|
||||
# https://www.semrush.com/bot/
|
||||
SemrushBot
|
||||
# SEO
|
||||
# User-Agent: Mozilla/5.0 (compatible; seoscanners.net/1; +spider@seoscanners.net)
|
||||
seoscanners.net
|
||||
# scraping framework
|
||||
# https://scrapy.org/
|
||||
# User-Agent: Scrapy/VERSION (+https://scrapy.org)
|
||||
Scrapy/
|
||||
# https://www.wappalyzer.com/
|
||||
Wappalyzer
|
||||
@@ -0,0 +1,59 @@
|
||||
# This list comes from the default IIS error pages
|
||||
# To renerate get the files from a default installation and use:
|
||||
# grep -h '<title' *.htm
|
||||
|
||||
<title>401.1 - Unauthorized: Access is denied due to invalid credentials.</title>
|
||||
<title>401.2 - Unauthorized: Access is denied due to server configuration.</title>
|
||||
<title>401.3 - Unauthorized: Access is denied due to an ACL set on the requested resource.</title>
|
||||
<title>401.4 - Unauthorized: Authorization failed by filter installed on the Web server.</title>
|
||||
<title>401.5 - Unauthorized: Authorization failed by an ISAPI/CGI application.</title>
|
||||
<title>401 - Unauthorized: Access is denied due to invalid credentials.</title>
|
||||
<title>403.1 - Forbidden: Execute access is denied.</title>
|
||||
<title>403.10 - Forbidden: Web server is configured to deny Execute access.</title>
|
||||
<title>403.11 - Forbidden: Password has been changed.</title>
|
||||
<title>403.12 - Forbidden: Client certificate is denied access by the server certificate mapper.</title>
|
||||
<title>403.13 - Forbidden: Client certificate has been revoked on the Web server.</title>
|
||||
<title>403.14 - Forbidden: Directory listing denied.</title>
|
||||
<title>403.15 - Forbidden: Client access licenses have exceeded limits on the Web server.</title>
|
||||
<title>403.16 - Forbidden: Client certificate is ill-formed or is not trusted by the Web server.</title>
|
||||
<title>403.17 - Forbidden: Client certificate has expired or is not yet valid.</title>
|
||||
<title>403.18 - Forbidden: Cannot execute requested URL in the current application pool.</title>
|
||||
<title>403.19 - Forbidden: Cannot execute CGIs for the client in this application pool.</title>
|
||||
<title>403.2 - Forbidden: Read access is denied.</title>
|
||||
<title>403.3 - Forbidden: Write access is denied.</title>
|
||||
<title>403.4 - Forbidden: SSL is required to view this resource.</title>
|
||||
<title>403.5 - Forbidden: SSL 128 is required to view this resource.</title>
|
||||
<title>403.6 - Forbidden: IP address of the client has been rejected.</title>
|
||||
<title>403.7 - Forbidden: SSL client certificate is required.</title>
|
||||
<title>403.8 - Forbidden: DNS name of the client is rejected.</title>
|
||||
<title>403.9 - Forbidden: Too many clients are trying to connect to the Web server.</title>
|
||||
<title>403 - Forbidden: Access is denied.</title>
|
||||
<title>404.1 - File or directory not found: Web site not accessible on the requested port.</title>
|
||||
<title>404.11 - URL is double-escaped.</title>
|
||||
<title>404.12 - URL has high bit characters.</title>
|
||||
<title>404.14 - URL too long.</title>
|
||||
<title>404.15 - Query-String too long.</title>
|
||||
<title>404.2 - File or directory not found: Lockdown policy prevents this request.</title>
|
||||
<title>404.3 - File or directory not found: MIME map policy prevents this request.</title>
|
||||
<title>404.4 - File or directory not found: No module handler is registered to handle the request.</title>
|
||||
<title>404.5 - URL sequence denied.</title>
|
||||
<title>404.6 - HTTP verb denied.</title>
|
||||
<title>404.7 - File extension denied.</title>
|
||||
<title>404.8 - URL namespace hidden.</title>
|
||||
<title>404.9 - File attribute hidden.</title>
|
||||
<title>404 - File or directory not found.</title>
|
||||
<title>405 - HTTP verb used to access this page is not allowed.</title>
|
||||
<title>406 - Client browser does not accept the MIME type of the requested page.</title>
|
||||
<title>412 - Precondition set by the client failed when evaluated on the Web server.</title>
|
||||
<title>413.1 - Content-Length too large.</title>
|
||||
<title>431 - Request header too long.</title>
|
||||
<title>500.13 - Server error: Web server is too busy.</title>
|
||||
<title>500.14 - Server error: Invalid application configuration on the server.</title>
|
||||
<title>500.15 - Server error: Direct requests for GLOBAL.ASA are not allowed.</title>
|
||||
<title>500.16 - Server error: UNC authorization credentials incorrect.</title>
|
||||
<title>500.17 - Server error: URL authorization store cannot be found.</title>
|
||||
<title>500.18 - Server error: URL authorization store cannot be opened.</title>
|
||||
<title>500.19 - Server error: Data for this file is configured improperly.</title>
|
||||
<title>500 - Internal server error.</title>
|
||||
<title>501 - Header values specify a method that is not implemented.</title>
|
||||
<title>502 - Web server received an invalid response while acting as a gateway or proxy server.</title>
|
||||
@@ -0,0 +1,61 @@
|
||||
# Java Classes for use with Java RCEs
|
||||
#
|
||||
# Used With Rule 944130 in Apache Struts and Oracle Weblogic RCEs Detection:
|
||||
#
|
||||
# CVE-2017-5638 (2017.01.29) https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5638
|
||||
# CVE-2017-9791 (2017.06.21) https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-9791
|
||||
# CVE-2017-9805 (2017.06.21) https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-9805
|
||||
# CVE-2017-10271 (2017.06.21) https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-10271
|
||||
# CVE-2018-11776 (2018.06.05) https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-11776
|
||||
#
|
||||
# Additional Resources
|
||||
# Apache S2-057 (2019.01.20) https://cwiki.apache.org/confluence/display/WW/S2-057
|
||||
|
||||
com.opensymphony.xwork2
|
||||
com.sun.org.apache
|
||||
freemarker.core
|
||||
freemarker.template
|
||||
freemarker.ext.rhino
|
||||
java.io.BufferedInputStream
|
||||
java.io.BufferedReader
|
||||
java.io.ByteArrayInputStream
|
||||
java.io.ByteArrayOutputStream
|
||||
java.io.CharArrayReader
|
||||
java.io.DataInputStream
|
||||
java.io.File
|
||||
java.io.FileOutputStream
|
||||
java.io.FilePermission
|
||||
java.io.FileWriter
|
||||
java.io.FilterInputStream
|
||||
java.io.FilterOutputStream
|
||||
java.io.FilterReader
|
||||
java.io.InputStream
|
||||
java.io.InputStreamReader
|
||||
java.io.LineNumberReader
|
||||
java.io.ObjectOutputStream
|
||||
java.io.OutputStream
|
||||
java.io.PipedOutputStream
|
||||
java.io.PipedReader
|
||||
java.io.PrintStream
|
||||
java.io.PushbackInputStream
|
||||
java.io.Reader
|
||||
java.io.StringReader
|
||||
java.lang.Class
|
||||
java.lang.Integer
|
||||
java.lang.Number
|
||||
java.lang.Object
|
||||
java.lang.Process
|
||||
java.lang.ProcessBuilder
|
||||
java.lang.reflect
|
||||
java.lang.Runtime
|
||||
java.lang.String
|
||||
java.lang.StringBuilder
|
||||
java.lang.System
|
||||
javassist
|
||||
javax.script.ScriptEngineManager
|
||||
org.apache.commons
|
||||
org.apache.struts
|
||||
org.apache.struts2
|
||||
org.omg.CORBA
|
||||
java.beans.XMLDecode
|
||||
sun.reflect
|
||||
@@ -0,0 +1,17 @@
|
||||
<jsp:
|
||||
javax.servlet
|
||||
.addheader
|
||||
.createtextfile
|
||||
.getfile
|
||||
.loadfromfile
|
||||
response.binarywrite
|
||||
response.write
|
||||
scripting.filesystemobject
|
||||
server.createobject
|
||||
server.execute
|
||||
server.htmlencode
|
||||
server.mappath
|
||||
server.urlencode
|
||||
vbscript.encode
|
||||
wscript.network
|
||||
wscript.shell
|
||||
@@ -0,0 +1,10 @@
|
||||
[java.lang.
|
||||
class java.lang.
|
||||
java.lang.NullPointerException
|
||||
java.rmi.ServerException
|
||||
at java.lang.
|
||||
onclick="toggle('full exception chain stacktrace')"
|
||||
at org.apache.catalina
|
||||
at org.apache.coyote.
|
||||
at org.apache.tomcat.
|
||||
at org.apache.jasper.
|
||||
@@ -0,0 +1,720 @@
|
||||
# This list comes from:
|
||||
# - https://github.com/lightos/Panoptic
|
||||
# - https://github.com/danielmiessler/SecLists
|
||||
# /proc and /sys entries should be kept in sync with restricted-files.data
|
||||
|
||||
# Entries in this list generally use the shortest path that suffices for identifying them as dangerous.
|
||||
# .ssh/id_rsa and .ssh/id_dsa for example, are both dangerous paths but are represented in this list as .ssh.
|
||||
# The same applies to different log files below /var/log/mysql: var/log/mysql is enough to tell us that the request is suspicious.
|
||||
# Additionally, similar paths with different roots are represented as a single entry.
|
||||
# For example, the two entries usr/local/mysql/data/mysql.err and xampp/mysql/data/mysql.err are
|
||||
# represented as mysal/data, as that is enough to identify the paths as being suspicious.
|
||||
|
||||
|
||||
# Most of the dotfile entries can be generated from the following three commands.
|
||||
# Unfortunately, the output contains many more entries, including some file
|
||||
# extensions. There are also some entries that probably added by hand.
|
||||
# curl -s https://raw.githubusercontent.com/lightos/Panoptic/master/home.txt | grep -E "^\." | awk '{ print tolower($0) }' | sort | uniq
|
||||
# curl -s https://raw.githubusercontent.com/lightos/Panoptic/master/cases.xml | grep "file value" | cut -d'"' -f2 | grep -E "^\." | awk '{ print tolower($0) }' | sort | uniq
|
||||
# curl -s https://raw.githubusercontent.com/danielmiessler/SecLists/master/Fuzzing/fuzz-Bo0oM.txt | grep -Ev '\\|\.\.|=\b|%' | grep -E "^\." | awk '{ print tolower($0) }' | sort | uniq
|
||||
.addressbook
|
||||
.anydesk/
|
||||
.aptitude/config
|
||||
.atom/
|
||||
.aws/
|
||||
.azure/
|
||||
.bash_
|
||||
.bashrc
|
||||
.boto
|
||||
.cache/notify-osd.log
|
||||
.config/
|
||||
.cshrc
|
||||
.cups/
|
||||
.dbus/
|
||||
.docker
|
||||
.drush/
|
||||
.env
|
||||
.eslintignore
|
||||
.fbcindex
|
||||
.forward
|
||||
.gem/
|
||||
.gitattributes
|
||||
.gitconfig
|
||||
.gnonme/
|
||||
.gnupg/
|
||||
.gsutil/
|
||||
.hplip/hplip.conf
|
||||
.htaccess
|
||||
.htdigest
|
||||
.htpasswd
|
||||
.java/
|
||||
.ksh_history
|
||||
.kube/
|
||||
.lesshst
|
||||
.lftp/
|
||||
.lhistory
|
||||
.lighttpdpassword
|
||||
.lldb-history
|
||||
.local/share/mc/
|
||||
.lynx_cookies
|
||||
.minikube/
|
||||
.my.cnf
|
||||
.mysql_history
|
||||
.nano_history
|
||||
.netrc
|
||||
.node_repl_history
|
||||
.npm/
|
||||
.nsconfig
|
||||
.nsr
|
||||
.nvm/
|
||||
.oh-my-
|
||||
.password-store
|
||||
.pearrc
|
||||
.pgpass
|
||||
.php_history
|
||||
.pinerc
|
||||
.pki/
|
||||
.proclog
|
||||
.procmailrc
|
||||
.profile
|
||||
.psql_history
|
||||
.python_history
|
||||
.rediscli_history
|
||||
.rhistory
|
||||
.rhosts
|
||||
.sh_history
|
||||
.sqlite_history
|
||||
.ssh/
|
||||
.subversion/
|
||||
.tconn/
|
||||
.tcshrc
|
||||
.thunderbird/
|
||||
.tor/
|
||||
.vidalia/
|
||||
.vim/
|
||||
.viminfo
|
||||
.vimrc
|
||||
.vmware/
|
||||
.www_acl
|
||||
.wwwacl
|
||||
.xauthority
|
||||
.zhistory
|
||||
.zsh_history
|
||||
.zshrc
|
||||
|
||||
|
||||
/php.ini
|
||||
/tmp/
|
||||
|
||||
# Apache httpd entries can be generated with the following command:
|
||||
# curl -s https://raw.githubusercontent.com/lightos/Panoptic/master/cases.xml | grep "file value" | cut -d'"' -f2 | awk -F/ '{ { if (length($NF) > 0) {v1 = NF-1; v2 = NF} else {v1 = NF-2; v2 = NF-1} print tolower($v1"/"$v2) }) }' | grep apache | sort | uniq
|
||||
apache/access.conf
|
||||
apache/apache.conf
|
||||
apache/apache2.conf
|
||||
apache/audit_log
|
||||
apache/conf
|
||||
apache/default-server.conf
|
||||
apache/error_log
|
||||
apache/error.log
|
||||
apache/httpd.conf
|
||||
apache/log
|
||||
apache2/apache.conf
|
||||
apache2/apache2.conf
|
||||
apache2/conf
|
||||
apache2/default-server.conf
|
||||
apache2/envvars
|
||||
apache2/httpd.conf
|
||||
apache2/httpd2.conf
|
||||
apache2/logs
|
||||
apache2/mods
|
||||
apache2/ports.conf
|
||||
apache2/sites
|
||||
apache2/ssl-global.conf
|
||||
apache2/vhosts.d
|
||||
apache22/conf
|
||||
apache22/httpd.conf
|
||||
apache22/logs
|
||||
apache24/conf
|
||||
apache24/httpd.conf
|
||||
apache24/logs
|
||||
app/etc/local.xml
|
||||
boot.ini
|
||||
boot/grub/grub.cfg
|
||||
boot/grub/menu.lst
|
||||
config_dev.yml
|
||||
config_prod.yml
|
||||
config_test.yml
|
||||
config.inc.php
|
||||
config.php
|
||||
config.yml
|
||||
config/app.php
|
||||
config/custom.php
|
||||
config/database.php
|
||||
configuration.php
|
||||
cpanel/logs
|
||||
data/elasticsearch
|
||||
data/kafka
|
||||
etc/.java
|
||||
etc/acpi
|
||||
etc/adduser.conf
|
||||
etc/alias
|
||||
etc/alsa
|
||||
etc/alternatives
|
||||
etc/anacrontab
|
||||
etc/ansible
|
||||
etc/apache/access.conf
|
||||
etc/apache/apache.conf
|
||||
etc/apache/default-server.conf
|
||||
etc/apache/httpd.conf
|
||||
etc/apache/vhosts.conf
|
||||
etc/apache2
|
||||
etc/apm
|
||||
etc/apparmor
|
||||
etc/apport
|
||||
etc/apt
|
||||
etc/asciidoc
|
||||
etc/at.allow
|
||||
etc/at.deny
|
||||
etc/avahi
|
||||
etc/bash_completion.d
|
||||
etc/bash.bashrc
|
||||
etc/bashrc
|
||||
etc/bind
|
||||
etc/binfmt.d
|
||||
etc/bluetooth
|
||||
etc/bonobo-activation
|
||||
etc/bootptab
|
||||
etc/brltty
|
||||
etc/ca-certificates
|
||||
etc/calendar
|
||||
etc/casper.conf
|
||||
etc/centos-release
|
||||
etc/chatscripts
|
||||
etc/chkrootkit.conf
|
||||
etc/chromium-browser
|
||||
etc/chrootusers
|
||||
etc/chttp.conf
|
||||
etc/clam.d
|
||||
etc/clamav
|
||||
etc/cni
|
||||
etc/console-setup
|
||||
etc/coraza-waf
|
||||
etc/cracklib
|
||||
etc/cron.allow
|
||||
etc/cron.d
|
||||
etc/cron.hourly
|
||||
etc/cron.monthly
|
||||
etc/cron.weekly
|
||||
etc/crontab
|
||||
etc/crypttab
|
||||
etc/cups
|
||||
etc/cvs-cron.conf
|
||||
etc/cvs-pserver.conf
|
||||
etc/dbus-1
|
||||
etc/dconf
|
||||
etc/debconf.conf
|
||||
etc/debian_version
|
||||
etc/default
|
||||
etc/deluser.conf
|
||||
etc/depmod.d
|
||||
etc/dhcp
|
||||
etc/dictionaries-common
|
||||
etc/dkms
|
||||
etc/dns2tcpd.conf
|
||||
etc/dnsmasq.d
|
||||
etc/dockeretc/dpkg
|
||||
etc/e2fsck.conf
|
||||
etc/elasticsearch
|
||||
etc/emacs
|
||||
etc/environment.d
|
||||
etc/esound/esd.conf
|
||||
etc/etter.conf
|
||||
etc/exports
|
||||
etc/fail2ban
|
||||
etc/fedora-release
|
||||
etc/firebird
|
||||
etc/firefox
|
||||
etc/firewall
|
||||
etc/fonts
|
||||
etc/foremost.conf
|
||||
etc/freshclam.conf
|
||||
etc/fstab
|
||||
etc/ftpaccess
|
||||
etc/ftpchroot
|
||||
etc/ftphosts
|
||||
etc/ftpusers
|
||||
etc/fuse.conf
|
||||
etc/fwupd
|
||||
etc/gconf
|
||||
etc/gdb
|
||||
etc/gdm3
|
||||
etc/geoclue
|
||||
etc/ghostscript
|
||||
etc/gimp
|
||||
etc/glvnd
|
||||
etc/gnome
|
||||
etc/gnucash
|
||||
etc/gnustep
|
||||
etc/groff
|
||||
etc/group
|
||||
etc/grub.conf
|
||||
etc/grub.d
|
||||
etc/gshadow
|
||||
etc/gss
|
||||
etc/gtk-2.0
|
||||
etc/gtk-3.0
|
||||
etc/hdparm.conf
|
||||
etc/host.conf
|
||||
etc/hostname
|
||||
etc/hosts
|
||||
etc/hp
|
||||
etc/http/conf
|
||||
etc/http/httpd.conf
|
||||
etc/httpd
|
||||
etc/ifplugd
|
||||
etc/imagemagick-6
|
||||
etc/inetd.conf
|
||||
etc/init
|
||||
etc/insserv.conf.d
|
||||
etc/ipfw
|
||||
etc/iproute2
|
||||
etc/iptables
|
||||
etc/issue
|
||||
etc/java
|
||||
etc/kafka
|
||||
etc/kbd/config
|
||||
etc/kernel
|
||||
etc/kibana
|
||||
etc/ld.so.conf
|
||||
etc/ldap
|
||||
etc/libblockdev
|
||||
etc/libibverbs.d
|
||||
etc/libnl-3
|
||||
etc/libpaper.d
|
||||
etc/libreoffice
|
||||
etc/lighttpd
|
||||
etc/lilo.conf
|
||||
etc/logcheck
|
||||
etc/login.defs
|
||||
etc/logrotate.conf
|
||||
etc/logrotate.d
|
||||
etc/logstash
|
||||
etc/lsb-release
|
||||
etc/ltrace.conf
|
||||
etc/lvm
|
||||
etc/lynx
|
||||
etc/mail
|
||||
etc/mandrake-release
|
||||
etc/manpath.config
|
||||
etc/mc
|
||||
etc/menu
|
||||
etc/miredo-server.conf
|
||||
etc/miredo.conf
|
||||
etc/miredo/miredo-server.conf
|
||||
etc/miredo/miredo.conf
|
||||
etc/modprobe.d
|
||||
etc/modsecurity
|
||||
etc/modulesf
|
||||
etc/mongod.conf
|
||||
etc/monit
|
||||
etc/mono
|
||||
etc/motd
|
||||
etc/mplayer
|
||||
etc/mpv
|
||||
etc/mtab
|
||||
etc/mtools.conf
|
||||
etc/muddleftpd
|
||||
etc/muddleftpd.com
|
||||
etc/muttrc.d
|
||||
etc/my.cnf
|
||||
etc/my.conf
|
||||
etc/mysql
|
||||
etc/netplan
|
||||
etc/network
|
||||
etc/networkmanager
|
||||
etc/newsyslog.conf
|
||||
etc/newt
|
||||
etc/nghttpx
|
||||
etc/nginx/
|
||||
etc/nikto
|
||||
etc/npasswd
|
||||
etc/nuxeo.conf
|
||||
etc/odbcdatasources
|
||||
etc/openal
|
||||
etc/openldap/ldap.conf
|
||||
etc/openmpi
|
||||
etc/opt
|
||||
etc/os-release
|
||||
etc/osxhttpd
|
||||
etc/osync
|
||||
etc/packagekit
|
||||
etc/pam.conf
|
||||
etc/pam.d
|
||||
etc/pam.d/proftpd
|
||||
etc/passwd
|
||||
etc/password
|
||||
etc/pcmcia
|
||||
etc/perl
|
||||
etc/php
|
||||
etc/pki
|
||||
etc/pm
|
||||
etc/polkit-1
|
||||
etc/postfix
|
||||
etc/postgresql
|
||||
etc/ppp
|
||||
etc/printcap
|
||||
etc/profile
|
||||
etc/proftp.conf
|
||||
etc/proftpd
|
||||
etc/pulse
|
||||
etc/pure-ftpd
|
||||
etc/pureftpd
|
||||
etc/python
|
||||
etc/rc.conf
|
||||
etc/rc.d/rc.httpd
|
||||
etc/rc0.d
|
||||
etc/rc1.d
|
||||
etc/rc2.d
|
||||
etc/rc3.d
|
||||
etc/rc4.d
|
||||
etc/rc5.d
|
||||
etc/rc6.d
|
||||
etc/rcs.d
|
||||
etc/redhat-release
|
||||
etc/redis-sentinel.conf
|
||||
etc/redis.conf
|
||||
etc/resolv.conf
|
||||
etc/resolvconf
|
||||
etc/rsyslog.d
|
||||
etc/samba
|
||||
etc/sane.d
|
||||
etc/scw-release
|
||||
etc/security
|
||||
etc/selinux
|
||||
etc/sensors.conf
|
||||
etc/sensors.d
|
||||
etc/sensors3.conf
|
||||
etc/sgml
|
||||
etc/shadow
|
||||
etc/signon-ui
|
||||
etc/skel
|
||||
etc/slackware-release
|
||||
etc/smb.conf
|
||||
etc/smbpasswd
|
||||
etc/smi.conf
|
||||
etc/snmp
|
||||
etc/sound
|
||||
etc/spamassassin
|
||||
etc/speech-dispatcher
|
||||
etc/squid
|
||||
etc/squirrelmail
|
||||
etc/ssh
|
||||
etc/ssl
|
||||
etc/sso
|
||||
etc/stunnel
|
||||
etc/subgid
|
||||
etc/subuid
|
||||
etc/subversion
|
||||
etc/sudoers
|
||||
etc/suse-release
|
||||
etc/sw-cp-server/applications.d
|
||||
etc/sysconfig
|
||||
etc/sysctl.conf
|
||||
etc/sysctl.d
|
||||
etc/syslog.conf
|
||||
etc/sysstat
|
||||
etc/system-release-cpe
|
||||
etc/systemd
|
||||
etc/termcap
|
||||
etc/terminfo
|
||||
etc/texmf
|
||||
etc/thermald
|
||||
etc/thnuclnt
|
||||
etc/thunderbird
|
||||
etc/timezone
|
||||
etc/timidity
|
||||
etc/tinyproxy
|
||||
etc/tmpfiles.d
|
||||
etc/tor/tor-tsocks.conf
|
||||
etc/tsocks.conf
|
||||
etc/ubuntu-advantage
|
||||
etc/udev
|
||||
etc/udisks2
|
||||
etc/ufw
|
||||
etc/update-manager
|
||||
etc/update-motd.d
|
||||
etc/update-notifier
|
||||
etc/updatedb.conf
|
||||
etc/upower
|
||||
etc/urlview
|
||||
etc/usb_modeswitch.d
|
||||
etc/utmp
|
||||
etc/vhcs2/proftpd/proftpd.conf
|
||||
etc/vim
|
||||
etc/vmware
|
||||
etc/vsftpd.chroot_list
|
||||
etc/vsftpd.conf
|
||||
etc/vsftpd/vsftpd.conf
|
||||
etc/vulkan
|
||||
etc/w3m
|
||||
etc/webmin
|
||||
etc/wicd
|
||||
etc/wireshark
|
||||
etc/wpa_supplicant
|
||||
etc/wu-ftpd
|
||||
etc/x11
|
||||
etc/xdg
|
||||
etc/xml
|
||||
gruntfile.js
|
||||
home/postgres
|
||||
http/httpd.conf
|
||||
httpd/conf/httpd.conf
|
||||
inc/config.php
|
||||
includes/config.php
|
||||
includes/configure.php
|
||||
inetpub/wwwroot/global.asa
|
||||
jakarta/dist/tomcat
|
||||
jakarta/tomcat/conf
|
||||
jakarta/tomcat/logs
|
||||
library/webserver/documents
|
||||
lighttpd/conf
|
||||
lighttpd/lighttpd.conf
|
||||
lighttpd/log
|
||||
localsettings.php
|
||||
logs/access_log
|
||||
logs/access.log
|
||||
logs/error_log
|
||||
logs/error.log
|
||||
logs/pure-ftpd.log
|
||||
logs/samba.log
|
||||
logs/security_debug_log
|
||||
logs/security_log
|
||||
lsws/conf
|
||||
lsws/logs
|
||||
mysql/bin/my.ini
|
||||
mysql/data
|
||||
mysql/my.cnf
|
||||
mysql/my.ini
|
||||
nginx/conf/nginx.conf
|
||||
npm-debug.log
|
||||
opt/apache
|
||||
opt/apache2
|
||||
opt/httpd/apache.conf
|
||||
opt/httpd/apache2.conf
|
||||
opt/httpd/conf/
|
||||
opt/jboss
|
||||
opt/lampp
|
||||
opt/nuxeo
|
||||
opt/tomcat
|
||||
opt/xampp
|
||||
ormconfig.json
|
||||
package-lock.json
|
||||
package.json
|
||||
parameters.yml
|
||||
pgsql/bin/pg_passwd
|
||||
pgsql/data
|
||||
php/apache.conf
|
||||
php/apache2.conf
|
||||
php/httpd.conf
|
||||
php5/apache.conf
|
||||
php5/apache2.conf
|
||||
php5/httpd.conf
|
||||
postgresql/log/
|
||||
proc/0
|
||||
proc/1
|
||||
proc/2
|
||||
proc/3
|
||||
proc/4
|
||||
proc/5
|
||||
proc/6
|
||||
proc/7
|
||||
proc/8
|
||||
proc/9
|
||||
proc/acpi
|
||||
proc/asound
|
||||
proc/bootconfig
|
||||
proc/buddyinfo
|
||||
proc/bus
|
||||
proc/cgroups
|
||||
proc/cmdline
|
||||
proc/config.gz
|
||||
proc/consoles
|
||||
proc/cpuinfo
|
||||
proc/crypto
|
||||
proc/devices
|
||||
proc/diskstats
|
||||
proc/dma
|
||||
proc/docker
|
||||
proc/driver
|
||||
proc/dynamic_debug
|
||||
proc/execdomains
|
||||
proc/fb
|
||||
proc/filesystems
|
||||
proc/fs
|
||||
proc/interrupts
|
||||
proc/iomem
|
||||
proc/ioports
|
||||
proc/ipmi
|
||||
proc/irq
|
||||
proc/kallsyms
|
||||
proc/kcore
|
||||
proc/key-users
|
||||
proc/keys
|
||||
proc/kmsg
|
||||
proc/kpagecgroup
|
||||
proc/kpagecount
|
||||
proc/kpageflags
|
||||
proc/latency_stats
|
||||
proc/loadavg
|
||||
proc/locks
|
||||
proc/mdstat
|
||||
proc/meminfo
|
||||
proc/misc
|
||||
proc/modules
|
||||
proc/mounts
|
||||
proc/mpt
|
||||
proc/mtd
|
||||
proc/mtrr
|
||||
proc/net
|
||||
proc/pagetypeinfo
|
||||
proc/partitions
|
||||
proc/pressure
|
||||
proc/sched_debug
|
||||
proc/schedstat
|
||||
proc/scsi
|
||||
proc/self
|
||||
proc/slabinfo
|
||||
proc/softirqs
|
||||
proc/stat
|
||||
proc/swaps
|
||||
proc/sys
|
||||
proc/sysrq-trigger
|
||||
proc/sysvipc
|
||||
proc/thread-self
|
||||
proc/timer_list
|
||||
proc/timer_stats
|
||||
proc/tty
|
||||
proc/uptime
|
||||
proc/version
|
||||
proc/version_signature
|
||||
proc/vmallocinfo
|
||||
proc/vmstat
|
||||
proc/zoneinfo
|
||||
program files
|
||||
psa/admin
|
||||
pureftpd/etc
|
||||
root/anaconda-ks.cfg
|
||||
routing.yml
|
||||
samba/lib
|
||||
sb/config
|
||||
security.yml
|
||||
server/default/conf
|
||||
server/default/deploy
|
||||
server/default/log
|
||||
services.yml
|
||||
sftp-config.json
|
||||
sites/default/default.settings.php
|
||||
sites/default/settings.local.php
|
||||
sites/default/settings.php
|
||||
squirrelmail/config/config.php
|
||||
squirrelmail/www
|
||||
sys/block
|
||||
sys/bus
|
||||
sys/class
|
||||
sys/dev
|
||||
sys/devices
|
||||
sys/firmware
|
||||
sys/fs
|
||||
sys/hypervisor
|
||||
sys/kernel
|
||||
sys/module
|
||||
sys/power
|
||||
system/library/webobjects/adaptors
|
||||
system32/config
|
||||
system32/inetsrv/config
|
||||
tmp/access.log
|
||||
tmp/kafka-logs
|
||||
tsconfig.json
|
||||
typo3conf/localconf.php
|
||||
usr/etc/pure-ftpd.conf
|
||||
usr/home/user/lighttpd
|
||||
usr/lib/cron/log
|
||||
usr/lib/php
|
||||
usr/lib/rpm/rpm.log
|
||||
usr/lib/security
|
||||
usr/local/zeus/web
|
||||
usr/pkg/etc/httpd
|
||||
usr/pkgsrc/net/pureftpd
|
||||
usr/ports/contrib/pure-ftpd
|
||||
usr/ports/ftp/pure-ftpd
|
||||
usr/sbin/mudlogd
|
||||
usr/sbin/mudpasswd
|
||||
usr/sbin/pure-config.pl
|
||||
usr/share/adduser
|
||||
usr/share/logs
|
||||
usr/share/squirrelmail
|
||||
usr/share/tomcat
|
||||
usr/spool/lp
|
||||
usr/spool/mqueue
|
||||
var/adm
|
||||
var/apache/logs
|
||||
var/apache2/config.inc
|
||||
var/cpanel
|
||||
var/cron/log
|
||||
var/data/elasticsearch
|
||||
var/data/mysql-bin
|
||||
var/htmp
|
||||
var/lib/elasticsearch
|
||||
var/lib/mysql
|
||||
var/lib/pgsql
|
||||
var/lib/squirrelmail
|
||||
var/lighttpd
|
||||
var/local/www/conf
|
||||
var/log
|
||||
var/lp/logs
|
||||
var/mail
|
||||
var/mysql-bin
|
||||
var/mysql.log
|
||||
var/nm2/postgresql.conf
|
||||
var/postgresql
|
||||
var/run/utmp
|
||||
var/saf/_log
|
||||
var/saf/port/log
|
||||
var/spool
|
||||
var/webmin
|
||||
var/www/conf
|
||||
var/www/html/squirrelmail
|
||||
var/www/log
|
||||
volumes/macintosh_hd
|
||||
volumes/webbackup
|
||||
wamp/bin/apache
|
||||
wamp/bin/mysql
|
||||
wamp/bin/php
|
||||
wamp/logs
|
||||
web.config
|
||||
webpack.config.js
|
||||
windows/comsetup.log
|
||||
windows/debug/netsetup.log
|
||||
windows/odbc.ini
|
||||
windows/repair/setup.log
|
||||
windows/setupact.log
|
||||
windows/setupapi.log
|
||||
windows/setuperr.log
|
||||
windows/system32
|
||||
windows/updspapi.log
|
||||
windows/windowsupdate.log
|
||||
windows/wmsetup.log
|
||||
winnt/repair
|
||||
winnt/system32/logfiles
|
||||
wp-config.
|
||||
www/conf/httpd.conf
|
||||
www/logs
|
||||
xampp/apache/logs
|
||||
xampp/filezillaftp
|
||||
xampp/htdocs
|
||||
xampp/mercurymail
|
||||
xampp/mysql/data
|
||||
xampp/php
|
||||
xampp/sendmail
|
||||
xampp/webalizer/webalizer.conf
|
||||
yarn.lock
|
||||
@@ -0,0 +1,571 @@
|
||||
# This list comes mainly from:
|
||||
# - https://www.php.net/manual/en/ini.core.php
|
||||
# - https://www.php.net/manual/en/ini.list.php
|
||||
#
|
||||
# There are additional directives defined in some of the modules, that can be parsed from each modules's configuration page:
|
||||
# - https://www.php.net/manual/en/$book.configuration.php (book comes from funcref.php)
|
||||
#
|
||||
# As the source code is in docbook format with many dependencies, the easiest
|
||||
# way to get it is using an xpath parser on the ini list and getting all
|
||||
# using '//table/tbody/tr/td[1]'. A simple helper tool you can use is https://www.videlibri.de/xidel.html
|
||||
#
|
||||
# Small post-processing is needed to remove numbers coming from a column,
|
||||
# and `*` chars (e.g. `pdo.dsn.*`).
|
||||
# Also removed single words like `engine`, `extension`, `from` and `precision`, to prevent FP.
|
||||
#
|
||||
# Example usage:
|
||||
# `xidel https://www.php.net/manual/en/ini.core.php https://www.php.net/manual/en/ini.list.php --xpath '//table/tbody/tr/td[1]' | sort | uniq`
|
||||
#
|
||||
# And for configuration in submodules:
|
||||
#
|
||||
# for book in $(xidel https://www.php.net/manual/en/funcref.php -e '//a/extract(@href, "book\.(.+)\.php", 1)[. != ""]') ─╯
|
||||
# do
|
||||
# xidel https://www.php.net/manual/en/$book.configuration.php --xpath '//table/tbody/tr/td[1]' >> php-config-directives.txt
|
||||
# done
|
||||
#
|
||||
# ** Remember to always `sort` the output so its easy to spot the changes, and remove duplicates if any.
|
||||
|
||||
allow_url_fopen
|
||||
allow_url_include
|
||||
apc.coredump_unmap
|
||||
apc.enable_cli
|
||||
apc.enabled
|
||||
apc.entries_hint
|
||||
apc.gc_ttl
|
||||
apc.mmap_file_mask
|
||||
apc.preload_path
|
||||
apc.serializer
|
||||
apc.shm_segments
|
||||
apc.shm_size
|
||||
apc.slam_defense
|
||||
apc.ttl
|
||||
apc.use_request_time
|
||||
arg_separator.input
|
||||
arg_separator.output
|
||||
assert.active
|
||||
assert.bail
|
||||
assert.callback
|
||||
assert.exception
|
||||
assert.quiet_eval
|
||||
assert.warning
|
||||
auto_append_file
|
||||
auto_detect_line_endings
|
||||
auto_globals_jit
|
||||
auto_prepend_file
|
||||
bcmath.scale
|
||||
browscap
|
||||
cgi.check_shebang_line
|
||||
cgi.discard_path
|
||||
cgi.fix_pathinfo
|
||||
cgi.force_redirect
|
||||
cgi.nph
|
||||
cgi.redirect_status_env
|
||||
cgi.rfc2616_headers
|
||||
child_terminate
|
||||
cli_server.color
|
||||
cli.pager
|
||||
cli.prompt
|
||||
com.allow_dcom
|
||||
com.autoregister_casesensitive
|
||||
com.autoregister_typelib
|
||||
com.autoregister_verbose
|
||||
com.code_page
|
||||
com.dotnet_version
|
||||
com.typelib_file
|
||||
curl.cainfo
|
||||
date.default_latitude
|
||||
date.default_longitude
|
||||
date.sunrise_zenith
|
||||
date.sunset_zenith
|
||||
date.timezone
|
||||
dba.default_handler
|
||||
default_charset
|
||||
default_mimetype
|
||||
default_socket_timeout
|
||||
disable_classes
|
||||
disable_functions
|
||||
display_errors
|
||||
display_startup_errors
|
||||
doc_root
|
||||
docref_ext
|
||||
docref_root
|
||||
enable_dl
|
||||
enable_post_data_reading
|
||||
engine
|
||||
error_append_string
|
||||
error_log
|
||||
error_prepend_string
|
||||
error_reporting
|
||||
exif.decode_jis_intel
|
||||
exif.decode_jis_motorola
|
||||
exif.decode_unicode_intel
|
||||
exif.decode_unicode_motorola
|
||||
exif.encode_jis
|
||||
exif.encode_unicode
|
||||
exit_on_timeout
|
||||
extension
|
||||
expect.logfile
|
||||
expect.loguser
|
||||
expect.match_max
|
||||
expect.timeout
|
||||
expose_php
|
||||
extension_dir
|
||||
fastcgi.impersonate
|
||||
fastcgi.logging
|
||||
ffi.enable
|
||||
ffi.preload
|
||||
file_uploads
|
||||
filter.default
|
||||
filter.default_flags
|
||||
gd.jpeg_ignore_warning
|
||||
geoip.custom_directory
|
||||
hard_timeout
|
||||
highlight.comment
|
||||
highlight.default
|
||||
highlight.html
|
||||
highlight.keyword
|
||||
highlight.string
|
||||
html_errors
|
||||
ibase.allow_persistent
|
||||
ibase.dateformat
|
||||
ibase.default_charset
|
||||
ibase.default_db
|
||||
ibase.default_password
|
||||
ibase.default_user
|
||||
ibase.max_links
|
||||
ibase.max_persistent
|
||||
ibase.timeformat
|
||||
ibase.timestampformat
|
||||
ibm_db2.binmode
|
||||
ibm_db2.i5_all_pconnect
|
||||
ibm_db2.i5_allow_commit
|
||||
ibm_db2.i5_dbcs_alloc
|
||||
ibm_db2.i5_ignore_userid
|
||||
ibm_db2.instance_name
|
||||
iconv.input_encoding
|
||||
iconv.internal_encoding
|
||||
iconv.output_encoding
|
||||
igbinary.compact_strings
|
||||
ignore_repeated_errors
|
||||
ignore_repeated_source
|
||||
ignore_user_abort
|
||||
imagick.locale_fix
|
||||
imagick.progress_monitor
|
||||
imagick.skip_version_check
|
||||
imap.enable_insecure_rsh
|
||||
implicit_flush
|
||||
include_path
|
||||
input_encoding
|
||||
internal_encoding
|
||||
intl.default_locale
|
||||
intl.error_level
|
||||
intl.use_exceptions
|
||||
ldap.max_links
|
||||
log_errors
|
||||
log_errors_max_len
|
||||
magic_quotes_gpc
|
||||
magic_quotes_runtime
|
||||
mail.add_x_header
|
||||
mail.force_extra_parameters
|
||||
mail.log
|
||||
mailparse.def_charset
|
||||
max_execution_time
|
||||
max_file_uploads
|
||||
max_input_nesting_level
|
||||
max_input_time
|
||||
max_input_vars
|
||||
mbstring.detect_order
|
||||
mbstring.encoding_translation
|
||||
mbstring.func_overload
|
||||
mbstring.http_input
|
||||
mbstring.http_output
|
||||
mbstring.http_output_conv_mimetypes
|
||||
mbstring.internal_encoding
|
||||
mbstring.language
|
||||
mbstring.regex_retry_limit
|
||||
mbstring.regex_stack_limit
|
||||
mbstring.strict_detection
|
||||
mbstring.substitute_character
|
||||
mcrypt.algorithms_dir
|
||||
mcrypt.modes_dir
|
||||
memcache.allow_failover
|
||||
memcache.chunk_size
|
||||
memcache.compress_threshold
|
||||
memcache.default_port
|
||||
memcache.hash_function
|
||||
memcache.hash_strategy
|
||||
memcache.lock_timeout
|
||||
memcache.max_failover_attempts
|
||||
memcache.protocol
|
||||
memcache.redundancy
|
||||
memcache.session_redundancy
|
||||
memcached.compression_factor
|
||||
memcached.compression_threshold
|
||||
memcached.compression_type
|
||||
memcached.default_binary_protocol
|
||||
memcached.default_connect_timeout
|
||||
memcached.default_consistent_hash
|
||||
memcached.serializer
|
||||
memcached.sess_binary
|
||||
memcached.sess_binary_protocol
|
||||
memcached.sess_connect_timeout
|
||||
memcached.sess_consistent_hash
|
||||
memcached.sess_consistent_hash_type
|
||||
memcached.sess_lock_expire
|
||||
memcached.sess_lock_retries
|
||||
memcached.sess_lock_wait
|
||||
memcached.sess_lock_wait_max
|
||||
memcached.sess_lock_wait_min
|
||||
memcached.sess_locking
|
||||
memcached.sess_number_of_replicas
|
||||
memcached.sess_persistent
|
||||
memcached.sess_prefix
|
||||
memcached.sess_randomize_replica_read
|
||||
memcached.sess_remove_failed
|
||||
memcached.sess_remove_failed_servers
|
||||
memcached.sess_sasl_password
|
||||
memcached.sess_sasl_username
|
||||
memcached.sess_server_failure_limit
|
||||
memcached.store_retry_count
|
||||
memcached.use_sasl
|
||||
memory_limit
|
||||
mysql.allow_local_infile
|
||||
mysql.allow_persistent
|
||||
mysql.connect_timeout
|
||||
mysql.default_host
|
||||
mysql.default_password
|
||||
mysql.default_port
|
||||
mysql.default_socket
|
||||
mysql.default_user
|
||||
mysql.max_links
|
||||
mysql.max_persistent
|
||||
mysql.trace_mode
|
||||
mysqli.allow_local_infile
|
||||
mysqli.allow_persistent
|
||||
mysqli.default_host
|
||||
mysqli.default_port
|
||||
mysqli.default_pw
|
||||
mysqli.default_socket
|
||||
mysqli.default_user
|
||||
mysqli.local_infile_directory
|
||||
mysqli.max_links
|
||||
mysqli.max_persistent
|
||||
mysqli.reconnect
|
||||
mysqli.rollback_on_cached_plink
|
||||
mysqlnd.collect_memory_statistics
|
||||
mysqlnd.collect_statistics
|
||||
mysqlnd.debug
|
||||
mysqlnd.fetch_data_copy
|
||||
mysqlnd.log_mask
|
||||
mysqlnd.mempool_default_size
|
||||
mysqlnd.net_cmd_buffer_size
|
||||
mysqlnd.net_read_buffer_size
|
||||
mysqlnd.net_read_timeout
|
||||
mysqlnd.sha256_server_public_key
|
||||
mysqlnd.trace_alloc
|
||||
oci8.connection_class
|
||||
oci8.default_prefetch
|
||||
oci8.events
|
||||
oci8.max_persistent
|
||||
oci8.old_oci_close_semantics
|
||||
oci8.persistent_timeout
|
||||
oci8.ping_interval
|
||||
oci8.prefetch_lob_size
|
||||
oci8.privileged_connect
|
||||
oci8.statement_cache_size
|
||||
odbc.allow_persistent
|
||||
odbc.check_persistent
|
||||
odbc.default_cursortype
|
||||
odbc.default_db
|
||||
odbc.default_pw
|
||||
odbc.default_user
|
||||
odbc.defaultbinmode
|
||||
odbc.defaultlrl
|
||||
odbc.max_links
|
||||
odbc.max_persistent
|
||||
opcache.blacklist_filename
|
||||
opcache.cache_id
|
||||
opcache.consistency_checks
|
||||
opcache.dups_fix
|
||||
opcache.enable
|
||||
opcache.enable_cli
|
||||
opcache.enable_file_override
|
||||
opcache.error_log
|
||||
opcache.fast_shutdown
|
||||
opcache.file_cache
|
||||
opcache.file_cache_consistency_checks
|
||||
opcache.file_cache_fallback
|
||||
opcache.file_cache_only
|
||||
opcache.file_update_protection
|
||||
opcache.force_restart_timeout
|
||||
opcache.huge_code_pages
|
||||
opcache.inherited_hack
|
||||
opcache.interned_strings_buffer
|
||||
opcache.jit
|
||||
opcache.jit_bisect_limit
|
||||
opcache.jit_blacklist_root_trace
|
||||
opcache.jit_blacklist_side_trace
|
||||
opcache.jit_buffer_size
|
||||
opcache.jit_debug
|
||||
opcache.jit_hot_func
|
||||
opcache.jit_hot_loop
|
||||
opcache.jit_hot_return
|
||||
opcache.jit_hot_side_exit
|
||||
opcache.jit_max_exit_counters
|
||||
opcache.jit_max_loop_unrolls
|
||||
opcache.jit_max_polymorphic_calls
|
||||
opcache.jit_max_recursive_calls
|
||||
opcache.jit_max_recursive_returns
|
||||
opcache.jit_max_root_traces
|
||||
opcache.jit_max_side_traces
|
||||
opcache.jit_prof_threshold
|
||||
opcache.lockfile_path
|
||||
opcache.log_verbosity_level
|
||||
opcache.max_accelerated_files
|
||||
opcache.max_file_size
|
||||
opcache.max_wasted_percentage
|
||||
opcache.memory_consumption
|
||||
opcache.mmap_base
|
||||
opcache.opt_debug_level
|
||||
opcache.optimization_level
|
||||
opcache.preferred_memory_model
|
||||
opcache.preload
|
||||
opcache.preload_user
|
||||
opcache.protect_memory
|
||||
opcache.record_warnings
|
||||
opcache.restrict_api
|
||||
opcache.revalidate_freq
|
||||
opcache.revalidate_path
|
||||
opcache.save_comments
|
||||
opcache.use_cwd
|
||||
opcache.validate_permission
|
||||
opcache.validate_root
|
||||
opcache.validate_timestamps
|
||||
open_basedir
|
||||
openssl.cafile
|
||||
openssl.capath
|
||||
output_buffering
|
||||
output_encoding
|
||||
output_handler
|
||||
pcre.backtrack_limit
|
||||
pcre.jit
|
||||
pcre.recursion_limit
|
||||
pdo_odbc.connection_pooling
|
||||
pdo_odbc.db2_instance_name
|
||||
pdo.dsn
|
||||
pgsql.allow_persistent
|
||||
pgsql.auto_reset_persistent
|
||||
pgsql.ignore_notice
|
||||
pgsql.log_notice
|
||||
pgsql.max_links
|
||||
pgsql.max_persistent
|
||||
phar.cache_list
|
||||
phar.readonly
|
||||
phar.require_hash
|
||||
phpdbg.eol
|
||||
phpdbg.path
|
||||
precision
|
||||
post_max_size
|
||||
realpath_cache_size
|
||||
realpath_cache_ttl
|
||||
register_argc_argv
|
||||
report_memleaks
|
||||
report_zend_debug
|
||||
request_order
|
||||
runkit.internal_override
|
||||
runkit.superglobal
|
||||
seaslog.appender
|
||||
seaslog.appender_retry
|
||||
seaslog.buffer_disabled_in_cli
|
||||
seaslog.buffer_size
|
||||
seaslog.default_basepath
|
||||
seaslog.default_datetime_format
|
||||
seaslog.default_logger
|
||||
seaslog.default_template
|
||||
seaslog.disting_by_hour
|
||||
seaslog.disting_folder
|
||||
seaslog.disting_type
|
||||
seaslog.ignore_warning
|
||||
seaslog.level
|
||||
seaslog.recall_depth
|
||||
seaslog.remote_host
|
||||
seaslog.remote_port
|
||||
seaslog.remote_timeout
|
||||
seaslog.throw_exception
|
||||
seaslog.trace_error
|
||||
seaslog.trace_exception
|
||||
seaslog.trace_notice
|
||||
seaslog.trace_warning
|
||||
seaslog.trim_wrap
|
||||
seaslog.use_buffer
|
||||
sendmail_from
|
||||
sendmail_path
|
||||
serialize_precision
|
||||
session.auto_start
|
||||
session.cache_expire
|
||||
session.cache_limiter
|
||||
session.cookie_domain
|
||||
session.cookie_httponly
|
||||
session.cookie_lifetime
|
||||
session.cookie_path
|
||||
session.cookie_samesite
|
||||
session.cookie_secure
|
||||
session.entropy_file
|
||||
session.entropy_length
|
||||
session.gc_divisor
|
||||
session.gc_maxlifetime
|
||||
session.gc_probability
|
||||
session.hash_bits_per_character
|
||||
session.hash_function
|
||||
session.lazy_write
|
||||
session.name
|
||||
session.referer_check
|
||||
session.save_handler
|
||||
session.save_path
|
||||
session.serialize_handler
|
||||
session.sid_bits_per_character
|
||||
session.sid_length
|
||||
session.trans_sid_hosts
|
||||
session.trans_sid_tags
|
||||
session.upload_progress.cleanup
|
||||
session.upload_progress.enabled
|
||||
session.upload_progress.freq
|
||||
session.upload_progress.min_freq
|
||||
session.upload_progress.name
|
||||
session.upload_progress.prefix
|
||||
session.use_cookies
|
||||
session.use_only_cookies
|
||||
session.use_strict_mode
|
||||
session.use_trans_sid
|
||||
short_open_tag
|
||||
smtp
|
||||
smtp_port
|
||||
soap.wsdl_cache
|
||||
soap.wsdl_cache_dir
|
||||
soap.wsdl_cache_enabled
|
||||
soap.wsdl_cache_limit
|
||||
soap.wsdl_cache_ttl
|
||||
sql.safe_mode
|
||||
sqlite3.defensive
|
||||
sqlite3.extension_dir
|
||||
stomp.default_broker
|
||||
stomp.default_connection_timeout_sec
|
||||
stomp.default_connection_timeout_usec
|
||||
stomp.default_read_timeout_sec
|
||||
stomp.default_read_timeout_usec
|
||||
swoole.aio_thread_num
|
||||
swoole.display_errors
|
||||
swoole.enable_coroutine
|
||||
swoole.enable_library
|
||||
swoole.enable_preemptive_scheduler
|
||||
swoole.fast_serialize
|
||||
swoole.unixsock_buffer_size
|
||||
swoole.use_namespace
|
||||
swoole.use_shortname
|
||||
sys_temp_dir
|
||||
syslog.facility
|
||||
syslog.filter
|
||||
syslog.ident
|
||||
sysvshm.init_mem
|
||||
taint.enable
|
||||
taint.error_level
|
||||
tidy.clean_output
|
||||
tidy.default_config
|
||||
track_errors
|
||||
trader.real_precision
|
||||
trader.real_round_mode
|
||||
unserialize_callback_func
|
||||
unserialize_max_depth
|
||||
uopz.disable
|
||||
uopz.exit
|
||||
uopz.overloads
|
||||
upload_max_filesize
|
||||
upload_tmp_dir
|
||||
uploadprogress.file.filename_template
|
||||
url_rewriter.hosts
|
||||
url_rewriter.tags
|
||||
user_agent
|
||||
user_dir
|
||||
user_ini.cache_ttl
|
||||
user_ini.filename
|
||||
v8js.flags
|
||||
v8js.max_disposed_contexts
|
||||
variables_order
|
||||
vld.active
|
||||
vld.execute
|
||||
vld.skip_append
|
||||
vld.skip_prepend
|
||||
wincache.chkinterval
|
||||
wincache.enablecli
|
||||
wincache.fcachesize
|
||||
wincache.fcenabled
|
||||
wincache.fcenabledfilter
|
||||
wincache.fcndetect
|
||||
wincache.filecount
|
||||
wincache.filemapdir
|
||||
wincache.ignorelist
|
||||
wincache.maxfilesize
|
||||
wincache.namesalt
|
||||
wincache.ocachesize
|
||||
wincache.ocenabled
|
||||
wincache.ocenabledfilter
|
||||
wincache.reroute_enabled
|
||||
wincache.rerouteini
|
||||
wincache.scachesize
|
||||
wincache.srwlocks
|
||||
wincache.ttlmax
|
||||
wincache.ucachesize
|
||||
wincache.ucenabled
|
||||
windows.show_crt_warning
|
||||
wkhtmltox.graphics
|
||||
xbithack
|
||||
xhprof.output_dir
|
||||
xmlrpc_error_number
|
||||
xmlrpc_errors
|
||||
yac.compress_threshold
|
||||
yac.debug
|
||||
yac.enable
|
||||
yac.enable_cli
|
||||
yac.keys_memory_size
|
||||
yac.serializer
|
||||
yac.values_memory_size
|
||||
yaconf.check_delay
|
||||
yaconf.directory
|
||||
yaf.action_prefer
|
||||
yaf.cache_config
|
||||
yaf.environ
|
||||
yaf.forward_limit
|
||||
yaf.library
|
||||
yaf.lowcase_path
|
||||
yaf.name_separator
|
||||
yaf.name_suffix
|
||||
yaf.use_namespace
|
||||
yaf.use_spl_autoload
|
||||
yaml.decode_binary
|
||||
yaml.decode_php
|
||||
yaml.decode_timestamp
|
||||
yaml.output_canonical
|
||||
yaml.output_indent
|
||||
yaml.output_width
|
||||
yar.connect_timeout
|
||||
yar.debug
|
||||
yar.expose_info
|
||||
yar.packager
|
||||
yar.timeout
|
||||
yaz.keepalive
|
||||
yaz.log_mask
|
||||
zend_extension
|
||||
zend.assertions
|
||||
zend.detect_unicode
|
||||
zend.enable_gc
|
||||
zend.exception_ignore_args
|
||||
zend.exception_string_param_max_len
|
||||
zend.multibyte
|
||||
zend.script_encoding
|
||||
zend.signal_check
|
||||
zlib.output_compression
|
||||
zlib.output_compression_level
|
||||
zlib.output_handler
|
||||
zookeeper.recv_timeout
|
||||
zookeeper.sess_lock_wait
|
||||
zookeeper.session_lock
|
||||
@@ -0,0 +1,5 @@
|
||||
# For more information, see comments at the beginning of the php-errors.data file.
|
||||
|
||||
Invalid date
|
||||
Static function
|
||||
The function
|
||||
2147
plugins/wasm-go/extensions/waf/wasmplugin/rules/crs/php-errors.data
Normal file
2147
plugins/wasm-go/extensions/waf/wasmplugin/rules/crs/php-errors.data
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,44 @@
|
||||
__halt_compiler
|
||||
apache_child_terminate
|
||||
base64_decode
|
||||
bzdecompress
|
||||
call_user_func
|
||||
call_user_func_array
|
||||
call_user_method
|
||||
call_user_method_array
|
||||
convert_uudecode
|
||||
file_get_contents
|
||||
file_put_contents
|
||||
fsockopen
|
||||
get_class_methods
|
||||
get_class_vars
|
||||
get_defined_constants
|
||||
get_defined_functions
|
||||
get_defined_vars
|
||||
gzdecode
|
||||
gzinflate
|
||||
gzuncompress
|
||||
include_once
|
||||
invokeargs
|
||||
pcntl_exec
|
||||
pcntl_fork
|
||||
pfsockopen
|
||||
posix_getcwd
|
||||
posix_getpwuid
|
||||
posix_getuid
|
||||
posix_uname
|
||||
ReflectionFunction
|
||||
require_once
|
||||
shell_exec
|
||||
str_rot13
|
||||
sys_get_temp_dir
|
||||
wp_remote_fopen
|
||||
wp_remote_get
|
||||
wp_remote_head
|
||||
wp_remote_post
|
||||
wp_remote_request
|
||||
wp_safe_remote_get
|
||||
wp_safe_remote_head
|
||||
wp_safe_remote_post
|
||||
wp_safe_remote_request
|
||||
zlib_decode
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,30 @@
|
||||
# The data in this list comes from
|
||||
# https://www.php.net/manual/en/reserved.variables.php
|
||||
# https://www.php.net/manual/en/language.variables.superglobals.php
|
||||
# https://www.php.net/manual/en/language.constants.predefined.php
|
||||
|
||||
# These superglobal variables are:
|
||||
$GLOBALS
|
||||
$_COOKIE
|
||||
$_ENV
|
||||
$_FILES
|
||||
$_GET
|
||||
$_POST
|
||||
$_REQUEST
|
||||
$_SERVER
|
||||
$_SESSION
|
||||
$argc
|
||||
$argv
|
||||
$http_response_header
|
||||
# Deprecated
|
||||
$php_errormsg
|
||||
|
||||
# This is really old, completely deprecated vars (PHP >= 4 < 5.3)
|
||||
$HTTP_COOKIE_VARS
|
||||
$HTTP_ENV_VARS
|
||||
$HTTP_GET_VARS
|
||||
$HTTP_POST_FILES
|
||||
$HTTP_POST_VARS
|
||||
$HTTP_RAW_POST_DATA
|
||||
$HTTP_REQUEST_VARS
|
||||
$HTTP_SERVER_VARS
|
||||
@@ -0,0 +1,261 @@
|
||||
# Apache
|
||||
# (no slash; also guards against old.htaccess, old.htpasswd, etc.)
|
||||
.htaccess
|
||||
.htdigest
|
||||
.htpasswd
|
||||
# home level dotfiles (keep in sync with lfi-os-files.data)
|
||||
# grep -E '^\.' lfi-os-files.data
|
||||
.addressbook
|
||||
.aptitude/config
|
||||
.aws/
|
||||
.azure/
|
||||
.bash_
|
||||
.bashrc
|
||||
.cache/notify-osd.log
|
||||
.config/
|
||||
.cshrc
|
||||
.docker
|
||||
.drush/
|
||||
.env
|
||||
.eslintignore
|
||||
.fbcindex
|
||||
.forward
|
||||
.gitattributes
|
||||
.gitconfig
|
||||
.gnupg/
|
||||
.hplip/hplip.conf
|
||||
.htaccess
|
||||
.htdigest
|
||||
.htpasswd
|
||||
.ksh_history
|
||||
.lesshst
|
||||
.lftp/
|
||||
.lhistory
|
||||
.lighttpdpassword
|
||||
.lldb-history
|
||||
.local/share/mc/
|
||||
.lynx_cookies
|
||||
.my.cnf
|
||||
.mysql_history
|
||||
.nano_history
|
||||
.node_repl_history
|
||||
.nsconfig
|
||||
.nsr
|
||||
.oh-my-
|
||||
.password-store
|
||||
.pearrc
|
||||
.pgpass
|
||||
.php_history
|
||||
.pinerc
|
||||
.pki/
|
||||
.proclog
|
||||
.procmailrc
|
||||
.profile
|
||||
.psql_history
|
||||
.python_history
|
||||
.rediscli_history
|
||||
.rhistory
|
||||
.rhosts
|
||||
.sh_history
|
||||
.sqlite_history
|
||||
.ssh/
|
||||
.subversion/
|
||||
.tconn/
|
||||
.tcshrc
|
||||
.tor/
|
||||
.vidalia/
|
||||
.vim/
|
||||
.viminfo
|
||||
.vimrc
|
||||
.www_acl
|
||||
.wwwacl
|
||||
.xauthority
|
||||
.zhistory
|
||||
.zsh_history
|
||||
.zshrc
|
||||
# Version control
|
||||
/.git/
|
||||
/.gitignore
|
||||
/.hg/
|
||||
/.hgignore
|
||||
/.svn/
|
||||
# Wordpress
|
||||
wp-config.php
|
||||
wp-config.bak
|
||||
wp-config.old
|
||||
wp-config.temp
|
||||
wp-config.tmp
|
||||
wp-config.txt
|
||||
# Symfony
|
||||
/config/config.yml
|
||||
/config/config_dev.yml
|
||||
/config/config_prod.yml
|
||||
/config/config_test.yml
|
||||
/config/parameters.yml
|
||||
/config/routing.yml
|
||||
/config/security.yml
|
||||
/config/services.yml
|
||||
# Drupal
|
||||
/sites/default/default.settings.php
|
||||
/sites/default/settings.php
|
||||
/sites/default/settings.local.php
|
||||
# Prestashop configuration file
|
||||
/config/settings.inc.php
|
||||
# Magento
|
||||
/app/etc/local.xml
|
||||
# Sublime Text
|
||||
/sftp-config.json
|
||||
# ASP.NET
|
||||
/Web.config
|
||||
# Node
|
||||
/package.json
|
||||
/package-lock.json
|
||||
/npm-shrinkwrap.json
|
||||
/gruntfile.js
|
||||
/npm-debug.log
|
||||
/ormconfig.json
|
||||
/tsconfig.json
|
||||
/webpack.config.js
|
||||
/yarn.lock
|
||||
# Composer
|
||||
/composer.json
|
||||
/composer.lock
|
||||
/packages.json
|
||||
# dotenv
|
||||
/.env
|
||||
# OSX
|
||||
/.DS_Store
|
||||
# WS FTP
|
||||
/.ws_ftp.ini
|
||||
# New Per-Project Files
|
||||
.idea
|
||||
nbproject/
|
||||
bower.json
|
||||
.bowerrc
|
||||
.eslintrc
|
||||
.jshintrc
|
||||
.gitlab-ci.yml
|
||||
.travis.yml
|
||||
database.yml
|
||||
Dockerfile
|
||||
# PHP_CodeSniffer configuration files
|
||||
.php_cs.dist
|
||||
.phpcs.xml
|
||||
phpcs.xml
|
||||
.phpcs.xml.dist
|
||||
phpcs.xml.dist
|
||||
# Windows desktop configuration file
|
||||
Desktop.ini
|
||||
# Windows Explorer cache of thumbnail images
|
||||
Thumbs.db
|
||||
# PHP configuration files
|
||||
.user.ini
|
||||
php.ini
|
||||
# Oracle WebLogic Server configuration file
|
||||
weblogic.xml
|
||||
# Oracle SOAP Request Handler configuration file
|
||||
soapConfig.xml
|
||||
# Common names for local PHP error logs
|
||||
php_error.log
|
||||
php_errors.log
|
||||
# Java directory for non-pubic application data
|
||||
WEB-INF/
|
||||
# Fortinet SSL VPN session file
|
||||
sslvpn_websession
|
||||
|
||||
# /proc entries (keep in sync with lfi-os-files.data)
|
||||
# grep -E "^proc/" lfi-os-files.data
|
||||
proc/0
|
||||
proc/1
|
||||
proc/2
|
||||
proc/3
|
||||
proc/4
|
||||
proc/5
|
||||
proc/6
|
||||
proc/7
|
||||
proc/8
|
||||
proc/9
|
||||
proc/acpi
|
||||
proc/asound
|
||||
proc/bootconfig
|
||||
proc/buddyinfo
|
||||
proc/bus
|
||||
proc/cgroups
|
||||
proc/cmdline
|
||||
proc/config.gz
|
||||
proc/consoles
|
||||
proc/cpuinfo
|
||||
proc/crypto
|
||||
proc/devices
|
||||
proc/diskstats
|
||||
proc/dma
|
||||
proc/docker
|
||||
proc/driver
|
||||
proc/dynamic_debug
|
||||
proc/execdomains
|
||||
proc/fb
|
||||
proc/filesystems
|
||||
proc/fs
|
||||
proc/interrupts
|
||||
proc/iomem
|
||||
proc/ioports
|
||||
proc/ipmi
|
||||
proc/irq
|
||||
proc/kallsyms
|
||||
proc/kcore
|
||||
proc/key-users
|
||||
proc/keys
|
||||
proc/kmsg
|
||||
proc/kpagecgroup
|
||||
proc/kpagecount
|
||||
proc/kpageflags
|
||||
proc/latency_stats
|
||||
proc/loadavg
|
||||
proc/locks
|
||||
proc/mdstat
|
||||
proc/meminfo
|
||||
proc/misc
|
||||
proc/modules
|
||||
proc/mounts
|
||||
proc/mpt
|
||||
proc/mtd
|
||||
proc/mtrr
|
||||
proc/net
|
||||
proc/pagetypeinfo
|
||||
proc/partitions
|
||||
proc/pressure
|
||||
proc/sched_debug
|
||||
proc/schedstat
|
||||
proc/scsi
|
||||
proc/self
|
||||
proc/slabinfo
|
||||
proc/softirqs
|
||||
proc/stat
|
||||
proc/swaps
|
||||
proc/sys
|
||||
proc/sysrq-trigger
|
||||
proc/sysvipc
|
||||
proc/thread-self
|
||||
proc/timer_list
|
||||
proc/timer_stats
|
||||
proc/tty
|
||||
proc/uptime
|
||||
proc/version
|
||||
proc/version_signature
|
||||
proc/vmallocinfo
|
||||
proc/vmstat
|
||||
proc/zoneinfo
|
||||
|
||||
# /sys entries (keep in sync with lfi-os-files.data)
|
||||
# grep -E "^sys/" lfi-os-files.data
|
||||
sys/block
|
||||
sys/bus
|
||||
sys/class
|
||||
sys/dev
|
||||
sys/devices
|
||||
sys/firmware
|
||||
sys/fs
|
||||
sys/hypervisor
|
||||
sys/kernel
|
||||
sys/module
|
||||
sys/power
|
||||
@@ -0,0 +1,23 @@
|
||||
# Apache webserver
|
||||
.htaccess
|
||||
.htdigest
|
||||
.htpasswd
|
||||
# WordPress configuration file
|
||||
wp-config.php
|
||||
# Symfony configuration files
|
||||
config.yml
|
||||
config_dev.yml
|
||||
config_prod.yml
|
||||
config_test.yml
|
||||
parameters.yml
|
||||
routing.yml
|
||||
security.yml
|
||||
services.yml
|
||||
# Drupal configuration files
|
||||
default.settings.php
|
||||
settings.php
|
||||
settings.local.php
|
||||
# Magento configuration files
|
||||
local.xml
|
||||
# dotenv configuration file
|
||||
.env
|
||||
@@ -0,0 +1,8 @@
|
||||
acunetix-product
|
||||
(acunetix web vulnerability scanner
|
||||
acunetix-scanning-agreement
|
||||
acunetix-user-agreement
|
||||
myvar=1234
|
||||
x-ratproxy-loop
|
||||
bytes=0-,5-0,5-1,5-2,5-3,5-4,5-5,5-6,5-7,5-8,5-9,5-10,5-11,5-12,5-13,5-14
|
||||
x-scanner
|
||||
@@ -0,0 +1,17 @@
|
||||
/.adSensepostnottherenonobook
|
||||
/<invalid>hello.html
|
||||
/actSensepostnottherenonotive
|
||||
/acunetix-wvs-test-for-some-inexistent-file
|
||||
/antidisestablishmentarianism
|
||||
/appscan_fingerprint/mac_address
|
||||
/arachni-
|
||||
/cybercop
|
||||
/nessus_is_probing_you_
|
||||
/nessustest
|
||||
/netsparker-
|
||||
/rfiinc.txt
|
||||
/thereisnowaythat-you-canbethere
|
||||
/w3af/remotefileinclude.html
|
||||
appscan_fingerprint
|
||||
w00tw00t.at.ISC.SANS.DFind
|
||||
w00tw00t.at.blackhats.romanian.anti-sec
|
||||
@@ -0,0 +1,231 @@
|
||||
# Vulnerability scanners, bruteforce password crackers and exploitation tools
|
||||
|
||||
# password cracker
|
||||
# http://sectools.org/tool/hydra/
|
||||
(hydra)
|
||||
# vuln scanner
|
||||
# http://virtualblueness.net/nasl.html
|
||||
.nasl
|
||||
# sql injection
|
||||
# https://sourceforge.net/projects/absinthe/
|
||||
absinthe
|
||||
# email harvesting
|
||||
# dead? 2004
|
||||
advanced email extractor
|
||||
# vuln scanner
|
||||
# http://www.arachni-scanner.com/
|
||||
arachni/
|
||||
autogetcontent
|
||||
# nessus frontend
|
||||
# http://www.crossley-nilsen.com/Linux/Bilbo_-_Nessus_WEB/bilbo_-_nessus_web.html
|
||||
# dead? 2003
|
||||
bilbo
|
||||
# Backup File Artifacts Checker
|
||||
# https://github.com/mazen160/bfac
|
||||
BFAC
|
||||
# password cracker
|
||||
# http://sectools.org/tool/brutus/
|
||||
brutus
|
||||
brutus/aet
|
||||
# sql injection
|
||||
# https://www.notsosecure.com/bsqlbf-v2-blind-sql-injection-brute-forcer/
|
||||
bsqlbf
|
||||
# vuln scanner assistance
|
||||
# example:
|
||||
# Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like \
|
||||
# Gecko) Chrome/55.0.2883.87 Safari/537.36 root@foo.burpcollaborator.net
|
||||
# https://portswigger.net/burp/documentation/collaborator
|
||||
burpcollaborator
|
||||
# vuln scanner
|
||||
# http://freecode.com/projects/cgichk dead? 2001
|
||||
cgichk
|
||||
# vuln scanner
|
||||
# https://sourceforge.net/projects/cisco-torch/
|
||||
cisco-torch
|
||||
# vuln scanner
|
||||
# https://github.com/stasinopoulos/commix
|
||||
commix
|
||||
# MS FrontPage vuln scanner?
|
||||
core-project/1.0
|
||||
# vuln scanner?
|
||||
crimscanner/
|
||||
# vuln scanner
|
||||
datacha0s
|
||||
# Detectify website vulnerability scanner
|
||||
# https://detectify.com/
|
||||
Detectify
|
||||
# hidden page scanner
|
||||
# https://www.owasp.org/index.php/Category:OWASP_DirBuster_Project
|
||||
dirbuster
|
||||
# vuln scanner
|
||||
# https://sourceforge.net/projects/dominohunter/
|
||||
domino hunter
|
||||
# vuln scanner - directory traversal fuzzer
|
||||
# https://github.com/wireghoul/dotdotpwn
|
||||
dotdotpwn
|
||||
# User-Agent: mozilla/5.0 ecairn-grabber/1.0 (+http://ecairn.com/grabber)
|
||||
ecairn-grabber
|
||||
email extractor
|
||||
# vuln scanner
|
||||
fhscan core 1.
|
||||
floodgate
|
||||
# vuln scanner
|
||||
# https://github.com/ffuf/ffuf
|
||||
Fuzz Faster U Fool
|
||||
# "F-Secure Radar is a turnkey vulnerability scanning and management platform."
|
||||
F-Secure Radar
|
||||
get-minimal
|
||||
# Scanner that looks for existing or hidden web objects
|
||||
# https://github.com/OJ/gobuster
|
||||
gobuster
|
||||
# vuln scanner
|
||||
gootkit auto-rooter scanner
|
||||
grabber
|
||||
# vuln scanner
|
||||
# https://sourceforge.net/projects/grendel/
|
||||
grendel-scan
|
||||
# sql injection
|
||||
havij
|
||||
# vuln scanner
|
||||
# https://github.com/projectdiscovery/httpx
|
||||
httpx - Open-source project
|
||||
# vuln scanner - path disclosure finder
|
||||
# http://seclists.org/fulldisclosure/2010/Sep/375
|
||||
inspath
|
||||
internet ninja
|
||||
# vuln scanner
|
||||
jaascois
|
||||
# "Mozilla/5.0 Jorgee", vuln scanner
|
||||
Jorgee
|
||||
# port scanner
|
||||
# https://github.com/robertdavidgraham/masscan
|
||||
masscan
|
||||
# vuln scanner
|
||||
# http://www.severus.org/sacha/metis/
|
||||
metis
|
||||
# vuln scanner
|
||||
morfeus fucking scanner
|
||||
# sql injection
|
||||
# https://github.com/dtrip/mysqloit
|
||||
mysqloit
|
||||
# vuln scanner
|
||||
# http://www.nstalker.com/
|
||||
n-stealth
|
||||
# vuln scanner
|
||||
# http://www.tenable.com/products/nessus-vulnerability-scanner
|
||||
nessus
|
||||
# vuln scanner
|
||||
# https://www.netsparker.com/web-vulnerability-scanner/
|
||||
netsparker
|
||||
# vuln scanner
|
||||
# https://cirt.net/Nikto2
|
||||
nikto
|
||||
# vuln scanner
|
||||
nmap nse
|
||||
nmap scripting engine
|
||||
nmap-nse
|
||||
# vuln scanner
|
||||
# http://www.nsauditor.com/
|
||||
nsauditor
|
||||
# vuln scanner
|
||||
# https://github.com/projectdiscovery/nuclei
|
||||
Nuclei
|
||||
# vuln scanner
|
||||
# http://www.openvas.org/
|
||||
openvas
|
||||
# sql injection
|
||||
# http://www.vealtel.com/software/nosec/pangolin/
|
||||
pangolin
|
||||
# web proxy & vuln scanner
|
||||
# https://sourceforge.net/projects/paros/
|
||||
paros
|
||||
# phpmyadmin vuln scanner
|
||||
# dead 2005?
|
||||
pmafind
|
||||
prog.customcrawler
|
||||
# QQGameHall DoS/Virus/Malware/Adware
|
||||
# https://twitter.com/bagder/status/1244982556958826496?s=20
|
||||
QQGameHall
|
||||
# vuln scanner
|
||||
# https://www.qualys.com/suite/web-application-scanning/
|
||||
qualys was
|
||||
s.t.a.l.k.e.r.
|
||||
security scan
|
||||
# vuln scanner
|
||||
# https://sourceforge.net/projects/springenwerk/
|
||||
springenwerk
|
||||
# sql injection
|
||||
# http://www.sqlpowerinjector.com/
|
||||
sql power injector
|
||||
# sql injection
|
||||
# http://sqlmap.org/
|
||||
sqlmap
|
||||
# sql injection
|
||||
# http://sqlninja.sourceforge.net/
|
||||
sqlninja
|
||||
# vuln scanner
|
||||
# https://github.com/mazen160/struts-pwn
|
||||
struts-pwn
|
||||
# https://www.cyber.nj.gov/threat-profiles/trojan-variants/sysscan
|
||||
sysscan
|
||||
# LeakIX web scanner (User-Agent: TBI-WebScanner/0.0.1 (+https://leakix.net/))
|
||||
# https://leakix.net/
|
||||
TBI-WebScanner
|
||||
# password cracker
|
||||
# http://foofus.net/goons/jmk/medusa/medusa.html
|
||||
teh forest lobster
|
||||
this is an exploit
|
||||
# vuln scanner?
|
||||
toata dragostea
|
||||
toata dragostea mea pentru diavola
|
||||
# SQL bot
|
||||
# http://tools.cisco.com/security/center/viewIpsSignature.x?signatureId=22142&signatureSubId=0
|
||||
uil2pn
|
||||
# badly scripted UAs (e.g. User-Agent: User-Agent: foo)
|
||||
user-agent:
|
||||
# vuln scannr
|
||||
# https://subgraph.com/vega/
|
||||
vega/
|
||||
# vuln scanner
|
||||
# dead?
|
||||
voideye
|
||||
# vuln scanner
|
||||
# http://w3af.org/
|
||||
w3af.sf.net
|
||||
w3af.sourceforge.net
|
||||
w3af.org
|
||||
# site scanner (legacy)
|
||||
# http://www.robotstxt.org/db/webbandit.html
|
||||
webbandit
|
||||
# vuln scanner
|
||||
# http://www8.hp.com/us/en/software-solutions/webinspect-dynamic-analysis-dast/
|
||||
webinspect
|
||||
# site scanner
|
||||
# http://www.scrt.ch/en/attack/downloads/webshag
|
||||
webshag
|
||||
# vuln scanner
|
||||
# dead?
|
||||
webtrends security analyzer
|
||||
# vuln scanner
|
||||
# https://github.com/hhucn/webvulnscan
|
||||
webvulnscan
|
||||
# vuln scanner
|
||||
# https://github.com/xmendez/wfuzz
|
||||
Wfuzz
|
||||
# web technology scanner
|
||||
# https://www.morningstarsecurity.com/research/whatweb
|
||||
whatweb
|
||||
# vuln scanner
|
||||
whcc/
|
||||
# exploit poc
|
||||
wordpress hash grabber
|
||||
# wordpress vuln scanner
|
||||
# https://wpscan.org/
|
||||
WPScan
|
||||
# exploit
|
||||
xmlrpc exploit
|
||||
# ZGrab scanner (Mozilla/5.0 zgrab/0.x)
|
||||
# https://zmap.io
|
||||
zgrab
|
||||
# vuln scanner
|
||||
zmeu
|
||||
@@ -0,0 +1,68 @@
|
||||
# Generic HTTP clients (popular libraries)
|
||||
|
||||
# http library
|
||||
# https://docs.aiohttp.org/en/stable/
|
||||
# User-Agent: Python/VERSION aiohttp/VERSION
|
||||
aiohttp/
|
||||
|
||||
# http library
|
||||
# http://search.cpan.org/~opera/HTTP-DAV/DAV.pm
|
||||
dav.pm/v
|
||||
|
||||
# http library
|
||||
# https://pkg.go.dev/net/http
|
||||
# User-Agent: Go http package
|
||||
# User-Agent: Go 1.1 package http
|
||||
# User-Agent: Go-http-client/VERSION
|
||||
Go http package
|
||||
Go 1.1 package http
|
||||
Go-http-client/
|
||||
|
||||
# http library
|
||||
# http://search.cpan.org/dist/libwww-perl/lib/LWP.pm
|
||||
libwww-perl
|
||||
# generic
|
||||
mozilla/4.0 (compatible)
|
||||
mozilla/4.0 (compatible; msie 6.0; win32)
|
||||
mozilla/5.0 sf/
|
||||
mozilla/5.0 sf//
|
||||
|
||||
# http library
|
||||
# https://pypi.python.org/pypi/httplib2
|
||||
python-httplib2
|
||||
|
||||
# http library
|
||||
# https://www.python-httpx.org/
|
||||
# User-Agent: python-httpx/VERSION
|
||||
python-httpx/
|
||||
|
||||
# http library
|
||||
# http://docs.python-requests.org/en/master/
|
||||
python-requests
|
||||
|
||||
# http library
|
||||
# https://docs.python.org/2/library/urllib.html
|
||||
Python-urllib
|
||||
|
||||
# http library
|
||||
# https://github.com/typhoeus/typhoeus
|
||||
typhoeus
|
||||
|
||||
# http library
|
||||
# https://msdn.microsoft.com/en-us/library/windows/desktop/aa382925%28v=vs.85%29.aspx
|
||||
winhttp.winhttprequest
|
||||
|
||||
# http library
|
||||
# https://kong.github.io/unirest-java/
|
||||
# User-Agent: unirest-java/VERSION
|
||||
unirest-java/
|
||||
|
||||
# http library (deprecated since 2022)
|
||||
# https://index.scala-lang.org/scalaj/scalaj-http
|
||||
# User-Agent: scalaj-http/VERSION
|
||||
scalaj-http/
|
||||
|
||||
# http library
|
||||
# https://http4s.org/
|
||||
# User-Agent: http4s-ember
|
||||
http4s-ember
|
||||
@@ -0,0 +1,81 @@
|
||||
MySqlClient.
|
||||
Server message
|
||||
SQL error
|
||||
Oracle error
|
||||
JET Database Engine
|
||||
Procedure or function
|
||||
SQLite.Exception
|
||||
[IBM][CLI Driver][DB2/6000]
|
||||
the used select statements have different number of columns
|
||||
org.postgresql.util.PSQLException
|
||||
Access Database Engine
|
||||
Incorrect syntax near
|
||||
Syntax error in string in query expression
|
||||
SQLiteException
|
||||
' doesn't exist
|
||||
CLI Driver
|
||||
on MySQL result index
|
||||
sybase
|
||||
com.informix.jdbc
|
||||
[MySQL][ODBC
|
||||
Error
|
||||
has occurred in the vicinity of:
|
||||
Sintaxis incorrecta cerca de
|
||||
MySQL server version for the right syntax to use
|
||||
com.mysql.jdbc.exceptions
|
||||
You have an error in your SQL syntax near
|
||||
You have an error in your SQL syntax;
|
||||
An illegal character has been found in the statement
|
||||
pg_query() [:
|
||||
supplied argument is not a valid MySQL
|
||||
mssql_query()
|
||||
mysql_fetch_array()
|
||||
Exception
|
||||
java.sql.SQLException
|
||||
Column count doesn't match value count at row
|
||||
Sybase message
|
||||
SQL Server
|
||||
PostgreSQL query failed:
|
||||
Dynamic SQL Error
|
||||
System.Data.SQLite.SQLiteException
|
||||
SQLite/JDBCDriver
|
||||
Unclosed quotation mark before the character string
|
||||
System.Data.SqlClient.
|
||||
Unclosed quotation mark after the character string
|
||||
System.Data.OleDb.OleDbException
|
||||
[DM_QUERY_E_SYNTAX]
|
||||
[SqlException
|
||||
Unexpected end of command in statement
|
||||
valid PostgreSQL result
|
||||
pg_exec() [:
|
||||
SQL Server
|
||||
[SQLITE_ERROR]
|
||||
Microsoft OLE DB Provider for ODBC Drivers
|
||||
PostgreSQL
|
||||
org.hsqldb.jdbc
|
||||
ADODB.Field (0x800A0BCD)
|
||||
SQL syntax
|
||||
Exception
|
||||
System.Data.SqlClient.SqlException
|
||||
Data type mismatch in criteria expression.
|
||||
Driver
|
||||
DB2 SQL error
|
||||
Sybase message:
|
||||
ORA-
|
||||
[Microsoft][ODBC SQL Server Driver]
|
||||
'80040e14'
|
||||
Microsoft OLE DB Provider for SQL Server
|
||||
in query expression
|
||||
Npgsql.
|
||||
valid MySQL result
|
||||
supplied argument is not a valid PostgreSQL result
|
||||
db2_
|
||||
Ingres SQLSTATE
|
||||
Column count doesn't match
|
||||
Warning
|
||||
[Microsoft][ODBC Microsoft Access Driver]
|
||||
[Macromedia][SQLServer JDBC Driver]
|
||||
<b>Warning</b>: ibase_
|
||||
Roadhouse.Cms.
|
||||
DB2 SQL error:
|
||||
SQLSTATE[
|
||||
144
plugins/wasm-go/extensions/waf/wasmplugin/rules/crs/ssrf.data
Normal file
144
plugins/wasm-go/extensions/waf/wasmplugin/rules/crs/ssrf.data
Normal file
@@ -0,0 +1,144 @@
|
||||
# Sources:
|
||||
# - https://gist.githubusercontent.com/jhaddix/78cece26c91c6263653f31ba453e273b/raw/a4869d58a5ce337d1465c2d1b29777b9eecd371f/cloud_metadata.txt
|
||||
# - https://book.hacktricks.xyz/pentesting-web/ssrf-server-side-request-forgery/cloud-ssrf
|
||||
# - https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Request%20Forgery
|
||||
# - https://github.com/assetnote/blind-ssrf-chains
|
||||
|
||||
## AWS
|
||||
# from http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html#instancedata-data-categories
|
||||
#
|
||||
# To fully protect, use IMDSv2 (see https://aws.amazon.com/blogs/security/defense-in-depth-open-firewalls-reverse-proxies-ssrf-vulnerabilities-ec2-instance-metadata-service/)
|
||||
|
||||
http://instance-data/latest/
|
||||
http://169.254.169.254/latest/
|
||||
|
||||
# Common evasion techniques:
|
||||
http://2852039166/latest/
|
||||
http://025177524776/latest/
|
||||
http://0251.0376.0251.0376/latest/
|
||||
http://[::ffff:a9fe:a9fe]/latest/
|
||||
http://[0:0:0:0:0:ffff:a9fe:a9fe]/latest/
|
||||
http://[0:0:0:0:0:ffff:169.254.169.254]/latest/
|
||||
http://169.254.169.254.nip.io/latest/
|
||||
http://nicob.net/redir-http-169.254.169.254:80-
|
||||
|
||||
# http://127.0.0.1
|
||||
http://2130706433/
|
||||
# http://192.168.0.1
|
||||
http://3232235521/
|
||||
# http://192.168.1.1
|
||||
http://3232235777/
|
||||
# http://169.254.169.254
|
||||
http://2852039166/
|
||||
# IPv6 base
|
||||
http://[::]:
|
||||
|
||||
# AWS ECS
|
||||
http://169.254.170.2/v2
|
||||
|
||||
## Google Cloud
|
||||
# https://cloud.google.com/compute/docs/metadata
|
||||
# - Requires the header "Metadata-Flavor: Google" or "X-Google-Metadata-Request: True"
|
||||
|
||||
http://169.254.169.254/computeMetadata/v1/
|
||||
http://metadata.google.internal/computeMetadata/v1/
|
||||
http://metadata/computeMetadata/v1/
|
||||
# Common evasion techniques:
|
||||
http://2852039166/computeMetadata/v1/
|
||||
http://[::ffff:a9fe:a9fe]/computeMetadata/v1/
|
||||
http://[0:0:0:0:0:ffff:a9fe:a9fe]/computeMetadata/v1/
|
||||
http://[0:0:0:0:0:ffff:169.254.169.254]/computeMetadata/v1/
|
||||
http://169.254.169.254.nip.io/computeMetadata/v1/
|
||||
|
||||
# Google allows recursive pulls
|
||||
http://metadata.google.internal/computeMetadata/v1/instance/disks/?recursive=true
|
||||
|
||||
## Google
|
||||
# Beta does NOT require a header atm
|
||||
http://metadata.google.internal/computeMetadata/v1beta1/
|
||||
|
||||
## Digital Ocean
|
||||
# https://developers.digitalocean.com/documentation/metadata/
|
||||
|
||||
http://169.254.169.254/metadata/v1.json
|
||||
# This other prefix will be used from Azure: http://169.254.169.254/metadata/v1/
|
||||
|
||||
## Packetcloud
|
||||
|
||||
https://metadata.packet.net/userdata
|
||||
|
||||
## Azure
|
||||
#
|
||||
# To be effective, these also have to:
|
||||
#
|
||||
# - contain the header Metadata: true
|
||||
# - not contain an X-Forwarded-For header
|
||||
|
||||
http://169.254.169.254/metadata/v1/
|
||||
http://169.254.169.254/metadata/instance?api-version=2017-04-02
|
||||
http://169.254.169.254/metadata/instance/network/interface/0/ipv4/ipAddress/0/publicIpAddress?api-version=2017-04-02&format=text
|
||||
# Common evasion techniques:
|
||||
http://2852039166/metadata/v1/
|
||||
http://[::ffff:a9fe:a9fe]/metadata/v1/
|
||||
http://[0:0:0:0:0:ffff:a9fe:a9fe]/metadata/v1/
|
||||
http://[0:0:0:0:0:ffff:169.254.169.254]/metadata/v1/
|
||||
http://169.254.169.254.nip.io/metadata/v1/
|
||||
|
||||
|
||||
## OpenStack/RackSpace
|
||||
http://169.254.169.254/openstack
|
||||
|
||||
## HP Helion
|
||||
# (header required? unknown)
|
||||
http://169.254.169.254/2009-04-04/meta-data/
|
||||
|
||||
## Oracle Cloud
|
||||
http://192.0.0.192/latest/
|
||||
|
||||
## Alibaba
|
||||
http://100.100.100.200/latest/meta-data/
|
||||
|
||||
# Rancher metadata
|
||||
http://rancher-metadata/
|
||||
|
||||
# Local Docker
|
||||
http://127.0.0.1:2375
|
||||
http://2130706433:2375/
|
||||
http://[::]:2375/
|
||||
http://[0000::1]:2375/
|
||||
http://[0:0:0:0:0:ffff:127.0.0.1]:2375/
|
||||
http://2130706433:2375/
|
||||
http://017700000001:2375/
|
||||
http://0x7f000001:2375/
|
||||
http://0xc0a80014:2375/
|
||||
# Kubernetes etcd
|
||||
http://127.0.0.1:2379
|
||||
|
||||
# Enclosed alphanumerics
|
||||
http://169。254。169。254
|
||||
http://169。254。169。254
|
||||
http://⑯⑨。②⑤④。⑯⑨。②⑤④
|
||||
http://⓪ⓧⓐ⑨。⓪ⓧⓕⓔ。⓪ⓧⓐ⑨。⓪ⓧⓕⓔ
|
||||
http://⓪ⓧⓐ⑨ⓕⓔⓐ⑨ⓕⓔ
|
||||
http://②⑧⑤②⓪③⑨①⑥⑥
|
||||
http://④②⑤。⑤①⓪。④②⑤。⑤①⓪
|
||||
http://⓪②⑤①。⓪③⑦⑥。⓪②⑤①。⓪③⑦⑥
|
||||
http://⓪⓪②⑤①。⓪⓪⓪③⑦⑥。⓪⓪⓪⓪②⑤①。⓪⓪⓪⓪⓪③⑦⑥
|
||||
http://[::①⑥⑨。②⑤④。⑯⑨。②⑤④]
|
||||
http://[::ⓕⓕⓕⓕ:①⑥⑨。②⑤④。⑯⑨。②⑤④]
|
||||
http://⓪ⓧⓐ⑨。⓪③⑦⑥。④③⑤①⑧
|
||||
http://⓪ⓧⓐ⑨。⑯⑥⑧⑨⑥⑥②
|
||||
http://⓪⓪②⑤①。⑯⑥⑧⑨⑥⑥②
|
||||
http://⓪⓪②⑤①。⓪ⓧⓕⓔ。④③⑤①⑧
|
||||
|
||||
# Java only blind ssrf
|
||||
jar:http://127.0.0.1!/
|
||||
jar:https://127.0.0.1!/
|
||||
jar:ftp://127.0.0.1!/
|
||||
|
||||
# Other PL1 protocols
|
||||
gopher://127.0.0.1
|
||||
gopher://localhost
|
||||
|
||||
# AWS Lambda
|
||||
http://localhost:9001/2018-06-01/runtime/
|
||||
@@ -0,0 +1,634 @@
|
||||
# This list has generic unix shell variables, shells and commands that affect Unix systems.
|
||||
# To generate the list, we get the data from all places first. Strip or add the path to commands so it begins with `bin`.
|
||||
# Sort the file content ascending, and remove duplicate lines.
|
||||
#
|
||||
# Data comes from multiple places, listed below.
|
||||
# - Binaries:
|
||||
# - GTFOBins. Update list using `curl -H "Accept: application/vnd.github.v3+json" https://api.github.com/repos/GTFOBins/GTFOBins.github.io/contents/_gtfobins | jq '.[].name' | grep '.md' | tr -d '"' | cut -f1 -d.`
|
||||
# - Shell lists:
|
||||
# - https://tldp.org/LDP/Linux-Filesystem-Hierarchy/html/etc.html
|
||||
# - https://en.wikipedia.org/wiki/Unix_shell
|
||||
# - https://hyperpolyglot.org/unix-shells
|
||||
# - Generic shell variables (Ad-Hoc for now, needs references)
|
||||
# - Generic /etc and /dev files (Ad-Hoc, needs references)
|
||||
# - Compression and decompression utilities present on Arch Linux (as of 2022-08-02) and Debian 11
|
||||
|
||||
${CDPATH}
|
||||
${DIRSTACK}
|
||||
${HOME}
|
||||
${HOSTNAME}
|
||||
${IFS}
|
||||
${OLDPWD}
|
||||
${OSTYPE}
|
||||
${PATH}
|
||||
${PWD}
|
||||
$CDPATH
|
||||
$DIRSTACK
|
||||
$HOME
|
||||
$HOSTNAME
|
||||
$IFS
|
||||
$OLDPWD
|
||||
$OSTYPE
|
||||
$PATH
|
||||
$PWD
|
||||
bin/7z
|
||||
bin/7za
|
||||
bin/7zr
|
||||
bin/7zx
|
||||
bin/ab
|
||||
bin/adduser
|
||||
bin/agetty
|
||||
bin/alias
|
||||
bin/alpine
|
||||
bin/ansible-playbook
|
||||
bin/apt
|
||||
bin/apt-get
|
||||
bin/ar
|
||||
bin/arch
|
||||
bin/aria2c
|
||||
bin/arj
|
||||
bin/arp
|
||||
bin/as
|
||||
bin/ascii-xfr
|
||||
bin/ascii85
|
||||
bin/ash
|
||||
bin/aspell
|
||||
bin/at
|
||||
bin/atobm
|
||||
bin/awk
|
||||
bin/aws
|
||||
bin/base32
|
||||
bin/base64
|
||||
bin/basenc
|
||||
bin/bash
|
||||
bin/batch
|
||||
bin/bpftrace
|
||||
bin/breaksw
|
||||
bin/bridge
|
||||
bin/bsdcat
|
||||
bin/bsdiff
|
||||
bin/bsdtar
|
||||
bin/builtin
|
||||
bin/bundler
|
||||
bin/bunzip2
|
||||
bin/busctl
|
||||
bin/busybox
|
||||
bin/byebug
|
||||
bin/bzcat
|
||||
bin/bzcmp
|
||||
bin/bzdiff
|
||||
bin/bzegrep
|
||||
bin/bzexe
|
||||
bin/bzfgrep
|
||||
bin/bzgrep
|
||||
bin/bzip2
|
||||
bin/bzip2recover
|
||||
bin/bzless
|
||||
bin/bzmore
|
||||
bin/bzz
|
||||
bin/c89
|
||||
bin/c99
|
||||
bin/cancel
|
||||
bin/capsh
|
||||
bin/cat
|
||||
bin/cc
|
||||
bin/certbot
|
||||
bin/chattr
|
||||
bin/chdir
|
||||
bin/check_by_ssh
|
||||
bin/check_cups
|
||||
bin/check_log
|
||||
bin/check_memory
|
||||
bin/check_raid
|
||||
bin/check_ssl_cert
|
||||
bin/check_statusfile
|
||||
bin/chflags
|
||||
bin/chmod
|
||||
bin/choom
|
||||
bin/chown
|
||||
bin/chroot
|
||||
bin/clang
|
||||
bin/clang++
|
||||
bin/cmp
|
||||
bin/cobc
|
||||
bin/column
|
||||
bin/comm
|
||||
bin/command
|
||||
bin/composer
|
||||
bin/compress
|
||||
bin/coproc
|
||||
bin/core_perl/zipdetails
|
||||
bin/cowsay
|
||||
bin/cowthink
|
||||
bin/cp
|
||||
bin/cpan
|
||||
bin/cpio
|
||||
bin/cpulimit
|
||||
bin/crash
|
||||
bin/crontab
|
||||
bin/csh
|
||||
bin/csplit
|
||||
bin/csvtool
|
||||
bin/cupsfilter
|
||||
bin/curl
|
||||
bin/cut
|
||||
bin/dash
|
||||
bin/date
|
||||
bin/dd
|
||||
bin/dhclient
|
||||
bin/dialog
|
||||
bin/diff
|
||||
bin/dig
|
||||
bin/dmesg
|
||||
bin/dmidecode
|
||||
bin/dmsetup
|
||||
bin/dnf
|
||||
bin/doas
|
||||
bin/docker
|
||||
bin/done
|
||||
bin/dosbox
|
||||
bin/dpkg
|
||||
bin/du
|
||||
bin/dvips
|
||||
bin/easy_install
|
||||
bin/eb
|
||||
bin/echo
|
||||
bin/ed
|
||||
bin/efax
|
||||
bin/egrep
|
||||
bin/emacs
|
||||
bin/endif
|
||||
bin/endsw
|
||||
bin/env
|
||||
bin/env-update
|
||||
bin/eqn
|
||||
bin/es
|
||||
bin/esac
|
||||
bin/esh
|
||||
bin/eval
|
||||
bin/ex
|
||||
bin/exec
|
||||
bin/exiftool
|
||||
bin/expand
|
||||
bin/expect
|
||||
bin/export
|
||||
bin/expr
|
||||
bin/facter
|
||||
bin/fc
|
||||
bin/fetch
|
||||
bin/fgrep
|
||||
bin/fi
|
||||
bin/file
|
||||
bin/filetest
|
||||
bin/find
|
||||
bin/finger
|
||||
bin/fish
|
||||
bin/flock
|
||||
bin/fmt
|
||||
bin/fold
|
||||
bin/foreach
|
||||
bin/fping
|
||||
bin/ftp
|
||||
bin/ftpstats
|
||||
bin/ftpwho
|
||||
bin/function
|
||||
bin/gawk
|
||||
bin/gcc
|
||||
bin/gcore
|
||||
bin/gdb
|
||||
bin/gem
|
||||
bin/genie
|
||||
bin/genisoimage
|
||||
bin/GET
|
||||
bin/getfacl
|
||||
bin/ghc
|
||||
bin/ghci
|
||||
bin/gimp
|
||||
bin/ginsh
|
||||
bin/git
|
||||
bin/go
|
||||
bin/grc
|
||||
bin/grep
|
||||
bin/gtester
|
||||
bin/gunzip
|
||||
bin/gzcat
|
||||
bin/gzexe
|
||||
bin/gzip
|
||||
bin/hd
|
||||
bin/head
|
||||
bin/hexdump
|
||||
bin/highlight
|
||||
bin/history
|
||||
bin/hostid
|
||||
bin/hostname
|
||||
bin/hping3
|
||||
bin/htdigest
|
||||
bin/htpasswd
|
||||
bin/hup
|
||||
bin/iconv
|
||||
bin/id
|
||||
bin/ifconfig
|
||||
bin/iftop
|
||||
bin/install
|
||||
bin/ionice
|
||||
bin/ip
|
||||
bin/ip6tables
|
||||
bin/ipconfig
|
||||
bin/iptables
|
||||
bin/irb
|
||||
bin/ispell
|
||||
bin/java
|
||||
bin/jexec
|
||||
bin/jjs
|
||||
bin/jobs
|
||||
bin/join
|
||||
bin/journalctl
|
||||
bin/jq
|
||||
bin/jrunscript
|
||||
bin/kill
|
||||
bin/killall
|
||||
bin/knife
|
||||
bin/ksh
|
||||
bin/ksshell
|
||||
bin/last
|
||||
bin/lastcomm
|
||||
bin/lastlog
|
||||
bin/lastlogin
|
||||
bin/latex
|
||||
bin/ld
|
||||
bin/ldconfig
|
||||
bin/ldd
|
||||
bin/less
|
||||
bin/lessecho
|
||||
bin/lessfile
|
||||
bin/lesspipe
|
||||
bin/lftp
|
||||
bin/lftpget
|
||||
bin/links
|
||||
bin/ln
|
||||
bin/local
|
||||
bin/locate
|
||||
bin/loginctl
|
||||
bin/logname
|
||||
bin/logsave
|
||||
bin/look
|
||||
bin/lp
|
||||
bin/ls
|
||||
bin/ls-F
|
||||
bin/lsb_release
|
||||
bin/lscpu
|
||||
bin/lshw
|
||||
bin/lsmod
|
||||
bin/lsof
|
||||
bin/lspci
|
||||
bin/lsusb
|
||||
bin/ltrace
|
||||
bin/lua
|
||||
bin/lualatex
|
||||
bin/luatex
|
||||
bin/lwp-download
|
||||
bin/lwp-dump
|
||||
bin/lwp-mirror
|
||||
bin/lwp-request
|
||||
bin/lynx
|
||||
bin/lz
|
||||
bin/lz4
|
||||
bin/lz4c
|
||||
bin/lz4cat
|
||||
bin/lzcat
|
||||
bin/lzcmp
|
||||
bin/lzdiff
|
||||
bin/lzegrep
|
||||
bin/lzfgrep
|
||||
bin/lzgrep
|
||||
bin/lzless
|
||||
bin/lzma
|
||||
bin/lzmadec
|
||||
bin/lzmainfo
|
||||
bin/lzmore
|
||||
bin/mail
|
||||
bin/mailq
|
||||
bin/mailx
|
||||
bin/make
|
||||
bin/man
|
||||
bin/mawk
|
||||
bin/mkdir
|
||||
bin/mkfifo
|
||||
bin/mknod
|
||||
bin/mlocate
|
||||
bin/more
|
||||
bin/mosquitto
|
||||
bin/mount
|
||||
bin/msgattrib
|
||||
bin/msgcat
|
||||
bin/msgconv
|
||||
bin/msgfilter
|
||||
bin/msgmerge
|
||||
bin/msguniq
|
||||
bin/mtr
|
||||
bin/mutt
|
||||
bin/mv
|
||||
bin/mysql
|
||||
bin/mysqladmin
|
||||
bin/mysqldump
|
||||
bin/mysqldumpslow
|
||||
bin/mysqlhotcopy
|
||||
bin/mysqlshow
|
||||
bin/nano
|
||||
bin/nasm
|
||||
bin/nawk
|
||||
bin/nc
|
||||
bin/nc.openbsd
|
||||
bin/nc.traditional
|
||||
bin/ncat
|
||||
bin/neofetch
|
||||
bin/net
|
||||
bin/netcat
|
||||
bin/netkit-ftp
|
||||
bin/netstat
|
||||
bin/nice
|
||||
bin/nl
|
||||
bin/nm
|
||||
bin/nmap
|
||||
bin/node
|
||||
bin/nohup
|
||||
bin/nping
|
||||
bin/npm
|
||||
bin/nroff
|
||||
bin/nsenter
|
||||
bin/nslookup
|
||||
bin/nstat
|
||||
bin/octave
|
||||
bin/od
|
||||
bin/onintr
|
||||
bin/openssl
|
||||
bin/openvpn
|
||||
bin/openvt
|
||||
bin/opkg
|
||||
bin/passwd
|
||||
bin/paste
|
||||
bin/patch
|
||||
bin/pax
|
||||
bin/pdb
|
||||
bin/pdflatex
|
||||
bin/pdftex
|
||||
bin/pdksh
|
||||
bin/perf
|
||||
bin/perl
|
||||
bin/perl5
|
||||
bin/perlsh
|
||||
bin/perms
|
||||
bin/pf
|
||||
bin/pftp
|
||||
bin/pg
|
||||
bin/pgrep
|
||||
bin/php
|
||||
bin/php-cgi
|
||||
bin/php5
|
||||
bin/php7
|
||||
bin/pic
|
||||
bin/pico
|
||||
bin/pidstat
|
||||
bin/pigz
|
||||
bin/ping
|
||||
bin/pip
|
||||
bin/pkexec
|
||||
bin/pkg
|
||||
bin/pkg_info
|
||||
bin/pkginfo
|
||||
bin/pkill
|
||||
bin/popd
|
||||
bin/pr
|
||||
bin/printenv
|
||||
bin/printf
|
||||
bin/pry
|
||||
bin/ps
|
||||
bin/psed
|
||||
bin/psftp
|
||||
bin/psql
|
||||
bin/ptar
|
||||
bin/ptardiff
|
||||
bin/ptargrep
|
||||
bin/ptx
|
||||
bin/puppet
|
||||
bin/pushd
|
||||
bin/pxz
|
||||
bin/python
|
||||
bin/python2
|
||||
bin/python3
|
||||
bin/rake
|
||||
bin/raku
|
||||
bin/rar
|
||||
bin/rbash
|
||||
bin/rc
|
||||
bin/rcp
|
||||
bin/readelf
|
||||
bin/realpath
|
||||
bin/red
|
||||
bin/redcarpet
|
||||
bin/rename
|
||||
bin/repeat
|
||||
bin/replace
|
||||
bin/restic
|
||||
bin/rev
|
||||
bin/rlogin
|
||||
bin/rlwrap
|
||||
bin/rm
|
||||
bin/rmdir
|
||||
bin/rmuser
|
||||
bin/rnano
|
||||
bin/route
|
||||
bin/rpm
|
||||
bin/rpmdb
|
||||
bin/rpmquery
|
||||
bin/rpmverify
|
||||
bin/rsync
|
||||
bin/ruby
|
||||
bin/run-mailcap
|
||||
bin/run-parts
|
||||
bin/rview
|
||||
bin/rvim
|
||||
bin/sash
|
||||
bin/sched
|
||||
bin/scp
|
||||
bin/screen
|
||||
bin/script
|
||||
bin/sdiff
|
||||
bin/sed
|
||||
bin/sendmail
|
||||
bin/service
|
||||
bin/set
|
||||
bin/setarch
|
||||
bin/setenv
|
||||
bin/setfacl
|
||||
bin/setsid
|
||||
bin/sftp
|
||||
bin/sg
|
||||
bin/sh
|
||||
bin/sh.distrib
|
||||
bin/shuf
|
||||
bin/shutdown
|
||||
bin/sleep
|
||||
bin/slsh
|
||||
bin/smbclient
|
||||
bin/snap
|
||||
bin/socat
|
||||
bin/soelim
|
||||
bin/sort
|
||||
bin/source
|
||||
bin/split
|
||||
bin/sqlite3
|
||||
bin/ss
|
||||
bin/ssh
|
||||
bin/ssh-keygen
|
||||
bin/ssh-keyscan
|
||||
bin/sshpass
|
||||
bin/start-stop-daemon
|
||||
bin/stdbuf
|
||||
bin/strace
|
||||
bin/strings
|
||||
bin/su
|
||||
bin/sudo
|
||||
bin/svn
|
||||
bin/sysctl
|
||||
bin/systemctl
|
||||
bin/systemd-resolve
|
||||
bin/tac
|
||||
bin/tail
|
||||
bin/tailf
|
||||
bin/tar
|
||||
bin/task
|
||||
bin/taskset
|
||||
bin/tbl
|
||||
bin/tclsh
|
||||
bin/tcpdump
|
||||
bin/tcping
|
||||
bin/tcptraceroute
|
||||
bin/tcsh
|
||||
bin/tee
|
||||
bin/telnet
|
||||
bin/tex
|
||||
bin/tftp
|
||||
bin/tic
|
||||
bin/time
|
||||
bin/timedatectl
|
||||
bin/timeout
|
||||
bin/tmux
|
||||
bin/top
|
||||
bin/touch
|
||||
bin/traceroute
|
||||
bin/traceroute6
|
||||
bin/troff
|
||||
bin/tshark
|
||||
bin/ul
|
||||
bin/ulimit
|
||||
bin/uname
|
||||
bin/uncompress
|
||||
bin/unexpand
|
||||
bin/uniq
|
||||
bin/unlink
|
||||
bin/unlz4
|
||||
bin/unlzma
|
||||
bin/unpigz
|
||||
bin/unrar
|
||||
bin/unset
|
||||
bin/unshare
|
||||
bin/unxz
|
||||
bin/unzip
|
||||
bin/unzstd
|
||||
bin/update-alternatives
|
||||
bin/useradd
|
||||
bin/userdel
|
||||
bin/usermod
|
||||
bin/uudecode
|
||||
bin/uuencode
|
||||
bin/valgrind
|
||||
bin/vi
|
||||
bin/view
|
||||
bin/vigr
|
||||
bin/vim
|
||||
bin/vimdiff
|
||||
bin/vipw
|
||||
bin/virsh
|
||||
bin/volatility
|
||||
bin/w3m
|
||||
bin/wall
|
||||
bin/watch
|
||||
bin/wc
|
||||
bin/wget
|
||||
bin/whiptail
|
||||
bin/who
|
||||
bin/whoami
|
||||
bin/whois
|
||||
bin/wireshark
|
||||
bin/wish
|
||||
bin/xargs
|
||||
bin/xelatex
|
||||
bin/xetex
|
||||
bin/xmodmap
|
||||
bin/xmore
|
||||
bin/xpad
|
||||
bin/xterm
|
||||
bin/xxd
|
||||
bin/xz
|
||||
bin/xzcat
|
||||
bin/xzcmp
|
||||
bin/xzdec
|
||||
bin/xzdiff
|
||||
bin/xzegrep
|
||||
bin/xzfgrep
|
||||
bin/xzgrep
|
||||
bin/xzless
|
||||
bin/xzmore
|
||||
bin/yarn
|
||||
bin/yelp
|
||||
bin/yes
|
||||
bin/yum
|
||||
bin/zathura
|
||||
bin/zcat
|
||||
bin/zcmp
|
||||
bin/zdiff
|
||||
bin/zegrep
|
||||
bin/zfgrep
|
||||
bin/zgrep
|
||||
bin/zip
|
||||
bin/zipcloak
|
||||
bin/zipcmp
|
||||
bin/zipdetails
|
||||
bin/zipgrep
|
||||
bin/zipinfo
|
||||
bin/zipmerge
|
||||
bin/zipnote
|
||||
bin/zipsplit
|
||||
bin/ziptool
|
||||
bin/zless
|
||||
bin/zmore
|
||||
bin/zrun
|
||||
bin/zsh
|
||||
bin/zsoelim
|
||||
bin/zstd
|
||||
bin/zstdcat
|
||||
bin/zstdgrep
|
||||
bin/zstdless
|
||||
bin/zstdmt
|
||||
bin/zypper
|
||||
dev/fd
|
||||
dev/null
|
||||
dev/stderr
|
||||
dev/stdin
|
||||
dev/stdout
|
||||
dev/tcp
|
||||
dev/udp
|
||||
dev/zero
|
||||
etc/group
|
||||
etc/master.passwd
|
||||
etc/passwd
|
||||
etc/pwd.db
|
||||
etc/shadow
|
||||
etc/shells
|
||||
etc/spwd.db
|
||||
proc/self
|
||||
sbin/capsh
|
||||
sbin/logsave
|
||||
sbin/service
|
||||
sbin/start-stop-daemon
|
||||
@@ -0,0 +1,148 @@
|
||||
# This list contains patterns of various web shells, backdoors and similar
|
||||
# software written in PHP language. There is no way how to automatically update
|
||||
# this list, so it must be done by hand. Here is a recommended way how to add
|
||||
# new malicious software:
|
||||
# 1.) As patterns are matched against RESPONSE_BODY, you need to run a malicious
|
||||
# software (ideally in an isolated environment) and catch the output.
|
||||
# 2.) In the output, search for static pattern unique enough to match only
|
||||
# the software in question and to not do any FPs. The best pick is usually
|
||||
# a part of HTML code with software name.
|
||||
# 3.) Include software name and URL (if available) in the comment above
|
||||
# the pattern.
|
||||
#
|
||||
# Data comes from multiple places of which some doesn't work anymore. Few are
|
||||
# listed below:
|
||||
# - https://github.com/JohnTroony/php-webshells/tree/master/Collection
|
||||
# - https://www.localroot.net/shell/
|
||||
# - Google search (keywords like webshells, php backdoor and similar)
|
||||
|
||||
# 1n73ction web shell
|
||||
<title>=[ 1n73ct10n privat shell ]=</title>
|
||||
# Ajax/PHP Command Shell web shell
|
||||
>Ajax/PHP Command Shell<
|
||||
# AK-74 Security Team Web-shell
|
||||
.:: :[ AK-74 Security Team Web-shell ]: ::.
|
||||
# ALFA-SHELL web shell (https://github.com/solevisible)
|
||||
~ ALFA TEaM Shell -
|
||||
# Andela Yuwono Priv8 Shell web shell
|
||||
<title>--==[[ Andela Yuwono Priv8 Shell ]]==--</title>
|
||||
# Ani-Shell web shell (http://ani-shell.sourceforge.net/)
|
||||
<title>Ani-Shell | India</title>
|
||||
# AnonymousFox PHP web shell
|
||||
<input type='submit' value='file' /></form>AnonymousFox
|
||||
# Antichat Shell web shell
|
||||
- Antichat Shell</title>
|
||||
# AYT web shell
|
||||
Ayyildiz Tim | AYT
|
||||
# b374k web shell (https://github.com/b374k/b374k)
|
||||
<link rel='SHORTCUT ICON' href='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MkRFNDY2MDQ4MDgyMTFFM0FDRDdBN0MzOTAxNzZFQUYiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MkRFNDY2MDU4MDgyMTFFM0FDRDdBN0MzOTAxNzZFQUYiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDoyREU0NjYwMjgwODIxMUUzQUNEN0E3QzM5MDE3NkVBRiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDoyREU0NjYwMzgwODIxMUUzQUNEN0E3QzM5MDE3NkVBRiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pu6UWJYAAAKySURBVHjafFNdSJNhFH7e/fhDkrm2i03QphsxhYSgMIUgIeiiK6/SCAKTKNlFoEtBRfEvXYhM+0GQMtMUL7qSgqS0QCNKTDS6cJWGi6n577Zv3/e+b+934ZgxPfDBd3jP85xznnOOzufz4SCr7R7knKOg4eaVd9WPBgsZY/3NZcWJ0TGaaKeuZzgz2ueMgFF+p6WnL0OAjzMK+f8k+wg4xXxN91D5ns8ok8CRH5S2GogS8HBKk1xud+uBBIwpm5zyRvW/+sHAJuM8nsrMIElHi0/aHAmFl/OI2WRyOevrK/YwJFoD0ecFkfWthpDNRH1Cct4ZOzRaglX/DsY+TcNqTUd2phEjo1OiWg5KKUhJTbua6XTT7SKvSlLpGWB6DUjuWQeW/m4iJIWho8DvBT+2tgOwpZsxM/tm/sn9Trsar2OMq6rOV3X19wncJUNSEsnKSsWifx0BKYTgdhDxiENBfjZCuxJejX0W4frZiAZNZUVxVKYfmcyuKTI15ZxKw4IA74aCCIiMeqZDptWIuV8+hAkXOlFo9eaLNyrvOfdp4Gp/FjKlpMSbLMlY2dhCaCcEnUJgt5sF4QqkkIKsDAtGXn9QSThlMmFCg8gUmELpkXg99FoNwgEJ2jBBWpoBP/8sC7AMi/EY/EvLUBQJCpOMT921hDG5JkIglPd8/7EIFpShCQMnrAYsrW0gLERUwTNfv2FyaloddWmvu25NxTzvaG6MELRVXK/SgL8fHZ9AjsMCKUzFqBhSjQZAkrC6viqyy+ILdxU775bH3APVblW3j3POzuc4bGIHNPgyM4dAcFdtslT07OWcvhRVJIvVtg0/9nhJrGMqqWzpFb1eFYuiVfdbACcGOlvzYx0cOewaVStyuiY5U3JFVbahhx3eQ48plr3obDtHqSxTRZ6K9f5PgAEAm/hvADIkGOQAAAAASUVORK5CYII='>
|
||||
# BloodSecurity Hackers Shell web shell
|
||||
<title>BloodSecurity Hackers Shell</title>
|
||||
# Bypass Attack Shell web shell
|
||||
<font color='red' size='6px' face='Fredericka the Great'> Bypass Attack Shell </font>
|
||||
# c0derz shell web shell
|
||||
title='.::[c0derz shell]::.'>
|
||||
# C99Shell + N3tShell web shell
|
||||
<font face=Webdings size=6><b>!</b></font>
|
||||
# Con7ext Shell V.2 web shell
|
||||
<title>Con7ext Shell V.2</title>
|
||||
# Crystal shell web shell
|
||||
<font face="Wingdings 3" size="5">y</font><b>Crystal shell v.
|
||||
# CWShell web shell
|
||||
~ CWShell ~</font></a>
|
||||
# dC3 Security Crew web shell
|
||||
&dir&pic=o.b height= width=>
|
||||
# Defacing Tool Pro web shell
|
||||
<b>[ Defacing Tool Pro v
|
||||
# Dive Shell web shell
|
||||
<title>Dive Shell - Emperor Hacking Team</title>
|
||||
# easy simple php web shell
|
||||
<script>document.getElementById("cmd").focus();</script>
|
||||
# ex0 shell web shell
|
||||
color=DeepSkyBlue size=6> ## ex0 shell
|
||||
# FaTaLSheLL web shell
|
||||
<p align="center" class="style4">FaTaLSheLL v
|
||||
# G-Security Webshell
|
||||
<title>G-Security Webshell</title>
|
||||
# h4ntu shell web shell
|
||||
<title>h4ntu shell [powered by tsoi]</title>
|
||||
# IDBTEAM SHELLS file manager
|
||||
<H1><center>-=[+] IDBTEAM SHELLS
|
||||
# IndoXploit web shell
|
||||
<title>IndoXploit</title>
|
||||
# KA_uShell web shell
|
||||
<KAdot Universal Shell> |
|
||||
# Lifka Shell web shell
|
||||
>LIFKA SHELL</span></big></big></big></a>
|
||||
# Loader'z web shell
|
||||
<title>Loader'z WEB shell</title>
|
||||
# Locus7Shell web shell
|
||||
b>--[ x2300 Locus7Shell v.
|
||||
# Lolipop web shell
|
||||
<title>Lolipop.php - Edited By KingDefacer -
|
||||
# MARIJUANA web shell (https://0x5a455553.github.io/MARIJUANA/)
|
||||
<link rel="icon" href="//0x5a455553.github.io/MARIJUANA/icon.png" />
|
||||
# Matamu Mat web shell
|
||||
<title> Matamu Mat </title>
|
||||
# MyShell web shell
|
||||
<b>MyShell</b> ©2001 Digitart Producciones</a>
|
||||
# NCC Shell web shell
|
||||
<h1>.:NCC:. Shell v
|
||||
# PHPShell by Macker web shell
|
||||
<font size=3>PHPShell by Macker - Version
|
||||
# PHPShell by MAX666 web shell
|
||||
PHPShell by MAX666, Private Exploit, For Server Hacking
|
||||
# qsd web shell
|
||||
<form action="" METHOD="GET" >Execute Shell Command (safe mode is off): <input type="text" name="c"><input type="submit" value="Go"></form>
|
||||
# Rootshell web shell
|
||||
<p align="center"><font face="Verdana" size="2">Rootshell v
|
||||
# rusuh web shell
|
||||
<font color=lime>./rusuh</font>
|
||||
# Safe0ver web shell
|
||||
<font color="navy"><strong>##Safe0ver##</strong></font>
|
||||
# Shany's web shell
|
||||
<center><h1>Watch Your system Shany was here.</h1></center><center><h1>Linux Shells</h1></center><hr><hr>
|
||||
# Simple PHP backdoor web shell
|
||||
<!-- Simple PHP backdoor by DK
|
||||
# SimShell web shell
|
||||
<title>SimShell - Simorgh Security MGZ</title>
|
||||
# Sincap web shell
|
||||
<title>:: AventGrup ::.. - Sincap
|
||||
# Small Shell file manager
|
||||
<title>Small Shell - Edited By KingDefacer</title>
|
||||
# Small Web Shell
|
||||
<title>small web shell by zaco
|
||||
# SoldiersofAllah Private Shell web shell
|
||||
<title>SoldiersofAllah Private Shell |
|
||||
# Sosyete web shell
|
||||
<title>Sosyete Safe Mode Bypass Shell -
|
||||
# STNC WebShell
|
||||
STNC WebShell
|
||||
# StresBypass shell web shell
|
||||
<font face="Wingdings 3" size="5">y</font><b>StresBypass<span lang="en-us">v
|
||||
# SyRiAn Sh3ll web shell
|
||||
<title>SyRiAn Sh3ll ~
|
||||
# Turk Shell web shell
|
||||
<head><title>Wardom | Ne Mutlu T
|
||||
# Unknown web shell
|
||||
<hr>to browse go to http://?d=[directory here]
|
||||
# Ustadcage48 Filemanager
|
||||
<font color="red">USTADCAGE_48</font> <font color="dodgerblue">FILE MANAGER</font>
|
||||
# WebRoot Hack Tools shell
|
||||
<title>WebRoot Hack Tools</title>
|
||||
# web shell by BLaSTER
|
||||
<div align="center"><span class="style6">By BLaSTER</span><br />
|
||||
# WinX Shell web shell
|
||||
<title>-:[GreenwooD]:- WinX Shell</title>
|
||||
# wwwolf web shell
|
||||
<sup><a href="#" onclick="cmd.value=''; cmd.focus(); return false;">Clear cmd</a></sup>
|
||||
# Yourman.sh Mini Shell web shell
|
||||
<title>Yourman.sh Mini Shell</title>
|
||||
# Zerion Mini Shell web shell
|
||||
</div><center><br />Zerion Mini Shell <font color=
|
||||
# Zero Byte Mini Shell V2 web shell
|
||||
<title>0byt3m1n1-V2</title>
|
||||
# Zerostore web shell
|
||||
<title>ZEROSHELL | ZEROSTORE</title>
|
||||
# Unknown web shell
|
||||
<input type=submit name=find value='find writeable'>
|
||||
@@ -0,0 +1,425 @@
|
||||
# Sources:
|
||||
# Microsoft PowerShell Docs: https://github.com/MicrosoftDocs/PowerShell-Docs
|
||||
# - curl -H "Accept: application/vnd.github.v3+json" https://api.github.com/repos/MicrosoftDocs/PowerShell-Docs/git/trees/main\?recursive\=1 | jq -r '.tree[] .path | capture("reference/\\d.\\d/(.*)/(?<fn>[A-Z]\\w+-\\w+).md") | .fn' | sort | uniq
|
||||
|
||||
powershell
|
||||
Add-Computer
|
||||
Add-Content
|
||||
Add-History
|
||||
Add-JobTrigger
|
||||
Add-LocalGroupMember
|
||||
Add-Member
|
||||
Add-PSSnapin
|
||||
Add-Type
|
||||
Checkpoint-Computer
|
||||
Clear-Content
|
||||
Clear-EventLog
|
||||
Clear-History
|
||||
Clear-Host
|
||||
Clear-Item
|
||||
Clear-ItemProperty
|
||||
Clear-RecycleBin
|
||||
Clear-Variable
|
||||
Compare-Object
|
||||
Complete-Transaction
|
||||
Compress-Archive
|
||||
Connect-PSSession
|
||||
Connect-WSMan
|
||||
Convert-Path
|
||||
Convert-String
|
||||
ConvertFrom-Csv
|
||||
ConvertFrom-Json
|
||||
ConvertFrom-Markdown
|
||||
ConvertFrom-SddlString
|
||||
ConvertFrom-SecureString
|
||||
ConvertFrom-String
|
||||
ConvertFrom-StringData
|
||||
ConvertTo-Csv
|
||||
ConvertTo-Html
|
||||
ConvertTo-Json
|
||||
ConvertTo-SecureString
|
||||
ConvertTo-Xml
|
||||
Copy-Item
|
||||
Copy-ItemProperty
|
||||
Debug-Job
|
||||
Debug-Process
|
||||
Debug-Runspace
|
||||
Disable-ComputerRestore
|
||||
Disable-ExperimentalFeature
|
||||
Disable-JobTrigger
|
||||
Disable-LocalUser
|
||||
Disable-PSBreakpoint
|
||||
Disable-PSRemoting
|
||||
Disable-PSSessionConfiguration
|
||||
Disable-PSTrace
|
||||
Disable-PSWSManCombinedTrace
|
||||
Disable-RunspaceDebug
|
||||
Disable-ScheduledJob
|
||||
Disable-WSManCredSSP
|
||||
Disable-WSManTrace
|
||||
Disconnect-PSSession
|
||||
Disconnect-WSMan
|
||||
Enable-ComputerRestore
|
||||
Enable-ExperimentalFeature
|
||||
Enable-JobTrigger
|
||||
Enable-LocalUser
|
||||
Enable-PSBreakpoint
|
||||
Enable-PSRemoting
|
||||
Enable-PSSessionConfiguration
|
||||
Enable-PSTrace
|
||||
Enable-PSWSManCombinedTrace
|
||||
Enable-RunspaceDebug
|
||||
Enable-ScheduledJob
|
||||
Enable-WSManCredSSP
|
||||
Enable-WSManTrace
|
||||
Enter-PSHostProcess
|
||||
Enter-PSSession
|
||||
Exit-PSHostProcess
|
||||
Exit-PSSession
|
||||
Expand-Archive
|
||||
Export-Alias
|
||||
Export-BinaryMiLog
|
||||
Export-Clixml
|
||||
Export-Console
|
||||
Export-Counter
|
||||
Export-Csv
|
||||
Export-FormatData
|
||||
Export-ModuleMember
|
||||
Export-ODataEndpointProxy
|
||||
Export-PSSession
|
||||
Find-Command
|
||||
Find-DscResource
|
||||
Find-Module
|
||||
Find-Package
|
||||
Find-PackageProvider
|
||||
Find-RoleCapability
|
||||
Find-Script
|
||||
ForEach-Object
|
||||
Format-Custom
|
||||
Format-Hex
|
||||
Format-List
|
||||
Format-Table
|
||||
Format-Wide
|
||||
Get-Acl
|
||||
Get-Alias
|
||||
Get-AuthenticodeSignature
|
||||
Get-ChildItem
|
||||
Get-CimAssociatedInstance
|
||||
Get-CimClass
|
||||
Get-CimInstance
|
||||
Get-CimSession
|
||||
Get-Clipboard
|
||||
Get-CmsMessage
|
||||
Get-Command
|
||||
Get-ComputerInfo
|
||||
Get-ComputerRestorePoint
|
||||
Get-Content
|
||||
Get-ControlPanelItem
|
||||
Get-Counter
|
||||
Get-Credential
|
||||
Get-Culture
|
||||
Get-Date
|
||||
Get-Error
|
||||
Get-Event
|
||||
Get-EventLog
|
||||
Get-EventSubscriber
|
||||
Get-ExecutionPolicy
|
||||
Get-ExperimentalFeature
|
||||
Get-FileHash
|
||||
Get-FormatData
|
||||
Get-Help
|
||||
Get-History
|
||||
Get-Host
|
||||
Get-HotFix
|
||||
Get-InstalledModule
|
||||
Get-InstalledScript
|
||||
Get-IseSnippet
|
||||
Get-Item
|
||||
Get-ItemProperty
|
||||
Get-ItemPropertyValue
|
||||
Get-Job
|
||||
Get-JobTrigger
|
||||
Get-LocalGroup
|
||||
Get-LocalGroupMember
|
||||
Get-LocalUser
|
||||
Get-Location
|
||||
Get-LogProperties
|
||||
Get-MarkdownOption
|
||||
Get-Member
|
||||
Get-Module
|
||||
Get-OperationValidation
|
||||
Get-PSBreakpoint
|
||||
Get-PSCallStack
|
||||
Get-PSDrive
|
||||
Get-PSHostProcessInfo
|
||||
Get-PSProvider
|
||||
Get-PSReadLineKeyHandler
|
||||
Get-PSReadLineOption
|
||||
Get-PSRepository
|
||||
Get-PSSession
|
||||
Get-PSSessionCapability
|
||||
Get-PSSessionConfiguration
|
||||
Get-PSSnapin
|
||||
Get-PSSubsystem
|
||||
Get-Package
|
||||
Get-PackageProvider
|
||||
Get-PackageSource
|
||||
Get-PfxCertificate
|
||||
Get-Process
|
||||
Get-Random
|
||||
Get-Runspace
|
||||
Get-RunspaceDebug
|
||||
Get-ScheduledJob
|
||||
Get-ScheduledJobOption
|
||||
Get-Service
|
||||
Get-TimeZone
|
||||
Get-TraceSource
|
||||
Get-Transaction
|
||||
Get-TypeData
|
||||
Get-UICulture
|
||||
Get-Unique
|
||||
Get-Uptime
|
||||
Get-Variable
|
||||
Get-Verb
|
||||
Get-WSManCredSSP
|
||||
Get-WSManInstance
|
||||
Get-WinEvent
|
||||
Get-WmiObject
|
||||
Group-Object
|
||||
Import-Alias
|
||||
Import-BinaryMiLog
|
||||
Import-Clixml
|
||||
Import-Counter
|
||||
Import-Csv
|
||||
Import-IseSnippet
|
||||
Import-LocalizedData
|
||||
Import-Module
|
||||
Import-PSSession
|
||||
Import-PackageProvider
|
||||
Import-PowerShellDataFile
|
||||
Install-Module
|
||||
Install-Package
|
||||
Install-PackageProvider
|
||||
Install-Script
|
||||
Invoke-AsWorkflow
|
||||
Invoke-CimMethod
|
||||
Invoke-Command
|
||||
Invoke-Expression
|
||||
Invoke-History
|
||||
Invoke-Item
|
||||
Invoke-OperationValidation
|
||||
Invoke-RestMethod
|
||||
Invoke-WSManAction
|
||||
Invoke-WebRequest
|
||||
Invoke-WmiMethod
|
||||
Join-Path
|
||||
Join-String
|
||||
Limit-EventLog
|
||||
Measure-Command
|
||||
Measure-Object
|
||||
Move-Item
|
||||
Move-ItemProperty
|
||||
New-Alias
|
||||
New-CimInstance
|
||||
New-CimSession
|
||||
New-CimSessionOption
|
||||
New-Event
|
||||
New-EventLog
|
||||
New-FileCatalog
|
||||
New-Guid
|
||||
New-IseSnippet
|
||||
New-Item
|
||||
New-ItemProperty
|
||||
New-JobTrigger
|
||||
New-LocalGroup
|
||||
New-LocalUser
|
||||
New-Module
|
||||
New-ModuleManifest
|
||||
New-Object
|
||||
New-PSDrive
|
||||
New-PSRoleCapabilityFile
|
||||
New-PSSession
|
||||
New-PSSessionConfigurationFile
|
||||
New-PSSessionOption
|
||||
New-PSTransportOption
|
||||
New-PSWorkflowExecutionOption
|
||||
New-PSWorkflowSession
|
||||
New-ScheduledJobOption
|
||||
New-ScriptFileInfo
|
||||
New-Service
|
||||
New-TemporaryFile
|
||||
New-TimeSpan
|
||||
New-Variable
|
||||
New-WSManInstance
|
||||
New-WSManSessionOption
|
||||
New-WebServiceProxy
|
||||
New-WinEvent
|
||||
Out-Default
|
||||
Out-File
|
||||
Out-GridView
|
||||
Out-Host
|
||||
Out-Null
|
||||
Out-Printer
|
||||
Out-String
|
||||
Pop-Location
|
||||
Protect-CmsMessage
|
||||
Publish-Module
|
||||
Publish-Script
|
||||
Push-Location
|
||||
Read-Host
|
||||
Receive-Job
|
||||
Receive-PSSession
|
||||
Register-ArgumentCompleter
|
||||
Register-CimIndicationEvent
|
||||
Register-EngineEvent
|
||||
Register-ObjectEvent
|
||||
Register-PSRepository
|
||||
Register-PSSessionConfiguration
|
||||
Register-PackageSource
|
||||
Register-ScheduledJob
|
||||
Register-WmiEvent
|
||||
Remove-Alias
|
||||
Remove-CimInstance
|
||||
Remove-CimSession
|
||||
Remove-Computer
|
||||
Remove-Event
|
||||
Remove-EventLog
|
||||
Remove-Item
|
||||
Remove-ItemProperty
|
||||
Remove-Job
|
||||
Remove-JobTrigger
|
||||
Remove-LocalGroup
|
||||
Remove-LocalGroupMember
|
||||
Remove-LocalUser
|
||||
Remove-Module
|
||||
Remove-PSBreakpoint
|
||||
Remove-PSDrive
|
||||
Remove-PSReadLineKeyHandler
|
||||
Remove-PSSession
|
||||
Remove-PSSnapin
|
||||
Remove-Service
|
||||
Remove-TypeData
|
||||
Remove-Variable
|
||||
Remove-WSManInstance
|
||||
Remove-WmiObject
|
||||
Rename-Computer
|
||||
Rename-Item
|
||||
Rename-ItemProperty
|
||||
Rename-LocalGroup
|
||||
Rename-LocalUser
|
||||
Reset-ComputerMachinePassword
|
||||
Resolve-Path
|
||||
Restart-Computer
|
||||
Restart-Service
|
||||
Restore-Computer
|
||||
Resume-Job
|
||||
Resume-Service
|
||||
Save-Help
|
||||
Save-Module
|
||||
Save-Package
|
||||
Save-Script
|
||||
Select-Object
|
||||
Select-String
|
||||
Select-Xml
|
||||
Send-MailMessage
|
||||
Set-Acl
|
||||
Set-Alias
|
||||
Set-AuthenticodeSignature
|
||||
Set-CimInstance
|
||||
Set-Clipboard
|
||||
Set-Content
|
||||
Set-Date
|
||||
Set-ExecutionPolicy
|
||||
Set-Item
|
||||
Set-ItemProperty
|
||||
Set-JobTrigger
|
||||
Set-LocalGroup
|
||||
Set-LocalUser
|
||||
Set-Location
|
||||
Set-LogProperties
|
||||
Set-MarkdownOption
|
||||
Set-PSBreakpoint
|
||||
Set-PSDebug
|
||||
Set-PSReadLineKeyHandler
|
||||
Set-PSReadLineOption
|
||||
Set-PSRepository
|
||||
Set-PSSessionConfiguration
|
||||
Set-PackageSource
|
||||
Set-ScheduledJob
|
||||
Set-ScheduledJobOption
|
||||
Set-Service
|
||||
Set-StrictMode
|
||||
Set-TimeZone
|
||||
Set-TraceSource
|
||||
Set-Variable
|
||||
Set-WSManInstance
|
||||
Set-WSManQuickConfig
|
||||
Set-WmiInstance
|
||||
Show-Command
|
||||
Show-ControlPanelItem
|
||||
Show-EventLog
|
||||
Show-Markdown
|
||||
Sort-Object
|
||||
Split-Path
|
||||
Start-Job
|
||||
Start-Process
|
||||
Start-Service
|
||||
Start-Sleep
|
||||
Start-ThreadJob
|
||||
Start-Trace
|
||||
Start-Transaction
|
||||
Start-Transcript
|
||||
Stop-Computer
|
||||
Stop-Job
|
||||
Stop-Process
|
||||
Stop-Service
|
||||
Stop-Trace
|
||||
Stop-Transcript
|
||||
Suspend-Job
|
||||
Suspend-Service
|
||||
Switch-Process
|
||||
Tee-Object
|
||||
Test-ComputerSecureChannel
|
||||
Test-Connection
|
||||
Test-FileCatalog
|
||||
Test-Json
|
||||
Test-ModuleManifest
|
||||
Test-PSSessionConfigurationFile
|
||||
Test-Path
|
||||
Test-ScriptFileInfo
|
||||
Test-WSMan
|
||||
Trace-Command
|
||||
Unblock-File
|
||||
Undo-Transaction
|
||||
Uninstall-Module
|
||||
Uninstall-Package
|
||||
Uninstall-Script
|
||||
Unprotect-CmsMessage
|
||||
Unregister-Event
|
||||
Unregister-PSRepository
|
||||
Unregister-PSSessionConfiguration
|
||||
Unregister-PackageSource
|
||||
Unregister-ScheduledJob
|
||||
Update-FormatData
|
||||
Update-Help
|
||||
Update-List
|
||||
Update-Module
|
||||
Update-ModuleManifest
|
||||
Update-Script
|
||||
Update-ScriptFileInfo
|
||||
Update-TypeData
|
||||
Use-Transaction
|
||||
Wait-Debugger
|
||||
Wait-Event
|
||||
Wait-Job
|
||||
Wait-Process
|
||||
Where-Object
|
||||
Write-Debug
|
||||
Write-Error
|
||||
Write-EventLog
|
||||
Write-Host
|
||||
Write-Information
|
||||
Write-Output
|
||||
Write-Progress
|
||||
Write-Verbose
|
||||
Write-Warning
|
||||
@@ -0,0 +1,36 @@
|
||||
# Overrides default SecResponseBodyMimeType in order to add application/json (httpbin response Content-Type)
|
||||
SecResponseBodyMimeType text/plain text/html text/xml application/json
|
||||
# crs-setup.conf.example defaults SecAction only for phase 1 and 2.
|
||||
# Adding logs for phase 3, 4 and 5 otherwise go-ftw is not able to detected the triggered rules
|
||||
SecDefaultAction "phase:3,log,auditlog,pass"
|
||||
SecDefaultAction "phase:4,log,auditlog,pass"
|
||||
SecDefaultAction "phase:5,log,auditlog,pass"
|
||||
SecDebugLogLevel 3
|
||||
|
||||
# Rule 900005 from https://github.com/coreruleset/coreruleset/blob/v4.0/dev/tests/regression/README.md#requirements
|
||||
# By default rule 900340 is commented, therefore max_file_size is added to 900005 in order to test 920400-* rules
|
||||
SecAction "id:900005,\
|
||||
phase:1,\
|
||||
nolog,\
|
||||
pass,\
|
||||
ctl:ruleEngine=DetectionOnly,\
|
||||
ctl:ruleRemoveById=910000,\
|
||||
setvar:tx.blocking_paranoia_level=4,\
|
||||
setvar:tx.crs_validate_utf8_encoding=1,\
|
||||
setvar:tx.arg_name_length=100,\
|
||||
setvar:tx.arg_length=400,\
|
||||
setvar:tx.total_arg_length=64000,\
|
||||
setvar:tx.max_num_args=255,\
|
||||
setvar:tx.max_file_size=64100,\
|
||||
setvar:tx.combined_file_sizes=65535"
|
||||
|
||||
# Write the value from the X-CRS-Test header as a marker to the log
|
||||
# Requests with X-CRS-Test header will not be matched by any rule. See https://github.com/coreruleset/go-ftw/pull/133
|
||||
SecRule REQUEST_HEADERS:X-CRS-Test "@rx ^.*$" \
|
||||
"id:999999,\
|
||||
phase:1,\
|
||||
pass,\
|
||||
t:none,\
|
||||
log,\
|
||||
msg:'X-CRS-Test %{MATCHED_VAR}',\
|
||||
ctl:ruleRemoveById=1-999999"
|
||||
119
plugins/wasm-go/extensions/waf/wasmplugin/utils.go
Normal file
119
plugins/wasm-go/extensions/waf/wasmplugin/utils.go
Normal file
@@ -0,0 +1,119 @@
|
||||
package wasmplugin
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/alibaba/higress/plugins/wasm-go/pkg/wrapper"
|
||||
ctypes "github.com/corazawaf/coraza/v3/types"
|
||||
"github.com/tetratelabs/proxy-wasm-go-sdk/proxywasm"
|
||||
"github.com/tetratelabs/proxy-wasm-go-sdk/proxywasm/types"
|
||||
"math"
|
||||
"net"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
const noGRPCStream int32 = -1
|
||||
const replaceResponseBody int = 10
|
||||
|
||||
// retrieveAddressInfo retrieves address properties from the proxy
|
||||
// Expected targets are "source" or "destination"
|
||||
// Envoy ref: https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/advanced/attributes#connection-attributes
|
||||
func retrieveAddressInfo(logger wrapper.Log, target string) (string, int) {
|
||||
var targetIP, targetPortStr string
|
||||
var targetPort int
|
||||
targetAddressRaw, err := proxywasm.GetProperty([]string{target, "address"})
|
||||
if err != nil {
|
||||
logger.Debug(fmt.Sprintf("Failed to get %s address", target))
|
||||
} else {
|
||||
targetIP, targetPortStr, err = net.SplitHostPort(string(targetAddressRaw))
|
||||
if err != nil {
|
||||
logger.Debug(fmt.Sprintf("Failed to parse %s address", target))
|
||||
}
|
||||
}
|
||||
targetPortRaw, err := proxywasm.GetProperty([]string{target, "port"})
|
||||
if err == nil {
|
||||
targetPort, err = parsePort(targetPortRaw)
|
||||
if err != nil {
|
||||
logger.Debug(fmt.Sprintf("Failed to parse %s port", target))
|
||||
}
|
||||
} else if targetPortStr != "" {
|
||||
// If GetProperty fails we rely on the port inside the Address property
|
||||
// Mostly useful for proxies other than Envoy
|
||||
targetPort, err = strconv.Atoi(targetPortStr)
|
||||
if err != nil {
|
||||
logger.Debug(fmt.Sprintf("Failed to get %s port", target))
|
||||
}
|
||||
}
|
||||
return targetIP, targetPort
|
||||
}
|
||||
|
||||
// parsePort converts port, retrieved as little-endian bytes, into int
|
||||
func parsePort(b []byte) (int, error) {
|
||||
// Port attribute ({"source", "port"}) is populated as uint64 (8 byte)
|
||||
// Ref: https://github.com/envoyproxy/envoy/blob/1b3da361279a54956f01abba830fc5d3a5421828/source/common/network/utility.cc#L201
|
||||
if len(b) < 8 {
|
||||
return 0, errors.New("port bytes not found")
|
||||
}
|
||||
// 0 < Port number <= 65535, therefore the retrieved value should never exceed 16 bits
|
||||
// and correctly fit int (at least 32 bits in size)
|
||||
unsignedInt := binary.LittleEndian.Uint64(b)
|
||||
if unsignedInt > math.MaxInt32 {
|
||||
return 0, errors.New("port conversion error")
|
||||
}
|
||||
return int(unsignedInt), nil
|
||||
}
|
||||
|
||||
// parseServerName parses :authority pseudo-header in order to retrieve the
|
||||
// virtual host.
|
||||
func parseServerName(logger wrapper.Log, authority string) string {
|
||||
host, _, err := net.SplitHostPort(authority)
|
||||
if err != nil {
|
||||
// missing port or bad format
|
||||
logger.Debug("Failed to parse server name from authority")
|
||||
host = authority
|
||||
}
|
||||
return host
|
||||
}
|
||||
|
||||
func handleInterruption(ctx wrapper.HttpContext, phase string, interruption *ctypes.Interruption, log wrapper.Log) types.Action {
|
||||
if ctx.GetContext("interruptionHandled").(bool) {
|
||||
// handleInterruption should never be called more than once
|
||||
panic("Interruption already handled")
|
||||
}
|
||||
|
||||
log.Infof("Transaction interrupted at %s", phase)
|
||||
|
||||
ctx.SetContext("interruptionHandled", true)
|
||||
if phase == "http_response_body" {
|
||||
return replaceResponseBodyWhenInterrupted(log, replaceResponseBody)
|
||||
}
|
||||
|
||||
statusCode := interruption.Status
|
||||
//log.Infof("Status code is %d", statusCode)
|
||||
if statusCode == 0 {
|
||||
statusCode = 403
|
||||
}
|
||||
if err := proxywasm.SendHttpResponse(uint32(statusCode), nil, nil, noGRPCStream); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// SendHttpResponse must be followed by ActionPause in order to stop malicious content
|
||||
return types.ActionPause
|
||||
}
|
||||
|
||||
// replaceResponseBodyWhenInterrupted address an interruption raised during phase 4.
|
||||
// At this phase, response headers are already sent downstream, therefore an interruption
|
||||
// can not change anymore the status code, but only tweak the response body
|
||||
func replaceResponseBodyWhenInterrupted(logger wrapper.Log, bodySize int) types.Action {
|
||||
// TODO(M4tteoP): Update response body interruption logic after https://github.com/corazawaf/coraza-proxy-wasm/issues/26
|
||||
// Currently returns a body filled with null bytes that replaces the sensitive data potentially leaked
|
||||
err := proxywasm.ReplaceHttpResponseBody(bytes.Repeat([]byte("\x00"), bodySize))
|
||||
if err != nil {
|
||||
logger.Error("Failed to replace response body")
|
||||
return types.ActionContinue
|
||||
}
|
||||
logger.Warn("Response body intervention occurred: body replaced")
|
||||
return types.ActionContinue
|
||||
}
|
||||
@@ -24,6 +24,10 @@ if [ ! -n "$INNER_PLUGIN_NAME" ]; then
|
||||
echo "build all wasmplugins under folder of $EXTENSIONS_DIR"
|
||||
for file in `ls $EXTENSIONS_DIR`
|
||||
do
|
||||
# TODO: adjust waf build
|
||||
if [ $file == "waf" ]; then
|
||||
continue
|
||||
fi
|
||||
if [ -d $EXTENSIONS_DIR$file ]; then
|
||||
name=${file##*/}
|
||||
echo "build wasmplugin name of $name"
|
||||
|
||||
Reference in New Issue
Block a user