Giter Site home page Giter Site logo

wallarm / gotestwaf Goto Github PK

View Code? Open in Web Editor NEW
1.5K 40.0 204.0 13.38 MB

An open-source project in Golang to asess different API Security tools and WAF for detection logic and bypasses

Home Page: https://lab.wallarm.com/test-your-waf-before-hackers/

License: MIT License

Go 86.79% Dockerfile 0.28% Makefile 0.50% HTML 10.25% Ruby 1.63% Shell 0.55%
owasp api-security security bugbounty security-tools waf web-application-security web-application-firewall security-testing graphql-security

gotestwaf's Introduction

GoTestWAF Black Hat Arsenal USA 2022

GoTestWAF is a tool for API and OWASP attack simulation that supports a wide range of API protocols including REST, GraphQL, gRPC, SOAP, XMLRPC, and others.

It was designed to evaluate web application security solutions, such as API security proxies, Web Application Firewalls, IPS, API gateways, and others.



How it works

GoTestWAF generates malicious requests using encoded payloads placed in different parts of HTTP requests: its body, headers, URL parameters, etc. Generated requests are sent to the application security solution URL specified during GoTestWAF launch. The results of the security solution evaluation are recorded in the report file created on your machine.

Default conditions for request generation are defined in the testcases folder in the YAML files of the following format:

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
type: SQL Injection
  • payload is a malicious attack sample (e.g XSS payload like <script>alert(111)</script> or something more sophisticated). Since the format of the YAML string is required for payloads, they must be encoded as binary data.

  • encoder is an encoder to be applied to the payload before placing it to the HTTP request. Possible encoders are:

    • Base64
    • Base64Flat
    • JSUnicode
    • URL
    • Plain (to keep the payload string as-is)
    • XML Entity
  • placeholder is a place inside HTTP request where encoded payload should be. Possible placeholders are:

    • gRPC
    • Header
    • UserAgent
    • RequestBody
    • JSONRequest
    • JSONBody
    • HTMLForm
    • HTMLMultipartForm
    • SOAPBody
    • XMLBody
    • URLParam
    • URLPath
    • RawRequest

    The RawRequest placeholder will allow you to do an arbitrary HTTP request. The payload is substituted by replacing the string {{payload}} in the URL path, Headers or body. Fields of RawRequest placeholder:

    • method
    • path
    • headers
    • body

    Required fields for RawRequest placeholder:

    • method field

    Example:

    payload:
      - test
    encoder:
      - Plain
    placeholder:
      - RawRequest:
          method: "POST"
          path: "/"
          headers:
            Content-Type: "multipart/form-data; boundary=boundary"
          body: |
            --boundary
            Content-disposition: form-data; name="field1"
            
            Test
            --boundary
            Content-disposition: form-data; name="field2"
            Content-Type: text/plain; charset=utf-7
            
            Knock knock.
            {{payload}}
            --boundary--
    type: RawRequest test
  • type is a name of entire group of the payloads in file. It can be arbitrary, but should reflect the type of attacks in the file.

Request generation is a three-step process involving the multiplication of payload amount by encoder and placeholder amounts. Let's say you defined 2 payloads, 3 encoders (Base64, JSUnicode, and URL) and 1 placeholder (URLParameter - HTTP GET parameter). In this case, GoTestWAF will send 2x3x1 = 6 requests in a test case.

During GoTestWAF launch, you can also choose test cases between two embedded: OWASP Top-10, OWASP-API, or your own (by using the configuration option testCasePath).

Requirements

  • GoTestwaf supports all the popular operating systems (Linux, Windows, macOS), and can be built natively if Go is installed in the system. If you want to run GoTestWaf natively, make sure you have the Chrome web browser to be able to generate PDF reports. In case you don't have Chrome, you can create a report in HTML format.
  • If running GoTestWAF as the Docker container, please ensure you have installed and configured Docker, and GoTestWAF and evaluated application security solution are connected to the same Docker network.
  • For GoTestWAF to be successfully started, please ensure the IP address of the machine running GoTestWAF is whitelisted on the machine running the application security solution.

Quick start with Docker

The steps below walk through downloading and starting GoTestWAF with minimal configuration on Docker.

  1. Pull the GoTestWAF image from Docker Hub:

    docker pull wallarm/gotestwaf
    
  2. Start the GoTestWAF image:

    docker run --rm --network="host" -it -v ${PWD}/reports:/app/reports \
        wallarm/gotestwaf --url=<EVALUATED_SECURITY_SOLUTION_URL>

    If required, you can replace ${PWD}/reports with the path to another folder used to place the evaluation report.

    If you don't want to optionally email the report, just press Enter after the email request message appears, or you can use --noEmailReport to skip the message:

    docker run --rm --network="host" -v ${PWD}/reports:/app/reports \
        wallarm/gotestwaf --url=<EVALUATED_SECURITY_SOLUTION_URL> --noEmailReport

    If the evaluated security tool is available externally, you can skip the option --network="host". This option enables interaction of Docker containers running on 127.0.0.1.

    To perform the gRPC tests you must have a working endpoint and use the --grpcPort cli option.

    docker run --rm --network="host" -it -v ${PWD}/reports:/app/reports \
        wallarm/gotestwaf --grpcPort 9000 --url=http://my.grpc.endpoint
  3. Check your email for the report.

You have successfully evaluated your application security solution by using GoTestWAF with minimal configuration. To learn advanced configuration options, please use this link.

Checking the evaluation results

Check the evaluation results logged using the STDOUT and STDERR services. For example:

INFO[0000] GoTestWAF started                             version=v0.4.11-1-g8ccc316
INFO[0000] Test cases loading started                   
INFO[0000] Test cases loading finished                  
INFO[0000] Test cases fingerprint                        fp=23c3ae919db5e6edcb62815de1a09fdf
INFO[0000] Try to identify WAF solution                 
INFO[0000] WAF was not identified                       
INFO[0000] WAF pre-check                                 url="http://localhost:8080"
INFO[0000] WAF pre-check                                 blocked=true code=403 status=done
INFO[0000] WebSocket pre-check                           status=started url="ws://localhost:8080"
INFO[0000] WebSocket pre-check                           connection="not available" error="websocket: bad handshake" status=done
INFO[0000] gRPC pre-check                                status=started
INFO[0000] gRPC pre-check                                connection="not available" status=done
INFO[0000] Scanning started                              url="http://localhost:8080"
INFO[0025] Scanning finished                             duration=25.043996212s                                                                                                                          
True-Positive Tests:
+-----------------------+-------------------------+-----------------------+-----------------------+-----------------------+-----------------------+-----------------------+-----------------------+
|       TEST SET        |        TEST CASE        |     PERCENTAGE, %     |        BLOCKED        |       BYPASSED        |      UNRESOLVED       |         SENT          |        FAILED         |
+-----------------------+-------------------------+-----------------------+-----------------------+-----------------------+-----------------------+-----------------------+-----------------------+
| community             | community-128kb-rce     |                  0.00 |                     0 |                     0 |                     1 |                     1 |                     0 |
| community             | community-128kb-sqli    |                  0.00 |                     0 |                     0 |                     1 |                     1 |                     0 |
| community             | community-128kb-xss     |                  0.00 |                     0 |                     0 |                     1 |                     1 |                     0 |
| community             | community-16kb-rce      |                100.00 |                     1 |                     0 |                     0 |                     1 |                     0 |
| community             | community-16kb-sqli     |                100.00 |                     1 |                     0 |                     0 |                     1 |                     0 |
| community             | community-16kb-xss      |                100.00 |                     1 |                     0 |                     0 |                     1 |                     0 |
| community             | community-32kb-rce      |                100.00 |                     1 |                     0 |                     0 |                     1 |                     0 |
| community             | community-32kb-sqli     |                100.00 |                     1 |                     0 |                     0 |                     1 |                     0 |
| community             | community-32kb-xss      |                100.00 |                     1 |                     0 |                     0 |                     1 |                     0 |
| community             | community-64kb-rce      |                100.00 |                     1 |                     0 |                     0 |                     1 |                     0 |
| community             | community-64kb-sqli     |                100.00 |                     1 |                     0 |                     0 |                     1 |                     0 |
| community             | community-64kb-xss      |                100.00 |                     1 |                     0 |                     0 |                     1 |                     0 |
| community             | community-8kb-rce       |                100.00 |                     1 |                     0 |                     0 |                     1 |                     0 |
| community             | community-8kb-sqli      |                100.00 |                     1 |                     0 |                     0 |                     1 |                     0 |
| community             | community-8kb-xss       |                100.00 |                     1 |                     0 |                     0 |                     1 |                     0 |
| community             | community-lfi           |                100.00 |                     8 |                     0 |                     0 |                     8 |                     0 |
| community             | community-lfi-multipart |                  0.00 |                     0 |                     0 |                     9 |                     9 |                     0 |
| community             | community-rce           |                 83.33 |                    10 |                     2 |                     0 |                    12 |                     0 |
| community             | community-sqli          |                100.00 |                    32 |                     0 |                     0 |                    32 |                     0 |
| community             | community-user-agent    |                 70.00 |                     7 |                     3 |                     0 |                    10 |                     0 |
| community             | community-xss           |                 95.80 |                   502 |                    22 |                     0 |                   524 |                     0 |
| community             | community-xxe           |                  0.00 |                     0 |                     2 |                     0 |                     2 |                     0 |
| owasp                 | crlf                    |                 77.78 |                     7 |                     2 |                     0 |                     9 |                     0 |
| owasp                 | ldap-injection          |                  3.13 |                     2 |                    62 |                     0 |                    64 |                     0 |
| owasp                 | mail-injection          |                 12.50 |                     3 |                    21 |                     0 |                    24 |                     0 |
| owasp                 | nosql-injection         |                  0.00 |                     0 |                    70 |                     0 |                    70 |                     0 |
| owasp                 | path-traversal          |                 24.77 |                    27 |                    82 |                     1 |                   110 |                     0 |
| owasp                 | rce                     |                 33.33 |                    22 |                    44 |                     0 |                    66 |                     0 |
| owasp                 | rce-urlparam            |                 33.33 |                     3 |                     6 |                     0 |                     9 |                     0 |
| owasp                 | shell-injection         |                 27.08 |                    13 |                    35 |                     0 |                    48 |                     0 |
| owasp                 | sql-injection           |                 24.36 |                    38 |                   118 |                     0 |                   156 |                     0 |
| owasp                 | ss-include              |                 37.50 |                    15 |                    25 |                     0 |                    40 |                     0 |
| owasp                 | sst-injection           |                 18.75 |                    12 |                    52 |                     0 |                    64 |                     0 |
| owasp                 | xml-injection           |                  0.00 |                     0 |                    12 |                     1 |                    13 |                     0 |
| owasp                 | xss-scripting           |                 33.20 |                   167 |                   336 |                     1 |                   504 |                     0 |
| owasp-api             | graphql                 |                  0.00 |                     0 |                     6 |                     0 |                     6 |                     0 |
| owasp-api             | graphql-post            |                 50.00 |                     2 |                     2 |                     0 |                     4 |                     0 |
| owasp-api             | grpc                    |                  0.00 |                     0 |                     0 |                     0 |                     0 |                     0 |
| owasp-api             | non-crud                |                100.00 |                     2 |                     0 |                     0 |                     2 |                     0 |
| owasp-api             | rest                    |                 23.08 |                     3 |                    10 |                     0 |                    13 |                     0 |
| owasp-api             | soap                    |                 23.08 |                     3 |                    10 |                     0 |                    13 |                     0 |
+-----------------------+-------------------------+-----------------------+-----------------------+-----------------------+-----------------------+-----------------------+-----------------------+
|         DATE:         |      PROJECT NAME:      | TRUE-POSITIVE SCORE:  |  BLOCKED (RESOLVED):  | BYPASSED (RESOLVED):  |  UNRESOLVED (SENT):   |      TOTAL SENT:      |    FAILED (TOTAL):    |
|      2024-02-08       |         GENERIC         |        49.12%         |   890/1812 (49.12%)   |   922/1812 (50.88%)   |    15/1827 (0.82%)    |         1827          |    0/1827 (0.00%)     |
+-----------------------+-------------------------+-----------------------+-----------------------+-----------------------+-----------------------+-----------------------+-----------------------+

True-Negative Tests:
+-----------------------+-----------------------+-----------------------+-----------------------+-----------------------+-----------------------+-----------------------+-----------------------+
|       TEST SET        |       TEST CASE       |     PERCENTAGE, %     |        BLOCKED        |       BYPASSED        |      UNRESOLVED       |         SENT          |        FAILED         |
+-----------------------+-----------------------+-----------------------+-----------------------+-----------------------+-----------------------+-----------------------+-----------------------+
| false-pos             | texts                 |                 85.65 |                    31 |                   185 |                     0 |                   216 |                     0 |
+-----------------------+-----------------------+-----------------------+-----------------------+-----------------------+-----------------------+-----------------------+-----------------------+
|         DATE:         |     PROJECT NAME:     | TRUE-NEGATIVE SCORE:  |  BLOCKED (RESOLVED):  | BYPASSED (RESOLVED):  |  UNRESOLVED (SENT):   |      TOTAL SENT:      |    FAILED (TOTAL):    |
|      2024-02-08       |        GENERIC        |        85.65%         |    31/216 (14.35%)    |   185/216 (85.65%)    |     0/216 (0.00%)     |          216          |     0/216 (0.00%)     |
+-----------------------+-----------------------+-----------------------+-----------------------+-----------------------+-----------------------+-----------------------+-----------------------+

Summary:
+-----------------------------+-----------------------------+-----------------------------+-----------------------------+
|            TYPE             | TRUE-POSITIVE TESTS BLOCKED | TRUE-NEGATIVE TESTS PASSED  |           AVERAGE           |
+-----------------------------+-----------------------------+-----------------------------+-----------------------------+
| API Security                | 26.32%                      | n/a                         | 26.32%                      |
| Application Security        | 49.61%                      | 85.65%                      | 67.63%                      |
+-----------------------------+-----------------------------+-----------------------------+-----------------------------+
|                                                                        SCORE            |           46.97%            |
+-----------------------------+-----------------------------+-----------------------------+-----------------------------+

The report file waf-evaluation-report-<date>.pdf is available in the reports folder of the user directory. You can also specify the directory to save the reports with the reportPath parameter and the name of the report file with the reportName parameter. To learn advanced configuration options, please use this link.

Example of GoTestWaf report

Demos

You can try GoTestWAF by running the demo environment that deploys NGINX‑based ModSecurity using OWASP Core Rule Set and GoTestWAF evaluating ModSecurity on Docker.

To run the demo environment:

  1. Clone this repository and go to the cloned directory:

    git clone https://github.com/wallarm/gotestwaf.git
    cd gotestwaf
  2. Start ModSecurity from the Docker image by using the following make command:

    make modsec

    Settings for running the ModSecurity Docker container are defined in the rule modsec of the cloned Makefile. It runs the ModSecurity Docker container on port 8080 with minimal configuration defined in the cloned file ./resources/default.conf.template and the PARANOIA value set to 1.

    If required, you can change these settings by editing the rule modsec in the cloned Makefile. Available options for ModSecurity configuration are described on Docker Hub.

    To stop ModSecurity containers use the following command:

    make modsec_down
  3. Start GoTestWAF with minimal configuration by using one of the following methods:

    Start the Docker image by using the following docker pull and docker run commands:

    docker pull wallarm/gotestwaf
    docker run --rm --network="host" -v ${PWD}/reports:/app/reports \
        wallarm/gotestwaf --url=http://127.0.0.1:8080 --noEmailReport

    Build the GoTestWAF Docker image from the Dockerfile and run the image by using the following make commands (make sure ModSec is running on port 8080; if not, update the port value in the Makefile):

    make gotestwaf
    make scan_local_from_docker

    Start GoTestWAF natively with go by using the following make command: (make sure ModSec is running on port 8080; if not, update the port value in the Makefile):

    make scan_local
  4. Find the report file waf-evaluation-report-<date>.pdf in the reports folder that you mapped to /app/reports inside the container.

Other options to run GoTestWAF

In addition to running the GoTestWAF Docker image downloaded from Docker Hub, you can run GoTestWAF by using the following options:

  • Clone this repository and build the GoTestWAF Docker image from the Dockerfile, for example:

    git clone https://github.com/wallarm/gotestwaf.git
    cd gotestwaf
    DOCKER_BUILDKIT=1 docker build --force-rm -t gotestwaf .
    docker run --rm --network="host" -it -v ${PWD}/reports:/app/reports \
        gotestwaf --url=<EVALUATED_SECURITY_SOLUTION_URL>

    If the evaluated security tool is available externally, you can skip the option --network="host". This option enables interaction of Docker containers running on 127.0.0.1.

  • Clone this repository and run GoTestWAF with go, for example:

    git clone https://github.com/wallarm/gotestwaf.git
    cd gotestwaf
    go run ./cmd --url=<EVALUATED_SECURITY_SOLUTION_URL>
  • Clone this repository and build GoTestWAF as the Go module:

    git clone https://github.com/wallarm/gotestwaf.git
    cd gotestwaf
    go build -mod vendor -o gotestwaf ./cmd

Supported GoTestWAF configuration options are described below.

Configuration options

Usage: ./gotestwaf [OPTIONS] --url <URL>

Options:
      --addDebugHeader          Add header with a hash of the test information in each request
      --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
      --blockStatusCodes ints   HTTP status code that WAF uses while blocking requests (default [403])
      --configPath string       Path to the config file (default "config.yaml")
      --email string            E-mail to which the report will be sent
      --followCookies           If true, use cookies sent by the server. May work only with --maxIdleConns=1 (gohttp only)
      --graphqlURL string       GraphQL URL to check
      --grpcPort uint16         gRPC port to check
      --httpClient string       Which HTTP client use to send requests: chrome, gohttp (default "gohttp")
      --idleConnTimeout int     The maximum amount of time a keep-alive connection will live (gohttp only) (default 2)
      --ignoreUnresolved        If true, unresolved test cases will be considered as bypassed (affect score and results)
      --includePayloads         If true, payloads will be included in HTML/PDF report
      --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 (gohttp only) (default 2)
      --maxRedirects int        The maximum number of handling redirects (gohttp only) (default 50)
      --noEmailReport           Save report locally
      --nonBlockedAsPassed      If true, count requests that weren't blocked as passed. If false, requests that don't satisfy to PassStatusCodes/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
      --passStatusCodes 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 (gohttp only)
      --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)

GoTestWAF supports two HTTP clients for performing requests, selectable via the --httpClient option. The default client is the standard Golang HTTP client. The second option is Chrome, which can be used with the --httpClient=chrome CLI argument. Note that on Linux systems, you must add the --cap-add=SYS_ADMIN argument to the Docker arguments to run GoTestWAF with Chrome as the request performer.

Report name

With the reportName option you can set your own filename for GoTestWAF reports. This option supports golang's time package for timestamps. Details can be found there. You can use following placeholders to add timestamp to your report name:

  • Year: 2006, 06
  • Month: Jan, January
  • Textual day of the week: Mon, Monday
  • Numeric day of the month: 2, _2, 02
  • Numeric day of the year: __2, 002
  • Hour: 15, 3, 03 (PM or AM)
  • Minute: 4, 04
  • Second: 5, 05
  • AM/PM mark: PM
  • Numeric zones: Z0700 = Z or ±hhmm, Z07:00 = Z or ±hh:mm, Z07 = Z or ±hh

For example, default reportName is waf-evaluation-report-2006-January-02-15-04-05, where 2006 will be replaced with actual year, January - month, 02 - day, 15 - hour, 04 - minute and 05 - second.

Scan based on OpenAPI file

For better scanning, GTW supports sending malicious vectors through valid application requests. Instead of constructing requests that are simple in structure and send them to the URL specified at startup, GoTestWAF creates valid requests based on the application's API description in the OpenAPI 3.0 format.

How it works:

  1. GoTestWAF loads an OpenAPI file and constructs request templates. All templates are then divided into groups based on what placeholders they support (e.g., if there is a string parameter in the request path, then such a request will be assigned to a group of requests that support URLPath placeholder)

  2. The next malicious vector is selected from the queue for sending. Based on the placeholder specified for it, all query templates are selected into which this vector can be substituted. Next, the vector is substituted into template and the request is sent.

  3. Based on the possible responses specified in the OpenAPI file, it is determined whether the request was blocked by WAF or passed to the application. If the status of the response code and its scheme match those described in the OpenAPI file, the request is marked as bypassed. Otherwise, it will be marked as blocked. It is possible that the application only responds with a status code, and this status code matches the response from the WAF. In this case, the request will be marked as unresolved.

Some supported OpenAPI features:

  • numeric and string parameters in headers, paths, query parameters and body of requests;

  • the following content-types are supported for the request body: application/json, application/xml, application/x-www-form-urlencoded, text/plain;

  • the following modifiers are supported for XML: name, wrapped, attribute, prefix, namespace;

  • length limits for strings are supported through the minLength and maxLength parameters;

  • value restrictions for numbers are supported through minimum, maximum, exclusiveMinimum and exclusiveMaximum;

  • restrictions on the length of arrays through minItems and maxItems are supported;

  • combination of schemes via oneOf, anyOf, allOf is supported.

Based on the described principle of operation, it is extremely important that the OpenAPI file correctly represents the implemented application API. Therefore, for example, you cannot use default to describe possible responses to queries.

Note: You need to forward volume with openapi spec to GoTestWAF container.

-v ${PWD}/api.yaml:/app/api.yaml

Complete Docker Example:

docker run --rm --network="host" -it -v ${PWD}/reports:/app/reports -v ${PWD}/api.yaml:/app/api.yaml wallarm/gotestwaf --wafName your_waf_name --url=https://example.com/v1 --openapiFile api.yaml

Running with OWASP Core Rule Set regression testing suite

GoTestWAF allows easy integration of additional test suites.

In this example, we will demonstrate how to add tests from the OWASP Core Rule Set regression testing suite.

Since the tests are written in a different format than the GoTestWAF format, a conversion is required. For this purpose, the script misc/modsec_regression_testset_converter.rb is provided.

To convert the tests, run make modsec_crs_regression_tests_convert. Then, build a container with the updated set of tests. make gotestwaf

Note that by default, tests are converted for only a subset of rules. The following categories have been chosen:

  • REQUEST-932-APPLICATION-ATTACK-RCE
  • REQUEST-933-APPLICATION-ATTACK-PHP
  • REQUEST-941-APPLICATION-ATTACK-XSS
  • REQUEST-930-APPLICATION-ATTACK-LFI
  • REQUEST-931-APPLICATION-ATTACK-RFI
  • REQUEST-942-APPLICATION-ATTACK-SQLI
  • REQUEST-944-APPLICATION-ATTACK-JAVA
  • REQUEST-934-APPLICATION-ATTACK-GENERIC
  • REQUEST-913-SCANNER-DETECTION

If needed, modify the variable "crs_testcases" in misc/modsec_regression_testset_converter.rb to add or remove test categories.

gotestwaf's People

Contributors

0x566164696d avatar afr1ka avatar anastasiatww avatar antoineblaud avatar arnovandash avatar brandonshope avatar d0znpp avatar d1nko avatar dankegel avatar dnkolegov avatar hi-unc1e avatar jgrmnprz avatar keisari-ch avatar manmolecular avatar mendhak avatar nedvna avatar no-github avatar semenchenkoa avatar smziaurrashid avatar svkirillov avatar vinglogn avatar vulners avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

gotestwaf's Issues

Tool is not working on the new Mac Chips

Digest: sha256:d1d7bcfccfde963af096bb57690b95120f076beb08c00336a21f001390cce2c8
Status: Downloaded newer image for wallarm/gotestwaf:latest
WARNING: The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested

Hardware informations:

Model Name: MacBook Pro
Model Identifier: MacBookPro18,2
Chip: Apple M1 Max
Total Number of Cores: 10 (8 performance and 2 efficiency)
Memory: 64 GB

couldn't export full report to HTML - Go Version and Docker Version

Good Morning everyone,

version = main branch

in tests of waf attached to an api gateway. gotestwaf cannot write HTML Report to filesystem.

I test the following commands with

go run ./cmd --addHeader "Authorization: Basic AUTHTOKEN" --url=https://URL/ --openapiFile=/home/oru/openapi_2.yaml

docker run -v /home/oru:/app/reports -v /home/oru/openapi_2.yaml:/app/openapi.yaml --network="host" wallarm/gotestwaf --addHeader "Authorization: Basic AUTHTOKEN" --url=https://URL/ --openapiFile=openapi.yaml

ERRO[0165] caught error in main function error="couldn't export full report: couldn't render HTML report to PDF: couldn't find Chrome/Chromium to render HTML file to PDF: chrome not found" exit status 1

time="2022-09-05T09:53:16Z" level=error msg="caught error in main function" error="couldn't export full report: couldn't export report to HTML: couldn't execute template: template: report:756:41: executing "report" at : wrong number of args for StringsSplit: want 2 got 1"

without the parameter " --addHeader " the report can be normal created

Has someone else the problem or is this maybe local problem ?

Thanks and best regards Oliver

Go package

Just a question, please.

Running GoTestWAF in any capacity, for instance in Docker or just a plain instance of Kali requires the Go package, is that correct?

No way to tune MaxIdleConnsPerHost

https://go.dev/src/net/http/transport.go says

// DefaultMaxIdleConnsPerHost is the default value of Transport's
// MaxIdleConnsPerHost.
const DefaultMaxIdleConnsPerHost = 2

Tuning just MaxIdleConns isn't enough; you also need to be able to tune MaxIdleConnsPerHost.
Otherwise your effective connection pool isn't the size you thought it was!

Fortunately, setting them to the same value is close enough to right, so it's probably overkill to change the UI.

change PDF report file access rights to a+r

the tool generates two different reports with different access rights. PDF file should be also readable for all

-rw-r--r--  1 root   root      4790 Dec  8 18:09 waf-evaluation-payloads-generic-2021-December-09-02-09-03.csv
-rw-------  1 root   root   1257039 Dec  8 18:09 waf-evaluation-report-generic-2021-December-09-02-09-03.pdf

test case not completing waiting at last test

main.go:173: main: interrupt : scan canceled
GOTESTWAF : 2022/02/02 13:31:50.263639 scanner.go:291: http sending: sending http request: Post "http://localhost:4300": context canceled
GOTESTWAF : 2022/02/02 13:31:50.263741 scanner.go:201: Scanning Time: 348ns
GOTESTWAF : 2022/02/02 13:31:50.263772 scanner.go:201: Scanning finished
GOTESTWAF : 2022/02/02 13:31:50.263800 main.go:46: main error: run scanning: context canceled

waited for 30 min but nothing happend
image
server is simple express server

const express = require('express');
const app = express();
const port = 4300;

app.get("/", (req, res) => {
console.log("In Get Req");
console.log("Header " + JSON.stringify(req.headers));
console.log("Body " + JSON.stringify(req.body));

res.status(200).send("Hello");

})
app.post("/", (req, res) => {
console.log("In Post Req");
console.log("Header " + JSON.stringify(req.headers));
console.log("Body " + JSON.stringify(req.body));
res.status(200).send()
})

app.listen(port, () => {
console.log("Server Started on Port: " + port);
})

With NAP (nginx App Protect) got "WAF was not detected"

Hello

When I make a test with docker or binaries the WAF is not detected:
docker run --network="host" -v /tmp:/tmp/report wallarm/gotestwaf --url=http://localhost:8080
or
./gotestwaf --url=http://localhost:8080
I got the same result:

GOTESTWAF : 2021/04/14 16:12:42.738727 main.go:61: Test cases loading started
GOTESTWAF : 2021/04/14 16:12:42.741591 main.go:68: Test cases loading finished
GOTESTWAF : 2021/04/14 16:12:42.741650 main.go:74: Scanned URL: http://localhost:8080
GOTESTWAF : 2021/04/14 16:12:42.746837 main.go:42: main error: WAF was not detected. Please use the '--blockStatusCode' or '--blockRegex' flags. Use '--help' for additional info.
Baseline attack status code: 200

From the WAF point of view, I saw the attacks:

Apr 14 16:12:42  NAP[597]: #000attack_type="Non-browser Client,Abuse of Functionality,SQL-Injection,Cross Site Scripting (XSS)",blocking_exception_reason="N/A",date_time="2021-04-14 16:12:42",dest_port="8080",ip_client="172.28.0.1",is_truncated="false",method="GET",policy_name="policy_name",protocol="HTTP",request_status="blocked",response_code="0",severity="Critical",sig_cves="N/A",sig_ids="200001475,200000098,200001088,200101609,200002550,200000073,200002736",sig_names="XSS script tag end (Parameter) (2),XSS script tag (Parameter),alert() (Parameter)...",sig_set_names="{Cross Site Scripting Signatures;High Accuracy Signatures},{Cross Site Scripting Signatures;High Accuracy Signatures},{Cross Site Scripting Signatures}...",src_port="58346",sub_violations="N/A",support_id="8044859148369198398",threat_campaign_names="N/A",unit_hostname="cb40cdd8d538",uri="/",violation_rating="5",vs_name="22-app.example.com:1-/",x_forwarded_for_header_value="N/A",outcome="REJECTED",outcome_reason="SECURITY_WAF_VIOLATION",violations="Illegal meta character in value,Attack signature detected,Violation Rating Threat detected",violation_details="<?xml version='1.0' encoding='UTF-8'?><BAD_MSG><violation_masks><block>10000000200c00-3030430000070</block><alarm>477f0ffcbbd0fea-8003f35cb000007c</alarm><learn>0-0</learn><staging>0-0</staging></violation_masks><request-violations><violation><viol_index>42</viol_index><viol_name>VIOL_ATTACK_SIGNATURE</viol_name><context>parameter</context><parameter_data><value_error/><enforcement_level>global</enforcement_level><name>NTU3ODE5Y2U4Mw==</name><auto_detected_type>alpha-numeric</auto_detected_type><value>PHNjcmlwdD5hbGVydCgndW5pb24gc2VsZWN0IHBhc3N3b3JkIGZyb20gdXNlcnMnKTwvc2NyaXB0Pg==</value><param_name_pattern>*</param_name_pattern><staging>0</staging></parameter_data><staging>0</staging><sig_data><sig_id>200001475</sig_id><blocking_mask>3</blocking_mask><kw_data><buffer>NTU3ODE5Y2U4Mz08c2NyaXB0PmFsZXJ0KCd1bmlvbiBzZWxlY3QgcGFzc3dvcmQgZnJvbSB1c2VycycpPC9z</buffer><offset>12</offset><length>7</length></kw_data></sig_data><sig_data><sig_id>200000098</sig_id><blocking_mask>3</blocking_mask><kw_data><buffer>NTU3ODE5Y2U4Mz08c2NyaXB0PmFsZXJ0KCd1bmlvbiBzZWxlY3QgcGFzc3dvcmQgZnJvbSB1c2VycycpPC9z</buffer><offset>11</offset><length>7</length></kw_data></sig_data><sig_data><sig_id>200001088</sig_id><blocking_mask>2</blocking_mask><kw_data><buffer>NTU3ODE5Y2U4Mz08c2NyaXB0PmFsZXJ0KCd1bmlvbiBzZWxlY3QgcGFzc3dvcmQgZnJvbSB1c2VycycpPC9z</buffer><offset>19</offset><length>6</length></kw_data></sig_data><sig_data><sig_id>200101609</sig_id><blocking_mask>3</blocking_mask><kw_data><buffer>OWNlODM9PHNjcmlwdD5hbGVydCh1bmlvbnNlbGVjdHBhc3N3b3JkZnJvbXVzZXJzKTwvc2NyaXB0Pg==</buffer><offset>6</offset><length>52</length></kw_data></sig_data><sig_data><sig_id>200002550</sig_id><blocking_mask>2</blocking_mask><kw_data><buffer>NTU3ODE5Y2U4Mz08c2NyaXB0PmFsZXJ0KCd1bmlvbiBzZWxlY3QgcGFzc3dvcmQgZnJvbSB1c2VycycpPC9z</buffer><offset>25</offset><length>6</length></kw_data></sig_data><sig_data><sig_id>200000073</sig_id><blocking_mask>2</blocking_mask><kw_data><buffer>NTU3ODE5Y2U4Mz08c2NyaXB0PmFsZXJ0KCd1bmlvbiBzZWxlY3QgcGFzc3dvcmQgZnJvbSB1c2VycycpPC9z</buffer><offset>26</offset><length>33</length></kw_data></sig_data><sig_data><sig_id>200002736</sig_id><blocking_mask>2</blocking_mask><kw_data><buffer>NTU3ODE5Y2U4Mz08c2NyaXB0PmFsZXJ0KCd1bmlvbiBzZWxlY3QgcGFzc3dvcmQgZnJvbSB1c2VycycpPC9z</buffer><offset>25</offset><length>13</length></kw_data></sig_data><sig_data><sig_id>200001475</sig_id><blocking_mask>3</blocking_mask><kw_data><buffer>NTU3ODE5Y2U4Mz08c2NyaXB0PmFsZXJ0KHVuaW9uIHNlbGVjdCBwYXNzd29yZCBmcm9tIHVzZXJzKTwvc2Ny</buffer><offset>12</offset><length>7</length></kw_data></sig_data><sig_data><sig_id>200000098</sig_id><blocking_mask>3</blocking_mask><kw_data><buffer>NTU3ODE5Y2U4Mz08c2NyaXB0PmFsZXJ0KHVuaW9uIHNlbGVjdCBwYXNzd29yZCBmcm9tIHVzZXJzKTwvc2Ny</buffer><offset>11</offset><length>7</length></kw_data></sig_data><sig_data><sig_id>200001088</sig_id><blocking_mask>2</blocking_mask><kw_data><buffer>NTU3ODE5Y2U4Mz08c2NyaXB0PmFsZXJ0KHVuaW9uIHNlbGVjdCBwYXNzd29yZCBmcm9tIHVzZXJzKTwvc2Ny</buffer><offset>19</offset><length>6</length></kw_data></sig_data><sig_data><sig_id>200000073</sig_id><blocking_mask>2</blocking_mask><kw_data><buffer>NTU3ODE5Y2U4Mz08c2NyaXB0PmFsZXJ0KHVuaW9uIHNlbGVjdCBwYXNzd29yZCBmcm9tIHVzZXJzKTwvc2Ny</buffer><offset>25</offset><length>33</length></kw_data></sig_data></violation><violation><viol_index>24</viol_index><viol_name>VIOL_PARAMETER_VALUE_METACHAR</viol_name><parameter_data><value_error/><enforcement_level>global</enforcement_level><name>NTU3ODE5Y2U4Mw==</name><auto_detected_type>alpha-numeric</auto_detected_type><value>PHNjcmlwdD5hbGVydCgndW5pb24gc2VsZWN0IHBhc3N3b3JkIGZyb20gdXNlcnMnKTwvc2NyaXB0Pg==</value></parameter_data><wildcard_entity>*</wildcard_entity><staging>0</staging><language_type>4</language_type><metachar_index>60</metachar_index><metachar_index>62</metachar_index><metachar_index>39</metachar_index></violation></request-violations></BAD_MSG>",bot_signature_name="N/A",bot_category="N/A",bot_anomalies="N/A",enforced_bot_anomalies="N/A",client_class="N/A",request="GET /?557819ce83=%3Cscript%3Ealert%28%27union+select+password+from+users%27%29%3C%2Fscript%3E HTTP/1.1\r\nHost: localhost:8080\r\nUser-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.102 Safari/537.36\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9\r\nAccept-Encoding: gzip, deflate\r\nAccept-Language: en-US,en;q=0.9\r\nCache-Control: no-cache\r\nConnection: close\r\nPragma: no-cache\r\nSec-Fetch-Dest: document\r\nSec-Fetch-Mode: navigate\r\nSec-Fetch-Site: none\r\nSec-Fetch-User: ?1\r\nUpgrade-Insecure-Requests: 1\r\n\r\n"#000

Is there a way to make it work?
Thks for yr help!

Missing content-type on parts of multipart requests?

internal/payload/placeholder/htmlmultipartform.go doesn't know the content type of the bytes it is stuffing into the form,
so when the URL encoder is in use, it can't set the content byte to application/x-www-form-urlencoded, and the web server being probed won't url decode the bytes.

Is this intentional? i.e. is gotestwaf targeting vulnerabilities where applications (perhaps unwisely) do their own additional urldecoding of the payload handed to it by the web server?

If this is a bug, it may be fixable by copying the source for the convenience function CreateFormField() and setting a content type as CreateFormFile does.

Command failed Docker

Any idea why this fails? what am I doing wrong?

root@localhost:# /usr/local/emhttp/plugins/dynamix.docker.manager/scripts/docker run -d --name='GoTestWAF' --net='host' --cpuset-cpus='8,9,10,11,20,21,22,23' -e TZ="Europe/Paris" -e HOST_OS="Unraid" -v '/mnt/user/Docker/GoTestWAF':'/app/reports':'rw' --url=https://www.myurl.com/ --verbose 'wallarm/gotestwaf'

unknown flag: --url
See 'docker run --help'.

The command failed.

Error when trying to generate Go module

Hey, tried to build the go module, however, I am getting the following error:

git clone https://github.com/wallarm/gotestwaf.git
cd gotestwaf
gotestwaf> go build -mod vendor -o gotestwaf ./cmd/main.go

# command-line-arguments
cmd\main.go:47:15: undefined: parseFlags
cmd\main.go:52:5: undefined: quiet
cmd\main.go:55:18: undefined: logLevel
cmd\main.go:57:5: undefined: logFormat
cmd\main.go:57:18: undefined: jsonLogFormat
cmd\main.go:61:14: undefined: loadConfig
cmd\main.go:162:103: undefined: logFormat

openapiFile - no such file or directory

Good morning erveryone,

thanks for the good waf testing tools. In preparation to test waf with API Gateway on AWS i want to load a prepared openAPI Definition in version openAPI 3.0.0.

In testcase i run the docker container with follow command to add the openapi file to the docker container testing. Based on that with full qualified folder information or with relative path i get the error message no such file or directory.

docker run -v /home/oru/:/app/reports --network="host" wallarm/gotestwaf --url=https://url/api/v1/ --openapiFile=openapidefinition.yaml

Does anyone has an idea to this topic ? Best regards and thanks for support.
Oliver

JSON export beside HTML/PDF report

Is there a possibilities to get results in a JSON file beside ready-to-go HTML/PDF report ?

Is it a possible feature, or already in the roadmap ?
I would like to implement the result of the tool with other tools :)

add flag to skip WAF validation

It would be great to have a flag that removes the WAF validation so we can continue with the tests even if no WAF is present. This will allow us to have a report of vulnerabilities and attacks performed on a target and support the use for a WAF solution.

Alex

Add support for Windows

Hi,
Really love the tool.
Is it possible to provide a support for Windows OS as well?

While using Windows, I changed the line:

parts := strings.Split(testcaseFile, "/")

to

parts := strings.Split(testcaseFile, "\\")

Can you please make it support Linux/Windows simultaneously?

parts := strings.Split(testcaseFile, "/")

Adding folder and creating custom test cases

I created a folder under testcases and added my custom.yml file. Using the docker run command with --testSet produces an error.

GOTESTWAF : 2022/03/22 17:00:57.943406 main.go:46: main error: loading test case: no tests were selected

I have tried various methods to get a custom test case to run with no success.

Is there documentation for adding custom test cases to the tool?

Command with errors:
docker run -v ${PWD}/reports:/app/reports wallarm/gotestwaf --url=http://192.168.1.4 --testSet custom-urls --verbose

Command that works:
docker run -v ${PWD}/reports:/app/reports wallarm/gotestwaf --url=http://192.168.1.4 --testSet community --verbose

The tool will read in the yml files from the community folder. It will not read in custom.yml from my folder custom-urls.

Thanks!

Quits without any output

I've tried running this via all the docker methods, including pulling the repo and building the image from scratch. Does not log any output, doesn't work, doesn't put anything in reports directory... not sure what else I can do since the self-contained Docker solution isn't working.

WAF blockRegex Functionality

Not entirely sure what is happening, but could any anybody explain how to format the regex so that they match something returned by the WAF, for example awselb/2.0 header

When i try:
docker run -v ${PWD}/reports:/app/reports --network="host" wallarm/gotestwaf --followCookies --maxIdleConns 1 --proxy http://127.0.0.1:8080 --testCase xss-scripting --addHeader "X-Request-Identifier: SomeName" --blockRegex awselb/2.0 --url <https-url-here> --verbose
GOTESTWAF : 2021/12/17 14:03:08.885123 main.go:61: GoTestWAF unknown
GOTESTWAF : 2021/12/17 14:03:08.886578 main.go:71: Test cases loading started
GOTESTWAF : 2021/12/17 14:03:08.888345 main.go:78: Test cases loading finished
GOTESTWAF : 2021/12/17 14:03:08.888415 main.go:91: gRPC pre-check: IN PROGRESS
GOTESTWAF : 2021/12/17 14:03:09.078516 main.go:101: gRPC pre-check: GRPC IS NOT AVAILABLE
GOTESTWAF : 2021/12/17 14:03:09.078564 main.go:106: Scanned URL: <https-url-here>
GOTESTWAF : 2021/12/17 14:03:09.440094 main.go:46: main error: WAF was not detected. Please use the '--blockStatusCode' or '--blockRegex' flags. Use '--help' for additional info.
Baseline attack status code: 403

it exits instantly, but when I remove the --blockRegex it runs fine

Not sure what is going on but the regex feature would be very helpful as the WAF responds with multiple different status codes when it blocks requests, not just one, and some don't match the 'block' status code

gotestwaf error message "WAF was not detected.

I'm trying to use GoTestWAF with "go" but the test is returning the below error message. please how do i fix this and able to test my WAF?

INFO[0000] Try to identify WAF solution                 
INFO[0000] WAF was not identified                       
INFO[0000] WAF pre-check                                 url="url-of-load-balancer"
ERRO[0000] caught error in main function                 error="WAF was not detected. Please use the '--blockStatusCode' or '--blockRegex' flags. Use '--help' for additional info. Baseline attack status code: 503"

[discuss] Is there a fair way to test waf?

Hi :
I'm thinking gotestwaf is forced on test method (such as placeholder/encoders) and the test case is little.
The waf provider can add rules for then. And it is not fair for other waf who didn't know this project.
If all waf provider know the test case. all waf get reject rate 100%.
Do you think is there a fair way to test waf and give it an grade?
Thanks!

Caught error in main function

Getting This error when trying to test WAF from one of the WAF Providers

level=error msg="caught error in main function" error="couldn't detect: couldn't identify WAF: failed to sent request:
Any ideas what could be the reason??
This works fine for some other domains hosted behind same WAF Provider.

docker run -v $Users:/app/reports --network="host"
wallarm/gotestwaf --url=https://abc.xyz.com/ --blockStatusCode 200
time="2022-11-22T16:10:04Z" level=info msg="GoTestWAF started" version=unknown
time="2022-11-22T16:10:04Z" level=info msg="Test cases loading started"
time="2022-11-22T16:10:04Z" level=info msg="Test cases loading finished"
time="2022-11-22T16:10:04Z" level=info msg="Test cases fingerprint" fp=ba6e4eb2ac65ba17afa18b04d62af8b9
time="2022-11-22T16:10:04Z" level=info msg="Try to identify WAF solution"
time="2022-11-22T16:10:09Z" level=error msg="caught error in main function" error="couldn't detect: couldn't identify WAF: failed to sent request: Get "https://abc.xyz.com?a=%3Cscript%3Ealert%28%22XSS%22%29%3B%3C%2Fscript%3E&b=UNION+SELECT+ALL+FROM+information_schema+AND+%27+or+SLEEP%285%29+or+%27&c=..%2F..%2F..%2F..%2Fetc%2Fpasswd&d=%2Fbin%2Fcat+%2Fetc%2Fpasswd%3B+ping+127.0.0.1%3B+curl+google.com&e=%3C%21ENTITY+xxe+SYSTEM+%22file%3A%2F%2F%2Fetc%2Fshadow%22%3E%5D%3E%3Cpwn%3E%26hack%3B%3C%2Fpwn%3E\": dial tcp: lookup abc.xyz.com: Try again"

I take a tcpdump on my machine outbound port but i don't even see any request going out!!

zsh: parse error near `\n'

Unable to execute the command getting below error while executing in Kali Linux
zsh: parse error near `\n'

Certificate Error when using BurpSuite as proxy

Hey,

I am trying to run GoTestWaF with go run against a site. Whenever I try to set Burpsuite as my proxy with the --proxy option, it sends back:

main.go44: main error: running pre-check: sending http request: Get "https://thesite.com?blablaiamtestingjiji": x509: certificate signed by unknown authority.
exit status 1

Any help on how to skip the verification of the certificate?

Cheers

Nginx + ModSecurity

Hello I was using GoTestWaf to test Nginx + ModSecurity with Paranoia Level 3 and I am getting a lot of True Positives

image

WAF score

Add overall score (WAF score) to console output.

Scan report issue with false-pos

After a scan has successfully executed, I get the output below. As you can see, the false-pos Test Set was included but the fact that those test cases were not blocked has lowered the efficacy score of my WAF target from 100% to 94.74%. I have confirmed that the false-positive test cases were NOT blocked by my WAF therefore the BYPASS is correct, however it should be considered a success for this particular Test Set.

Command I ran is: sudo docker run -v tmp:/tmp/gotestwaf gotestwaf --url=http://www.MYDOMAIN.com/ --verbose --passRegex 'OWASP Juice Shop' --followCookies --maxIdleConns=1 --blockStatusCode 200

+-----------+-----------------+---------------+----------------+-----------------+
| TEST SET | TEST CASE | PERCENTAGE, % | PASSED/BLOCKED | FAILED/BYPASSED |
+-----------+-----------------+---------------+----------------+-----------------+
| community | community-lfi | 100.00 | 6 | 0 |
| community | community-rce | 100.00 | 42 | 0 |
| community | community-sqli | 100.00 | 48 | 0 |
| community | community-xss | 100.00 | 304 | 0 |
| community | community-xxe | 100.00 | 4 | 0 |
| false-pos | texts | 0.00 | 0 | 8 |
| owasp | ldap-injection | 100.00 | 8 | 0 |
| owasp | mail-injection | 100.00 | 12 | 0 |
| owasp | nosql-injection | 100.00 | 24 | 0 |
| owasp | path-traversal | 100.00 | 24 | 0 |
| owasp | shell-injection | 100.00 | 8 | 0 |
| owasp | sql-injection | 100.00 | 32 | 0 |
| owasp | ss-include | 100.00 | 20 | 0 |
| owasp | sst-injection | 100.00 | 20 | 0 |
| owasp | xml-injection | 100.00 | 12 | 0 |
| owasp | xss-scripting | 100.00 | 28 | 0 |
| owasp-api | graphql | 100.00 | 1 | 0 |
| owasp-api | rest | 100.00 | 2 | 0 |
| owasp-api | soap | 100.00 | 2 | 0 |
+-----------+-----------------+---------------+----------------+-----------------+
| WAF SCORE: | 94.74% |
+-----------+-----------------+---------------+----------------+-----------------+

Ask: Can we add logic to the report to consider bypass a success for anything in the false positive category?

Adding statistics

Is it possible to get a statistic which how many requests were passed for each encoder/placeholder?
Thanks

panic: runtime error: slice bounds out of range [-2:] on macOS 13.0

INFO[0000] GoTestWAF started version=unknown
INFO[0000] Test cases loading started
panic: runtime error: slice bounds out of range [-2:]

goroutine 1 [running]:
github.com/wallarm/gotestwaf/internal/db.LoadTestCases(0xc0000a8680)
/Users/davidkrohn/Downloads/gotestwaf-master/internal/db/load.go:36 +0x708
main.run({0x183e958, 0xc00013cc40}, 0xc00053bb20)
/Users/davidkrohn/Downloads/gotestwaf-master/cmd/main.go:91 +0x345
main.main()
/Users/davidkrohn/Downloads/gotestwaf-master/cmd/main.go:42 +0x20d

Rendering of PDF report fails

Hi,

I'm using the Docker image on a M1 Mac to run the tests. The command line report generate fine, but the PDF does not.

The command I'm running:

docker run -v reports:/app/reports wallarm/gotestwaf --url=https://

The error:

time="2022-08-10T13:53:37Z" level=error msg="caught error in main function" error="couldn't export full report: couldn't render HTML report to PDF: signal: trace/breakpoint trap"

AWS WAF (Web ACL): "WAF was not detected"

I have a web app setup through AWS CloudFront + S3 + WAF.

When I run the command to test against the target:

sudo docker run -v ${PWD}/reports:/app/reports wallarm/gotestwaf --url=https://waf-protected-url.example

I get the following error output:

GOTESTWAF : 2021/10/29 19:32:09.692105 main.go:60: GoTestWAF unknown
GOTESTWAF : 2021/10/29 19:32:09.692670 main.go:70: Test cases loading started
GOTESTWAF : 2021/10/29 19:32:09.694009 main.go:77: Test cases loading finished
GOTESTWAF : 2021/10/29 19:32:09.694023 main.go:90: gRPC pre-check: IN PROGRESS
GOTESTWAF : 2021/10/29 19:32:12.695429 main.go:94: gRPC pre-check: connection is not available, reason: sending gRPC request: context deadline exceeded
GOTESTWAF : 2021/10/29 19:32:12.695483 main.go:104: Scanned URL: https://waf-protected-url.example
GOTESTWAF : 2021/10/29 19:32:13.244458 main.go:45: main error: WAF was not detected. Please use the '--blockStatusCode' or '--blockRegex' flags. Use '--help' for additional info.

Adding --blockStatusCode or --blockRegex does not change the output for me.


When I access the Web ACL dashboard, I can see the requests fired by gotestwaf are being captured and blocked.

Any insight into the issue would be very helpful.
Thank you!

For attack requests handle the broken TCP connections like the WAF has blocked the requests

An example of relevant site:

$ docker run gotestwaf --url https://www.ksl.com
GOTESTWAF : 2021/05/25 02:13:53.954364 main.go:61: Test cases loading started
GOTESTWAF : 2021/05/25 02:13:53.959131 main.go:68: Test cases loading finished
GOTESTWAF : 2021/05/25 02:13:53.959178 main.go:78: Scanned URL: https://www.ksl.com
GOTESTWAF : 2021/05/25 02:13:54.273750 main.go:42: main error: running pre-check: sending http request: Get https://www.ksl.com/?7aae3edb92=%3Cscript%3Ealert%28%27union+select+password+from+users%27%29%3C%2Fscript%3E: EOF
$

--nonBlockedAsPassed incorrectly counts 404s on positive tests as blocked?

If you run gotestwaf on a dummy web server that returns OK to every request, it should get zero false positives. This works, of course.

As I understand it, --nonBlockedAsPassed is a convenience; it lets you set up a waf in front of a dummy
server without bothering to make the dummy server actually return OK for every request.

But when I tried the option, it said that all the positive tests had failed; evidently -nonBlockedAsPassed treats 404s as false positives.

It seems the logic in internal/db/statistics.go related to nonBlockedAsPassed does the wrong thing in the isPositive case....?

Error message : "panic: assignment to entry in nil map"

Hi,

I have a "panic: assignment to entry in nil map" error message in the last gotestwaf versions.

This seems to be related to an uninitialized map, however I'm not a go expert and I don't know if my fix has a side effect on the grpc tests that I don't use, so I'll let you check.

I fixed it by initializing counters["api"] in ligne 151 in the report/chart.go file :

if !s.IsGrpcAvailable {
// gRPC is part of the API Security tests
counters["api"] = make(map[string]pair)
counters["api"]["grpc"] = pair{}
}

Unable to send report to email

Hello I'm wondering why the report is unable to be sent to my email. any help will be appreciated.thanks

ERRO[0500] caught error in main function                 error="couldn't send report by email: couldn't marshal report data into JSON format: json: unsupported value: NaN"

[Feature Request] Ability to add a unique identifier for each test case

We're currently using this tool to test the effectiveness of our WAF and have run into an issue when trying to compare our logs against each other between configuration changes. Since we didn't enable (yet) the blocking mechanism on our WAF, we can't rely on the results from GoTestWAF however the WAF logs still indicates when it encounters suspicious requests.

Would it be possible to add an additional header or something containing a unique identifier (ex. a hash of the payload, placeholder, encoder and test case) for each test that can be used to map the results between the logs?

gotestwaf not working against a WAF using 302 Redirect as blocked page

Hi,

I used both the latest Docker image and latest source code today against a WAF that return a HTTP 302 Redirect when blocking an URL (probably NetScaler)

I tried to play around the options --maxRedirects 0 --blockStatusCode 302
but even with that, GTW was not able to count/recognize 302 responses as a block, so it proceeds to all the 1415 requests but at the end the reports it said 0 requests blockeds, althought there were few hundreds of 302 redirects that are related to a blocked request from the WAF.

I think the problem is that gotestwaf follow the redirection no matter what, and so the 302 response is never returned and compared

line 54 || internal/scanner/http_client.go

	redirectFunc = func(req *http.Request, via []*http.Request) error {
		if len(via) > cfg.MaxRedirects {
			return errors.New("max redirect number exceeded")
		}
		return nil
	}

should be replaced by something like that probably:

	redirectFunc = func(req *http.Request, via []*http.Request) error {
		return http.ErrUseLastResponse
	}

So the redirection is not followed and the 302 response is returned until the last control and compared with the provided --blockStatusCode parameter

Cheers ! :)

[Feature Request] Ability to specify a static report file name

Background

In TeamCity and Jenkins, there's the ability to present an HTML file as a custom report for a build/job.
To use this feature we'd simply specify the path and name of the HTML file and TC/J will display a custom report if that file is found.
But TeamCity's Build Reports feature requires a specific file name, it doesn't support wildcards! Unsure about Jenkins.

Currently GoTestWaf creates a report file with a dynamic name, such as waf-evaluation-report-generic-2022-April-04-16-54-19.html

Request

So it would be good if we could get a static report file name, so that TC/J can display these along with the builds.

Some kind of flag, such as --reportFileName which we pass a value to, and that value gets used in place of the generated file name(s).

eg, --reportFileName=gotestwaf_report.html results in reports/gotestwaf_report.html (or .csv or .pdf)

Current workaround

After running a test, use this command to rename the latest HTML file in the reports folder

ls -ltr reports/*.html | awk '{ field = $NF }; END{ print field }' | xargs -I '{}' mv '{}' reports/gotestwaf_report.html

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.