diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..cbffc8a --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,162 @@ +name: Build and Release + +on: + pull_request: + branches: main + push: + branches: main + tags: + - v* + workflow_dispatch: + release: + types: [published] + + +# Automatically cancel any previous workflow on new push. +concurrency: + group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }} + cancel-in-progress: true + + +jobs: + build: + strategy: + matrix: + # Include amd64 on all platforms. + goos: [windows, freebsd, openbsd, linux, dragonfly, darwin] + goarch: [amd64, 386] + exclude: + # Exclude i386 on darwin and dragonfly + # because they are not supported by go. + - goarch: 386 + goos: dragonfly + - goarch: 386 + goos: darwin + include: + # BEIGIN MacOS ARM64 + - goos: darwin + goarch: arm64 + # END MacOS ARM64 + # BEGIN Linux ARM 5 6 7 + - goos: linux + goarch: arm + goarm: 7 + - goos: linux + goarch: arm + goarm: 6 + - goos: linux + goarch: arm + goarm: 5 + # END Linux ARM 5 6 7 + # BEGIN Android ARM 8 + - goos: android + goarch: arm64 + # END Android ARM 8 + # Windows ARM 7 + - goos: windows + goarch: arm + goarm: 7 + # BEGIN Other architectures + # BEGIN riscv64 & ARM64 + - goos: linux + goarch: arm64 + - goos: linux + goarch: riscv64 + # END riscv64 & ARM64 + # BEGIN MIPS + - goos: linux + goarch: mips64 + - goos: linux + goarch: mips64le + - goos: linux + goarch: mipsle + - goos: linux + goarch: mipsle + gomips: -softfloat + - goos: linux + goarch: mips + - goos: linux + goarch: mips + gomips: -softfloat + # END MIPS + # BEGIN PPC + - goos: linux + goarch: ppc64 + - goos: linux + goarch: ppc64le + # END PPC + # BEGIN FreeBSD ARM + - goos: freebsd + goarch: arm64 + - goos: freebsd + goarch: arm + goarm: 7 + # END FreeBSD ARM + # BEGIN S390X + - goos: linux + goarch: s390x + # END S390X + # END Other architectures + # BEGIN OPENBSD ARM + - goos: openbsd + goarch: arm64 + - goos: openbsd + goarch: arm + goarm: 7 + # END OPENBSD ARM + fail-fast: false + + runs-on: ubuntu-latest + permissions: write-all + env: + GOOS: ${{ matrix.goos }} + GOARCH: ${{ matrix.goarch }} + GOARM: ${{ matrix.goarm }} + CGO_ENABLED: 0 + steps: + - name: Checkout codebase + uses: actions/checkout@v3 + + - name: Show workflow information + id: get_filename + run: | + export _NAME=$(jq ".[\"$GOOS-$GOARCH$GOARM$GOMIPS\"].friendlyName" -r < .github/build/friendly-filenames.json) + echo "GOOS: $GOOS, GOARCH: $GOARCH, GOARM: $GOARM, GOMIPS: $GOMIPS, RELEASE_NAME: $_NAME" + + - name: Set up Go + uses: actions/setup-go@v4 + with: + go-version: '^1.18' + cache: false + + - name: Build wafefficacy (any) + if: matrix.gomips != '-softfloat' + run: go build -o wafefficacy-${{ matrix.goos }}-${{ matrix.goarch }}${{ matrix.goarm }} + + - name: Build wafefficacy (mips softfloat) + if: matrix.gomips == '-softfloat' + run: GOMIPS=softfloat go build -o wafefficacy-${{ matrix.goos }}-${{ matrix.goarch }}${{ matrix.gomips }} + + - name: Rename Windows + if: matrix.goos == 'windows' + run: mv wafefficacy-${{ matrix.goos }}-${{ matrix.goarch }}${{ matrix.goarm }} wafefficacy-${{ matrix.goos }}-${{ matrix.goarch }}${{ matrix.goarm }}.exe + + - name: Build release zip + run: | + mkdir wafefficacy-release/ + mv -v ./wafefficacy-${{ matrix.goos }}-* wafefficacy-release/wafefficacy + cp -v LICENSE *.md run.sh score.py wafefficacy-release/ + cp -vr nuclei/ wafefficacy-release/nuclei/ + zip -r wafefficacy-${{ matrix.goos }}-${{ matrix.goarch }}${{ matrix.goarm }}${{ matrix.gomips }}.zip wafefficacy-release/ + + - name: Upload files to Artifacts + uses: actions/upload-artifact@v3 + with: + name: wafefficacy-${{ matrix.goos }}-${{ matrix.goarch }}${{ matrix.goarm }}${{ matrix.gomips }} + path: ./wafefficacy-*.zip + + - name: Release builds on tag + uses: softprops/action-gh-release@v1 + if: startsWith(github.ref, 'refs/tags/') + with: + files: ./wafefficacy-*.zip \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..16796c5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +reports/*.json +wafefficacy diff --git a/run.sh b/run.sh index 537162e..02a5fcb 100755 --- a/run.sh +++ b/run.sh @@ -1,5 +1,7 @@ #!/bin/bash +command -v nuclei >/dev/null 2>&1 || { echo >&2 "error: nuclei is required, but was not found."; exit 1; } + while getopts ht:b:c:i:k:o:p:r:w:v flag do case "${flag}" in diff --git a/score.py b/score.py index 55c0bc5..ee0b7dc 100644 --- a/score.py +++ b/score.py @@ -65,18 +65,27 @@ def score(self) -> None: print("False Positives", fp) sensitivity = tp / (tp + fn) specificity = tn / (tn + fp) + total = tp + fn + tn + fp balanced_accuracy = (sensitivity + specificity) / 2 efficacy_score = balanced_accuracy * 100 self.efficacy_scores[attack_type] = efficacy_score - print("Efficacy", self.percentage.format(efficacy_score)) + print("Efficacy", self.percentage.format(efficacy_score), "over", total, "tests.") + if (true_positives + false_negatives) == 0: + # avoid dividing by zero + false_negatives = 1 + if (true_negatives + false_positives) == 0: + # avoid dividing by zero + false_positives = 1 + print("------------- WAF Efficacy -------------" ) sensitivity = true_positives / (true_positives + false_negatives) specificity = true_negatives / (true_negatives + false_positives) balanced_accuracy = (sensitivity + specificity) / 2 efficacy_score = balanced_accuracy * 100 + total = true_positives + false_negatives + true_negatives + false_positives self.efficacy_scores['overall'] = efficacy_score - print(self.percentage.format(efficacy_score)) + print(self.percentage.format(efficacy_score), "over", total, "tests.") if self.outfile: with open(self.outfile, 'w') as fp: