GoTestWAF 2022年美国黑帽大会
GoTestWAF是一个用于API和OWASP攻击模拟的工具,支持广泛的API协议,包括REST、GraphQL、gRPC、WebSockets、SOAP、XMLRPC和其他。
它被设计用来评估网络应用安全解决方案,如API安全代理、网络应用防火墙、IPS、API网关和其他。
项目地址
它是如何工作的
GoTestWAF使用放置在HTTP请求的不同部分的编码有效载荷生成恶意请求:其正文、头文件、URL参数等。生成的请求被发送到GoTestWAF启动期间指定的应用程序安全解决方案URL。安全解决方案的评估结果记录在您机器上创建的报告文件中。
testcases
---
payload:
- '"union select -7431.1, name, @aaa from u_base--w-'
- "'or 123.22=123.22"
- "' waitfor delay '00:00:10'--"
- "')) or pg_sleep(5)--"
encoder:
- Base64Flat
- URL
placeholder:
- UrlPath
- UrlParam
- JSUnicode
- Header
...
payloadencoderplaceholder
请求生成是一个三步过程,涉及到有效载荷量与编码器和占位符量的乘法。假设你定义了2个有效载荷、3个编码器(Base64、JSUnicode和URL)和1个占位符(URLParameter – HTTP GET参数)。在这种情况下,GoTestWAF将在一个测试案例中发送2x3x1=6个请求。
testCasePath
要求
使用Docker快速启动
下面的步骤介绍了在Docker上以最小的配置下载和启动GoTestWAF。
从Docker Hub拉出GoTestWAF镜像。
docker pull wallarm/gotestwaf
启动GoTestWAF镜像。
docker run -v ${PWD}/reports:/app/reports --network="host" \
wallarm/gotestwaf --url=<EVALUATED_SECURITY_SOLUTION_URL>
${PWD}/reports
--network="host"
--grpcPort cli
docker run -v ${PWD}/reports:/app/reports \
wallarm/gotestwaf --grpcPort 9000 --url=http://my.grpc.endpoint
您已经通过使用GoTestWAF的最小配置成功地评估了您的应用程序安全解决方案。要了解高级配置选项,请使用此链接。
检查评估结果
检查使用STDOUT和STDERR服务记录的评估结果。比如说。
GOTESTWAF : 2021/10/07 16:06:38.401836 main.go:67: Test cases loading started
GOTESTWAF : 2021/10/07 16:06:38.403985 main.go:74: Test cases loading finished
GOTESTWAF : 2021/10/07 16:06:38.404007 main.go:87: gRPC pre-check: IN PROGRESS
GOTESTWAF : 2021/10/07 16:06:41.404701 main.go:91: gRPC pre-check: connection is not available, reason: sending gRPC request: context deadline exceeded
GOTESTWAF : 2021/10/07 16:06:41.404759 main.go:101: Scanned URL: http://172.17.0.1:8080/
GOTESTWAF : 2021/10/07 16:06:41.415870 main.go:125: WAF pre-check: OK. Blocking status code: 403
GOTESTWAF : 2021/10/07 16:06:41.415969 main.go:140: WebSocket pre-check. URL to check: ws://172.17.0.1:8080/
GOTESTWAF : 2021/10/07 16:06:41.426661 main.go:144: WebSocket pre-check: connection is not available, reason: websocket: bad handshake
GOTESTWAF : 2021/10/07 16:06:41.427029 main.go:172: Scanning http://172.17.0.1:8080/
GOTESTWAF : 2021/10/07 16:06:41.427117 scanner.go:149: Scanning started
GOTESTWAF : 2021/10/07 16:06:44.321301 scanner.go:154: Scanning Time: 2.89414802s
GOTESTWAF : 2021/10/07 16:06:44.321342 scanner.go:185: Scanning finished
Negative Tests:
+-----------------------+-----------------------+-----------------------+-----------------------+-----------------------+-----------------------+
| TEST SET | TEST CASE | PERCENTAGE, % | BLOCKED | BYPASSED | UNRESOLVED |
+-----------------------+-----------------------+-----------------------+-----------------------+-----------------------+-----------------------+
| community | community-lfi | 66.67 | 4 | 2 | 0 |
| community | community-rce | 14.29 | 6 | 36 | 0 |
| community | community-sqli | 70.83 | 34 | 14 | 0 |
| community | community-xss | 91.78 | 279 | 25 | 0 |
| community | community-xxe | 0.00 | 0 | 2 | 0 |
| owasp | crlf | 87.50 | 7 | 1 | 0 |
| owasp | ldap-injection | 12.50 | 1 | 7 | 0 |
| owasp | mail-injection | 25.00 | 3 | 9 | 0 |
| owasp | nosql-injection | 0.00 | 0 | 18 | 0 |
| owasp | path-traversal | 25.00 | 16 | 48 | 2 |
| owasp | rce | 22.22 | 4 | 14 | 0 |
| owasp | rce-urlparam | 33.33 | 1 | 2 | 0 |
| owasp | shell-injection | 25.00 | 6 | 18 | 0 |
| owasp | sql-injection | 25.00 | 12 | 36 | 0 |
| owasp | ss-include | 25.00 | 5 | 15 | 0 |
| owasp | sst-injection | 15.62 | 5 | 27 | 0 |
| owasp | xml-injection | 0.00 | 0 | 13 | 0 |
| owasp | xss-scripting | 25.00 | 17 | 51 | 0 |
| owasp-api | graphql | 0.00 | 0 | 2 | 0 |
| owasp-api | graphql-post | 33.33 | 1 | 2 | 0 |
| owasp-api | grpc | 0.00 | 0 | 0 | 2 |
| owasp-api | rest | 100.00 | 2 | 0 | 0 |
| owasp-api | soap | 100.00 | 2 | 0 | 0 |
+-----------------------+-----------------------+-----------------------+-----------------------+-----------------------+-----------------------+
| DATE: | WAF NAME: | WAF AVERAGE SCORE: | BLOCKED (RESOLVED): | BYPASSED (RESOLVED): | UNRESOLVED: |
| 2021-10-07 | GENERIC | 34.70% | 405/747 (54.22%) | 342/747 (45.78%) | 4/751 (0.53%) |
+-----------------------+-----------------------+-----------------------+-----------------------+-----------------------+-----------------------+
Positive Tests:
+-----------------------+-----------------------+-----------------------+-----------------------+-----------------------+-----------------------+
| TEST SET | TEST CASE | PERCENTAGE, % | BLOCKED | BYPASSED | UNRESOLVED |
+-----------------------+-----------------------+-----------------------+-----------------------+-----------------------+-----------------------+
| false-pos | texts | 17.65 | 14 | 3 | 0 |
+-----------------------+-----------------------+-----------------------+-----------------------+-----------------------+-----------------------+
| DATE: | WAF NAME: | WAF POSITIVE SCORE: | FALSE POSITIVE (RES): | TRUE POSITIVE (RES): | UNRESOLVED: |
| 2021-10-07 | GENERIC | 17.65% | 14/17 (82.35%) | 3/17 (17.65%) | 0/17 (0.00%) |
+-----------------------+-----------------------+-----------------------+-----------------------+-----------------------+-----------------------+
PDF report is ready: reports/waf-evaluation-report-generic-2021-October-07-16-06-44.pdf
waf-evaluation-report-.pdf
演示
你可以通过运行演示环境来尝试GoTestWAF,该环境使用OWASP核心规则集和GoTestWAF评估Docker上的ModSecurity,部署了基于NGINX的ModSecurity。
运行演示环境。
1.克隆这个资源库并进入克隆的目录。
git clone https://github.com/wallarm/gotestwaf.git
cd gotestwaf
2.通过使用以下make命令从Docker镜像中启动ModSecurity。
make modsec
运行ModSecurity Docker容器的设置被定义在克隆的Makefile的规则modsec中。它在8080端口运行ModSecurity Docker容器,在克隆的文件./resources/default.conf.template中定义了最小的配置,PARANOIA值设置为1。
如果需要,你可以通过编辑克隆的Makefile中的规则modsec来改变这些设置。ModSecurity配置的可用选项在Docker Hub上有描述。
要停止ModSecurity容器,请使用以下命令。
make modsec_down
3.通过使用以下方法之一,以最小的配置启动GoTestWAF。
通过使用以下docker pull和docker run命令启动Docker镜像。
docker pull wallarm/gotestwaf
docker run -v ${PWD}/reports:/app/reports --network="host" \
wallarm/gotestwaf --url=http://127.0.0.1:8080
从Docker文件中构建GoTestWAF Docker镜像,并通过使用以下make命令运行该镜像(确保ModSec在8080端口运行;如果不是,请更新Makefile中的端口值)。
make gotestwaf
make scan_local_from_docker
通过使用以下make命令,用go原生启动GoTestWAF。(确保ModSec运行在8080端口;如果不是,在Makefile中更新端口值)。
make scan_local
/app/reportswaf-evaluation-report-.pdf
运行GoTestWAF的其他选项
除了运行从Docker Hub下载的GoTestWAF Docker镜像外,您还可以通过使用以下选项来运行GoTestWAF。
git clone https://github.com/wallarm/gotestwaf.git
cd gotestwaf
docker build . --force-rm -t gotestwaf
docker run -v ${PWD}/reports:/app/reports --network="host" \
gotestwaf --url=<EVALUATED_SECURITY_SOLUTION_URL>
--network="host"
- 克隆这个资源库,用go运行GoTestWAF,比如说。
git clone https://github.com/wallarm/gotestwaf.git
cd gotestwaf
go run ./cmd --url=<EVALUATED_SECURITY_SOLUTION_URL> --verbose
- 克隆这个资源库并将GoTestWAF作为Go模块来构建。
git clone https://github.com/wallarm/gotestwaf.git
cd gotestwaf
go build -mod vendor -o gotestwaf ./cmd/main.go
支持的GoTestWAF配置选项描述如下。
配置选项
Usage: ./gotestwaf [OPTIONS] --url <url>
Options:
--addHeader string An HTTP header to add to requests
--blockConnReset If true, connection resets will be considered as block
--blockRegex string Regex to detect a blocking page with the same HTTP response status code as a not blocked request
--blockStatusCode int HTTP status code that WAF uses while blocking requests (default 403)
--configPath string Path to the config file (default "config.yaml")
--followCookies If true, use cookies sent by the server. May work only with --maxIdleConns=1
--grpcPort uint16 gRPC port to check
--idleConnTimeout int The maximum amount of time a keep-alive connection will live (default 2)
--ignoreUnresolved If true, unresolved test cases will be considered as bypassed (affect score and results)
--logFormat string Set logging format: text, json (default "text")
--logLevel string Logging level: panic, fatal, error, warn, info, debug, trace (default "info")
--maxIdleConns int The maximum number of keep-alive connections (default 2)
--maxRedirects int The maximum number of handling redirects (default 50)
--nonBlockedAsPassed If true, count requests that weren't blocked as passed. If false, requests that don't satisfy to PassStatusCode/PassRegExp as blocked
--openapiFile string Path to openAPI file
--passRegex string Regex to a detect normal (not blocked) web page with the same HTTP status code as a blocked request
--passStatusCode ints HTTP response status code that WAF uses while passing requests (default [200,404])
--proxy string Proxy URL to use
--quiet If true, disable verbose logging
--randomDelay int Random delay in ms in addition to the delay between requests (default 400)
--renewSession Renew cookies before each test. Should be used with --followCookies flag
--reportFormat string Export report to one of the following formats: none, pdf, html, json (default "pdf")
--reportName string Report file name. Supports `time' package template format (default "waf-evaluation-report-2006-January-02-15-04-05")
--reportPath string A directory to store reports (default "reports")
--sendDelay int Delay in ms between requests (default 400)
--skipWAFBlockCheck If true, WAF detection tests will be skipped
--skipWAFIdentification Skip WAF identification
--testCase string If set then only this test case will be run
--testCasesPath string Path to a folder with test cases (default "testcases")
--testSet string If set then only this test set's cases will be run
--tlsVerify If true, the received TLS certificate will be verified
--url string URL to check
--version Show GoTestWAF version and exit
--wafName string Name of the WAF product (default "generic")
--workers int The number of workers to scan (default 5)
--wsURL string WebSocket URL to check
所列的选项可以按以下方式传递给GoTestWAF。
如果运行GoTestWAF Docker容器,在Docker运行命令中,在Docker镜像名称后面传递配置选项。
例如,要运行带有WebSocket检查的GoTestWAF,您可以通过wsURL选项和verbose标志指定WebSocket URL,以包括关于检查过程的更多信息。
docker run -v ${PWD}/reports:/app/reports --network="host" wallarm/gotestwaf \
--url=http://127.0.0.1:8080/ --wsURL=ws://127.0.0.1:8080/api/ws --verbose
go run
wsURLverbose
go run ./cmd --url=http://127.0.0.1:8080/ --wsURL=ws://127.0.0.1:8080/api/ws --verbose