chore: auto-commit 2026-04-24 20:11
This commit is contained in:
parent
3915fa975f
commit
816e056ba1
13 changed files with 2711 additions and 77 deletions
157
AttackSurface/README.md
Normal file
157
AttackSurface/README.md
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
# AASD — API Attack Surface Discovery
|
||||
|
||||
Interactive booth application for GITEX 2026. Visitors enter a corporate email, and AASD runs a full attack surface discovery pipeline:
|
||||
|
||||
**Email → Domain Discovery → GoTestWAF Scan → AI Resilience Report**
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
Visitor Email
|
||||
│
|
||||
▼
|
||||
┌─────────────────┐
|
||||
│ /start (POST) │ Email validation + domain extraction
|
||||
└────────┬────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────┐
|
||||
│ domain-scan │ Passive subdomain enumeration (15s timeout)
|
||||
└────────┬────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────┐
|
||||
│ GoTestWAF │ WAF penetration test against Wallarm endpoint (120s)
|
||||
└────────┬────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────┐
|
||||
│ DeepSeek AI │ Generate resilience narrative from scan results
|
||||
└────────┬────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────┐
|
||||
│ HTML Report │ Static report served at /reports/<token>.html
|
||||
└─────────────────┘
|
||||
```
|
||||
|
||||
## Tech Stack
|
||||
|
||||
| Component | Technology |
|
||||
|-----------|-----------|
|
||||
| Backend | Go 1.25 — Gin web framework |
|
||||
| Frontend | HTML, JavaScript, Tailwind CSS (CDN) |
|
||||
| WAF Scanner | GoTestWAF |
|
||||
| Domain Discovery | domain-scan |
|
||||
| AI Narrative | DeepSeek API |
|
||||
| Email | SMTP (OpenXchange) |
|
||||
|
||||
## Quick Start (Development)
|
||||
|
||||
```bash
|
||||
# Option 1: Deploy via install script
|
||||
cd AttackSurface
|
||||
sudo bash install.sh
|
||||
|
||||
# Option 2: Run from dist/ directly
|
||||
cd AttackSurface/dist
|
||||
./aasd
|
||||
|
||||
# Option 3: Build from source
|
||||
cd AttackSurface/src
|
||||
go build -o ../dist/aasd ./cmd/aasd/
|
||||
cd ../dist
|
||||
./aasd
|
||||
```
|
||||
|
||||
## Endpoints
|
||||
|
||||
| Path | Description | Auth |
|
||||
|------|-------------|------|
|
||||
| `/` | Frontend landing page (email entry) | Public |
|
||||
| `/start` (POST) | Submit email, trigger scan pipeline | Public |
|
||||
| `/analysing` | Scan progress visualization | Public |
|
||||
| `/simulation` | Legacy alias for `/analysing` | Public |
|
||||
| `/scan-status/:token` | Poll scan status (JSON) | Public |
|
||||
| `/qrcode?text=...` | QR code generator | Public |
|
||||
| `/admin-dashboard` | Consultant dashboard | Basic Auth |
|
||||
| `/email-report` (POST) | Send report via email | Public |
|
||||
| `/reports/*` | Generated static reports | Public |
|
||||
| `/report-data/:token` | Raw scan result JSON | Public |
|
||||
| `/api/scans` | Scan summaries (JSON) | Public |
|
||||
|
||||
## Configuration
|
||||
|
||||
Edit `dist/config.yaml` (or `/opt/aasd/config.yaml` after install) with your values:
|
||||
|
||||
```yaml
|
||||
ai:
|
||||
api_key: "sk-..." # DeepSeek API key for AI narratives
|
||||
server:
|
||||
base_url: "https://..." # Public URL for QR codes & email links
|
||||
admin:
|
||||
password: "..." # Admin dashboard password
|
||||
```
|
||||
|
||||
Alternatively, set these via environment variables:
|
||||
- `AASD_BASE_URL` — public-facing URL
|
||||
- `AASD_AI_API_KEY` — DeepSeek API key
|
||||
- `AASD_ADMIN_PASSWORD` — admin dashboard password
|
||||
- `SMTP_HOST`, `SMTP_PORT`, `SMTP_USERNAME`, `SMTP_PASSWORD`, `SMTP_FROM` — SMTP config
|
||||
|
||||
## Deployment (Production)
|
||||
|
||||
See `install.sh` for automated deployment. The script:
|
||||
|
||||
1. Creates an `app` system user if it doesn't exist
|
||||
2. Downloads the pre-built release archive from GitHub
|
||||
3. Extracts to `/opt/aasd`
|
||||
4. Creates a systemd service (`aasd.service`) for auto-start on boot
|
||||
5. Prompts for required configuration values
|
||||
|
||||
### Systemd Service Management
|
||||
|
||||
```bash
|
||||
sudo systemctl start aasd # Start the server
|
||||
sudo systemctl stop aasd # Stop the server
|
||||
sudo systemctl restart aasd # Restart
|
||||
sudo systemctl status aasd # Check status
|
||||
sudo journalctl -u aasd -f # Follow logs
|
||||
```
|
||||
|
||||
## Version
|
||||
|
||||
**2026-04.1** — See [CHANGELOG.md](docs/CHANGELOG.md) for full history.
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
AttackSurface/
|
||||
├── dist/ # Deployment directory (self-contained)
|
||||
│ ├── aasd # Compiled Go binary
|
||||
│ ├── config.yaml # Application configuration
|
||||
│ ├── prompt.txt # DeepSeek AI system prompt
|
||||
│ ├── gotestwaf # GoTestWAF binary
|
||||
│ ├── domain-scan # Domain discovery tool
|
||||
│ ├── testcases/ # GoTestWAF test cases
|
||||
│ ├── static/ # Frontend HTML/JS
|
||||
│ ├── templates/ # Go HTML templates
|
||||
│ ├── reports/ # Generated scan reports
|
||||
│ └── logs/ # Server logs
|
||||
├── src/ # Go source code
|
||||
│ ├── cmd/aasd/ # Main entry point
|
||||
│ ├── internal/ # Core packages (scanner, ai, mailer, report)
|
||||
│ ├── static/ # Frontend source files
|
||||
│ ├── templates/ # Template source files
|
||||
│ └── gotestwaf/ # Vendored GoTestWAF
|
||||
├── docs/ # Documentation
|
||||
│ ├── CHANGELOG.md
|
||||
│ └── DEVELOPMENT_STATUS.md
|
||||
├── install.sh # Automated deployment script
|
||||
├── VERSION
|
||||
└── README.md # This file
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
Proprietary — For internal event use at GITEX 2026.
|
||||
BIN
AttackSurface/dist/aasd
vendored
BIN
AttackSurface/dist/aasd
vendored
Binary file not shown.
9
AttackSurface/dist/config.yaml
vendored
9
AttackSurface/dist/config.yaml
vendored
|
|
@ -1,4 +1,11 @@
|
|||
ai:
|
||||
provider_url: "https://api.deepseek.com"
|
||||
api_key: "sk-0553e582701e4d2a893f68826e941726"
|
||||
api_key: "CHANGE_ME_DEEPSEEK_API_KEY" # <-- required: set your DeepSeek API key
|
||||
model: "deepseek-chat"
|
||||
|
||||
server:
|
||||
base_url: "CHANGE_ME_BASE_URL" # <-- required: e.g. https://aasd.sechpoint.app
|
||||
|
||||
admin:
|
||||
username: "sechpoint"
|
||||
password: "CHANGE_ME_ADMIN_PASSWORD" # <-- required: set a secure password
|
||||
|
|
|
|||
124
AttackSurface/dist/reports/4a48e516-2320-4db3-b717-75e5a72a28b6.html
vendored
Normal file
124
AttackSurface/dist/reports/4a48e516-2320-4db3-b717-75e5a72a28b6.html
vendored
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
||||
<title>Security Report - lohmar.co.uk - API Attack Surface Discovery</title>
|
||||
<script src="https://cdn.tailwindcss.com/"></script>
|
||||
</head>
|
||||
<body class="bg-slate-900 text-slate-100 min-h-screen">
|
||||
<div class="container mx-auto px-4 py-6 max-w-lg">
|
||||
<!-- Header -->
|
||||
<div class="text-center mb-6">
|
||||
<h1 class="text-2xl font-bold bg-gradient-to-r from-blue-400 to-purple-400 bg-clip-text text-transparent">AASD</h1>
|
||||
<p class="text-sm text-slate-400">API Attack Surface Discovery</p>
|
||||
</div>
|
||||
|
||||
<!-- Report Content -->
|
||||
<div class="bg-gray-900 text-gray-100 p-8 rounded-lg shadow-lg max-w-4xl mx-auto font-sans">
|
||||
<!-- Scan Overview -->
|
||||
<div class="mb-8 border-b border-gray-700 pb-6">
|
||||
<h2 class="text-2xl font-bold text-emerald-400 mb-4">🔍 Scan Overview</h2>
|
||||
<p class="text-lg leading-relaxed">
|
||||
Your application at <span class="text-cyan-300 font-mono">git.sechpoint.app</span> underwent a comprehensive security assessment on <strong>24 April 2026</strong>.
|
||||
The test sent <strong>816 requests</strong> covering OWASP API and Application Security categories. While the current configuration shows room for improvement,
|
||||
recognizing these gaps is the <span class="text-emerald-300 font-semibold">first step toward resilience</span>.
|
||||
The scan reveals exactly where your defenses need attention — empowering you to take targeted, effective action.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Key Findings -->
|
||||
<div class="mb-8 border-b border-gray-700 pb-6">
|
||||
<h2 class="text-2xl font-bold text-amber-400 mb-4">⚠️ Key Findings</h2>
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<div class="bg-gray-800 rounded-lg p-4 border-l-4 border-red-500">
|
||||
<p class="font-semibold text-red-300">API Security Grade: <span class="text-2xl">F</span></p>
|
||||
<p class="text-sm text-gray-400">0% of true-positive attacks were blocked</p>
|
||||
</div>
|
||||
<div class="bg-gray-800 rounded-lg p-4 border-l-4 border-red-500">
|
||||
<p class="font-semibold text-red-300">Application Security Grade: <span class="text-2xl">F</span></p>
|
||||
<p class="text-sm text-gray-400">0% of true-positive attacks were blocked</p>
|
||||
</div>
|
||||
<div class="bg-gray-800 rounded-lg p-4 border-l-4 border-yellow-500">
|
||||
<p class="font-semibold text-yellow-300">True-Negative Accuracy: <span class="text-xl">33.3%</span></p>
|
||||
<p class="text-sm text-gray-400">94 legitimate requests were incorrectly blocked</p>
|
||||
</div>
|
||||
<div class="bg-gray-800 rounded-lg p-4 border-l-4 border-purple-500">
|
||||
<p class="font-semibold text-purple-300">Attack Surface Exposure</p>
|
||||
<p class="text-sm text-gray-400">675 malicious requests bypassed your current security</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Resilience Score -->
|
||||
<div class="mb-8 border-b border-gray-700 pb-6">
|
||||
<h2 class="text-2xl font-bold text-cyan-400 mb-4">📊 Resilience Score: <span class="text-4xl font-black">0.0 / 100</span></h2>
|
||||
<div class="bg-gray-800 rounded-lg p-5">
|
||||
<div class="flex items-center gap-3 mb-3">
|
||||
<div class="w-full bg-gray-700 rounded-full h-4">
|
||||
<div class="bg-gradient-to-r from-red-500 via-amber-500 to-emerald-500 h-4 rounded-full" style="width: 0%;"></div>
|
||||
</div>
|
||||
<span class="text-sm font-bold text-red-400">Baseline</span>
|
||||
</div>
|
||||
<p class="text-gray-300">
|
||||
Your current resilience score is at a starting point. The good news? Industry leaders like Wallarm achieve <strong>98.9%</strong> overall scores.
|
||||
With continuous monitoring and the right tuning, you can rapidly climb the resilience ladder.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Remediation Recommendations -->
|
||||
<div class="mb-6">
|
||||
<h2 class="text-2xl font-bold text-emerald-400 mb-4">🛡️ Remediation Roadmap</h2>
|
||||
<p class="text-gray-300 mb-4">
|
||||
Based on this scan, your path to robust API security is clear. Here are the <span class="text-cyan-300">high-impact actions</span> to take:
|
||||
</p>
|
||||
<div class="space-y-3">
|
||||
<div class="bg-gray-800 rounded-lg p-4 border-l-4 border-emerald-500">
|
||||
<h3 class="font-bold text-emerald-300">1. Deploy Continuous API Attack Surface Monitoring</h3>
|
||||
<p class="text-sm text-gray-400">Set up automated weekly scans to catch new vulnerabilities as your APIs evolve. Awareness is your first line of defense.</p>
|
||||
</div>
|
||||
<div class="bg-gray-800 rounded-lg p-4 border-l-4 border-cyan-500">
|
||||
<h3 class="font-bold text-cyan-300">2. Tune WAF Rules for True-Positive Detection</h3>
|
||||
<p class="text-sm text-gray-400">Focus on SQL injection, XSS, and RCE payloads — these bypassed completely in your test. Use the detailed scan report as a rules checklist.</p>
|
||||
</div>
|
||||
<div class="bg-gray-800 rounded-lg p-4 border-l-4 border-amber-500">
|
||||
<h3 class="font-bold text-amber-300">3. Reduce False Positives</h3>
|
||||
<p class="text-sm text-gray-400">94 legitimate requests were blocked. Whitelist trusted patterns while maintaining strong attack detection — balance is key.</p>
|
||||
</div>
|
||||
<div class="bg-gray-800 rounded-lg p-4 border-l-4 border-purple-500">
|
||||
<h3 class="font-bold text-purple-300">4. Benchmark Against Industry Leaders</h3>
|
||||
<p class="text-sm text-gray-400">Top solutions detect over 97% of attacks. Your baseline of 0% means every improvement will deliver massive gains — celebrate each milestone!</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-6 bg-gradient-to-r from-gray-800 to-gray-700 rounded-lg p-5 text-center">
|
||||
<p class="text-2xl font-bold text-emerald-300">💪 Your API Resilience Journey Starts Now</p>
|
||||
<p class="text-gray-400 mt-2">Continuous monitoring transforms today's gaps into tomorrow's strengths.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Token Reference -->
|
||||
<div class="mt-6 p-4 bg-slate-800 rounded-xl text-center">
|
||||
<p class="text-xs text-slate-500 mb-2">Report Token</p>
|
||||
<p class="text-sm font-mono text-slate-300">4a48e516-2320-4db3-b717-75e5a72a28b6</p>
|
||||
</div>
|
||||
|
||||
<!-- QR Code -->
|
||||
<div class="mt-4 text-center">
|
||||
<img src="/qrcode?text=https://aasd.sechpoint.app/reports/report_4a48e516-2320-4db3-b717-75e5a72a28b6.html" alt="QR Code" class="inline-block w-40 h-40 rounded-xl border-2 border-slate-700 bg-white p-2" loading="lazy">
|
||||
<p class="text-xs text-slate-500 mt-2">Ask a consultant to scan for your detailed report</p>
|
||||
</div>
|
||||
|
||||
<!-- CTA -->
|
||||
<div class="mt-6 p-4 bg-slate-800 rounded-xl text-center border-2 border-blue-500/30">
|
||||
<p class="text-sm text-slate-300">Show this code to <strong class="text-blue-400">Sechpoint Aftica Team</strong></p>
|
||||
<p class="text-xs text-slate-500 mt-1">Your consultant will walk you through the findings</p>
|
||||
</div>
|
||||
|
||||
<div class="mt-6 text-center text-xs text-slate-600">
|
||||
GITEX 2026 — sechpoint.app
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
821
AttackSurface/dist/reports/report_4a48e516-2320-4db3-b717-75e5a72a28b6.csv
vendored
Normal file
821
AttackSurface/dist/reports/report_4a48e516-2320-4db3-b717-75e5a72a28b6.csv
vendored
Normal file
File diff suppressed because one or more lines are too long
1286
AttackSurface/dist/reports/report_4a48e516-2320-4db3-b717-75e5a72a28b6.html
vendored
Normal file
1286
AttackSurface/dist/reports/report_4a48e516-2320-4db3-b717-75e5a72a28b6.html
vendored
Normal file
File diff suppressed because it is too large
Load diff
2
AttackSurface/dist/templates/admin.html
vendored
2
AttackSurface/dist/templates/admin.html
vendored
|
|
@ -71,7 +71,7 @@
|
|||
<td class="p-3 text-slate-400 hidden sm:table-cell">{{ len .Subdomains }}</td>
|
||||
<td class="p-3">
|
||||
{{ if eq .Status "completed" }}
|
||||
<a href="/reports/{{ .ReportToken }}.html" target="_blank" class="text-blue-400 hover:text-blue-300 text-xs font-medium underline underline-offset-2">View Report</a>
|
||||
<a href="/reports/report_{{ .ReportToken }}.html" target="_blank" class="text-blue-400 hover:text-blue-300 text-xs font-medium underline underline-offset-2">Consultant Report</a>
|
||||
{{ else }}
|
||||
<span class="text-slate-600 text-xs">Pending</span>
|
||||
{{ end }}
|
||||
|
|
|
|||
250
AttackSurface/install.sh
Normal file
250
AttackSurface/install.sh
Normal file
|
|
@ -0,0 +1,250 @@
|
|||
#!/usr/bin/env bash
|
||||
#
|
||||
# install.sh — AASD (API Attack Surface Discovery) installer
|
||||
#
|
||||
# Supports: Debian 12+ | RHEL 9+ (AlmaLinux, Rocky Linux)
|
||||
# Usage: sudo bash install.sh [--release-url URL]
|
||||
#
|
||||
# Environment variables (all optional):
|
||||
# AASD_RELEASE_URL — URL to download the dist/ tarball
|
||||
# AASD_AI_API_KEY — DeepSeek API key (prompted if empty)
|
||||
# AASD_BASE_URL — Public base URL (prompted if empty)
|
||||
# AASD_ADMIN_PASSWORD — Admin dashboard password (prompted if empty)
|
||||
#
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# ──────────────────────────────────────────────
|
||||
# Color helpers
|
||||
# ──────────────────────────────────────────────
|
||||
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; CYAN='\033[0;36m'; NC='\033[0m'
|
||||
info() { echo -e "${CYAN}[INFO]${NC} $*"; }
|
||||
pass() { echo -e "${GREEN}[OK]${NC} $*"; }
|
||||
warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
|
||||
fail() { echo -e "${RED}[FAIL]${NC} $*"; exit 1; }
|
||||
|
||||
# ──────────────────────────────────────────────
|
||||
# Root check
|
||||
# ──────────────────────────────────────────────
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
fail "This script must be run as root (sudo)."
|
||||
fi
|
||||
|
||||
# ──────────────────────────────────────────────
|
||||
# OS detection
|
||||
# ──────────────────────────────────────────────
|
||||
info "Detecting operating system..."
|
||||
|
||||
if [[ -f /etc/os-release ]]; then
|
||||
. /etc/os-release
|
||||
OS_ID="${ID,,}"
|
||||
OS_VERSION_ID="${VERSION_ID:-0}"
|
||||
elif [[ -f /etc/redhat-release ]]; then
|
||||
OS_ID="rhel"
|
||||
OS_VERSION_ID="$(rpm -q --qf '%{VERSION}' $(rpm -q --whatprovides redhat-release) 2>/dev/null || echo '0')"
|
||||
else
|
||||
fail "Unsupported OS. Only Debian 12+ and RHEL 9+ are supported."
|
||||
fi
|
||||
|
||||
case "$OS_ID" in
|
||||
debian|ubuntu)
|
||||
PKG_MGR="apt-get"
|
||||
PKG_UPDATE="$PKG_MGR update -qq"
|
||||
PKG_INSTALL="$PKG_MGR install -y -qq"
|
||||
info "Detected Debian/Ubuntu — using apt"
|
||||
;;
|
||||
rhel|centos|rocky|almalinux|fedora)
|
||||
PKG_MGR="dnf"
|
||||
PKG_UPDATE="$PKG_MGR check-update || true"
|
||||
PKG_INSTALL="$PKG_MGR install -y -q"
|
||||
info "Detected RHEL family — using dnf"
|
||||
;;
|
||||
*)
|
||||
fail "Unsupported OS: $OS_ID. Only Debian 12+ and RHEL 9+ are supported."
|
||||
;;
|
||||
esac
|
||||
|
||||
# ──────────────────────────────────────────────
|
||||
# Prerequisites
|
||||
# ──────────────────────────────────────────────
|
||||
info "Installing prerequisites..."
|
||||
eval "$PKG_UPDATE"
|
||||
eval "$PKG_INSTALL curl tar gzip"
|
||||
|
||||
# ──────────────────────────────────────────────
|
||||
# Create 'app' user
|
||||
# ──────────────────────────────────────────────
|
||||
APP_USER="app"
|
||||
APP_HOME="/opt/aasd"
|
||||
|
||||
if id "$APP_USER" &>/dev/null; then
|
||||
pass "User '$APP_USER' already exists"
|
||||
else
|
||||
info "Creating user '$APP_USER' (system user, no login)..."
|
||||
case "$OS_ID" in
|
||||
debian|ubuntu)
|
||||
useradd --system --no-create-home --shell /usr/sbin/nologin "$APP_USER"
|
||||
;;
|
||||
rhel|centos|rocky|almalinux|fedora)
|
||||
useradd --system --no-create-home --shell /sbin/nologin "$APP_USER"
|
||||
;;
|
||||
esac
|
||||
pass "User '$APP_USER' created"
|
||||
fi
|
||||
|
||||
# ──────────────────────────────────────────────
|
||||
# Determine source of dist/
|
||||
# ──────────────────────────────────────────────
|
||||
RELEASE_URL="${AASD_RELEASE_URL:-}"
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
LOCAL_DIST="$SCRIPT_DIR/dist"
|
||||
|
||||
if [[ -n "$RELEASE_URL" ]]; then
|
||||
# Download from URL
|
||||
info "Downloading release archive from: $RELEASE_URL"
|
||||
TMP_DIR=$(mktemp -d)
|
||||
TARBALL="$TMP_DIR/aasd-release.tar.gz"
|
||||
curl -fsSL "$RELEASE_URL" -o "$TARBALL"
|
||||
[[ -s "$TARBALL" ]] || fail "Downloaded archive is empty — check RELEASE_URL"
|
||||
|
||||
info "Extracting to $APP_HOME ..."
|
||||
mkdir -p "$APP_HOME"
|
||||
tar -xzf "$TARBALL" -C "$APP_HOME" --strip-components=1
|
||||
rm -rf "$TMP_DIR"
|
||||
pass "Release downloaded and extracted"
|
||||
elif [[ -d "$LOCAL_DIST" ]]; then
|
||||
# Copy from local dist/
|
||||
info "Copying local dist/ to $APP_HOME ..."
|
||||
mkdir -p "$APP_HOME"
|
||||
cp -r "$LOCAL_DIST"/* "$APP_HOME/"
|
||||
pass "Local dist/ copied"
|
||||
else
|
||||
fail "No release URL set (AASD_RELEASE_URL) and no local dist/ found at $LOCAL_DIST"
|
||||
fi
|
||||
|
||||
# ──────────────────────────────────────────────
|
||||
# Set ownership
|
||||
# ──────────────────────────────────────────────
|
||||
chown -R "$APP_USER:$APP_USER" "$APP_HOME"
|
||||
chmod 755 "$APP_HOME"
|
||||
pass "Ownership set to $APP_USER"
|
||||
|
||||
# ──────────────────────────────────────────────
|
||||
# Create runtime directories
|
||||
# ──────────────────────────────────────────────
|
||||
mkdir -p "$APP_HOME/reports" "$APP_HOME/logs"
|
||||
chown "$APP_USER:$APP_USER" "$APP_HOME/reports" "$APP_HOME/logs"
|
||||
|
||||
# ──────────────────────────────────────────────
|
||||
# Configure secrets (prompt if not set via env)
|
||||
# ──────────────────────────────────────────────
|
||||
AI_API_KEY="${AASD_AI_API_KEY:-}"
|
||||
BASE_URL="${AASD_BASE_URL:-}"
|
||||
ADMIN_PASS="${AASD_ADMIN_PASSWORD:-}"
|
||||
|
||||
if [[ -z "$AI_API_KEY" ]]; then
|
||||
echo ""
|
||||
read -rp "Enter DeepSeek API key (or press Enter to skip AI reports): " AI_API_KEY
|
||||
fi
|
||||
|
||||
if [[ -z "$BASE_URL" ]]; then
|
||||
echo ""
|
||||
read -rp "Enter public base URL (e.g. https://aasd.sechpoint.app): " BASE_URL
|
||||
fi
|
||||
|
||||
if [[ -z "$ADMIN_PASS" ]]; then
|
||||
echo ""
|
||||
read -rp "Enter admin dashboard password: " ADMIN_PASS
|
||||
if [[ -z "$ADMIN_PASS" ]]; then
|
||||
ADMIN_PASS="$(tr -dc A-Za-z0-9 </dev/urandom 2>/dev/null | head -c 16 || echo "aasd$(date +%s)")"
|
||||
warn "Generated random password: $ADMIN_PASS"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Write config.yaml
|
||||
CONFIG_FILE="$APP_HOME/config.yaml"
|
||||
cat > "$CONFIG_FILE" <<CONFIGEOF
|
||||
ai:
|
||||
provider_url: "https://api.deepseek.com"
|
||||
api_key: "${AI_API_KEY:-}"
|
||||
model: "deepseek-chat"
|
||||
|
||||
server:
|
||||
base_url: "${BASE_URL:-}"
|
||||
|
||||
admin:
|
||||
username: "sechpoint"
|
||||
password: "${ADMIN_PASS:-}"
|
||||
CONFIGEOF
|
||||
|
||||
chown "$APP_USER:$APP_USER" "$CONFIG_FILE"
|
||||
chmod 600 "$CONFIG_FILE"
|
||||
pass "Configuration written to $CONFIG_FILE"
|
||||
|
||||
# ──────────────────────────────────────────────
|
||||
# Create systemd service
|
||||
# ──────────────────────────────────────────────
|
||||
SYSTEMD_FILE="/etc/systemd/system/aasd.service"
|
||||
|
||||
cat > "$SYSTEMD_FILE" <<SERVICEEOF
|
||||
[Unit]
|
||||
Description=AASD — API Attack Surface Discovery
|
||||
Documentation=https://github.com/valllabh/aasd
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=$APP_USER
|
||||
Group=$APP_USER
|
||||
WorkingDirectory=$APP_HOME
|
||||
ExecStart=$APP_HOME/aasd
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
LimitNOFILE=4096
|
||||
|
||||
# Security hardening
|
||||
NoNewPrivileges=true
|
||||
ProtectSystem=full
|
||||
ProtectHome=true
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
SERVICEEOF
|
||||
|
||||
chmod 644 "$SYSTEMD_FILE"
|
||||
systemctl daemon-reload
|
||||
systemctl enable aasd.service
|
||||
pass "Systemd service created and enabled"
|
||||
|
||||
# ──────────────────────────────────────────────
|
||||
# Start service
|
||||
# ──────────────────────────────────────────────
|
||||
info "Starting aasd.service..."
|
||||
systemctl start aasd.service
|
||||
sleep 2
|
||||
|
||||
if systemctl is-active --quiet aasd.service; then
|
||||
pass "aasd.service is running"
|
||||
else
|
||||
warn "Service did not start — check: sudo journalctl -u aasd -n 50 --no-pager"
|
||||
fi
|
||||
|
||||
# ──────────────────────────────────────────────
|
||||
# Summary
|
||||
# ──────────────────────────────────────────────
|
||||
echo ""
|
||||
echo -e "${GREEN}══════════════════════════════════════════════${NC}"
|
||||
echo -e "${GREEN} AASD installation complete${NC}"
|
||||
echo -e "${GREEN}══════════════════════════════════════════════${NC}"
|
||||
echo ""
|
||||
echo " URL: http://$(hostname -I 2>/dev/null | awk '{print $1}'):8080"
|
||||
echo " Binary: $APP_HOME/aasd"
|
||||
echo " Config: $CONFIG_FILE"
|
||||
echo " Service: aasd.service"
|
||||
echo ""
|
||||
echo " Admin login: sechpoint / ${ADMIN_PASS:-<see config>}"
|
||||
echo ""
|
||||
echo " Manage:"
|
||||
echo " sudo systemctl status aasd"
|
||||
echo " sudo journalctl -u aasd -f"
|
||||
echo ""
|
||||
|
|
@ -22,6 +22,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/goccy/go-yaml"
|
||||
"github.com/skip2/go-qrcode"
|
||||
|
||||
"aasd/internal/ai"
|
||||
|
|
@ -29,6 +30,23 @@ import (
|
|||
"aasd/internal/scanner"
|
||||
)
|
||||
|
||||
// AppConfig holds application-level configuration from config.yaml.
|
||||
type AppConfig struct {
|
||||
Server ServerConfig `yaml:"server"`
|
||||
Admin AdminConfig `yaml:"admin"`
|
||||
}
|
||||
|
||||
// ServerConfig holds server-level settings.
|
||||
type ServerConfig struct {
|
||||
BaseURL string `yaml:"base_url"`
|
||||
}
|
||||
|
||||
// AdminConfig holds admin dashboard credentials.
|
||||
type AdminConfig struct {
|
||||
Username string `yaml:"username"`
|
||||
Password string `yaml:"password"`
|
||||
}
|
||||
|
||||
var (
|
||||
emailRegex = regexp.MustCompile(`^[^@]+@[^@]+\.[^@]+$`)
|
||||
projectDir string
|
||||
|
|
@ -42,9 +60,20 @@ func main() {
|
|||
projectDir = "."
|
||||
}
|
||||
|
||||
// Read public base URL from environment (used for QR codes, email links)
|
||||
// e.g. AASD_BASE_URL=https://coding.sechpoint.app
|
||||
// Read config.yaml for server and admin settings
|
||||
var appCfg AppConfig
|
||||
if cfgData, err := os.ReadFile(filepath.Join(projectDir, "config.yaml")); err == nil {
|
||||
if err := yaml.Unmarshal(cfgData, &appCfg); err != nil {
|
||||
fmt.Printf("Warning: failed to parse config.yaml: %v\n", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Read public base URL: env var takes precedence, fallback to config.yaml
|
||||
// Used for QR codes and email report links
|
||||
baseURL := os.Getenv("AASD_BASE_URL")
|
||||
if baseURL == "" {
|
||||
baseURL = appCfg.Server.BaseURL
|
||||
}
|
||||
|
||||
// Initialize AI client (reads api_key from config.yaml in working directory)
|
||||
deepSeekClient, err := ai.NewClient()
|
||||
|
|
@ -115,8 +144,8 @@ func main() {
|
|||
return
|
||||
}
|
||||
|
||||
// Redirect to simulation page with token
|
||||
c.Redirect(http.StatusFound, "/simulation?token="+result.ReportToken)
|
||||
// Redirect to analysing page with token
|
||||
c.Redirect(http.StatusFound, "/analysing?token="+result.ReportToken)
|
||||
})
|
||||
|
||||
// ----- STATUS: Poll endpoint -----
|
||||
|
|
@ -152,8 +181,11 @@ func main() {
|
|||
c.JSON(http.StatusNotFound, gin.H{"error": "Scan not found"})
|
||||
})
|
||||
|
||||
// ----- ADMIN: Dashboard -----
|
||||
router.GET("/admin-dashboard", func(c *gin.Context) {
|
||||
// ----- ADMIN: Dashboard (basic auth) -----
|
||||
adminGroup := router.Group("/admin-dashboard", gin.BasicAuth(gin.Accounts{
|
||||
appCfg.Admin.Username: appCfg.Admin.Password,
|
||||
}))
|
||||
adminGroup.GET("", func(c *gin.Context) {
|
||||
results := orch.GetAllResults()
|
||||
total, completed, running := orch.CountStats()
|
||||
|
||||
|
|
@ -219,7 +251,9 @@ func main() {
|
|||
})
|
||||
})
|
||||
|
||||
// ----- SIMULATION: Serve new simulation page with token support -----
|
||||
// ----- ANALYSING: Serve the analysis progress page with token support -----
|
||||
router.StaticFile("/analysing", "./static/simulation.html")
|
||||
// Keep old /simulation route for backward compatibility
|
||||
router.StaticFile("/simulation", "./static/simulation.html")
|
||||
|
||||
// ----- DOWNLOAD: Serve the raw scan results for debugging -----
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@
|
|||
resetButton();
|
||||
} else {
|
||||
// Shouldn't get here, but handle gracefully
|
||||
window.location.href = '/simulation?domain=' + encodeURIComponent(email.split('@')[1]);
|
||||
window.location.href = '/analysing?domain=' + encodeURIComponent(email.split('@')[1]);
|
||||
}
|
||||
} catch (err) {
|
||||
showError('Network error. Please check your connection.');
|
||||
|
|
|
|||
|
|
@ -129,7 +129,7 @@
|
|||
|
||||
<!-- Footer -->
|
||||
<div class="text-center text-xs text-slate-600 mt-6">
|
||||
GITEX 2026 — sechpoint.app | <a href="/admin-dashboard" class="text-blue-500 hover:underline">Consultant Dashboard</a>
|
||||
GITEX 2026 — sechpoint.app
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@
|
|||
<td class="p-3 text-slate-400 hidden sm:table-cell">{{ len .Subdomains }}</td>
|
||||
<td class="p-3">
|
||||
{{ if eq .Status "completed" }}
|
||||
<a href="/reports/{{ .ReportToken }}.html" target="_blank" class="text-blue-400 hover:text-blue-300 text-xs font-medium underline underline-offset-2">View Report</a>
|
||||
<a href="/reports/report_{{ .ReportToken }}.html" target="_blank" class="text-blue-400 hover:text-blue-300 text-xs font-medium underline underline-offset-2">Consultant Report</a>
|
||||
{{ else }}
|
||||
<span class="text-slate-600 text-xs">Pending</span>
|
||||
{{ end }}
|
||||
|
|
|
|||
85
README.md
85
README.md
|
|
@ -1,84 +1,39 @@
|
|||
# Resilience Challenge - Interactive Booth Experience
|
||||
# GITEX 2026 — Sechpoint Booth Applications
|
||||
|
||||
An interactive booth experience that captures corporate emails, runs background security simulations using GoTestWAF, and provides a "Resilience Code" for lead conversion.
|
||||
This repository contains the applications powering the **Sechpoint Aftica** booth at **GITEX 2026**. Each application demonstrates a unique aspect of the Sechpoint cybersecurity platform — from attack surface discovery and WAF testing to automated remediation and compliance reporting.
|
||||
|
||||
## Project Structure
|
||||
## Repository Structure
|
||||
|
||||
```
|
||||
gitex2026/
|
||||
├── AttackSurface/ # Main application folder
|
||||
│ ├── dist/ # Deployment directory (self-contained)
|
||||
│ │ ├── aasd # Compiled application binary
|
||||
│ │ ├── static/ # HTML/JS/CSS frontend files
|
||||
│ │ ├── templates/ # Go HTML templates
|
||||
│ │ ├── gotestwaf # GoTestWAF binary
|
||||
│ │ ├── domain-scan # Domain discovery tool
|
||||
│ │ ├── testcases/ # GoTestWAF test cases
|
||||
│ │ ├── config.yaml # AI provider configuration
|
||||
│ │ ├── prompt.txt # AI system prompt
|
||||
│ │ ├── reports/ # Generated scan reports
|
||||
│ │ ├── logs/ # Server logs
|
||||
│ │ └── start.sh # Startup script
|
||||
│ ├── src/ # Source code (Go server, frontend)
|
||||
│ │ ├── cmd/ # Go command entry points
|
||||
│ │ ├── static/ # HTML/JS/CSS frontend files
|
||||
│ │ ├── templates/ # Go HTML templates
|
||||
│ │ ├── gotestwaf/ # Vendored GoTestWAF source
|
||||
│ │ ├── internal/ # Internal Go packages
|
||||
│ │ └── pkg/ # Public Go packages
|
||||
│ ├── docs/ # Documentation (CHANGELOG.md, DEVELOPMENT_STATUS.md)
|
||||
│ ├── VERSION # Current version
|
||||
│ └── .gitignore
|
||||
└── README.md # This file
|
||||
├── AttackSurface/ # API Attack Surface Discovery — booth demo app
|
||||
└── README.md # This file
|
||||
```
|
||||
|
||||
## Tech Stack
|
||||
## Applications
|
||||
|
||||
- **Backend**: Go (Golang) with Gin web framework
|
||||
- **Frontend**: HTML5, JavaScript, CSS
|
||||
- **Security Testing**: GoTestWAF (external binary)
|
||||
- **Data Storage**: In-memory map (volatile) for demo purposes
|
||||
| Application | Directory | Description |
|
||||
|-------------|-----------|-------------|
|
||||
| **AASD** — API Attack Surface Discovery | `AttackSurface/` | Interactive booth experience: email capture → domain discovery → GoTestWAF scan → AI resilience report |
|
||||
|
||||
## Features
|
||||
Each application directory contains its own `README.md` with detailed setup, deployment, and usage instructions.
|
||||
|
||||
1. **Email Capture & Validation**: POST `/start` endpoint with regex validation and security checks
|
||||
2. **Background Security Scan**: Concurrent GoTestWAF execution with 120-second timeout
|
||||
3. **Real-time Status Tracking**: Polling endpoint `/scan-status/:domain` for live updates
|
||||
4. **Interactive Simulation**: Frontend step sequencer with animated progress visualization
|
||||
5. **Resilience Code**: Static code `WX-2026` displayed after simulation completion
|
||||
6. **Consultant Dashboard**: Protected `/admin-dashboard` to monitor all scan results
|
||||
7. **Report Generation**: HTML reports served at `/reports/report_*.html`
|
||||
8. **Graceful Shutdown**: OS signal handling (SIGINT, SIGTERM) with proper cleanup
|
||||
## Deployment
|
||||
|
||||
## Quick Start
|
||||
Applications are deployed as systemd services under `/opt/`. See each application's `install.sh` for automated deployment:
|
||||
|
||||
```bash
|
||||
# Option 1: Run from dist/ (recommended - no build needed)
|
||||
cd AttackSurface/dist
|
||||
./start.sh
|
||||
|
||||
# Option 2: Build and run from source
|
||||
cd AttackSurface/src
|
||||
go build -o ../dist/aasd ./cmd/aasd/
|
||||
cd ../dist
|
||||
./start.sh
|
||||
|
||||
# Access the application
|
||||
# Frontend: http://localhost:8080 (or booth Wi-Fi IP)
|
||||
# Admin dashboard: http://localhost:8080/admin-dashboard
|
||||
# Deploy AttackSurface (example)
|
||||
cd AttackSurface
|
||||
sudo bash install.sh
|
||||
```
|
||||
|
||||
> **Note**: Before running, set your DeepSeek API key in `dist/config.yaml` if AI-generated reports are desired. Without it, the app uses built-in fallback reports.
|
||||
## Requirements
|
||||
|
||||
## Development
|
||||
|
||||
### Current Status
|
||||
**Version 2026-04.1**
|
||||
|
||||
### Documentation
|
||||
- [CHANGELOG.md](AttackSurface/docs/CHANGELOG.md) - Version history and detailed changes
|
||||
- [DEVELOPMENT_STATUS.md](AttackSurface/docs/DEVELOPMENT_STATUS.md) - Current status and testing results
|
||||
- **OS**: Debian 12+ or RHEL 9+ (AlmaLinux / Rocky Linux)
|
||||
- **Runtime**: Go 1.25+ (for building from source)
|
||||
- **Network**: Outbound HTTPS access for API calls and tool downloads
|
||||
|
||||
## License
|
||||
|
||||
Proprietary - For internal event use only.
|
||||
Proprietary — For internal event use at GITEX 2026.
|
||||
|
|
|
|||
Loading…
Reference in a new issue