ajaxmap.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  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, threading, re, base64, os, time
  10. import webbrowser, subprocess, urllib2, json, sys
  11. from urlparse import urlparse
  12. from main import UFONet
  13. import base64, traceback
  14. try:
  15. import pygeoip
  16. except:
  17. print "\nError importing: pygeoip lib. \n\n On Debian based systems:\n\n $ 'sudo apt-get install python-geoip' or 'pip install geoip')\n"
  18. sys.exit(2)
  19. class AjaxMap(object):
  20. def __init__(self):
  21. self._geoip=None
  22. self._geoasn=None
  23. self._geoipstatus='nomap'
  24. self._err=''
  25. ufonet = UFONet()
  26. ufonet.create_options()
  27. self.zombies = ufonet.extract_zombies()
  28. aliens_army = ufonet.extract_aliens()
  29. droids_army = ufonet.extract_droids()
  30. ucavs_army = ufonet.extract_ucavs()
  31. rpcs_army = ufonet.extract_rpcs()
  32. self.zombies.extend(aliens_army)
  33. self.zombies.extend(droids_army)
  34. self.zombies.extend(ucavs_army)
  35. self.zombies.extend(rpcs_army)
  36. def get_err(self):
  37. return self._err
  38. # check for geoip data status
  39. # basic lock file mechanism to avoid multiple downloads
  40. def get_status(self):
  41. if os.path.exists('maps.downloading'):
  42. if not os.path.exists('maps.downloadmsg'):
  43. f=open("maps.downloadmsg","wb")
  44. f.write("")
  45. f.close()
  46. print "[Webgui] GeoIP data download started"
  47. print "[Webgui] if this error message persists : remove maps.downloading and maps folder, then restart ufonet"
  48. self._geoipstatus='downloading'
  49. elif os.path.isdir('maps'):
  50. if self._geoip == None :
  51. self._geoip = pygeoip.GeoIP('maps/GeoLiteCity.dat')
  52. if self._geoasn == None :
  53. self._geoasn = pygeoip.GeoIP('maps/GeoIPASNum.dat')
  54. if os.path.exists("maps.downloadmsg") :
  55. os.remove("maps.downloadmsg")
  56. self._geoipstatus='ok'
  57. return self._geoipstatus
  58. def retrieve(self,url,name):
  59. try:
  60. handle = urllib2.urlopen(url)
  61. CHUNK = 16384
  62. with open(name,'wb') as fp:
  63. while True:
  64. chunk = handle.read(CHUNK)
  65. if not chunk:
  66. break
  67. fp.write(chunk)
  68. except:
  69. traceback.print_exc()
  70. def download_maps(self):
  71. import subprocess, shlex
  72. # generate geolocation values on a map
  73. if self.get_status() != 'nomap':
  74. return self._geoipstatus == 'ok'
  75. if os.path.exists("maps.downloadmsg"):
  76. os.remove("maps.downloadmsg")
  77. f=open("maps.downloading",'w')
  78. f.write("download started<script>$'('#ufomsg').load('/js/ajax.js?fetchmap=')")
  79. f.close()
  80. self._geoipstatus="downloading"
  81. # download maps folder
  82. geo_db_mirror1 = 'http://176.28.23.46/bordercheck/maps.tar.gz' # Turina Server
  83. geo_db_mirror2 = 'http://83.163.232.95/bordercheck/maps.tar.gz' # Mirror
  84. try: # mirror 1
  85. print "\n[Info] - Fetching maps from 'Mirror 1':", geo_db_mirror1 + "\n"
  86. response = self.retrieve(geo_db_mirror1, 'maps.tar.gz')
  87. except:
  88. try: # mirror 2
  89. print "[Error] - Mirror 1':", geo_db_mirror1 + " Failed!\n"
  90. print "[Info] - Fetching maps from 'Mirror 2':", geo_db_mirror2 + "\n"
  91. response = self.retrieve(geo_db_mirror2, 'maps.tar.gz')
  92. except:
  93. print("[Error] - Something wrong fetching maps from mirrors ...Aborting!"), "\n"
  94. traceback.print_exc()
  95. return False #sys.exit(2)
  96. subprocess.call(shlex.split('tar zxfv maps.tar.gz'))
  97. print "\n[Info] GeoIP maps and databases: ready!\n"
  98. # set pygeoip data sources
  99. self._geoip = pygeoip.GeoIP('maps/GeoLiteCity.dat')
  100. self._geoasn = pygeoip.GeoIP('maps/GeoIPASNum.dat')
  101. self._geoipstatus='ok'
  102. os.remove('maps.tar.gz')
  103. os.remove('maps.downloading')
  104. return True
  105. # fetches geoip data for specified zombie
  106. def geo_ip(self, zombie):
  107. # check for status, downloading is done by ajax() method
  108. if self.get_status() != 'ok':
  109. if self._geoipstatus =='downloading':
  110. print "\n[Info] GeoIP maps and databases: downloading\n"
  111. self._err= "ufomsg('Downloading maps...')"
  112. elif not os.path.exists('maps/GeoIPASNum.dat') or not os.path.exists('maps/GeoLiteCity.dat'):
  113. print "\n[Info] GeoIP maps and databases: download starting!\n"
  114. self._err= "ufomsg('[Info] Map download starting')\n$('#ufomsg').load('/js/ajax.js?fetchgeoip=')"
  115. else:
  116. print "\n[Info] GeoIP maps and databases: unknown error\n"
  117. self._err= "ufomsg('<font color='red'>[Info]</font> Maps: unknown error...')"
  118. return None
  119. if re.match(r'^127\.\d{1,3}\.\d{1,3}\.\d{1,3}$', zombie) or re.match(r'^10\.\d{1,3}\.\d{1,3}\.\d{1,3}$', zombie) or re.match(r'^192.168\.\d{1,3}\.\d{1,3}$', zombie) or re.match(r'^172.(1[6-9]|2[0-9]|3[0-1]).[0-9]{1,3}.[0-9]{1,3}$', zombie) or re.match('localhost', zombie):
  120. self._err= "ufomsg('<font color='red'>[Info]</font> Maps: invalid ip data...')"
  121. return None
  122. # create geoip data skeleton
  123. geo_zombie={}
  124. geo_zombie['qq']=zombie
  125. url = urlparse(zombie)
  126. geo_zombie['city'] = '-'
  127. geo_zombie['country'] = '-'
  128. geo_zombie['country_code'] = '-'
  129. geo_zombie['longitude'] = '-'
  130. geo_zombie['latitude'] = '-'
  131. geo_zombie['ip'] = '-'
  132. geo_zombie['host_name'] = '-'
  133. geo_zombie['asn'] = '-'
  134. geo_zombie['latitude'] = '-'
  135. # retrieve and allocate geoip data
  136. try:
  137. ip = socket.gethostbyname(url.netloc)
  138. except:
  139. self._err= "ufomsg('<font color='yellow'>[Info]</font> GeoIP: hostbyname failed for "+str(url.netloc)+"...')"
  140. return None
  141. if re.match(r"^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$",ip):
  142. geo_zombie['ip'] = ip
  143. try:
  144. record = self._geoip.record_by_addr(ip)
  145. except:
  146. self._err= "ufomsg('<font color='yellow'>[Info]</font> GeoIP: lookup failed for "+ip+", page reload required...')"
  147. return None
  148. try:
  149. asn = self._geoasn.org_by_addr(ip)
  150. if asn is not None:
  151. geo_zombie['asn'] = asn.encode('utf-8')
  152. except:
  153. geo_zombie['asn'] = 'No ASN provided'
  154. try:
  155. geo_zombie['host_name'] = socket.gethostbyaddr(ip)[0].encode('utf-8')
  156. except:
  157. geo_zombie['host_name'] = 'No hostname'
  158. try:
  159. longitude = str(float(record['longitude']))
  160. geo_zombie['longitude'] = longitude
  161. latitude = str(float(record['latitude']))
  162. geo_zombie['latitude'] = latitude
  163. except:
  164. pass
  165. try:
  166. geo_zombie['country'] = record["country_name"].encode('utf-8')
  167. geo_zombie['country_code'] = record["country_code"].lower().encode('utf-8')
  168. if record['city'] is not None:
  169. geo_zombie['city'] = record["city"].encode('utf-8')
  170. except:
  171. pass
  172. return geo_zombie
  173. # generates javascript for adding a new zombie with geoip data
  174. def get_js(self,z):
  175. ret = ""
  176. gz = self.geo_ip(z)
  177. if gz is not None and gz['latitude']!= '-':
  178. ret = "Zombies.add('"+z+"',Array(new L.LatLng("+str(gz['latitude'])+","+str(gz['longitude'])+"),'"+gz['city']+"','"+gz['country']+"','"+gz['country_code']+"','"+gz['asn']+"','"+gz['ip']+"','"+gz['host_name']+"'))\n"
  179. else:
  180. #print 'geozombie dead : ',z
  181. ret += "dead_zombies.push('"+z+"')\n"
  182. ret += "last_zombie = '"+z+"'\n"
  183. return ret
  184. # fetches next zombie from list (using all types of zombies)
  185. def get_next_zombie(self,name):
  186. if name in self.zombies:
  187. for z in self.zombies:
  188. if name == None:
  189. return z
  190. if z == name:
  191. name = None
  192. return None
  193. else:
  194. return self.zombies[0]
  195. # ajax controller
  196. def ajax(self,pGet={}):
  197. if 'fetchgeoip' in pGet.keys():
  198. if self.get_status() == "nomap":
  199. self.download_maps()
  200. return "[Info] Geoip data download done!<br/>"
  201. if 'stats' in pGet.keys():
  202. stat='<script>$(".ufo_stat_div").show()</script>'
  203. if os.path.exists('/tmp/ufonet.html'):
  204. for x in open(r'/tmp/ufonet.html').readlines():
  205. stat = stat + x
  206. else:
  207. stat="<i>[Info] Waiting for statistics generation...</i>"
  208. return stat+"</div>"
  209. if self.get_status() != "ok":
  210. dljs=""
  211. if self.get_status() == "nomap":
  212. dljs+="$('#ufomsg').load('/js/ajax.js?fetchgeoip=')\n"
  213. if 'doll' in pGet.keys():
  214. dljs+="$('#ufomsg').load('/js/ajax.js?fetchdoll="+pGet['doll']+"')\n"
  215. dljs+="doll=new Doll('"+pGet["doll"]+"')\n"
  216. return "[Info] GeoIP data download in progress...<br><i>see console for errors</i>+<script>"+dljs+"</script>"
  217. if 'zombie' in pGet.keys():
  218. zn=base64.b64decode(pGet['zombie'])
  219. nzn=self.get_next_zombie(zn)
  220. if nzn is not None:
  221. zombie=self.get_js(nzn)
  222. return """ <script>
  223. """+zombie+"""
  224. ufomsg('[Info] Adding zombie: """+nzn+"""...')
  225. </script>"""
  226. else:
  227. return "<script>zdone=true\nufomsg('[Info] All zombies deployed!...')\n </script>\n"
  228. if 'fetchdoll' in pGet.keys():
  229. tn=pGet['fetchdoll']
  230. target = self.geo_ip(tn)
  231. if target is None:
  232. return "doll waiting for geoip data !"
  233. return """ doll up !<script>
  234. doll.setData(Array(new L.LatLng("""+str(target['latitude'])+","+str(target['longitude'])+"),'"+target['city']+"','"+target['country']+"','"+target['country_code']+"','"+target['asn']+"','"+target['ip']+"','"+target['host_name']+"'))\nufomsg('[Info] Adding target: """+tn+"""...')\ndoll.show() </script>"""
  235. if 'doll' in pGet.keys():
  236. tn=pGet['doll']
  237. return """<script>
  238. doll=new Doll('"""+tn+"""')\n</script>"""
  239. return "\n"