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

000e33c227103035

演示

你可以通过运行演示环境来尝试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