s0md3v / XSStrike

Most advanced XSS scanner.
GNU General Public License v3.0
13.35k stars 1.9k forks source link

How can i test multiple parameters? #413

Open minchan02 opened 3 months ago

minchan02 commented 3 months ago

if i want test this url "http://test.com/?a=1&b=1", 'a' parameter is essential parameter that must not be omitted and i want test only about 'b' parameter but this tool can't test about multiple parameter and just test about each parameter

TheRealH0u commented 2 months ago

If I'm understanding you correctly you hate it that it goes and tests all parameters one by one. So in your example it would first test a and then b. This happens in the bruteforcer.py on line 23. It gets all the parameters and then tests them all. This feature could be added by adding a -p flag with an extended name --parameter-xss or adding a <XSS> placeholder and checking if any of the parameters have a <XSS> as value and then only test those. Would be a nice feature especially if you have many parameters.

TheRealH0u commented 2 months ago
import copy
from urllib.parse import urlparse, unquote

from core.colors import good, green, end
from core.requester import requester
from core.utils import getUrl, getParams
from core.log import setup_logger

logger = setup_logger(__name__)

def bruteforcer(target, paramData, payloadList, encoding, headers, delay, timeout):
    GET, POST = (False, True) if paramData else (True, False)
    host = urlparse(target).netloc  # Extracts host out of the url
    logger.debug('Parsed host to bruteforce: {}'.format(host))
    url = getUrl(target, GET)
    logger.debug('Parsed url to bruteforce: {}'.format(url))
    params = getParams(target, paramData, GET)
    logger.debug_json('Bruteforcer params:', params)
    if not params:
        logger.error('No parameters to test.')
        quit()

    xss_params = [param for param, value in params.items() if '<XSS' in value]
    if xss_params:
        logger.debug(f'Targeting parameters {xss_params} for XSS testing.')
        param_list = xss_params
    else:
        param_list = params.keys()
        logger.debug('No "<XSS>" parameters found. Testing all parameters.')
    for paramName in param_list:
        progress = 1
        paramsCopy = copy.deepcopy(params)

        # Replace <XSS:[default]> placeholders with default values
        for p, v in paramsCopy.items():
            if '<XSS:' in v and p != paramName:
                default_value = v.split('<XSS:')[1].strip('>')
                paramsCopy[p] = default_value
            elif '<XSS>' in v and p != paramName:
                paramsCopy[p] = v
        for payload in payloadList:
            logger.run('Bruteforcing %s[%s%s%s]%s: %i/%i\r' %
                       (green, end, paramName, green, end, progress, len(payloadList)))
            if encoding:
                payload = encoding(unquote(payload))
            paramsCopy[paramName] = payload
            response = requester(url, paramsCopy, headers,
                                 GET, delay, timeout).text
            if encoding:
                payload = encoding(payload)
            if payload in response:
                logger.info('%s %s' % (good, payload))
            progress += 1
    logger.no_format('')

This would be a quick workaround for and the value of parameters should be <XSS:[default_value> like <XSS:test>. The problem is that if the default value has any special characters like <XSS:<test>>. Further testing and editing would be needed but yeah. I'm using this for the past month and it helps out really nice. Maybe there's a better way but it's useful and quite straight forward.

TheRealH0u commented 2 months ago

A quick and very dirty fix to use special characters on line 38. Checking for <XSS:[default> should maybe be a function and return the parameters and their default value. I don't know how time consuming that would be...

import copy
from urllib.parse import urlparse, unquote

from core.colors import good, green, end
from core.requester import requester
from core.utils import getUrl, getParams
from core.log import setup_logger

logger = setup_logger(__name__)

def bruteforcer(target, paramData, payloadList, encoding, headers, delay, timeout):
    GET, POST = (False, True) if paramData else (True, False)
    host = urlparse(target).netloc  # Extracts host out of the url
    logger.debug('Parsed host to bruteforce: {}'.format(host))
    url = getUrl(target, GET)
    logger.debug('Parsed url to bruteforce: {}'.format(url))
    params = getParams(target, paramData, GET)
    logger.debug_json('Bruteforcer params:', params)
    if not params:
        logger.error('No parameters to test.')
        quit()

    xss_params = [param for param, value in params.items() if '<XSS:' in value]
    if xss_params:
        logger.debug(f'Targeting parameters {xss_params} for XSS testing.')
        param_list = xss_params
    else:
        param_list = params.keys()
        logger.debug('No "<XSS>" parameters found. Testing all parameters.')
    for paramName in param_list:
        progress = 1
        paramsCopy = copy.deepcopy(params)

        # Replace <XSS:[default]> placeholders with default values
        for p, v in paramsCopy.items():
            if '<XSS:' in v and p != paramName:
                default_value = v.split('<XSS:')[1][:-1]
                paramsCopy[p] = default_value
            elif '<XSS>' in v and p != paramName:
                paramsCopy[p] = v
        for payload in payloadList:
            logger.run('Bruteforcing %s[%s%s%s]%s: %i/%i\r' %
                       (green, end, paramName, green, end, progress, len(payloadList)))
            if encoding:
                payload = encoding(unquote(payload))
            paramsCopy[paramName] = payload
            response = requester(url, paramsCopy, headers,
                                 GET, delay, timeout).text
            if encoding:
                payload = encoding(payload)
            if payload in response:
                logger.info('%s %s' % (good, payload))
            progress += 1
    logger.no_format('')