#!/usr/bin/env python
# -*- coding: iso-8859-1 -*-
# XSSploit
# Copyright (C) 2008 Nicolas OBERLI
#
# This program 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 Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
__VERSION = '0.4'
"""Application version"""
import rlcompleter, code, time, sys, getopt
import random, string, re, os
import urllib, urllib2, cookielib, socket
import logging
_READLINE=0
"""Tells if the readline module is present"""
_BASEURL=''
"""Sets the base URL the user entered"""
try:
import readline
_READLINE=1
except ImportError:
print 'Unable to import readline. Tab completition will not be usable'
_READLINE=0
import BeautifulSoup
try:
from lxml import etree
except ImportError:
# Python 2.5
import xml.etree.ElementTree as etree
class xssAnalyzer:
"""
Request forgery, filter detection and avoidance
"""
PATTERNLENGTH=15
"""Sets the number of characters in the pattern"""
def __init__(self, wwwIOInstance=''):
self._params=[]
"""stores the param tests"""
self._analysisLevel=2
"""Sets the scanning level - 2 by default"""
self.badChars=[]
"""Stores the bad chars to check"""
if wwwIOInstance=='':
self._wwwIO=wwwIO()
else:
self._wwwIO=wwwIOInstance
self._loadKeywords()
def setAnalysisMode(self, mode):
"""
Defines the number of parameters to put together in a request
@type mode: Integer
@param mode: The maximum number of parameters to put in a request
"""
self._analysisLevel=mode
def _combineParams(self, k):
"""
Reorders and sort any unique combinations of the list
@type k: list
@param k: List of parameters to sort
@return: A list containing the randomized fields
"""
paramsList=[]
i=1
while i
for uc in self._xcombinations(k,i):
paramsList.append(uc)
i=i+1
return paramsList
def _generatePattern(self):
"""
Generates a pattern
@return: a pattern like (xxxxxxxxxxxxxxx)
"""
return '('+''.join([random.choice(string.ascii_letters+string.digits) for x in xrange(self.PATTERNLENGTH)])+')'
def _generateRequests(self, formID, params):
"""
Defines all the requests to test
@type formID: Integer
@param formID: The form ID for the requests
@type params: List
@param params: the parameter list
@return: The requests in a dictionnary form
"""
lsRequest=[]
finalRequests=[]
paramName=params[-1]
if len(params)==1:
pattern=self._generatePattern()
return [[[paramName, {paramName: pattern}]]]
paramValues=self._formDB.getParamValues(formID, paramName)
params.pop()
finalRequests=[]
for value in paramValues:
if value=='':
value='XSSploit'
for lsRequest in self._generateRequests(formID, params):
lsRequest[0][1].update({paramName: value})
finalRequests.append(lsRequest)
logging.debug('Request created : '+ str(lsRequest))
lsRequest=[]
return finalRequests
def analyzeFormDB(self, formDB, permCheck=1):
"""
Performs the first analysis on the formDB
@type formDB : formDB
@param formDB: The formDB instance to analyze
@type permCheck: Integer
@param permCheck: Tells if XSSploit should check for permanent XSS 0=No 1=Yes
@return: A list of xss instances (if found)
"""
self._formDB=formDB
"""Stores the formDB"""
results=[]
"""Stores the final request list"""
tmpFile=open('xssploit.tmp', 'w+')
logging.info('Checking for XSS...')
for form in self._formDB._forms:
formID=form[0]
formUrl=self._formDB.getFormUrl(formID)
formMethod=self._formDB.getFormMethod(formID)
requestParamsList=self._combineParams(formDB.getParamNames(formID))
for requestlist in requestParamsList:
for request in self._generateRequests(formID, requestlist):
tmpFile.write(str(formID)+'\\'+str(request[0][1])+'\n')
xss=self._checkXss(formID, request[0])
if xss:
for xssFound in results:
if xss.vulnerableParameter==xssFound.vulnerableParameter and xss.url==xssFound.url:
del xss
break
else:
results.append(xss)
tmpFile.close()
if permCheck==1:
logging.info('Checking for permanent XSS...')
patterns=self._wwwIO.spiderPermanent()
for permanentXSS in self._checkPermanentXss(patterns):
if permanentXSS:
for xssFound in results:
if permanentXSS.vulnerableParameter==xssFound.vulnerableParameter and permanentXSS.parameters==xssFound.parameters:
xssFound.type='persistant'
del permanentXSS
break
else:
results.append(permanentXSS)
os.remove("xssploit.tmp")
return results
def _escapeContext(self, xssObject):
"""
Try to escape a bad context by looking in the bad characters.
Updates the escapeHeader and escapeTrailer attributes
It will modify the escaped attribute if yes
@type xssObject: xss
@param xssObject: The xss instance to check
@return: 1 if successfull, 0 otherwise
"""
logging.debug('Begining context escaping for : '+ xssObject.url+'('+xssObject.vulnerableParameter+')')
#scriptWord will contain the script word we will use
regexp=re.compile("'(s.{0,1}c.{0,1}r.{0,1}i.{0,1}p.{0,1}t)'", re.IGNORECASE)
scriptWord = regexp.search(str(xssObject.goodChars))
if scriptWord:
scriptWord=scriptWord.group(1)
logging.debug('Script word used : '+scriptWord)
for context in xssObject.context:
_escaped=0
#Are we in a tag ?
if context[0]=='tag':
logging.debug('XSS is in a tag : '+ context[1])
#Are there any double quotes to escape ?
if "'" in xssObject.goodChars and '"' in xssObject.goodChars and '>' in xssObject.goodChars:
xssObject.escapeHeader='"\'>'
logging.debug('XSS escapeHeader (no magic_quotes) : '+xssObject.escapeHeader)
#We can also bypass this filter even with the PHP magic_quotes
if '"' in xssObject.badChars and "'" in xssObject.badChars:
if xssObject.badChars['"']=='\\"' and xssObject.badChars["'"]=="\\'":
xssObject.escapeHeader='"\'>'
logging.debug('XSS escapeHeader (magic_quotes) : '+xssObject.escapeHeader)
#Not necessary, but it's nicer to cleanly end the HTML
if '<' not in xssObject.badChars and '!' not in xssObject.badChars and '-' not in xssObject.badChars:
xssObject.escapeTrailer='
Monday, March 29, 2010
XSSexploit Python
Jalan-jalan dapet ginian moga bermanfaat :D