Skip to content

Instantly share code, notes, and snippets.

@namishelex01
Last active August 25, 2025 22:14
Show Gist options
  • Save namishelex01/fee1214458f610b0e291bb42c1271b71 to your computer and use it in GitHub Desktop.
Save namishelex01/fee1214458f610b0e291bb42c1271b71 to your computer and use it in GitHub Desktop.
#!/usr/bin/env bash
# bb-min-setup.sh — Minimal bug bounty setup for Raspberry Pi 5 (Raspberry Pi OS 64‑bit, ARM64)
# Focus: web app recon + vuln discovery ONLY (no pentest/forensics/heavy stuff).
# PEP 668 safe (pipx / per-tool venvs). Prefers official linux_arm64 binaries to avoid Go-compat hiccups.
# Idempotent: safe to re-run.
set -euo pipefail
if [[ $EUID -eq 0 ]]; then
echo "Run as a normal user (will sudo as needed), not root." >&2
exit 1
fi
log() { printf "\n==> %s\n" "$*"; }
apt_i(){ sudo DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends "$@"; }
ensure_line(){ local L="$1" F="$2"; grep -qxF "$L" "$F" 2>/dev/null || echo "$L" >> "$F"; }
SHELL_RC="$HOME/.bashrc"
TOOLS="$HOME/tools"
BIN="$HOME/.local/bin"
VENVS="$HOME/venvs"
mkdir -p "$TOOLS" "$BIN" "$VENVS" "$HOME/wordlists"
log "System update + tiny base deps"
sudo apt-get update -y
sudo apt-get -y full-upgrade
apt_i git curl wget ca-certificates jq unzip tar xz-utils \
build-essential pkg-config \
python3 python3-venv python3-pip pipx \
golang ripgrep
# PATHs
ensure_line 'export GOPATH="$HOME/go"' "$SHELL_RC"
ensure_line 'export PATH="$PATH:$HOME/go/bin:$HOME/.local/bin"' "$SHELL_RC"
export GOPATH="$HOME/go"
export PATH="$PATH:$HOME/go/bin:$BIN"
# pipx path (PEP 668 friendly)
python3 -m pipx ensurepath 2>/dev/null || true
export PATH="$HOME/.local/bin:$PATH"
# --- Helpers ---------------------------------------------------------------
# Install a GitHub release asset that matches a pattern and place the binary at $BIN/<dst>
install_from_release() {
# owner repo dst_name pattern
local owner="$1" repo="$2" dst="$3" pattern="$4"
local api="https://api.github.com/repos/$owner/$repo/releases/latest"
local tag asset_url name tmp
tag="$(curl -fsSL "$api" | jq -r .tag_name)"
if [[ -z "$tag" || "$tag" == "null" ]]; then
echo " [!] Could not determine latest tag for $owner/$repo" >&2
return 1
fi
asset_url="$(curl -fsSL "https://api.github.com/repos/$owner/$repo/releases/tags/$tag" \
| jq -r --arg pat "$pattern" '.assets[] | select(.name|test($pat)) | .browser_download_url' | head -n1)"
if [[ -z "$asset_url" ]]; then
echo " [!] No asset matched '$pattern' for $owner/$repo@$tag" >&2
return 1
fi
tmp="$(mktemp -d)"
curl -fsSL "$asset_url" -o "$tmp/asset"
# Detect archive type; extract and find the binary
if file "$tmp/asset" | grep -qi 'gzip compressed data'; then
tar -xzf "$tmp/asset" -C "$tmp"
elif file "$tmp/asset" | grep -qi 'Zip archive data'; then
unzip -q "$tmp/asset" -d "$tmp"
else
# maybe it's a raw binary
mv "$tmp/asset" "$tmp/$dst"
fi
# Find candidate binary in extracted dir
local binpath
binpath="$(find "$tmp" -maxdepth 2 -type f -name "$dst" -o -name "$dst-linux" 2>/dev/null | head -n1)"
if [[ -z "$binpath" ]]; then
# some projects ship as <name>_linux_arm64 or similar
binpath="$(find "$tmp" -maxdepth 2 -type f -perm -111 | grep -E "/$dst(_linux.*|)$" || true)"
fi
if [[ -z "$binpath" ]]; then
echo " [!] Could not locate $dst inside release asset for $owner/$repo" >&2
rm -rf "$tmp"; return 1
fi
install -m 0755 "$binpath" "$BIN/$dst"
rm -rf "$tmp"
echo " [+] Installed $dst -> $BIN/$dst"
}
# Minimal Go version compare (returns 0 if have >= need)
go_meets() {
local need="$1"
local have
have="$(go version 2>/dev/null | awk '{print $3}' | sed 's/go//')"
[[ -z "$have" ]] && return 1
printf '%s\n' "$need" "$have" | sort -V | tail -n1 | grep -qx "$have"
}
# Install a tool: prefer GitHub linux_arm64 binary; if unavailable, try `go install`
install_tool_bin_first() {
# owner repo bin_name pattern go_pkg
local owner="$1" repo="$2" binname="$3" pattern="$4" gopkg="$5"
if command -v "$binname" >/dev/null 2>&1; then
echo " [-] $binname already installed"
return 0
fi
echo " [*] Trying binary install for $binname..."
if install_from_release "$owner" "$repo" "$binname" "$pattern"; then
return 0
fi
if [[ -n "$gopkg" ]]; then
echo " [*] Fallback to go install: $gopkg"
go install -v "$gopkg" || {
echo " [!] Failed to install $binname via go. Skipping." >&2
return 1
}
fi
}
# Helper to install a repo tool into its own venv and add a wrapper
mkpytool () {
local name="$1" repo="$2" entry="$3"
local root="$VENVS/$name"
if ! command -v "$name" >/dev/null 2>&1; then
log "Installing $name (venv)"
if [[ ! -d "$root" ]]; then
python3 -m venv "$root"
"$root/bin/pip" install --upgrade pip wheel setuptools >/dev/null
git -C "$TOOLS" clone --depth=1 "$repo" "$TOOLS/$name"
if [[ -f "$TOOLS/$name/requirements.txt" ]]; then
"$root/bin/pip" install -r "$TOOLS/$name/requirements.txt" >/dev/null
fi
cat > "$BIN/$name" <<EOF
#!/usr/bin/env bash
exec "$root/bin/python" "$TOOLS/$name/$entry" "\$@"
EOF
chmod +x "$BIN/$name"
fi
fi
}
# --- Core installs ---------------------------------------------------------
log "Installing core *binary-first* tools (ARM64 releases where possible)"
# Per your request: ALWAYS binary for subfinder (no Go build to avoid v2.8.0 Go>=1.24 issue)
install_from_release "projectdiscovery" "subfinder" "subfinder" 'linux_arm64\.(tar\.gz|zip)$' || {
echo "[!] Subfinder binary install failed." >&2; exit 1;
}
# ProjectDiscovery: try binaries first, then `go install` fallback
install_tool_bin_first "projectdiscovery" "httpx" "httpx" 'linux_arm64\.(tar\.gz|zip)$' "github.com/projectdiscovery/httpx/cmd/httpx@latest"
install_tool_bin_first "projectdiscovery" "naabu" "naabu" 'linux_arm64\.(tar\.gz|zip)$' "github.com/projectdiscovery/naabu/v2/cmd/naabu@latest"
install_tool_bin_first "projectdiscovery" "katana" "katana" 'linux_arm64\.(tar\.gz|zip)$' "github.com/projectdiscovery/katana/cmd/katana@latest"
install_tool_bin_first "projectdiscovery" "nuclei" "nuclei" 'linux_arm64\.(tar\.gz|zip)$' "github.com/projectdiscovery/nuclei/v3/cmd/nuclei@latest"
# ffuf (binary-first)
install_tool_bin_first "ffuf" "ffuf" "ffuf" 'linux_arm64\.(tar\.gz|zip)$' "github.com/ffuf/ffuf/v2@latest"
# gau (binary-first), repo: lc/gau (v2 has releases)
install_tool_bin_first "lc" "gau" "gau" 'linux_arm64\.(tar\.gz|zip)$' "github.com/lc/gau/v2/cmd/gau@latest"
# dalfox (binary-first)
install_tool_bin_first "hahwul" "dalfox" "dalfox" 'linux_arm64\.(tar\.gz|zip)$' "github.com/hahwul/dalfox/v2@latest"
# Tools that usually compile fine against older Go (source-first)
# If you hit version issues later, we can swap to binary patterns or pin versions.
go install github.com/tomnomnom/waybackurls@latest || true
go install github.com/tomnomnom/anew@latest || true
go install github.com/tomnomnom/qsreplace@latest || true
# subzy (binary-first if available; otherwise go)
install_tool_bin_first "LukaSikic" "subzy" "subzy" 'linux_arm64\.(tar\.gz|zip)$' "github.com/LukaSikic/subzy@latest"
# kxss (source-first; small tool)
go install github.com/Emoe/kxss@latest || true
log "Installing minimal Python CLI tools with pipx (isolated)"
pipx install arjun >/dev/null 2>&1 || true
pipx install uro >/dev/null 2>&1 || true
pipx install dirsearch >/dev/null 2>&1 || true
log "Installing small repo-based helpers into their own venvs"
mkpytool "secretfinder" "https://github.com/m4ll0k/SecretFinder.git" "SecretFinder.py"
mkpytool "corsy" "https://github.com/s0md3v/Corsy.git" "corsy.py"
log "Nuclei templates"
nuclei -update-templates || true
log "Installing sqlmap via apt"
apt_i sqlmap
log "Fetching lean wordlists (avoid full SecLists to stay small)"
if [[ ! -f "$HOME/wordlists/raft-small-directories.txt" ]]; then
curl -fsSL -o "$HOME/wordlists/raft-small-directories.txt" \
https://raw.githubusercontent.com/danielmiessler/SecLists/master/Discovery/Web-Content/raft-small-directories.txt
fi
if [[ ! -f "$HOME/wordlists/common.txt" ]]; then
curl -fsSL -o "$HOME/wordlists/common.txt" \
https://raw.githubusercontent.com/danielmiessler/SecLists/master/Discovery/Web-Content/common.txt
fi
if [[ ! -f "$HOME/wordlists/params-small.txt" ]]; then
curl -fsSL -o "$HOME/wordlists/params-small.txt" \
https://raw.githubusercontent.com/assetnote/wordlists/master/data/parameters/minimal-params.txt
fi
log "Creating tiny workflow wrappers in ~/.local/bin"
cat > "$BIN/bb-subenum" <<'EOF'
#!/usr/bin/env bash
# Usage: bb-subenum example.com > subs.txt
set -euo pipefail
domain="${1:?domain required}"
subfinder -silent -all -d "$domain" | anew
EOF
chmod +x "$BIN/bb-subenum"
cat > "$BIN/bb-probe" <<'EOF'
#!/usr/bin/env bash
# Usage: cat subs.txt | bb-probe > hosts.json
set -euo pipefail
httpx -silent -follow-redirects -status-code -title -tech-detect -json
EOF
chmod +x "$BIN/bb-probe"
cat > "$BIN/bb-crawl" <<'EOF'
#!/usr/bin/env bash
# Usage: jq -r '.[].url' hosts.json | bb-crawl > urls.txt
set -euo pipefail
katana -silent -jc -fx -ef woff,woff2,png,jpg,jpeg,gif,svg,ttf -ps -kf
EOF
chmod +x "$BIN/bb-crawl"
cat > "$BIN/bb-urls" <<'EOF'
#!/usr/bin/env bash
# Usage: echo example.com | bb-urls > allurls.txt
set -euo pipefail
gau -subs | anew | uro
EOF
chmod +x "$BIN/bb-urls"
cat > "$BIN/bb-nuclei" <<'EOF'
#!/usr/bin/env bash
# Usage: jq -r '.[].url' hosts.json | bb-nuclei
set -euo pipefail
nuclei -silent -rl 50 -c 50 -severity low,medium,high,critical
EOF
chmod +x "$BIN/bb-nuclei"
cat > "$BIN/bb-xss" <<'EOF'
#!/usr/bin/env bash
# Usage: cat urls.txt | bb-xss
set -euo pipefail
rg -N 'https?://.*\?.*=.*' -o | anew | dalfox pipe --silence --skip-bav -o dalfox-results.txt
echo "dalfox-results.txt written."
EOF
chmod +x "$BIN/bb-xss"
cat > "$BIN/bb-dirs" <<'EOF'
#!/usr/bin/env bash
# Usage: bb-dirs https://target.tld [wordlist]
set -euo pipefail
url="${1:?URL required}"
wordlist="${2:-$HOME/wordlists/raft-small-directories.txt}"
ffuf -u "$url/FUZZ" -w "$wordlist" -mc 200,204,301,302,307,401,403 -fs 0
EOF
chmod +x "$BIN/bb-dirs"
cat > "$BIN/bb-params" <<'EOF'
#!/usr/bin/env bash
# Usage: bb-params https://target.tld
set -euo pipefail
url="${1:?Base URL required}"
arjun -u "$url" -w "$HOME/wordlists/params-small.txt" -oT -
EOF
chmod +x "$BIN/bb-params"
log "Shell quality-of-life"
ensure_line 'alias ll="ls -alF"' "$SHELL_RC"
ensure_line '# Bug bounty GOPATH and local bin' "$SHELL_RC"
ensure_line 'export PATH="$PATH:$HOME/go/bin:$HOME/.local/bin"' "$SHELL_RC"
log "Health check (quick versions)"
check_bin () { printf "%-12s: " "$1"; if command -v "$1" >/dev/null 2>&1; then "$1" -version 2>/dev/null | head -n1 || echo "installed"; else echo "missing"; fi; }
for b in subfinder httpx naabu katana nuclei ffuf gau waybackurls anew subzy qsreplace dalfox kxss sqlmap dirsearch arjun secretfinder corsy; do
check_bin "$b" || true
done
echo
log "Done. Open a new shell or 'source ~/.bashrc' to refresh PATH."
echo "Wordlists: $HOME/wordlists"
echo "Tools: $TOOLS"
echo "Wrappers: $BIN"
echo "Tip: run 'nuclei -update-templates' occasionally."
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment