Skip to content

Instantly share code, notes, and snippets.

@sonya75
Created February 25, 2018 08:45
Show Gist options
  • Save sonya75/b5f82d7b7ea5ed1ca4a5c71931d82647 to your computer and use it in GitHub Desktop.
Save sonya75/b5f82d7b7ea5ed1ca4a5c71931d82647 to your computer and use it in GitHub Desktop.
import os
import requests
from bs4 import BeautifulSoup as BS
from urllib.parse import urljoin
import time
import zipfile
import io
TORPATH=""
MAX_CONNECTIONS=10
CONNECT_DELAY=7
BAD_CIRCUIT_TIME=13
BAD_CIRCUIT_CLOSE=5
SOCKET_CHECK_TIMEOUT=15
C_CALLBACK=None
HIDE_WINDOW=None
def settorpath(x):
TORPATH=x
def gettorversion():
v=requests.get("https://www.torproject.org/download/download.html.en",timeout=30)
w=BS(v.text,"html.parser")
s=w.find("div",{"class":"downloads"}).find("a",{"class":"button"})["href"]
version=s.split("/")[-1].rsplit(".",1)[0].split("-")[-1]
return (urljoin(v.url,s),version)
def reporterror(x):
if C_CALLBACK!=None:
C_CALLBACK(x,2)
else:
print(x)
def reportsuccess(x):
if C_CALLBACK!=None:
C_CALLBACK(x,1)
else:
print(x)
def reportlog(x):
if C_CALLBACK!=None:
C_CALLBACK(x,0)
else:
print(x)
def downloadlatest(x,y=600):
currenttime=time.time()
while True:
try:
link,version=gettorversion()
break
except Exception as e:
reporterror("Error retrieving version number")
reporterror(str(e))
if (time.time()-currenttime)>y:
return ""
time.sleep(1)
reportsuccess("Successfully retrieved tor version: {0}".format(version))
if x==version:
reportsuccess("Tor already up-to-date")
return x
reportsuccess("Downloading tor from: {0}".format(link))
while True:
try:
w=requests.get(link,stream=True,timeout=30)
m=w.raw.read()
break
except Exception as e:
reporterror("Error downloading tor")
reporterror(str(e))
if (time.time()-currenttime)>y:
return ""
time.sleep(1)
try:
bt=io.BytesIO(m)
n=zipfile.ZipFile(bt)
n.extractall(TORPATH)
except Exception as e:
reporterror("Error extracting tor")
reporterror(str(e))
return ""
reportsuccess("Successfully extracted tor")
return version
import random
from threading import Thread,Lock
from stem import StreamStatus,CircStatus,CircBuildFlag,CircPurpose
import stem
import stem.process
import stem.control
import re
from queue import Queue
import socket
class BotData:
def __init__(self):
self.streams=[]
self.lastconnect=0
class StreamData:
def __init__(self,cid,target):
self.circid=str(cid)
self.connecttime=time.time()
self.target=target
class TorInstance:
def __init__(self,timeout=120,torport=None):
while True:
try:
self.torcontrol=random.randint(1000,60000)
if torport!=None:
self.torport=torport
else:
self.torport=random.randint(1000,60000)
reportlog("Starting tor with control port {0} and tor port {1}".format(self.torcontrol,self.torport))
self.torprocess=stem.process.launch_tor_with_config(config={'__LeaveStreamsUnattached':'1','ControlPort':str(self.torcontrol),'SocksPort':str(self.torport)},tor_cmd=os.path.join(TORPATH,"Tor\\tor.exe"),take_ownership=True)
reportsuccess("Successfully started tor process, pid: {0}".format(self.torprocess.pid))
self.stemclient=stem.control.Controller.from_port(port=self.torcontrol)
self.stemclient.authenticate()
reportsuccess("Successfully connected to control port {0}".format(self.torcontrol))
break
except Exception as e:
try:
self.torprocess.kill()
except:
pass
reporterror("Failed to start tor")
reporterror(str(e))
time.sleep(1)
self.streams={}
self.circuitdata={}
self.stemclient.add_event_listener(self.on_connection,stem.control.EventType.STREAM)
self.lastcircuit=0
self.circuitcheckqueue=Queue()
self.globallock=Lock()
Thread(target=self.checkbadcircuit).start()
if HIDE_WINDOW!=None:
HIDE_WINDOW(self.torprocess.pid)
def on_connection(self,x):
if x.id==None:
return
if x.status==StreamStatus.NEW:
if (x.target_address!=None)&(re.fullmatch("^216\.66\.17\.[0-9]*$",x.target_address)!=None)&(x.target_port==443):
q=self.stemclient.get_circuits()
v=[str(m.id) for m in q if (m.status==CircStatus.BUILT)&(CircBuildFlag.ONEHOP_TUNNEL not in m.build_flags)&(CircBuildFlag.IS_INTERNAL not in m.build_flags)&(m.purpose==CircPurpose.GENERAL)]
if x.target_address not in self.circuitdata:
self.circuitdata[x.target_address]={}
ck=self.circuitdata[x.target_address]
with self.globallock:
ckk=list(ck.keys())
for l in ckk:
if l not in v:
ck.pop(l,None)
goodid=None
mincount=-1
for l in v:
if l not in ck:
ck[l]=BotData()
pq=ck[l]
if (len(pq.streams)>=MAX_CONNECTIONS)|((time.time()-pq.lastconnect)<CONNECT_DELAY):
continue
if (mincount==-1)|(len(pq.streams)<mincount):
mincount=len(pq.streams)
goodid=l
if goodid!=None:
pq=ck[goodid]
try:
reportlog("Attaching stream {0} to circuit {1}".format(str(x.id),goodid))
self.stemclient.attach_stream(str(x.id),goodid)
reportsuccess("Successfully attached stream {0}".format(x.id))
except Exception as e:
reporterror("Attaching stream failed")
reporterror(str(e))
try:
self.stemclient.close_stream(str(x.id))
except:
pass
return
pq.streams.append(str(x.id))
pq.lastconnect=time.time()
self.streams[str(x.id)]=StreamData(goodid,x.target_address)
return
else:
try:
self.stemclient.close_stream(str(x.id))
except:
pass
if (time.time()-self.lastcircuit)<2:
return
try:
reportlog("Creating new circuit")
mp=self.stemclient.new_circuit()
reportsuccess("Started creating new circuit")
self.lastcircuit=time.time()
except Exception as e:
reporterror("Failed to open circuit")
reporterror(str(e))
pass
else:
try:
self.stemclient.close_stream(str(x.id))
except:
pass
elif (x.status==StreamStatus.CLOSED)|(x.status==StreamStatus.FAILED):
l=str(x.id)
try:
mm=self.streams.pop(l,None)
self.circuitdata[mm.target][mm.circid].streams.remove(l)
diff=time.time()-mm.connecttime
if (diff<BAD_CIRCUIT_TIME):
self.circuitcheckqueue.put((mm.circid,mm.target))
except:
pass
def getallcircuits(self):
with self.globallock:
vl=list(self.circuitdata.keys())
q=[]
for p in vl:
try:
q+=self.circuitdata[p].keys()
except:
pass
return q
def checkbadcircuit(self):
badcircuits={}
while True:
p,q=self.circuitcheckqueue.get()
with self.globallock:
mn=list(self.circuitdata.keys())
ok=False
for ty in mn:
try:
if len(self.circuitdata[ty][p].streams)>0:
ok=True
break
except:
pass
if ok:
continue
try:
v=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
v.settimeout(SOCKET_CHECK_TIMEOUT)
v.connect((q,443))
v.close()
except:
continue
if (q+" "+p) not in badcircuits:
badcircuits[q+" "+p]=0
badcircuits[q+" "+p]+=1
reporterror("Detected bad circuit, retry count {0}".format(badcircuits[q+" "+p]))
if (badcircuits[q+" "+p]>BAD_CIRCUIT_CLOSE):
reportlog("Closing bad circuit {0}".format(p))
try:
self.stemclient.close_circuit(p)
except:
pass
pl=list(badcircuits.keys())
vl=self.getallcircuits()
for sl in pl:
sl=sl.split(" ")[-1]
if sl not in vl:
badcircuits.pop(sl,None)
GLOBAL_LOCK=Lock()
TOTALCLIENT=0
def _prnt(x):
print(repr(x)[:100])
def evtest(port):
from evony import Client
global TOTALCLIENT
while True:
ok=False
try:
vl=Client("ca5",proxyhost="127.0.0.1",setproxy=True,proxyport=port,proxytype="SOCKS5",callback=_prnt)
with GLOBAL_LOCK:
TOTALCLIENT+=1
print("Total clients {0}".format(TOTALCLIENT))
ok=True
vl.registernewplayer()
except:
if ok:
with GLOBAL_LOCK:
TOTALCLIENT-=1
print("Total clients {0}".format(TOTALCLIENT))
time.sleep(1)
continue
time.sleep(60)
break
with GLOBAL_LOCK:
TOTALCLIENT-=1
TORINSTANCE=None
def gettorport():
TORINSTANCE=TorInstance()
return TORINSTANCE.torport
def test():
global TORPATH
TORPATH=os.path.join(os.getcwd(),"tordata")
try:
vl=json.loads(open('torconfig.json','r').read())
TORPORT=int(vl["port"])
except:
TORPORT=None
if TORPORT==None:
TORPORT=input("Enter port: ")
try:
TORPORT=int(TORPORT.strip())
except:
pass
try:
with open("torconfig.json",'w') as p:
json.dump({"port":TORPORT},p)
except:
pass
v=TorInstance(150,TORPORT)
if __name__=="__main__":
test()
while True:
time.sleep(3600)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment