mirror of
https://github.com/epi052/feroxbuster.git
synced 2026-05-23 04:51:13 -03:00
Compare commits
20 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
378d75964c | ||
|
|
ffdf871abe | ||
|
|
bedf4d3f8e | ||
|
|
7787c83e1e | ||
|
|
242b134a3d | ||
|
|
b4ceaef08d | ||
|
|
143d5710fc | ||
|
|
0efb0684b5 | ||
|
|
c7ed9c9899 | ||
|
|
510bad0473 | ||
|
|
23661d17c9 | ||
|
|
097d54f384 | ||
|
|
970ce73ac4 | ||
|
|
5bb42c4004 | ||
|
|
0732ee11ef | ||
|
|
47b4efdd1b | ||
|
|
e50e150fb9 | ||
|
|
84aef80cea | ||
|
|
9fe5bfd622 | ||
|
|
ddd04dac7f |
@@ -990,6 +990,63 @@
|
||||
"contributions": [
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "sebastiaanspeck",
|
||||
"name": "Sebastiaan Speck",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/12570668?v=4",
|
||||
"profile": "https://github.com/sebastiaanspeck",
|
||||
"contributions": [
|
||||
"bug",
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "OpenSourceKyle",
|
||||
"name": "OpenSourceKyle",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/173112933?v=4",
|
||||
"profile": "https://github.com/OpenSourceKyle",
|
||||
"contributions": [
|
||||
"doc",
|
||||
"bug"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "Antonio-R1",
|
||||
"name": "Antonio",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/54741970?v=4",
|
||||
"profile": "https://github.com/Antonio-R1",
|
||||
"contributions": [
|
||||
"code",
|
||||
"bug"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "redacean",
|
||||
"name": "Redacean",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/125687454?v=4",
|
||||
"profile": "https://github.com/redacean",
|
||||
"contributions": [
|
||||
"bug"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "ghsdpolley",
|
||||
"name": "ghsdpolley",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/19826831?v=4",
|
||||
"profile": "https://github.com/ghsdpolley",
|
||||
"contributions": [
|
||||
"bug"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "aldamd",
|
||||
"name": "Daniel Aldam",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/178115486?v=4",
|
||||
"profile": "https://github.com/aldamd",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
}
|
||||
],
|
||||
"contributorsPerLine": 7,
|
||||
|
||||
8
.github/pull_request_template.md
vendored
8
.github/pull_request_template.md
vendored
@@ -16,10 +16,10 @@ Long form explanations of most of the items below can be found in the [CONTRIBUT
|
||||
|
||||
## Documentation
|
||||
- [ ] New code is documented using [doc comments](https://doc.rust-lang.org/stable/rust-by-example/meta/doc.html)
|
||||
- [ ] Documentation about your PR is included in the `docs`, as needed. The docs live in a [separate repository](https://epi052.github.io/feroxbuster-docs/docs/). Update the appropriate pages at the links below.
|
||||
- [ ] update [example config file section](https://epi052.github.io/feroxbuster-docs/docs/configuration/ferox-config-toml/)
|
||||
- [ ] update [help output section](https://epi052.github.io/feroxbuster-docs/docs/configuration/command-line/)
|
||||
- [ ] add an [example](https://epi052.github.io/feroxbuster-docs/docs/examples/)
|
||||
- [ ] Documentation about your PR is included in the `docs`, as needed. The docs live in a [separate repository](https://epi052.github.io/feroxbuster-docs/). Update the appropriate pages at the links below.
|
||||
- [ ] update [example config file section](https://epi052.github.io/feroxbuster-docs/configuration/ferox-config-toml/)
|
||||
- [ ] update [help output section](https://epi052.github.io/feroxbuster-docs/configuration/command-line/)
|
||||
- [ ] add an [example](https://epi052.github.io/feroxbuster-docs/examples/auto-tune/)
|
||||
|
||||
## Additional Tests
|
||||
- [ ] New code is unit tested
|
||||
|
||||
310
.github/workflows/release.yml
vendored
310
.github/workflows/release.yml
vendored
@@ -1,310 +0,0 @@
|
||||
name: Release
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v*.*.*'
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
create-release:
|
||||
name: Create GitHub Release
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||
version: ${{ steps.get_version.outputs.version }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Get version from tag
|
||||
id: get_version
|
||||
run: echo "version=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Generate changelog
|
||||
id: changelog
|
||||
run: |
|
||||
# Get previous tag
|
||||
PREV_TAG=$(git describe --abbrev=0 --tags HEAD^ 2>/dev/null || echo "")
|
||||
|
||||
if [ -z "$PREV_TAG" ]; then
|
||||
# First release, get all commits
|
||||
CHANGELOG=$(git log --pretty=format:"- %s (%h)" --no-merges)
|
||||
else
|
||||
# Get commits since previous tag
|
||||
CHANGELOG=$(git log ${PREV_TAG}..HEAD --pretty=format:"- %s (%h)" --no-merges)
|
||||
fi
|
||||
|
||||
# Create changelog file
|
||||
{
|
||||
echo "## What's Changed"
|
||||
echo ""
|
||||
echo "$CHANGELOG"
|
||||
echo ""
|
||||
echo "**Full Changelog**: https://github.com/${{ github.repository }}/compare/${PREV_TAG}...${GITHUB_REF_NAME}"
|
||||
} > CHANGELOG.md
|
||||
|
||||
cat CHANGELOG.md
|
||||
|
||||
- name: Create Release
|
||||
id: create_release
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
body_path: CHANGELOG.md
|
||||
draft: false
|
||||
prerelease: false
|
||||
|
||||
download-and-upload-artifacts:
|
||||
name: Download & Upload Release Assets
|
||||
needs: create-release
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Get latest CD Pipeline run
|
||||
id: get_run
|
||||
run: |
|
||||
# Get the latest successful CD Pipeline run for main branch
|
||||
RUN_ID=$(gh run list --workflow="CD Pipeline" --branch=main --status=success --limit=1 --json databaseId --jq='.[0].databaseId')
|
||||
echo "run_id=$RUN_ID" >> $GITHUB_OUTPUT
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Download all artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
path: artifacts
|
||||
run-id: ${{ steps.get_run.outputs.run_id }}
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Display structure of downloaded files
|
||||
run: ls -R artifacts/
|
||||
|
||||
- name: Prepare release assets
|
||||
id: prepare
|
||||
run: |
|
||||
mkdir -p release-assets
|
||||
cd artifacts
|
||||
|
||||
# Process Linux x86_64 binary - create tar.gz
|
||||
if [ -d "x86_64-linux-feroxbuster" ]; then
|
||||
tar czf ../release-assets/x86_64-linux-feroxbuster.tar.gz -C x86_64-linux-feroxbuster feroxbuster
|
||||
fi
|
||||
|
||||
# Process Linux x86 binary - create tar.gz
|
||||
if [ -d "x86-linux-feroxbuster" ]; then
|
||||
tar czf ../release-assets/x86-linux-feroxbuster.tar.gz -C x86-linux-feroxbuster feroxbuster
|
||||
fi
|
||||
|
||||
# Process ARM binaries - create tar.gz
|
||||
if [ -d "armv7-linux-feroxbuster" ]; then
|
||||
tar czf ../release-assets/armv7-linux-feroxbuster.tar.gz -C armv7-linux-feroxbuster feroxbuster
|
||||
fi
|
||||
|
||||
if [ -d "aarch64-linux-feroxbuster" ]; then
|
||||
tar czf ../release-assets/aarch64-linux-feroxbuster.tar.gz -C aarch64-linux-feroxbuster feroxbuster
|
||||
fi
|
||||
|
||||
# Copy macOS tar.gz files (already compressed)
|
||||
if [ -f "x86_64-macos-feroxbuster.tar.gz/x86_64-macos-feroxbuster.tar.gz" ]; then
|
||||
cp x86_64-macos-feroxbuster.tar.gz/x86_64-macos-feroxbuster.tar.gz ../release-assets/
|
||||
fi
|
||||
|
||||
if [ -f "aarch64-macos-feroxbuster.tar.gz/aarch64-macos-feroxbuster.tar.gz" ]; then
|
||||
cp aarch64-macos-feroxbuster.tar.gz/aarch64-macos-feroxbuster.tar.gz ../release-assets/
|
||||
fi
|
||||
|
||||
# Copy Windows executables - create zip files
|
||||
if [ -d "x86_64-windows-feroxbuster.exe" ]; then
|
||||
cd x86_64-windows-feroxbuster.exe
|
||||
zip ../../release-assets/x86_64-windows-feroxbuster.zip feroxbuster.exe
|
||||
cd ..
|
||||
fi
|
||||
|
||||
if [ -d "x86-windows-feroxbuster.exe" ]; then
|
||||
cd x86-windows-feroxbuster.exe
|
||||
zip ../../release-assets/x86-windows-feroxbuster.zip feroxbuster.exe
|
||||
cd ..
|
||||
fi
|
||||
|
||||
# Copy .deb file
|
||||
if [ -d "feroxbuster_amd64.deb" ]; then
|
||||
cp feroxbuster_amd64.deb/*.deb ../release-assets/ || true
|
||||
fi
|
||||
|
||||
cd ..
|
||||
|
||||
# Generate SHA256 checksums
|
||||
cd release-assets
|
||||
sha256sum * > SHA256SUMS
|
||||
cat SHA256SUMS
|
||||
|
||||
# Extract specific hashes for homebrew
|
||||
LINUX_HASH=$(grep "x86_64-linux-feroxbuster.tar.gz" SHA256SUMS | awk '{print $1}')
|
||||
MACOS_X64_HASH=$(grep "x86_64-macos-feroxbuster.tar.gz" SHA256SUMS | awk '{print $1}')
|
||||
MACOS_ARM_HASH=$(grep "aarch64-macos-feroxbuster.tar.gz" SHA256SUMS | awk '{print $1}')
|
||||
|
||||
echo "linux_hash=$LINUX_HASH" >> $GITHUB_OUTPUT
|
||||
echo "macos_x64_hash=$MACOS_X64_HASH" >> $GITHUB_OUTPUT
|
||||
echo "macos_arm_hash=$MACOS_ARM_HASH" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Upload Release Assets
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
files: release-assets/*
|
||||
|
||||
publish-crates-io:
|
||||
name: Publish to crates.io
|
||||
needs: create-release
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Install Rust toolchain
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
|
||||
- name: Publish to crates.io
|
||||
env:
|
||||
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
|
||||
run: cargo publish
|
||||
|
||||
update-homebrew:
|
||||
name: Update Homebrew Taps
|
||||
needs: [create-release, download-and-upload-artifacts]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout TGotwig's homebrew-linux-feroxbuster
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: TGotwig/homebrew-linux-feroxbuster
|
||||
token: ${{ secrets.HOMEBREW_TAP_TOKEN }}
|
||||
path: homebrew-linux
|
||||
|
||||
- name: Update Linux formula
|
||||
run: |
|
||||
cd homebrew-linux
|
||||
VERSION="${{ needs.create-release.outputs.version }}"
|
||||
HASH="${{ needs.download-and-upload-artifacts.outputs.linux_hash }}"
|
||||
|
||||
# Update version and hash in formula
|
||||
sed -i "s|url \"https://github.com/epi052/feroxbuster/releases/download/v[^/]*/x86_64-linux-feroxbuster.tar.gz\"|url \"https://github.com/epi052/feroxbuster/releases/download/v${VERSION}/x86_64-linux-feroxbuster.tar.gz\"|g" feroxbuster.rb
|
||||
sed -i "s/sha256 \"[^\"]*\"/sha256 \"${HASH}\"/g" feroxbuster.rb
|
||||
|
||||
git config user.name "github-actions[bot]"
|
||||
git config user.email "github-actions[bot]@users.noreply.github.com"
|
||||
git add feroxbuster.rb
|
||||
git commit -m "Update feroxbuster to v${VERSION}" || echo "No changes to commit"
|
||||
git push
|
||||
|
||||
- name: Checkout feroxbuster main repo to get config
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
path: feroxbuster-src
|
||||
|
||||
- name: Check if config changed
|
||||
id: config_check
|
||||
run: |
|
||||
cd feroxbuster-src
|
||||
CONFIG_HASH=$(sha256sum ferox-config.toml.example | awk '{print $1}')
|
||||
echo "config_hash=$CONFIG_HASH" >> $GITHUB_OUTPUT
|
||||
|
||||
# Check if config changed since last tag
|
||||
PREV_TAG=$(git describe --abbrev=0 --tags HEAD^ 2>/dev/null || echo "")
|
||||
if [ -n "$PREV_TAG" ]; then
|
||||
if git diff ${PREV_TAG}..HEAD --quiet -- ferox-config.toml.example; then
|
||||
echo "config_changed=false" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "config_changed=true" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
else
|
||||
echo "config_changed=true" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
- name: Update config hash in homebrew if changed
|
||||
if: steps.config_check.outputs.config_changed == 'true'
|
||||
run: |
|
||||
cd homebrew-linux
|
||||
CONFIG_HASH="${{ steps.config_check.outputs.config_hash }}"
|
||||
|
||||
# Update config hash if it exists in formula
|
||||
if grep -q "ferox-config.toml.example" feroxbuster.rb; then
|
||||
sed -i "s/sha256 \"[^\"]*\" # ferox-config.toml.example/sha256 \"${CONFIG_HASH}\" # ferox-config.toml.example/g" feroxbuster.rb
|
||||
|
||||
git add feroxbuster.rb
|
||||
git commit -m "Update ferox-config.toml.example hash" || echo "No changes to commit"
|
||||
git push
|
||||
fi
|
||||
|
||||
publish-winget:
|
||||
name: Publish to Winget
|
||||
needs: [create-release, download-and-upload-artifacts]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: vedantmgoyal2009/winget-releaser@main
|
||||
with:
|
||||
identifier: epi052.feroxbuster
|
||||
installers-regex: '-windows-feroxbuster\.exe\.zip$'
|
||||
token: ${{ secrets.WINGET_TOKEN }}
|
||||
release-tag: v${{ needs.create-release.outputs.version }}
|
||||
|
||||
publish-snapcraft:
|
||||
name: Publish to Snapcraft
|
||||
needs: [create-release, download-and-upload-artifacts]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Publish to Snapcraft
|
||||
uses: snapcore/action-publish@v1
|
||||
env:
|
||||
SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.SNAPCRAFT_TOKEN }}
|
||||
with:
|
||||
snap: feroxbuster
|
||||
release: stable
|
||||
|
||||
manual-steps-reminder:
|
||||
name: Manual Steps Reminder
|
||||
needs: [create-release, download-and-upload-artifacts]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Create comment with manual steps
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
const version = '${{ needs.create-release.outputs.version }}';
|
||||
const linuxHash = '${{ needs.download-and-upload-artifacts.outputs.linux_hash }}';
|
||||
|
||||
const body = `## 🚀 Release v${version} Published!
|
||||
|
||||
### ✅ Automated Steps Completed
|
||||
- [x] GitHub Release created with changelog
|
||||
- [x] All artifacts uploaded with SHA256 checksums
|
||||
- [x] Published to crates.io
|
||||
- [x] Homebrew tap updated
|
||||
- [x] Winget package published
|
||||
- [x] Snapcraft published to stable
|
||||
|
||||
### 📋 Manual Steps Required
|
||||
|
||||
1. **Kali Linux**
|
||||
- Go to https://bugs.kali.org/login_page.php?return=%2Fmy_view_page.php
|
||||
- Request a tool update
|
||||
|
||||
3. **Announcement** (optional)
|
||||
- Tweet about the release if it's significant!
|
||||
|
||||
2. **Announcement** (optional)
|
||||
- Linux x86_64: \`${linuxHash}\`
|
||||
|
||||
See full checksums in release assets: SHA256SUMS
|
||||
`;
|
||||
|
||||
github.rest.issues.createComment({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: context.issue.number,
|
||||
body: body
|
||||
});
|
||||
21
.github/workflows/winget.yml
vendored
Normal file
21
.github/workflows/winget.yml
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
name: Publish to Winget
|
||||
on:
|
||||
release:
|
||||
types: [released]
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
tag_name:
|
||||
description: 'Tag name of release'
|
||||
required: true
|
||||
type: string
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: vedantmgoyal2009/winget-releaser@main
|
||||
with:
|
||||
identifier: epi052.feroxbuster
|
||||
installers-regex: '-windows-feroxbuster\.exe\.zip$'
|
||||
token: ${{ secrets.WINGET_TOKEN }}
|
||||
release-tag: ${{ inputs.tag_name || github.event.release.tag_name || github.ref_name }}
|
||||
11
Cargo.lock
generated
11
Cargo.lock
generated
@@ -116,13 +116,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "assert_cmd"
|
||||
version = "2.0.17"
|
||||
version = "2.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2bd389a4b2970a01282ee455294913c0a43724daedcd1a24c3eb0ec1c1320b66"
|
||||
checksum = "bcbb6924530aa9e0432442af08bbcafdad182db80d2e560da42a6d442535bf85"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"bstr",
|
||||
"doc-comment",
|
||||
"libc",
|
||||
"predicates",
|
||||
"predicates-core",
|
||||
@@ -790,12 +789,6 @@ dependencies = [
|
||||
"syn 2.0.104",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "doc-comment"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10"
|
||||
|
||||
[[package]]
|
||||
name = "dtoa"
|
||||
version = "1.0.10"
|
||||
|
||||
@@ -69,7 +69,7 @@ self_update = { version = "0.40", features = [
|
||||
[dev-dependencies]
|
||||
tempfile = "3.20"
|
||||
httpmock = "0.7"
|
||||
assert_cmd = "2.0"
|
||||
assert_cmd = "2.1"
|
||||
predicates = "3.1"
|
||||
|
||||
[profile.release]
|
||||
|
||||
2
LICENSE
2
LICENSE
@@ -1,6 +1,6 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020-2023 epi
|
||||
Copyright (c) 2020-2026 epi
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -50,12 +50,4 @@ condition = { env_not_set = ["CI"] }
|
||||
clear = true
|
||||
script = """
|
||||
cargo nextest run --all-features --all-targets --no-fail-fast --run-ignored all --retries 4
|
||||
"""
|
||||
|
||||
# coverage
|
||||
[tasks.coverage]
|
||||
clear = true
|
||||
script = """
|
||||
cargo llvm-cov nextest --all-features --no-fail-fast --retries 4 --html
|
||||
echo "Coverage report generated at target/llvm-cov/html/index.html"
|
||||
"""
|
||||
75
README.md
75
README.md
@@ -1,3 +1,18 @@
|
||||
> [!WARNING]
|
||||
> **Security Notice – Domain Impersonation**
|
||||
>
|
||||
> The domain **feroxbuster.com** is **NOT affiliated** with this project, its maintainers, or any official feroxbuster releases.
|
||||
>
|
||||
> Official feroxbuster downloads are distributed **ONLY** through:
|
||||
>
|
||||
> - [https://github.com/epi052/feroxbuster](https://github.com/epi052/feroxbuster/releases) (open source)
|
||||
> - [https://www.feroxbuster.pro](https://www.feroxbuster.pro) (commercial)
|
||||
> - package repositories listed in this README
|
||||
> - package repositories listed in the [installation docs](https://epi052.github.io/feroxbuster-docs/installation/android/)
|
||||
>
|
||||
> We do **not** distribute software from feroxbuster.com, and we cannot vouch for the authenticity or safety of files hosted there.
|
||||
> If you downloaded feroxbuster from any other domain, we strongly recommend deleting it and reinstalling from an official source.
|
||||
|
||||
<h1 align="center">
|
||||
<br>
|
||||
<a href="https://github.com/epi052/feroxbuster"><img src="img/logo/default-cropped.png" alt="feroxbuster"></a>
|
||||
@@ -43,29 +58,26 @@
|
||||

|
||||
|
||||
<p align="center">
|
||||
🦀
|
||||
<a href="https://github.com/epi052/feroxbuster/releases">Releases</a> ✨
|
||||
<a href="https://epi052.github.io/feroxbuster-docs/docs/examples/">Example Usage</a> ✨
|
||||
<a href="https://github.com/epi052/feroxbuster/blob/main/CONTRIBUTING.md">Contributing</a> ✨
|
||||
<a href="https://epi052.github.io/feroxbuster-docs/docs/">Documentation</a>
|
||||
🦀
|
||||
<a href="https://github.com/epi052/feroxbuster/releases"><img src="https://img.shields.io/badge/Releases-CF4F4B?style=flat-square&logo=github&logoColor=white" alt="Releases"></a>
|
||||
<a href="https://epi052.github.io/feroxbuster-docs/examples/auto-tune/"><img src="https://img.shields.io/badge/Examples-CF4F4B?style=flat-square" alt="Example Usage"></a>
|
||||
<a href="https://github.com/epi052/feroxbuster/blob/main/CONTRIBUTING.md"><img src="https://img.shields.io/badge/Contributing-CF4F4B?style=flat-square" alt="Contributing"></a>
|
||||
<a href="https://epi052.github.io/feroxbuster-docs/overview"><img src="https://img.shields.io/badge/Documentation-CF4F4B?style=flat-square&logo=bookstack&logoColor=white" alt="Documentation"></a>
|
||||
<a href="https://www.feroxbuster.pro"><img src="https://img.shields.io/badge/Pro-CF4F4B?style=flat-square" alt="Pro"></a>
|
||||
</p>
|
||||
|
||||
---
|
||||
|
||||
<h1><p align="center">✨🎉👉 <a href="https://epi052.github.io/feroxbuster-docs/docs/">NEW DOCUMENTATION SITE</a> 👈🎉✨</p></h1>
|
||||
> [!TIP]
|
||||
> **Documentation has moved!** — Instead of having a 1300 line `README.md` (sorry...), feroxbuster's documentation has moved to GitHub Pages. The move to hosting documentation on Pages should make it a LOT easier to find the information you're looking for, whatever that may be. Please check it out for anything you need beyond a quick-start.
|
||||
>
|
||||
> **[View the full documentation →](https://epi052.github.io/feroxbuster-docs/overview)**
|
||||
|
||||
|
||||
## 🚀 Documentation has **moved** 🚀
|
||||
|
||||
Instead of having a 1300 line `README.md` (sorry...), feroxbuster's documentation has moved to GitHub Pages. The move to hosting documentation on Pages should make it a LOT easier to find the information you're looking for, whatever that may be. Please check it out for anything you need beyond a quick-start. The new documentation can be found [here](https://epi052.github.io/feroxbuster-docs/docs/).
|
||||
|
||||
## 😕 What the heck is a ferox anyway?
|
||||
## What the heck is a ferox anyway?
|
||||
|
||||
Ferox is short for Ferric Oxide. Ferric Oxide, simply put, is rust. The name rustbuster was taken, so I decided on a
|
||||
variation. 🤷
|
||||
variation.
|
||||
|
||||
## 🤔 What's it do tho?
|
||||
## What's it do tho?
|
||||
|
||||
`feroxbuster` is a tool designed to perform [Forced Browsing](https://owasp.org/www-community/attacks/Forced_browsing).
|
||||
|
||||
@@ -79,17 +91,17 @@ credentials, internal network addressing, etc...
|
||||
This attack is also known as Predictable Resource Location, File Enumeration, Directory Enumeration, and Resource
|
||||
Enumeration.
|
||||
|
||||
## ⏳ Quick Start
|
||||
## Quick Start
|
||||
|
||||
This section will cover the minimum amount of information to get up and running with feroxbuster. Please refer the the [documentation](https://epi052.github.io/feroxbuster-docs/docs/), as it's much more comprehensive.
|
||||
This section will cover the minimum amount of information to get up and running with feroxbuster. Please refer the the [documentation](https://epi052.github.io/feroxbuster-docs/overview/), as it's much more comprehensive.
|
||||
|
||||
### 💿 Installation
|
||||
### Installation
|
||||
|
||||
There are quite a few other [installation methods](https://epi052.github.io/feroxbuster-docs/docs/installation/), but these snippets should cover the majority of users.
|
||||
There are quite a few other [installation methods](https://epi052.github.io/feroxbuster-docs/installation/android/), but these snippets should cover the majority of users.
|
||||
|
||||
#### Kali
|
||||
|
||||
If you're using kali, this is the preferred install method. Installing from the repos adds a [**ferox-config.toml**](https://epi052.github.io/feroxbuster-docs/docs/configuration/ferox-config-toml/) in `/etc/feroxbuster/`, adds command completion for bash, fish, and zsh, includes a man page entry, and installs `feroxbuster` itself.
|
||||
If you're using kali, this is the preferred install method. Installing from the repos adds a [**ferox-config.toml**](https://epi052.github.io/feroxbuster-docs/configuration/ferox-config-toml/) in `/etc/feroxbuster/`, adds command completion for bash, fish, and zsh, includes a man page entry, and installs `feroxbuster` itself.
|
||||
|
||||
```
|
||||
sudo apt update && sudo apt install -y feroxbuster
|
||||
@@ -135,7 +147,7 @@ choco install feroxbuster
|
||||
|
||||
#### All others
|
||||
|
||||
Please refer the the [documentation](https://epi052.github.io/feroxbuster-docs/docs/).
|
||||
Please refer the the [documentation](https://epi052.github.io/feroxbuster-docs/overview).
|
||||
|
||||
### Updating feroxbuster (new in v2.9.1)
|
||||
|
||||
@@ -143,9 +155,9 @@ Please refer the the [documentation](https://epi052.github.io/feroxbuster-docs/d
|
||||
./feroxbuster --update
|
||||
```
|
||||
|
||||
## 🧰 Example Usage
|
||||
## Example Usage
|
||||
|
||||
Here are a few brief examples to get you started. Please note, feroxbuster can do a **lot more** than what's listed below. As a result, there are **many more** examples, with **demonstration gifs** that highlight specific features, in the [documentation](https://epi052.github.io/feroxbuster-docs/docs/).
|
||||
Here are a few brief examples to get you started. Please note, feroxbuster can do a **lot more** than what's listed below. As a result, there are **many more** examples, with **demonstration gifs** that highlight specific features, in the [documentation](https://epi052.github.io/feroxbuster-docs/overview).
|
||||
|
||||
### Multiple Values
|
||||
|
||||
@@ -205,13 +217,12 @@ cat targets | ./feroxbuster --stdin --silent -s 200 301 302 --redirects -x js |
|
||||
./feroxbuster -u http://127.1 --data-urlencoded @file.payload
|
||||
```
|
||||
|
||||
## 🚀 Documentation has **moved** 🚀
|
||||
> [!TIP]
|
||||
> For realsies, there used to be over 1300 lines in this README, but it's all been moved to the [new documentation site](https://epi052.github.io/feroxbuster-docs/overview). Go check it out!
|
||||
>
|
||||
> **[View the full documentation →](https://epi052.github.io/feroxbuster-docs/overview)**
|
||||
|
||||
For realsies, there used to be over 1300 lines in this README, but it's all been moved to the [new documentation site](https://epi052.github.io/feroxbuster-docs/docs/). Go check it out!
|
||||
|
||||
<h1><p align="center">✨🎉👉 <a href="https://epi052.github.io/feroxbuster-docs/docs/">DOCUMENTATION</a> 👈🎉✨</p></h1>
|
||||
|
||||
## Contributors ✨
|
||||
## Contributors
|
||||
|
||||
Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
|
||||
|
||||
@@ -357,6 +368,12 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/pg9051"><img src="https://avatars.githubusercontent.com/u/202219877?v=4?s=100" width="100px;" alt="pg9051"/><br /><sub><b>pg9051</b></sub></a><br /><a href="https://github.com/epi052/feroxbuster/commits?author=pg9051" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/sebastiaanspeck"><img src="https://avatars.githubusercontent.com/u/12570668?v=4?s=100" width="100px;" alt="Sebastiaan Speck"/><br /><sub><b>Sebastiaan Speck</b></sub></a><br /><a href="https://github.com/epi052/feroxbuster/issues?q=author%3Asebastiaanspeck" title="Bug reports">🐛</a> <a href="https://github.com/epi052/feroxbuster/commits?author=sebastiaanspeck" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/OpenSourceKyle"><img src="https://avatars.githubusercontent.com/u/173112933?v=4?s=100" width="100px;" alt="OpenSourceKyle"/><br /><sub><b>OpenSourceKyle</b></sub></a><br /><a href="https://github.com/epi052/feroxbuster/commits?author=OpenSourceKyle" title="Documentation">📖</a> <a href="https://github.com/epi052/feroxbuster/issues?q=author%3AOpenSourceKyle" title="Bug reports">🐛</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Antonio-R1"><img src="https://avatars.githubusercontent.com/u/54741970?v=4?s=100" width="100px;" alt="Antonio"/><br /><sub><b>Antonio</b></sub></a><br /><a href="https://github.com/epi052/feroxbuster/commits?author=Antonio-R1" title="Code">💻</a> <a href="https://github.com/epi052/feroxbuster/issues?q=author%3AAntonio-R1" title="Bug reports">🐛</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/redacean"><img src="https://avatars.githubusercontent.com/u/125687454?v=4?s=100" width="100px;" alt="Redacean"/><br /><sub><b>Redacean</b></sub></a><br /><a href="https://github.com/epi052/feroxbuster/issues?q=author%3Aredacean" title="Bug reports">🐛</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ghsdpolley"><img src="https://avatars.githubusercontent.com/u/19826831?v=4?s=100" width="100px;" alt="ghsdpolley"/><br /><sub><b>ghsdpolley</b></sub></a><br /><a href="https://github.com/epi052/feroxbuster/issues?q=author%3Aghsdpolley" title="Bug reports">🐛</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/aldamd"><img src="https://avatars.githubusercontent.com/u/178115486?v=4?s=100" width="100px;" alt="Daniel Aldam"/><br /><sub><b>Daniel Aldam</b></sub></a><br /><a href="https://github.com/epi052/feroxbuster/commits?author=aldamd" title="Code">💻</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<licenseUrl>https://github.com/epi052/feroxbuster/blob/main/LICENSE</licenseUrl>
|
||||
<requireLicenseAcceptance>true</requireLicenseAcceptance>
|
||||
<projectSourceUrl>https://github.com/epi052/feroxbuster</projectSourceUrl>
|
||||
<docsUrl>https://epi052.github.io/feroxbuster-docs/docs/</docsUrl>
|
||||
<docsUrl>https://epi052.github.io/feroxbuster-docs/</docsUrl>
|
||||
<!--<mailingListUrl></mailingListUrl>-->
|
||||
<bugTrackerUrl>https://github.com/epi052/feroxbuster/issues</bugTrackerUrl>
|
||||
<tags>content-discovery pentesting-tool url-bruteforcer</tags>
|
||||
@@ -43,19 +43,19 @@ Enumeration.
|
||||
|
||||
## Quick Start
|
||||
|
||||
This section will cover the minimum amount of information to get up and running with feroxbuster. Please refer the the [documentation](https://epi052.github.io/feroxbuster-docs/docs/), as it's much more comprehensive.
|
||||
This section will cover the minimum amount of information to get up and running with feroxbuster. Please refer the the [documentation](https://epi052.github.io/feroxbuster-docs/overview), as it's much more comprehensive.
|
||||
|
||||
### Installation
|
||||
|
||||
There are quite a few other [installation methods](https://epi052.github.io/feroxbuster-docs/docs/installation/), but these snippets should cover the majority of users.
|
||||
There are quite a few other [installation methods](https://epi052.github.io/feroxbuster-docs/installation/android/), but these snippets should cover the majority of users.
|
||||
|
||||
#### All others Docs
|
||||
|
||||
Please refer the the [documentation](https://epi052.github.io/feroxbuster-docs/docs/).
|
||||
Please refer the the [documentation](https://epi052.github.io/feroxbuster-docs/overview).
|
||||
|
||||
## Example Usage
|
||||
|
||||
Here are a few brief examples to get you started. Please note, feroxbuster can do a **lot more** than what's listed below. As a result, there are **many more** examples, with **demonstration gifs** that highlight specific features, in the [documentation](https://epi052.github.io/feroxbuster-docs/docs/).
|
||||
Here are a few brief examples to get you started. Please note, feroxbuster can do a **lot more** than what's listed below. As a result, there are **many more** examples, with **demonstration gifs** that highlight specific features, in the [documentation](https://epi052.github.io/feroxbuster-docs/overview).
|
||||
|
||||
### Multiple Values
|
||||
|
||||
|
||||
@@ -10,9 +10,8 @@ description: |
|
||||
|
||||
This attack is also known as Predictable Resource Location, File Enumeration, Directory Enumeration, and Resource Enumeration.
|
||||
|
||||
confinement: strict
|
||||
grade: stable
|
||||
base: core22
|
||||
|
||||
base: core18
|
||||
|
||||
plugs:
|
||||
etc-feroxbuster:
|
||||
|
||||
@@ -381,32 +381,54 @@ impl ContentType {
|
||||
/// unless overridden by CLI options.
|
||||
///
|
||||
pub fn parse_request_file(config: &mut Configuration) -> Result<()> {
|
||||
// read in the file located at config.request_file
|
||||
// read in the file (raw bytes) located at config.request_file
|
||||
// parse the file into a Request struct
|
||||
let contents = std::fs::read_to_string(&config.request_file)?;
|
||||
let contents = std::fs::read(&config.request_file)?;
|
||||
|
||||
if contents.is_empty() {
|
||||
bail!("Empty --request-file file provided");
|
||||
}
|
||||
|
||||
// this should split the body from the request line and headers
|
||||
let lines = contents.split("\r\n\r\n").collect::<Vec<&str>>();
|
||||
// find the first header/body separator
|
||||
// locate both \r\n\r\n and \n\n and pick whichever appears earliest,
|
||||
// so that a \r\n\r\n inside the body doesn't shadow a \n\n separator
|
||||
// that terminates the headers
|
||||
let crlf = contents.windows(4).position(|w| w == b"\r\n\r\n");
|
||||
let lf = contents.windows(2).position(|w| w == b"\n\n");
|
||||
|
||||
if lines.len() < 2 {
|
||||
bail!("Invalid request: Missing head/body CRLF separator");
|
||||
}
|
||||
let (sep_idx, sep_len) = match (crlf, lf) {
|
||||
(Some(c), Some(l)) => {
|
||||
if c <= l {
|
||||
(c, 4)
|
||||
} else {
|
||||
(l, 2)
|
||||
}
|
||||
}
|
||||
(Some(c), None) => (c, 4),
|
||||
(None, Some(l)) => (l, 2),
|
||||
(None, None) => bail!("Invalid request: Missing head/body separator"),
|
||||
};
|
||||
|
||||
let head = lines[0];
|
||||
let body = lines[1].as_bytes().to_vec();
|
||||
// split the request head and body
|
||||
let head_bytes = &contents[..sep_idx];
|
||||
let body_bytes = &contents[sep_idx + sep_len..];
|
||||
|
||||
// we only want to use the request's body if the user hasn't
|
||||
// decode only the head; HTTP framing is generally ascii/utf-8
|
||||
// compatible
|
||||
let head = std::str::from_utf8(head_bytes)
|
||||
.map_err(|_| anyhow::anyhow!("Request headers contain invalid UTF-8"))?;
|
||||
|
||||
// normalize line endings in the decoded head
|
||||
let normalized = head.replace("\r\n", "\n");
|
||||
|
||||
// we only want to use the request's body bytes if the user hasn't
|
||||
// overridden it on the cli
|
||||
if config.data.is_empty() {
|
||||
config.data = body;
|
||||
config.data = body_bytes.to_vec();
|
||||
}
|
||||
|
||||
// begin parsing the request line and headers
|
||||
let mut head_parts = head.split("\r\n");
|
||||
// begin parsing the request line and normalized headers
|
||||
let mut head_parts = normalized.split("\n");
|
||||
|
||||
let Some(request_line) = head_parts.next() else {
|
||||
bail!("Invalid request: Missing request line");
|
||||
@@ -441,7 +463,7 @@ pub fn parse_request_file(config: &mut Configuration) -> Result<()> {
|
||||
}
|
||||
|
||||
for mut line in head_parts {
|
||||
line = line.trim();
|
||||
line = line.trim_matches('\r').trim();
|
||||
|
||||
if line.is_empty() {
|
||||
break; // Empty line signals the end of headers
|
||||
@@ -904,7 +926,7 @@ mod tests {
|
||||
assert!(result.is_err());
|
||||
assert_eq!(
|
||||
result.unwrap_err().to_string(),
|
||||
"Invalid request: Missing head/body CRLF separator"
|
||||
"Invalid request: Missing head/body separator"
|
||||
);
|
||||
|
||||
tmp.cleanup();
|
||||
@@ -1345,4 +1367,145 @@ mod tests {
|
||||
let result = split_query("");
|
||||
assert!(result.is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_raw_lf_only_request() -> io::Result<()> {
|
||||
let mut tmp = TempSetup::new();
|
||||
|
||||
tmp.file
|
||||
.write_all(b"GET / HTTP/1.1\nHost: example.com\n\nbody")?;
|
||||
|
||||
let result = parse_request_file(&mut tmp.config);
|
||||
|
||||
assert!(result.is_ok());
|
||||
assert_eq!(tmp.config.data, b"body".to_vec());
|
||||
|
||||
tmp.cleanup();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_raw_crlf_request() -> io::Result<()> {
|
||||
let mut tmp = TempSetup::new();
|
||||
|
||||
tmp.file
|
||||
.write_all(b"GET / HTTP/1.1\r\nHost: example.com\r\n\r\nbody")?;
|
||||
|
||||
let result = parse_request_file(&mut tmp.config);
|
||||
|
||||
assert!(result.is_ok());
|
||||
assert_eq!(tmp.config.data, b"body".to_vec());
|
||||
|
||||
tmp.cleanup();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_raw_crlf_body_preserved() -> io::Result<()> {
|
||||
let mut tmp = TempSetup::new();
|
||||
|
||||
let body = b"line1\r\nline2\r\nbinary\x00data";
|
||||
|
||||
let mut request = b"GET / HTTP/1.1\r\nHost: example.com\r\n\r\n".to_vec();
|
||||
request.extend_from_slice(body);
|
||||
|
||||
tmp.file.write_all(&request)?;
|
||||
|
||||
parse_request_file(&mut tmp.config).unwrap();
|
||||
|
||||
assert_eq!(tmp.config.data, body.to_vec());
|
||||
|
||||
tmp.cleanup();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_raw_lf_headers_crlf_body() -> io::Result<()> {
|
||||
let mut tmp = TempSetup::new();
|
||||
|
||||
let body = b"line1\r\nline2\r\n";
|
||||
|
||||
let mut request = b"GET / HTTP/1.1\nHost: example.com\n\n".to_vec();
|
||||
request.extend_from_slice(body);
|
||||
|
||||
tmp.file.write_all(&request)?;
|
||||
|
||||
parse_request_file(&mut tmp.config).unwrap();
|
||||
|
||||
assert_eq!(tmp.config.data, body.to_vec());
|
||||
|
||||
tmp.cleanup();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_raw_mixed_newlines_headers() -> io::Result<()> {
|
||||
let mut tmp = TempSetup::new();
|
||||
|
||||
tmp.file
|
||||
.write_all(b"GET / HTTP/1.1\r\nHost: example.com\nUser-Agent: test\r\n\nbody")?;
|
||||
|
||||
let result = parse_request_file(&mut tmp.config);
|
||||
|
||||
assert!(result.is_ok());
|
||||
assert_eq!(tmp.config.data, b"body".to_vec());
|
||||
assert!(tmp.config.headers.contains_key("Host"));
|
||||
assert_eq!(tmp.config.headers.get("Host").unwrap(), "example.com");
|
||||
assert_eq!(tmp.config.user_agent, "test");
|
||||
|
||||
tmp.cleanup();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_raw_binary_body_preserved() -> io::Result<()> {
|
||||
let mut tmp = TempSetup::new();
|
||||
|
||||
let body = b"\x00\xde\xad\xbe\xef\x80binary";
|
||||
|
||||
let mut request = b"GET / HTTP/1.1\r\nHost: example.com\r\n\r\n".to_vec();
|
||||
request.extend_from_slice(body);
|
||||
|
||||
tmp.file.write_all(&request)?;
|
||||
|
||||
parse_request_file(&mut tmp.config).unwrap();
|
||||
|
||||
assert_eq!(tmp.config.data, body.to_vec());
|
||||
|
||||
tmp.cleanup();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_raw_lf_headers_with_crlf_crlf_in_body() -> io::Result<()> {
|
||||
// headers are LF-separated; body contains \r\n\r\n
|
||||
let mut tmp = TempSetup::new();
|
||||
|
||||
tmp.file.write_all(
|
||||
b"POST /upload HTTP/1.1\nHost: example.com\nContent-Type: application/octet-stream\n\nabc\r\n\r\ndef",
|
||||
)?;
|
||||
|
||||
let result = parse_request_file(&mut tmp.config);
|
||||
|
||||
assert!(result.is_ok());
|
||||
assert_eq!(tmp.config.data, b"abc\r\n\r\ndef".to_vec());
|
||||
assert_eq!(tmp.config.target_url, "https://example.com/upload");
|
||||
|
||||
tmp.cleanup();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_raw_crlf_headers_with_lf_lf_in_body() -> io::Result<()> {
|
||||
let mut tmp = TempSetup::new();
|
||||
|
||||
tmp.file
|
||||
.write_all(b"POST /upload HTTP/1.1\r\nHost: example.com\r\n\r\nabc\n\ndef")?;
|
||||
|
||||
parse_request_file(&mut tmp.config).unwrap();
|
||||
assert_eq!(tmp.config.data, b"abc\n\ndef".to_vec());
|
||||
|
||||
tmp.cleanup();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -227,8 +227,10 @@ impl TermOutHandler {
|
||||
self.handles = Some(handles);
|
||||
}
|
||||
Command::Exit => {
|
||||
if self.file_task.is_some() && self.tx_file.send(Command::Exit).is_ok() {
|
||||
self.file_task.as_mut().unwrap().await??; // wait for death
|
||||
if self.tx_file.send(Command::Exit).is_ok() {
|
||||
if let Some(task) = self.file_task.as_mut() {
|
||||
task.await??; // wait for death
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -280,26 +282,31 @@ impl TermOutHandler {
|
||||
}
|
||||
log::trace!("report complete: {}", resp.url());
|
||||
|
||||
if self.config.replay_client.is_some() && should_process_response {
|
||||
// replay proxy specified/client created and this response's status code is one that
|
||||
// should be replayed; not using logged_request due to replay proxy client
|
||||
let data = if self.config.data.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(self.config.data.as_slice())
|
||||
};
|
||||
if should_process_response {
|
||||
if let Some(client) = self.config.replay_client.as_ref() {
|
||||
// replay proxy specified/client created and this response's status code is one that
|
||||
// should be replayed; not using logged_request due to replay proxy client
|
||||
let data = if self.config.data.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(self.config.data.as_slice())
|
||||
};
|
||||
|
||||
make_request(
|
||||
self.config.replay_client.as_ref().unwrap(),
|
||||
resp.url(),
|
||||
resp.method().as_str(),
|
||||
data,
|
||||
self.config.output_level,
|
||||
&self.config,
|
||||
tx_stats.clone(),
|
||||
)
|
||||
.await
|
||||
.with_context(|| "Could not replay request through replay proxy")?;
|
||||
make_request(
|
||||
client,
|
||||
resp.url(),
|
||||
resp.method().as_str(),
|
||||
data,
|
||||
self.config.output_level,
|
||||
&self.config,
|
||||
tx_stats.clone(),
|
||||
)
|
||||
.await
|
||||
.with_context(|| "Could not replay request through replay proxy")?;
|
||||
} else {
|
||||
// replay proxy not configured, skip replay without exiting response processing
|
||||
log::trace!("replay proxy not configured, skipping replay");
|
||||
}
|
||||
}
|
||||
|
||||
if self.config.collect_backups
|
||||
|
||||
@@ -51,7 +51,7 @@ pub(super) const LINKFINDER_REGEX: &str = r#"(?x)
|
||||
///
|
||||
/// ref: https://developers.google.com/search/reference/robots_txt
|
||||
pub(super) const ROBOTS_TXT_REGEX: &str =
|
||||
r#"(?m)^ *(Allow|Disallow): *(?P<url_path>[a-zA-Z0-9._/?#@!&'()+,;%=-]+?)$"#; // multi-line (?m)
|
||||
r#"(?m)^[ \t]*(?i)(allow|disallow)[ \t]*:[ \t]*(?P<url_path>[^ \t\r\n#$]*)?[ \t]*\$?(?:#.*)?$"#; // multi-line (?m), case-insensitive (?i)
|
||||
|
||||
/// Regular expression to filter bad characters from extracted url paths
|
||||
///
|
||||
@@ -136,11 +136,7 @@ impl<'a> ExtractorBuilder<'a> {
|
||||
links_regex: Regex::new(LINKFINDER_REGEX).unwrap(),
|
||||
robots_regex: Regex::new(ROBOTS_TXT_REGEX).unwrap(),
|
||||
url_regex: Regex::new(URL_CHARS_REGEX).unwrap(),
|
||||
response: if self.response.is_some() {
|
||||
Some(self.response.unwrap())
|
||||
} else {
|
||||
None
|
||||
},
|
||||
response: self.response,
|
||||
url: self.url.to_owned(),
|
||||
handles: self.handles.as_ref().unwrap().clone(),
|
||||
target: self.target,
|
||||
|
||||
@@ -233,9 +233,7 @@ impl<'a> Extractor<'a> {
|
||||
}
|
||||
|
||||
// request and report assumed file
|
||||
if (resp.is_file() || !resp.is_directory())
|
||||
&& !c_handles.config.force_recursion
|
||||
{
|
||||
if !resp.is_directory() && !c_handles.config.force_recursion {
|
||||
log::debug!("Extracted File: {resp}");
|
||||
|
||||
c_scanned_urls.add_file_scan(
|
||||
|
||||
@@ -743,12 +743,18 @@ pub fn initialize() -> Command {
|
||||
// which is fine, but if you add -h|--help, it still errors out on the bad flag/option,
|
||||
// never showing the full help message. This code addresses that behavior
|
||||
if arg == "--help" {
|
||||
app.print_long_help().unwrap();
|
||||
if let Err(err) = app.print_long_help() {
|
||||
eprintln!("couldn't print help message: {}", err);
|
||||
process::exit(1);
|
||||
}
|
||||
println!(); // just a newline to mirror original --help output
|
||||
process::exit(0);
|
||||
} else if arg == "-h" {
|
||||
// same for -h, just shorter
|
||||
app.print_help().unwrap();
|
||||
if let Err(err) = app.print_help() {
|
||||
eprintln!("couldn't print help message: {}", err);
|
||||
process::exit(1);
|
||||
}
|
||||
println!();
|
||||
process::exit(0);
|
||||
}
|
||||
@@ -813,7 +819,7 @@ EXAMPLES:
|
||||
./feroxbuster -u http://127.1 --auto-tune
|
||||
|
||||
Examples and demonstrations of all features
|
||||
https://epi052.github.io/feroxbuster-docs/docs/examples/
|
||||
https://epi052.github.io/feroxbuster-docs/examples/auto-tune/
|
||||
"#;
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
@@ -192,26 +192,6 @@ impl FeroxResponse {
|
||||
self.text.shrink_to_fit(); // allocated capacity shrinks to reflect the new size
|
||||
}
|
||||
|
||||
/// Make a reasonable guess at whether the response is a file or not
|
||||
///
|
||||
/// Examines the last part of a path to determine if it has an obvious extension
|
||||
/// i.e. http://localhost/some/path/stuff.js where stuff.js indicates a file
|
||||
///
|
||||
/// Additionally, inspects query parameters, as they're also often indicative of a file
|
||||
pub fn is_file(&self) -> bool {
|
||||
let has_extension = if let Some(mut path) = self.url.path_segments() {
|
||||
if let Some(last) = path.next_back() {
|
||||
last.contains('.') // last segment has some sort of extension, probably
|
||||
} else {
|
||||
false
|
||||
}
|
||||
} else {
|
||||
false
|
||||
};
|
||||
|
||||
self.url.query_pairs().count() > 0 || has_extension
|
||||
}
|
||||
|
||||
/// Returns line count of the response text.
|
||||
pub fn line_count(&self) -> usize {
|
||||
self.line_count
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
mod utils;
|
||||
use assert_cmd::Command;
|
||||
use assert_cmd::cargo_bin;
|
||||
use assert_cmd::prelude::*;
|
||||
use predicates::prelude::*;
|
||||
use std::process::Command;
|
||||
use utils::{setup_tmp_directory, teardown_tmp_directory};
|
||||
|
||||
#[test]
|
||||
@@ -13,15 +15,13 @@ fn banner_prints_proxy() -> Result<(), Box<dyn std::error::Error>> {
|
||||
];
|
||||
let (tmp_dir, file) = setup_tmp_directory(&urls, "wordlist")?;
|
||||
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--stdin")
|
||||
.arg("--proxy")
|
||||
.arg("http://127.0.0.1:8080")
|
||||
.arg("--wordlist")
|
||||
.arg("/definitely/doesnt/exist/0cd7fed0-47f4-4b18-a1b0-ac39708c1676")
|
||||
.pipe_stdin(file)
|
||||
.unwrap()
|
||||
.stdin(std::fs::File::open(file)?)
|
||||
.assert()
|
||||
.success()
|
||||
.stderr(
|
||||
@@ -53,15 +53,13 @@ fn banner_prints_replay_proxy() -> Result<(), Box<dyn std::error::Error>> {
|
||||
];
|
||||
let (tmp_dir, file) = setup_tmp_directory(&urls, "wordlist")?;
|
||||
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--stdin")
|
||||
.arg("--wordlist")
|
||||
.arg("/definitely/doesnt/exist/0cd7fed0-47f4-4b18-a1b0-ac39708c1676")
|
||||
.arg("--replay-proxy")
|
||||
.arg("http://127.0.0.1:8081")
|
||||
.pipe_stdin(file)
|
||||
.unwrap()
|
||||
.stdin(std::fs::File::open(file)?)
|
||||
.assert()
|
||||
.success()
|
||||
.stderr(
|
||||
@@ -87,8 +85,7 @@ fn banner_prints_replay_proxy() -> Result<(), Box<dyn std::error::Error>> {
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see all mandatory prints + multiple headers
|
||||
fn banner_prints_headers() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg("http://localhost")
|
||||
.arg("--headers")
|
||||
@@ -119,8 +116,7 @@ fn banner_prints_headers() {
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see all mandatory prints + multiple dont scan url & regex entries
|
||||
fn banner_prints_denied_urls() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg("http://localhost")
|
||||
.arg("--dont-scan")
|
||||
@@ -155,8 +151,7 @@ fn banner_prints_denied_urls() {
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see all mandatory prints + multiple scope url entries
|
||||
fn banner_prints_scope_urls() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg("http://localhost")
|
||||
.arg("--scope")
|
||||
@@ -188,8 +183,7 @@ fn banner_prints_scope_urls() {
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see all mandatory prints + multiple headers
|
||||
fn banner_prints_random_agent() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg("http://localhost")
|
||||
.arg("--random-agent")
|
||||
@@ -215,8 +209,7 @@ fn banner_prints_random_agent() {
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see all mandatory prints + multiple size filters
|
||||
fn banner_prints_filter_sizes() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg("http://localhost")
|
||||
.arg("-S")
|
||||
@@ -261,8 +254,7 @@ fn banner_prints_filter_sizes() {
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see all mandatory prints + queries
|
||||
fn banner_prints_queries() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg("http://localhost")
|
||||
.arg("-Q")
|
||||
@@ -293,8 +285,7 @@ fn banner_prints_queries() {
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see all mandatory prints + status codes
|
||||
fn banner_prints_status_codes() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg("http://localhost")
|
||||
.arg("-s")
|
||||
@@ -321,8 +312,7 @@ fn banner_prints_status_codes() {
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see all mandatory prints + replay codes
|
||||
fn banner_prints_replay_codes() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg("http://localhost")
|
||||
.arg("--replay-codes")
|
||||
@@ -353,8 +343,7 @@ fn banner_prints_replay_codes() {
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see all mandatory prints + output file
|
||||
fn banner_prints_output_file() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg("http://localhost")
|
||||
.arg("--output")
|
||||
@@ -385,8 +374,7 @@ fn banner_prints_output_file() {
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see all mandatory prints + insecure
|
||||
fn banner_prints_insecure() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg("http://localhost")
|
||||
.arg("-k")
|
||||
@@ -413,8 +401,7 @@ fn banner_prints_insecure() {
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see all mandatory prints + follow redirects
|
||||
fn banner_prints_redirects() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg("http://localhost")
|
||||
.arg("-r")
|
||||
@@ -441,8 +428,7 @@ fn banner_prints_redirects() {
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see all mandatory prints + extensions
|
||||
fn banner_prints_extensions() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg("http://localhost")
|
||||
.arg("-x")
|
||||
@@ -472,8 +458,7 @@ fn banner_prints_extensions() {
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see all mandatory prints + dont_filter
|
||||
fn banner_prints_dont_filter() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg("http://localhost")
|
||||
.arg("--dont-filter")
|
||||
@@ -500,8 +485,7 @@ fn banner_prints_dont_filter() {
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see all mandatory prints + verbosity=1
|
||||
fn banner_prints_verbosity_one() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg("http://localhost")
|
||||
.arg("-v")
|
||||
@@ -528,8 +512,7 @@ fn banner_prints_verbosity_one() {
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see all mandatory prints + verbosity=2
|
||||
fn banner_prints_verbosity_two() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg("http://localhost")
|
||||
.arg("-vv")
|
||||
@@ -556,8 +539,7 @@ fn banner_prints_verbosity_two() {
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see all mandatory prints + verbosity=3
|
||||
fn banner_prints_verbosity_three() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg("http://localhost")
|
||||
.arg("-vvv")
|
||||
@@ -584,8 +566,7 @@ fn banner_prints_verbosity_three() {
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see all mandatory prints + verbosity=4
|
||||
fn banner_prints_verbosity_four() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg("http://localhost")
|
||||
.arg("-vvvv")
|
||||
@@ -612,8 +593,7 @@ fn banner_prints_verbosity_four() {
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see all mandatory prints + add slash
|
||||
fn banner_prints_add_slash() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg("http://localhost")
|
||||
.arg("-f")
|
||||
@@ -640,8 +620,7 @@ fn banner_prints_add_slash() {
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see all mandatory prints + INFINITE recursion
|
||||
fn banner_prints_infinite_depth() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg("http://localhost")
|
||||
.arg("--depth")
|
||||
@@ -669,8 +648,7 @@ fn banner_prints_infinite_depth() {
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see all mandatory prints + recursion depth
|
||||
fn banner_prints_recursion_depth() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg("http://localhost")
|
||||
.arg("--depth")
|
||||
@@ -698,8 +676,7 @@ fn banner_prints_recursion_depth() {
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see all mandatory prints + server certs
|
||||
fn banner_prints_server_certs() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg("http://localhost")
|
||||
.arg("--server-certs")
|
||||
@@ -729,8 +706,7 @@ fn banner_prints_server_certs() {
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see all mandatory prints + server certs
|
||||
fn banner_prints_client_cert_and_key() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg("http://localhost")
|
||||
.arg("--client-cert")
|
||||
@@ -762,8 +738,7 @@ fn banner_prints_client_cert_and_key() {
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see all mandatory prints + no recursion
|
||||
fn banner_prints_no_recursion() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg("http://localhost")
|
||||
.arg("-n")
|
||||
@@ -790,8 +765,7 @@ fn banner_prints_no_recursion() {
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see nothing
|
||||
fn banner_doesnt_print() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg("http://localhost")
|
||||
.arg("-q")
|
||||
@@ -808,8 +782,7 @@ fn banner_doesnt_print() {
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see all mandatory prints + extract-links
|
||||
fn banner_prints_extract_links() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg("http://localhost")
|
||||
.arg("-e")
|
||||
@@ -836,8 +809,7 @@ fn banner_prints_extract_links() {
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see all mandatory prints + scan-limit
|
||||
fn banner_prints_scan_limit() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg("http://localhost")
|
||||
.arg("-L")
|
||||
@@ -865,8 +837,7 @@ fn banner_prints_scan_limit() {
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see all mandatory prints + response-size-limit
|
||||
fn banner_prints_response_size_limit() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg("http://localhost")
|
||||
.arg("--response-size-limit")
|
||||
@@ -894,8 +865,7 @@ fn banner_prints_response_size_limit() {
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see all mandatory prints + filter-status
|
||||
fn banner_prints_filter_status() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg("http://localhost")
|
||||
.arg("-C")
|
||||
@@ -922,8 +892,7 @@ fn banner_prints_filter_status() {
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see all mandatory prints + json
|
||||
fn banner_prints_json() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg("http://localhost")
|
||||
.arg("--json")
|
||||
@@ -952,8 +921,7 @@ fn banner_prints_json() {
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see all mandatory prints + json
|
||||
fn banner_prints_debug_log() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg("http://localhost")
|
||||
.arg("--debug-log")
|
||||
@@ -981,8 +949,7 @@ fn banner_prints_debug_log() {
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see all mandatory prints + regex filters
|
||||
fn banner_prints_filter_regex() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg("http://localhost")
|
||||
.arg("--filter-regex")
|
||||
@@ -1010,8 +977,7 @@ fn banner_prints_filter_regex() {
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see all mandatory prints + time limit
|
||||
fn banner_prints_time_limit() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg("http://localhost")
|
||||
.arg("--time-limit")
|
||||
@@ -1039,8 +1005,7 @@ fn banner_prints_time_limit() {
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see all mandatory prints + similarity filter
|
||||
fn banner_prints_similarity_filter() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg("http://localhost")
|
||||
.arg("--filter-similar-to")
|
||||
@@ -1068,8 +1033,7 @@ fn banner_prints_similarity_filter() {
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see all mandatory prints + rate limit
|
||||
fn banner_prints_rate_limit() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg("http://localhost")
|
||||
.arg("--rate-limit")
|
||||
@@ -1097,8 +1061,7 @@ fn banner_prints_rate_limit() {
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see all mandatory prints + auto tune
|
||||
fn banner_prints_auto_tune() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg("http://localhost")
|
||||
.arg("--auto-tune")
|
||||
@@ -1125,8 +1088,7 @@ fn banner_prints_auto_tune() {
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see all mandatory prints + auto bail
|
||||
fn banner_prints_auto_bail() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg("http://localhost")
|
||||
.arg("--auto-bail")
|
||||
@@ -1153,8 +1115,7 @@ fn banner_prints_auto_bail() {
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see no banner output
|
||||
fn banner_doesnt_print_when_silent() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg("http://localhost")
|
||||
.arg("--silent")
|
||||
@@ -1179,8 +1140,7 @@ fn banner_doesnt_print_when_silent() {
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see no banner output
|
||||
fn banner_doesnt_print_when_quiet() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg("http://localhost")
|
||||
.arg("--quiet")
|
||||
@@ -1205,8 +1165,7 @@ fn banner_doesnt_print_when_quiet() {
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see nothing as --parallel forces --silent to be true
|
||||
fn banner_prints_parallel() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--stdin")
|
||||
.arg("--quiet")
|
||||
.arg("--parallel")
|
||||
@@ -1231,8 +1190,7 @@ fn banner_prints_parallel() {
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see all mandatory prints + methods
|
||||
fn banner_prints_methods() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg("http://localhost")
|
||||
.arg("-m")
|
||||
@@ -1262,8 +1220,7 @@ fn banner_prints_methods() {
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see all mandatory prints + data body
|
||||
fn banner_prints_data() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg("http://localhost")
|
||||
.arg("-m")
|
||||
@@ -1295,8 +1252,7 @@ fn banner_prints_data() {
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see all mandatory prints + ignored extensions
|
||||
fn banner_prints_collect_extensions_and_dont_collect_default() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg("http://localhost")
|
||||
.arg("--collect-extensions")
|
||||
@@ -1324,8 +1280,7 @@ fn banner_prints_collect_extensions_and_dont_collect_default() {
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see all mandatory prints + collect extensions
|
||||
fn banner_prints_collect_extensions_and_dont_collect_with_input() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg("http://localhost")
|
||||
.arg("--collect-extensions")
|
||||
@@ -1356,8 +1311,7 @@ fn banner_prints_collect_extensions_and_dont_collect_with_input() {
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see all mandatory prints + collect backups
|
||||
fn banner_prints_collect_backups() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg("http://localhost")
|
||||
.arg("--collect-backups")
|
||||
@@ -1383,8 +1337,7 @@ fn banner_prints_collect_backups() {
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see all mandatory prints + collect words
|
||||
fn banner_prints_collect_words() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg("http://localhost")
|
||||
.arg("--collect-words")
|
||||
@@ -1410,8 +1363,7 @@ fn banner_prints_collect_words() {
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see all mandatory prints + collect words
|
||||
fn banner_prints_all_composite_settings_smart() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg("http://localhost")
|
||||
.arg("--smart")
|
||||
@@ -1440,8 +1392,7 @@ fn banner_prints_all_composite_settings_smart() {
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see all mandatory prints + collect words
|
||||
fn banner_prints_all_composite_settings_thorough() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg("http://localhost")
|
||||
.arg("--thorough")
|
||||
@@ -1470,8 +1421,7 @@ fn banner_prints_all_composite_settings_thorough() {
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see all mandatory prints + collect words
|
||||
fn banner_prints_all_composite_settings_burp() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg("http://localhost")
|
||||
.arg("--burp")
|
||||
@@ -1498,8 +1448,7 @@ fn banner_prints_all_composite_settings_burp() {
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see all mandatory prints + collect words
|
||||
fn banner_prints_all_composite_settings_data_json_stdin() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg("http://localhost")
|
||||
.arg("--data-json")
|
||||
@@ -1525,8 +1474,7 @@ fn banner_prints_all_composite_settings_data_json_stdin() {
|
||||
|
||||
#[test]
|
||||
fn banner_prints_all_composite_settings_data_json_file() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg("http://localhost")
|
||||
.arg("-m")
|
||||
@@ -1555,8 +1503,7 @@ fn banner_prints_all_composite_settings_data_json_file() {
|
||||
|
||||
#[test]
|
||||
fn banner_prints_all_composite_settings_data_urlencoded_stdin() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg("http://localhost")
|
||||
.arg("-m")
|
||||
@@ -1590,8 +1537,7 @@ fn banner_prints_all_composite_settings_data_urlencoded_stdin() {
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see all mandatory prints + collect words
|
||||
fn banner_prints_all_composite_settings_data_urlencoded_file() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg("http://localhost")
|
||||
.arg("--data-urlencoded")
|
||||
@@ -1622,8 +1568,7 @@ fn banner_prints_all_composite_settings_data_urlencoded_file() {
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see all mandatory prints + collect words
|
||||
fn banner_prints_all_composite_settings_burp_replay() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg("http://localhost")
|
||||
.arg("--burp-replay")
|
||||
@@ -1650,8 +1595,7 @@ fn banner_prints_all_composite_settings_burp_replay() {
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see all mandatory prints + force recursion
|
||||
fn banner_prints_force_recursion() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg("http://localhost")
|
||||
.arg("--force-recursion")
|
||||
@@ -1677,8 +1621,7 @@ fn banner_prints_force_recursion() {
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see all mandatory prints + scan-dir-listings
|
||||
fn banner_prints_scan_dir_listings() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg("http://localhost")
|
||||
.arg("--scan-dir-listings")
|
||||
@@ -1704,8 +1647,7 @@ fn banner_prints_scan_dir_listings() {
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see all mandatory prints + protocol
|
||||
fn banner_prints_limit_dirs() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg("localhost")
|
||||
.arg("--limit-bars")
|
||||
@@ -1732,8 +1674,7 @@ fn banner_prints_limit_dirs() {
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see all mandatory prints + force recursion
|
||||
fn banner_prints_update_app() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--update")
|
||||
.assert()
|
||||
.success()
|
||||
@@ -1744,8 +1685,7 @@ fn banner_prints_update_app() {
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see all mandatory prints + unique
|
||||
fn banner_prints_unique() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg("http://localhost")
|
||||
.arg("--unique")
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
mod utils;
|
||||
use assert_cmd::cargo_bin;
|
||||
use assert_cmd::prelude::*;
|
||||
use httpmock::MockServer;
|
||||
use predicates::prelude::*;
|
||||
@@ -12,8 +13,7 @@ fn read_in_config_file_for_settings() -> Result<(), Box<dyn std::error::Error>>
|
||||
|
||||
let (tmp_dir, file) = setup_tmp_directory(&["threads = 37".to_string()], "ferox-config.toml")?;
|
||||
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.current_dir(&tmp_dir)
|
||||
.arg("--url")
|
||||
.arg(srv.url("/"))
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
mod utils;
|
||||
use assert_cmd::cargo_bin;
|
||||
use assert_cmd::prelude::*;
|
||||
use assert_cmd::Command;
|
||||
use httpmock::Method::GET;
|
||||
use httpmock::MockServer;
|
||||
use predicates::prelude::*;
|
||||
use std::process::Command;
|
||||
use utils::{setup_tmp_directory, teardown_tmp_directory};
|
||||
|
||||
#[test]
|
||||
@@ -17,8 +18,7 @@ fn deny_list_works_during_with_a_normal_scan() {
|
||||
then.status(200).body("this is a test");
|
||||
});
|
||||
|
||||
let cmd = Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
let cmd = Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg(srv.url("/"))
|
||||
.arg("--wordlist")
|
||||
@@ -54,8 +54,7 @@ fn deny_list_works_during_extraction() {
|
||||
then.status(200);
|
||||
});
|
||||
|
||||
let cmd = Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
let cmd = Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg(srv.url("/"))
|
||||
.arg("--wordlist")
|
||||
@@ -109,8 +108,7 @@ fn deny_list_works_during_recursion() {
|
||||
.body("this is a test and is more bytes than other ones");
|
||||
});
|
||||
|
||||
let cmd = Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
let cmd = Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg(srv.url("/"))
|
||||
.arg("--wordlist")
|
||||
@@ -179,8 +177,7 @@ fn deny_list_works_during_recursion_with_inverted_parents() {
|
||||
.body("this is a test and is more bytes than other ones");
|
||||
});
|
||||
|
||||
let cmd = Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
let cmd = Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg(srv.url("/js"))
|
||||
.arg("--wordlist")
|
||||
@@ -222,8 +219,7 @@ fn deny_list_prevents_regex_that_denies_base_url() {
|
||||
then.status(200).body("this is a test");
|
||||
});
|
||||
|
||||
let cmd = Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
let cmd = Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg(srv.url("/"))
|
||||
.arg("--wordlist")
|
||||
@@ -256,8 +252,7 @@ fn deny_list_prevents_url_that_denies_base_url() {
|
||||
then.status(200).body("this is a test");
|
||||
});
|
||||
|
||||
let cmd = Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
let cmd = Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg(srv.url("/"))
|
||||
.arg("--wordlist")
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
mod utils;
|
||||
use assert_cmd::cargo_bin;
|
||||
use assert_cmd::prelude::*;
|
||||
use httpmock::Method::GET;
|
||||
use httpmock::MockServer;
|
||||
@@ -25,8 +26,7 @@ fn extractor_finds_absolute_url() -> Result<(), Box<dyn std::error::Error>> {
|
||||
then.status(200);
|
||||
});
|
||||
|
||||
let cmd = Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
let cmd = Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg(srv.url("/"))
|
||||
.arg("--wordlist")
|
||||
@@ -61,8 +61,7 @@ fn extractor_finds_absolute_url_to_different_domain() -> Result<(), Box<dyn std:
|
||||
.body("\"http://localhost/homepage/assets/img/icons/handshake.svg\"");
|
||||
});
|
||||
|
||||
let cmd = Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
let cmd = Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg(srv.url("/"))
|
||||
.arg("--wordlist")
|
||||
@@ -102,8 +101,7 @@ fn extractor_finds_relative_url() -> Result<(), Box<dyn std::error::Error>> {
|
||||
then.status(200);
|
||||
});
|
||||
|
||||
let cmd = Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
let cmd = Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg(srv.url("/"))
|
||||
.arg("--wordlist")
|
||||
@@ -151,8 +149,7 @@ fn extractor_finds_same_relative_url_twice() {
|
||||
then.status(200);
|
||||
});
|
||||
|
||||
let cmd = Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
let cmd = Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg(srv.url("/"))
|
||||
.arg("--wordlist")
|
||||
@@ -194,8 +191,7 @@ fn extractor_finds_filtered_content() -> Result<(), Box<dyn std::error::Error>>
|
||||
then.status(200).body("im a little teapot");
|
||||
});
|
||||
|
||||
let cmd = Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
let cmd = Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg(srv.url("/"))
|
||||
.arg("--wordlist")
|
||||
@@ -266,8 +262,7 @@ fn extractor_finds_robots_txt_links_and_displays_files_or_scans_directories() {
|
||||
then.status(403);
|
||||
});
|
||||
|
||||
let cmd = Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
let cmd = Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg(srv.url("/"))
|
||||
.arg("--wordlist")
|
||||
@@ -341,8 +336,7 @@ fn extractor_finds_robots_txt_links_and_displays_files_non_recursive() {
|
||||
then.status(404);
|
||||
});
|
||||
|
||||
let cmd = Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
let cmd = Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg(srv.url("/"))
|
||||
.arg("--wordlist")
|
||||
@@ -448,8 +442,7 @@ fn extractor_finds_directory_listing_links_and_displays_files() {
|
||||
then.status(200).body("im a little teapot too"); // 22
|
||||
});
|
||||
|
||||
let cmd = Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
let cmd = Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg(srv.url("/"))
|
||||
.arg("--wordlist")
|
||||
@@ -557,8 +550,7 @@ fn extractor_finds_directory_listing_links_and_displays_files_non_recursive() {
|
||||
then.status(200).body("im a little teapot too"); // 22
|
||||
});
|
||||
|
||||
let cmd = Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
let cmd = Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg(srv.url("/"))
|
||||
.arg("--wordlist")
|
||||
@@ -613,8 +605,7 @@ fn extractor_recurses_into_403_directories() -> Result<(), Box<dyn std::error::E
|
||||
then.status(403);
|
||||
});
|
||||
|
||||
let cmd = Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
let cmd = Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg(srv.url("/"))
|
||||
.arg("--wordlist")
|
||||
@@ -685,8 +676,7 @@ fn robots_text_extraction_doesnt_run_with_dont_extract_links() {
|
||||
then.status(404);
|
||||
});
|
||||
|
||||
let cmd = Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
let cmd = Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg(srv.url("/"))
|
||||
.arg("--wordlist")
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
mod utils;
|
||||
use assert_cmd::cargo_bin;
|
||||
use assert_cmd::prelude::*;
|
||||
use httpmock::Method::GET;
|
||||
use httpmock::MockServer;
|
||||
@@ -24,8 +25,7 @@ fn filters_status_code_should_filter_response() {
|
||||
then.status(200).body("this is also a test of some import");
|
||||
});
|
||||
|
||||
let cmd = Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
let cmd = Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg(srv.url("/"))
|
||||
.arg("--wordlist")
|
||||
@@ -71,8 +71,7 @@ fn filters_lines_should_filter_response() {
|
||||
.body("this is also a test of some import\nwith 2 lines, no less");
|
||||
});
|
||||
|
||||
let cmd = Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
let cmd = Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg(srv.url("/"))
|
||||
.arg("--wordlist")
|
||||
@@ -117,8 +116,7 @@ fn filters_words_should_filter_response() {
|
||||
.body("this is also a test of some import\nwith 2 lines, no less");
|
||||
});
|
||||
|
||||
let cmd = Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
let cmd = Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg(srv.url("/"))
|
||||
.arg("--wordlist")
|
||||
@@ -163,8 +161,7 @@ fn filters_size_should_filter_response() {
|
||||
.body("this is also a test of some import\nwith 2 lines, no less");
|
||||
});
|
||||
|
||||
let cmd = Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
let cmd = Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg(srv.url("/"))
|
||||
.arg("--wordlist")
|
||||
@@ -222,8 +219,7 @@ fn filters_similar_should_filter_response() {
|
||||
then.status(200).body(mutated);
|
||||
});
|
||||
|
||||
let cmd = Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
let cmd = Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg(srv.url("/"))
|
||||
.arg("--wordlist")
|
||||
@@ -266,8 +262,7 @@ fn collect_backups_should_be_filtered() {
|
||||
.body("im a backup file, but filtered out because im not 200");
|
||||
});
|
||||
|
||||
let cmd = Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
let cmd = Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg(srv.url("/"))
|
||||
.arg("--wordlist")
|
||||
@@ -316,8 +311,7 @@ fn filters_regex_should_filter_response_based_on_headers() {
|
||||
.body("this is also a test");
|
||||
});
|
||||
|
||||
let cmd = Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
let cmd = Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg(srv.url("/"))
|
||||
.arg("--wordlist")
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
mod utils;
|
||||
use assert_cmd::cargo_bin;
|
||||
use assert_cmd::prelude::*;
|
||||
use assert_cmd::Command;
|
||||
use httpmock::Method::GET;
|
||||
use httpmock::{MockServer, Regex};
|
||||
use predicates::prelude::*;
|
||||
use std::process::Command;
|
||||
use utils::{setup_tmp_directory, teardown_tmp_directory};
|
||||
|
||||
#[test]
|
||||
@@ -12,8 +13,7 @@ use utils::{setup_tmp_directory, teardown_tmp_directory};
|
||||
fn test_single_target_cannot_connect() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let (tmp_dir, file) = setup_tmp_directory(&["LICENSE".to_string()], "wordlist")?;
|
||||
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg("http://fjdksafjkdsajfkdsajkfdsajkfsdjkdsfdsafdsafdsajkr3l2ajfdskafdsjk")
|
||||
.arg("--wordlist")
|
||||
@@ -37,12 +37,11 @@ fn test_two_targets_cannot_connect() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let urls = vec![not_real.clone(), not_real];
|
||||
let (tmp_dir, file) = setup_tmp_directory(&urls, "wordlist")?;
|
||||
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--stdin")
|
||||
.arg("--wordlist")
|
||||
.arg(file.as_os_str())
|
||||
.pipe_stdin(file)
|
||||
.stdin(std::fs::File::open(file)?)
|
||||
.unwrap()
|
||||
.assert()
|
||||
.success()
|
||||
@@ -70,12 +69,11 @@ fn test_one_good_and_one_bad_target_scan_succeeds() -> Result<(), Box<dyn std::e
|
||||
then.status(200).body("this is a test");
|
||||
});
|
||||
|
||||
let mut cmd = Command::cargo_bin("feroxbuster").unwrap();
|
||||
|
||||
cmd.arg("--stdin")
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--stdin")
|
||||
.arg("--wordlist")
|
||||
.arg(file.as_os_str())
|
||||
.pipe_stdin(file)
|
||||
.stdin(std::fs::File::open(file)?)
|
||||
.unwrap()
|
||||
.assert()
|
||||
.success()
|
||||
@@ -96,8 +94,7 @@ fn test_one_good_and_one_bad_target_scan_succeeds() -> Result<(), Box<dyn std::e
|
||||
fn test_single_target_cannot_connect_due_to_ssl_errors() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let (tmp_dir, file) = setup_tmp_directory(&["LICENSE".to_string()], "wordlist")?;
|
||||
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg("https://expired.badssl.com")
|
||||
.arg("--wordlist")
|
||||
@@ -132,13 +129,11 @@ fn test_two_good_targets_scan_succeeds() -> Result<(), Box<dyn std::error::Error
|
||||
then.status(403).body("this also is a test");
|
||||
});
|
||||
|
||||
let mut cmd = Command::cargo_bin("feroxbuster").unwrap();
|
||||
|
||||
cmd.arg("--stdin")
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--stdin")
|
||||
.arg("--wordlist")
|
||||
.arg(file.as_os_str())
|
||||
.pipe_stdin(file)
|
||||
.unwrap()
|
||||
.stdin(std::fs::File::open(file)?)
|
||||
.assert()
|
||||
.success()
|
||||
.stdout(
|
||||
@@ -168,8 +163,7 @@ fn test_static_wildcard_request_found() -> Result<(), Box<dyn std::error::Error>
|
||||
then.status(200).body("this is a test");
|
||||
});
|
||||
|
||||
let cmd = Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
let cmd = Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg(srv.url("/"))
|
||||
.arg("--wordlist")
|
||||
@@ -205,8 +199,7 @@ fn heuristics_static_wildcard_request_with_dont_filter() -> Result<(), Box<dyn s
|
||||
then.status(200).body("this is a test");
|
||||
});
|
||||
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg(srv.url("/"))
|
||||
.arg("--wordlist")
|
||||
@@ -289,8 +282,7 @@ fn heuristics_wildcard_test_with_two_static_wildcards_with_silent_enabled(
|
||||
.body("this is a testAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
|
||||
});
|
||||
|
||||
let cmd = Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
let cmd = Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg(srv.url("/"))
|
||||
.arg("--wordlist")
|
||||
@@ -341,8 +333,7 @@ fn heuristics_wildcard_test_that_auto_filtering_403s_still_allows_for_recursion_
|
||||
then.status(200);
|
||||
});
|
||||
|
||||
let cmd = Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
let cmd = Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg(srv.url("/"))
|
||||
.arg("--wordlist")
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
mod utils;
|
||||
use assert_cmd::Command;
|
||||
use assert_cmd::cargo_bin;
|
||||
use assert_cmd::prelude::*;
|
||||
use httpmock::Method::GET;
|
||||
use httpmock::{MockServer, Regex};
|
||||
use predicates::prelude::*;
|
||||
use std::fs::{read_dir, read_to_string};
|
||||
use std::process::Command;
|
||||
use utils::{setup_tmp_directory, teardown_tmp_directory};
|
||||
|
||||
#[test]
|
||||
@@ -16,8 +18,7 @@ fn main_use_root_owned_file_as_wordlist() {
|
||||
then.status(200).body("this is a test");
|
||||
});
|
||||
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg(srv.url("/"))
|
||||
.arg("--wordlist")
|
||||
@@ -41,8 +42,7 @@ fn main_use_empty_wordlist() -> Result<(), Box<dyn std::error::Error>> {
|
||||
then.status(200).body("this is a test");
|
||||
});
|
||||
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg(srv.url("/"))
|
||||
.arg("--wordlist")
|
||||
@@ -65,14 +65,12 @@ fn main_use_empty_stdin_targets() -> Result<(), Box<dyn std::error::Error>> {
|
||||
|
||||
// get_targets is called before scan, so the empty wordlist shouldn't trigger
|
||||
// the 'Did not find any words' error
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--stdin")
|
||||
.arg("--wordlist")
|
||||
.arg(file.as_os_str())
|
||||
.arg("-vvv")
|
||||
.pipe_stdin(file)
|
||||
.unwrap()
|
||||
.stdin(std::fs::File::open(file)?)
|
||||
.assert()
|
||||
.success()
|
||||
.stderr(
|
||||
@@ -106,8 +104,7 @@ fn main_parallel_spawns_children() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let (tgt_tmp_dir, targets) =
|
||||
setup_tmp_directory(&[t1.url("/"), t2.url("/"), t3.url("/")], "targets")?;
|
||||
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.env("RUST_LOG", "trace")
|
||||
.arg("--stdin")
|
||||
.arg("--parallel")
|
||||
@@ -117,8 +114,7 @@ fn main_parallel_spawns_children() -> Result<(), Box<dyn std::error::Error>> {
|
||||
.arg(outfile.as_os_str())
|
||||
.arg("--wordlist")
|
||||
.arg(wordlist.as_os_str())
|
||||
.pipe_stdin(targets)
|
||||
.unwrap()
|
||||
.stdin(std::fs::File::open(targets)?)
|
||||
.assert()
|
||||
.success()
|
||||
.stderr(
|
||||
@@ -170,8 +166,7 @@ fn main_parallel_creates_output_directory() -> Result<(), Box<dyn std::error::Er
|
||||
let (tgt_tmp_dir, targets) =
|
||||
setup_tmp_directory(&[t1.url("/"), t2.url("/"), t3.url("/")], "targets")?;
|
||||
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--stdin")
|
||||
.arg("--quiet")
|
||||
.arg("--parallel")
|
||||
@@ -180,8 +175,7 @@ fn main_parallel_creates_output_directory() -> Result<(), Box<dyn std::error::Er
|
||||
.arg(outfile.as_os_str())
|
||||
.arg("--wordlist")
|
||||
.arg(wordlist.as_os_str())
|
||||
.pipe_stdin(targets)
|
||||
.unwrap()
|
||||
.stdin(std::fs::File::open(targets)?)
|
||||
.assert()
|
||||
.success()
|
||||
.stderr(
|
||||
@@ -276,8 +270,7 @@ fn main_download_wordlist_from_url() -> Result<(), Box<dyn std::error::Error>> {
|
||||
then.status(200);
|
||||
});
|
||||
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.current_dir(&tmp_dir)
|
||||
.arg("--url")
|
||||
.arg(srv.url("/"))
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
use assert_cmd::Command;
|
||||
use assert_cmd::cargo_bin;
|
||||
use assert_cmd::prelude::*;
|
||||
use predicates::prelude::*;
|
||||
use std::process::Command;
|
||||
|
||||
#[test]
|
||||
/// specify an incorrect param (-fc) with --help after it on the command line
|
||||
@@ -14,8 +16,7 @@ use predicates::prelude::*;
|
||||
/// the new behavior we expect to see is to print the long form help message, of which
|
||||
/// Ludicrous speed... go! is near the bottom of that output, so we can test for that
|
||||
fn parser_incorrect_param_with_tack_tack_help() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("-fc")
|
||||
.arg("--help")
|
||||
.assert()
|
||||
@@ -36,8 +37,7 @@ fn parser_incorrect_param_with_tack_tack_help() {
|
||||
/// the new behavior we expect to see is to print the short form help message, of which
|
||||
/// "[CAUTION] 4 -v's is probably too much" is near the bottom of that output, so we can test for that
|
||||
fn parser_incorrect_param_with_tack_h() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("-fc")
|
||||
.arg("-h")
|
||||
.assert()
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
mod utils;
|
||||
use assert_cmd::cargo_bin;
|
||||
use assert_cmd::prelude::*;
|
||||
use httpmock::Method::GET;
|
||||
use httpmock::MockServer;
|
||||
@@ -48,8 +49,7 @@ fn auto_bail_cancels_scan_with_403s() {
|
||||
.body("these guys need to be 403 in order to trigger 90% threshold");
|
||||
});
|
||||
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg(srv.url("/"))
|
||||
.arg("--wordlist")
|
||||
@@ -130,8 +130,7 @@ fn auto_bail_cancels_scan_with_429s() {
|
||||
.body("these guys need to be 403 in order to trigger 90% threshold");
|
||||
});
|
||||
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg(srv.url("/"))
|
||||
.arg("--wordlist")
|
||||
@@ -213,8 +212,7 @@ fn auto_tune_slows_scan_with_429s() {
|
||||
|
||||
let start = Instant::now();
|
||||
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg(srv.url("/"))
|
||||
.arg("--wordlist")
|
||||
@@ -277,8 +275,7 @@ fn auto_tune_slows_scan_with_403s() {
|
||||
|
||||
let start = Instant::now();
|
||||
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg(srv.url("/"))
|
||||
.arg("--wordlist")
|
||||
@@ -342,8 +339,7 @@ fn auto_tune_slows_scan_with_general_errors() {
|
||||
|
||||
let start = Instant::now();
|
||||
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg(srv.url("/"))
|
||||
.arg("--wordlist")
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
mod utils;
|
||||
|
||||
use assert_cmd::Command;
|
||||
use assert_cmd::cargo_bin;
|
||||
use assert_cmd::prelude::*;
|
||||
use httpmock::prelude::*;
|
||||
use httpmock::MockServer;
|
||||
use regex::Regex;
|
||||
use std::fs::{read_to_string, write};
|
||||
use std::process::Command;
|
||||
use utils::{setup_tmp_directory, teardown_tmp_directory};
|
||||
|
||||
/// Helper to create a test wordlist with controllable patterns
|
||||
@@ -63,8 +65,7 @@ fn scenario_high_403_rate() {
|
||||
then.status(403).body("Forbidden");
|
||||
});
|
||||
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg(srv.url("/"))
|
||||
.arg("--wordlist")
|
||||
@@ -124,8 +125,7 @@ fn scenario_high_429_rate() {
|
||||
then.status(429).body("Too Many Requests");
|
||||
});
|
||||
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg(srv.url("/"))
|
||||
.arg("--wordlist")
|
||||
@@ -191,8 +191,7 @@ fn scenario_recovery_pattern() {
|
||||
then.status(403).body("Forbidden");
|
||||
});
|
||||
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg(srv.url("/"))
|
||||
.arg("--wordlist")
|
||||
@@ -267,8 +266,7 @@ fn scenario_mixed_steady_state() {
|
||||
then.status(429).body("Too Many Requests");
|
||||
});
|
||||
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg(srv.url("/"))
|
||||
.arg("--wordlist")
|
||||
@@ -340,8 +338,7 @@ fn scenario_capped_auto_tune() {
|
||||
then.status(403).body("Forbidden");
|
||||
});
|
||||
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg(srv.url("/"))
|
||||
.arg("--wordlist")
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
mod utils;
|
||||
use assert_cmd::cargo_bin;
|
||||
use assert_cmd::prelude::*;
|
||||
use httpmock::Method::GET;
|
||||
use httpmock::MockServer;
|
||||
@@ -19,8 +20,7 @@ fn response_size_limit_small_response_not_truncated() {
|
||||
then.status(200).body(small_body);
|
||||
});
|
||||
|
||||
let cmd = Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
let cmd = Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg(srv.url("/"))
|
||||
.arg("--wordlist")
|
||||
@@ -55,8 +55,7 @@ fn response_size_limit_large_response_truncated() {
|
||||
then.status(200).body(&large_body);
|
||||
});
|
||||
|
||||
let cmd = Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
let cmd = Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg(srv.url("/"))
|
||||
.arg("--wordlist")
|
||||
@@ -109,8 +108,7 @@ fn response_size_limit_mixed_response_sizes() {
|
||||
then.status(200).body(&large_body);
|
||||
});
|
||||
|
||||
let cmd = Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
let cmd = Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg(srv.url("/"))
|
||||
.arg("--wordlist")
|
||||
@@ -173,8 +171,7 @@ fn response_size_limit_default_4mb() {
|
||||
then.status(200).body(&body);
|
||||
});
|
||||
|
||||
let cmd = Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
let cmd = Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg(srv.url("/"))
|
||||
.arg("--wordlist")
|
||||
@@ -206,8 +203,7 @@ fn response_size_limit_very_small_limit() {
|
||||
then.status(200).body(body);
|
||||
});
|
||||
|
||||
let cmd = Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
let cmd = Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg(srv.url("/"))
|
||||
.arg("--wordlist")
|
||||
@@ -242,8 +238,7 @@ fn response_size_limit_with_redirects() {
|
||||
.body(&large_redirect_body);
|
||||
});
|
||||
|
||||
let cmd = Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
let cmd = Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg(srv.url("/"))
|
||||
.arg("--wordlist")
|
||||
@@ -281,8 +276,7 @@ fn response_size_limit_with_error_responses() {
|
||||
then.status(500).body(&large_error_body);
|
||||
});
|
||||
|
||||
let cmd = Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
let cmd = Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg(srv.url("/"))
|
||||
.arg("--wordlist")
|
||||
@@ -318,8 +312,7 @@ fn response_size_limit_json_output_includes_truncated_field() {
|
||||
then.status(200).body(&large_body);
|
||||
});
|
||||
|
||||
let cmd = Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
let cmd = Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg(srv.url("/"))
|
||||
.arg("--wordlist")
|
||||
@@ -350,8 +343,7 @@ fn response_size_limit_json_output_includes_truncated_field() {
|
||||
fn response_size_limit_shows_in_banner() {
|
||||
let (tmp_dir, file) = setup_tmp_directory(&["test".to_string()], "wordlist").unwrap();
|
||||
|
||||
let cmd = Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
let cmd = Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg("http://127.0.0.1:1") // Non-existent server to trigger quick exit
|
||||
.arg("--wordlist")
|
||||
@@ -385,8 +377,7 @@ fn response_size_limit_exact_limit() {
|
||||
then.status(200).body(&exact_body);
|
||||
});
|
||||
|
||||
let cmd = Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
let cmd = Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg(srv.url("/"))
|
||||
.arg("--wordlist")
|
||||
@@ -425,8 +416,7 @@ fn response_size_limit_from_config_file() {
|
||||
then.status(200).body(&large_body);
|
||||
});
|
||||
|
||||
let cmd = Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
let cmd = Command::new(cargo_bin!("feroxbuster"))
|
||||
.current_dir(tmp_dir.path())
|
||||
.arg("--url")
|
||||
.arg(srv.url("/"))
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
mod utils;
|
||||
use assert_cmd::Command;
|
||||
use assert_cmd::cargo_bin;
|
||||
use assert_cmd::prelude::*;
|
||||
use httpmock::Method::GET;
|
||||
use httpmock::MockServer;
|
||||
use predicates::prelude::*;
|
||||
use std::fs::{read_to_string, write};
|
||||
use std::path::Path;
|
||||
use std::process::Command;
|
||||
use std::time;
|
||||
use utils::{setup_tmp_directory, teardown_tmp_directory};
|
||||
|
||||
@@ -67,8 +69,7 @@ fn resume_scan_works() {
|
||||
|
||||
let (tmp_dir2, state_file) = setup_tmp_directory(&[state_file_contents], "state-file").unwrap();
|
||||
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("-vvv")
|
||||
.arg("--resume-from")
|
||||
.arg(state_file.as_os_str())
|
||||
@@ -115,16 +116,14 @@ fn time_limit_enforced_when_specified() {
|
||||
let lower_bound = time::Duration::new(5, 0);
|
||||
let upper_bound = time::Duration::new(6, 0);
|
||||
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--stdin")
|
||||
.arg("-vv")
|
||||
.arg("--wordlist")
|
||||
.arg(file.as_os_str())
|
||||
.arg("--time-limit")
|
||||
.arg("5s")
|
||||
.pipe_stdin(targets)
|
||||
.unwrap()
|
||||
.stdin(std::fs::File::open(targets).unwrap())
|
||||
.assert()
|
||||
.failure();
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
mod utils;
|
||||
use assert_cmd::cargo_bin;
|
||||
use assert_cmd::prelude::*;
|
||||
use httpmock::Method::GET;
|
||||
use httpmock::MockServer;
|
||||
@@ -19,8 +20,7 @@ fn scanner_single_request_scan() -> Result<(), Box<dyn std::error::Error>> {
|
||||
then.status(200).body("this is a test");
|
||||
});
|
||||
|
||||
let cmd = Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
let cmd = Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg(srv.url("/"))
|
||||
.arg("--wordlist")
|
||||
@@ -72,8 +72,7 @@ fn scanner_recursive_request_scan() -> Result<(), Box<dyn std::error::Error>> {
|
||||
.body("this is a test and is more bytes than other ones");
|
||||
});
|
||||
|
||||
let cmd = Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
let cmd = Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg(srv.url("/"))
|
||||
.arg("--wordlist")
|
||||
@@ -135,8 +134,7 @@ fn scanner_recursive_request_scan_using_only_success_responses(
|
||||
.body("this is a test and is more bytes than other ones");
|
||||
});
|
||||
|
||||
let cmd = Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
let cmd = Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg(srv.url("/"))
|
||||
.arg("--wordlist")
|
||||
@@ -178,8 +176,7 @@ fn scanner_single_request_scan_with_file_output() -> Result<(), Box<dyn std::err
|
||||
|
||||
let outfile = tmp_dir.path().join("output");
|
||||
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg(srv.url("/"))
|
||||
.arg("--wordlist")
|
||||
@@ -214,8 +211,7 @@ fn scanner_single_request_scan_with_file_output_and_tack_q(
|
||||
|
||||
let outfile = tmp_dir.path().join("output");
|
||||
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg(srv.url("/"))
|
||||
.arg("--wordlist")
|
||||
@@ -250,8 +246,7 @@ fn scanner_single_request_scan_with_invalid_file_output() -> Result<(), Box<dyn
|
||||
|
||||
let outfile = tmp_dir.path(); // outfile is a directory
|
||||
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg(srv.url("/"))
|
||||
.arg("--wordlist")
|
||||
@@ -281,8 +276,7 @@ fn scanner_single_request_quiet_scan() -> Result<(), Box<dyn std::error::Error>>
|
||||
then.status(200).body("this is a test");
|
||||
});
|
||||
|
||||
let cmd = Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
let cmd = Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg(srv.url("/"))
|
||||
.arg("--wordlist")
|
||||
@@ -317,8 +311,7 @@ fn scanner_single_request_returns_301_without_location_header(
|
||||
then.status(301).body("this is a test");
|
||||
});
|
||||
|
||||
let cmd = Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
let cmd = Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg(srv.url("/"))
|
||||
.arg("--wordlist")
|
||||
@@ -358,8 +351,7 @@ fn scanner_single_request_replayed_to_proxy() -> Result<(), Box<dyn std::error::
|
||||
then.status(200).body("this is a test");
|
||||
});
|
||||
|
||||
let cmd = Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
let cmd = Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg(srv.url("/"))
|
||||
.arg("--wordlist")
|
||||
@@ -402,8 +394,7 @@ fn scanner_single_request_scan_with_filtered_result() -> Result<(), Box<dyn std:
|
||||
then.status(200).body("this is a test");
|
||||
});
|
||||
|
||||
let cmd = Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
let cmd = Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg(srv.url("/"))
|
||||
.arg("--wordlist")
|
||||
@@ -443,8 +434,7 @@ fn scanner_single_request_scan_with_debug_logging() {
|
||||
|
||||
let outfile = tmp_dir.path().join("debug.log");
|
||||
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg(srv.url("/"))
|
||||
.arg("--wordlist")
|
||||
@@ -481,8 +471,7 @@ fn scanner_single_request_scan_with_debug_logging_as_json() {
|
||||
|
||||
let outfile = tmp_dir.path().join("debug.log");
|
||||
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg(srv.url("/"))
|
||||
.arg("--wordlist")
|
||||
@@ -530,8 +519,7 @@ fn scanner_single_request_scan_with_regex_filtered_result() {
|
||||
.body("this is a test\nThat rug really tied the room together");
|
||||
});
|
||||
|
||||
let cmd = Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
let cmd = Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg(srv.url("/"))
|
||||
.arg("--wordlist")
|
||||
@@ -578,8 +566,7 @@ fn scanner_recursion_works_with_403_directories() {
|
||||
.body("this is a test\nThat rug really tied the room together");
|
||||
});
|
||||
|
||||
let cmd = Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
let cmd = Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg(srv.url("/"))
|
||||
.arg("--wordlist")
|
||||
@@ -628,8 +615,7 @@ fn rate_limit_enforced_when_specified() {
|
||||
let now = time::Instant::now();
|
||||
let lower_bound = time::Duration::new(5, 0);
|
||||
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg(srv.url("/"))
|
||||
.arg("--wordlist")
|
||||
@@ -665,8 +651,7 @@ fn add_discovered_extension_updates_bars_and_stats() {
|
||||
|
||||
assert!(!file_path.exists());
|
||||
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg(srv.url("/"))
|
||||
.arg("--wordlist")
|
||||
@@ -735,8 +720,7 @@ fn collect_backups_makes_appropriate_requests() {
|
||||
})
|
||||
.collect();
|
||||
|
||||
let cmd = Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
let cmd = Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg(srv.url("/"))
|
||||
.arg("--collect-backups")
|
||||
@@ -831,8 +815,7 @@ fn collect_words_makes_appropriate_requests() {
|
||||
})
|
||||
.collect();
|
||||
|
||||
let cmd = Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
let cmd = Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg(srv.url("/"))
|
||||
.arg("-vv")
|
||||
@@ -890,8 +873,7 @@ fn scanner_forced_recursion_ignores_normal_redirect_logic() -> Result<(), Box<dy
|
||||
|
||||
let outfile = tmp_dir.path().join("output");
|
||||
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg(srv.url("/"))
|
||||
.arg("--wordlist")
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
mod utils;
|
||||
use assert_cmd::cargo_bin;
|
||||
use assert_cmd::prelude::*;
|
||||
use httpmock::Method::GET;
|
||||
use httpmock::MockServer;
|
||||
@@ -26,8 +27,7 @@ fn word_and_status_makes_a_response_unique_and_isnt_seen() -> Result<(), Box<dyn
|
||||
.body(srv.url("this is a word count supplier"));
|
||||
});
|
||||
|
||||
let cmd = Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
let cmd = Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg(srv.url("/"))
|
||||
.arg("--wordlist")
|
||||
@@ -69,8 +69,7 @@ fn bytes_and_status_makes_a_redirect_response_unique_and_isnt_seen(
|
||||
.body(srv.url("this is a word count supplier")); // redirect + same body
|
||||
});
|
||||
|
||||
let cmd = Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
let cmd = Command::new(cargo_bin!("feroxbuster"))
|
||||
.arg("--url")
|
||||
.arg(srv.url("/"))
|
||||
.arg("--wordlist")
|
||||
|
||||
Reference in New Issue
Block a user