blackhole.py 17 KB

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