Pages

Monday, March 29, 2010

XSSexploit Python

Jalan-jalan dapet ginian moga bermanfaat :D



#!/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='