-
-
Notifications
You must be signed in to change notification settings - Fork 46
Expand file tree
/
Copy pathfast_run_as_r00t.sh
More file actions
executable file
·234 lines (199 loc) · 8.67 KB
/
Copy pathfast_run_as_r00t.sh
File metadata and controls
executable file
·234 lines (199 loc) · 8.67 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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
#!/bin/bash
# fast_run_as_r00t.sh — LazyOwn full-stack orchestrator
#
# Speed-run launcher: brings up every core service in a tmux session.
#
# Fixed panes:
# [0] Recon — lazynmap full scan
# [1] Network — addhosts + ping sweep
# [2] C2 implant — createcredentials + c2 launch
# [3] Auto-loop — autonomous loop (waits SLEEP_START)
# [4] lazyc2 — Flask C2 server (unprivileged)
# [5] www — HTTP file server + certs
# [6] VPN — tun interface
#
# Optional panes (driven by payload.json flags):
# DeepSeek/Ollama, Discord C2, Telegram C2, Cloudflare tunnel, NC revshell
SESSION="lazyown_sessions"
VPN=1
VENV_PATH="env"
JSON_FILE="payload.json"
NO_ATTACH=0 # set to 1 by --no-attach (MCP mode — skip tmux attach at the end)
CERTPASS="LazyOwn"
TARGET_UID=1000
TARGET_GID=1000
CHOWN_INTERVAL=30
# ── Read payload.json ─────────────────────────────────────────────────────────
_jq() { jq -r ".$1" "$JSON_FILE"; }
C2_PORT=$(_jq c2_port)
DOMAIN=$(_jq domain)
C2_USER=$(_jq c2_user)
C2_PASS=$(_jq c2_pass)
SLEEP_START=$(_jq sleep_start)
OS_ID=$(_jq os_id)
ENABLE_TELEGRAM_C2=$(_jq enable_telegram_c2)
ENABLE_DISCORD_C2=$(_jq enable_discord_c2)
ENABLE_DEEPSEEK=$(_jq enable_deepseek)
ENABLE_NC=$(_jq enable_nc)
ENABLE_CF=$(_jq enable_cloudflare)
TUNNEL=""
# ── Pretty-print helpers ──────────────────────────────────────────────────────
log() { gum log --time rfc822 --level info " [+] $*"; }
spin() { gum spin --spinner dot --title "$*" -- sleep 0.1; }
err_box(){ gum style \
--foreground 212 --border-foreground 212 --border double \
--align center --width 50 --margin "1 2" --padding "2 4" \
"$*"; }
# ── Ensure gum is installed ───────────────────────────────────────────────────
ensure_gum() {
command -v gum &>/dev/null && return
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://repo.charm.sh/apt/gpg.key \
| sudo gpg --dearmor -o /etc/apt/keyrings/charm.gpg
echo "deb [signed-by=/etc/apt/keyrings/charm.gpg] https://repo.charm.sh/apt/ * *" \
| sudo tee /etc/apt/sources.list.d/charm.list
sudo apt update && sudo apt install -y gum
}
# ── Dependency check ──────────────────────────────────────────────────────────
check_deps() {
for dep in tmux jq go; do
command -v "$dep" &>/dev/null && continue
err_box "Error: $dep is required but not installed."
exit 1
done
}
# ── Re-exec as root if needed ─────────────────────────────────────────────────
check_sudo() {
[[ "$EUID" -eq 0 ]] && return
err_box "[S] This script will reload as r00t ..."
local extra_flags=""
[[ "$NO_ATTACH" -eq 1 ]] && extra_flags="--no-attach"
exec sudo "$0" --vpn "$VPN" $extra_flags
}
# ── CLI argument parsing ──────────────────────────────────────────────────────
parse_args() {
while [[ "$#" -gt 0 ]]; do
case $1 in
--vpn)
[[ "$2" =~ ^[0-9]+$ ]] \
|| { err_box "Error: --vpn must be an integer."; exit 1; }
VPN=$2; shift ;;
--no-attach)
NO_ATTACH=1 ;; # MCP/automation mode: skip blocking tmux attach
*) err_box "Error: Unknown option: $1"; exit 1 ;;
esac
shift
done
}
# ── tmux helpers ──────────────────────────────────────────────────────────────
# Send one or more commands to the active tmux pane
t_send() {
for cmd in "$@"; do tmux send-keys -t "$SESSION" "$cmd" C-m; done
}
# Open a new pane (split v or h), start LazyOwn shell with optional run flags,
# then send any follow-up commands once the shell is up.
# Usage: t_lazyown <v|h> <delay_secs> <run_flags> [cmd1] [cmd2] ...
t_lazyown() {
local split=$1 delay=$2 flags=$3; shift 3
tmux split-window "-${split}"
t_send "sleep ${delay} && bash -c './run ${flags}'"
for cmd in "$@"; do t_send "$cmd"; done
}
# Open a new pane running a command as unprivileged user 1000 (with venv).
# Usage: t_priv_user <v|h> <command_string>
t_priv_user() {
local split=$1; shift
tmux split-window "-${split}"
t_send "sleep 5 && sudo -u \#1000 bash -c 'source \"${VENV_PATH}/bin/activate\" && $*'"
}
# ── Background chown watcher ──────────────────────────────────────────────────
# Re-chowns the project tree to the operator UID/GID every $CHOWN_INTERVAL
# seconds while the tmux session is alive, so root-owned writes from the panes
# do not leave files the unprivileged user cannot read on the next ./run.
# Survives the parent script exiting (MCP mode --no-attach).
start_chown_watcher() {
local project_root="$PWD"
local session_name="$SESSION"
local uid="$TARGET_UID"
local gid="$TARGET_GID"
local interval="$CHOWN_INTERVAL"
nohup setsid bash -c "
trap 'chown -R ${uid}:${gid} \"${project_root}\" 2>/dev/null; exit 0' TERM INT
while tmux has-session -t '${session_name}' 2>/dev/null; do
chown -R ${uid}:${gid} '${project_root}' 2>/dev/null
sleep ${interval}
done
chown -R ${uid}:${gid} '${project_root}' 2>/dev/null
" >/dev/null 2>&1 &
disown
}
# ── Entry point ───────────────────────────────────────────────────────────────
ensure_gum
log "Start the OPSEC."
parse_args "$@"
check_deps
spin "Host discovery..."
./modules/hostdiscover.sh 2>/dev/null &
[[ "$ENABLE_CF" == "true" ]] && TUNNEL="1"
log "Checking sudo."
check_sudo
python3 key.py
log "Start the session."
touch sessions/sessionLazyOwn.json
spin "Chmod..."
chmod 777 sessions/sessionLazyOwn.json
spin "Chown..."
chown 1000:1000 . -R
spin "Start chown watcher..."
start_chown_watcher
log "Chown watcher armed (interval ${CHOWN_INTERVAL}s)."
# ── Build tmux workspace ──────────────────────────────────────────────────────
tmux new-session -d -s "$SESSION"
# [0] Recon — full nmap scan
t_send "sleep 5 && bash -c './run'" "nmap"
# [1] Network — add hosts to /etc/hosts + ping sweep
t_lazyown v 5 "-c ping" "addhosts $DOMAIN"
# [opt] Local LLM inference (DeepSeek via Ollama)
[[ "$ENABLE_DEEPSEEK" == "true" ]] && \
t_priv_user v "ollama run deepseek-r1:1.5b"
# [opt] Discord C2 bot
[[ "$ENABLE_DISCORD_C2" == "true" ]] && \
t_priv_user v "python3 -W ignore discord_c2.py"
# [2] C2 implant — generate credentials then launch implant
t_lazyown v 5 "" "createcredentials" "$(printf 'c2 no_priv %s' "$OS_ID") $TUNNEL"
# [3] Auto-loop — waits SLEEP_START seconds so C2 server is up before starting
t_lazyown h "$SLEEP_START" "" "auto"
# [4] lazyc2 — Flask C2 server (runs as unprivileged user 1000)
tmux split-window -h
t_send "sudo -u \#1000 bash -c \"sleep 5 && /bin/bash -c \
'source \\\"${VENV_PATH}/bin/activate\\\" && \
python3 -W ignore lazyc2.py ${C2_PORT} ${C2_USER} ${C2_PASS}'\"" \
"$CERTPASS"
# Return to pane 0 to add www + vpn side by side
tmux select-pane -t 0
# [5] HTTP file server + certs (www)
tmux split-window -h
t_send "bash -c './run'" "www" "$CERTPASS"
# [6] VPN — bring up tun interface
tmux split-window -h
t_send "bash -c './run'" "vpn $VPN"
# [opt] Netcat reverse shell listener
if [[ "$ENABLE_NC" == "true" ]]; then
t_lazyown v 0 "" "createrevshell" "rnc"
fi
# [opt] Telegram C2 bot
[[ "$ENABLE_TELEGRAM_C2" == "true" ]] && \
t_priv_user v "python3 -W ignore telegram_c2.py"
# [opt] Cloudflare tunnel
if [[ "$ENABLE_CF" == "true" ]]; then
tmux split-window -v
t_send "sleep 5 && sudo -u \#1000 bash -c './run'" "cloudflare_tunnel"
fi
tmux select-pane -t 5
log "Session ready."
if [[ "$NO_ATTACH" -eq 1 ]]; then
log "MCP mode: tmux session '$SESSION' is running — attach manually: tmux attach -t $SESSION"
else
log "Attaching to session..."
tmux attach -t "$SESSION"
fi