Done.
'''
riaEnumerator.py
Copyright 2009 Jon Rose
This file is part of w3af, w3af.sourceforge.net .
w3af 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 version 2 of the License.
w3af 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 w3af; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
'''
import core.controllers.outputManager as om
# options
from core.data.options.option import option
from core.data.options.optionList import optionList
from core.controllers.basePlugin.baseDiscoveryPlugin import baseDiscoveryPlugin
from core.controllers.misc.levenshtein import relative_distance
from core.controllers.w3afException import w3afRunOnce, w3afException
import core.data.parsers.urlParser as urlParser
from core.data.db.temp_persist import disk_list
import core.data.kb.knowledgeBase as kb
import core.data.kb.vuln as vuln
import core.data.kb.info as info
import core.data.constants.severity as severity
import xml.dom.minidom
import os
class riaEnumerator(baseDiscoveryPlugin):
'''
Fingerprint Rich Internet Apps - Google Gears Manifest files, Silverlight and Flash.
@author: Jon Rose ( jr...@owasp.org )
'''
def __init__(self):
baseDiscoveryPlugin.__init__(self)
self._exec = True
# User configured parameters
self._wordlist = 'plugins' + os.path.sep + 'discovery' + os.path.sep + 'riaEnumerator'
self._wordlist += os.path.sep + 'common_filenames.db'
# This is a list of common files for google gears manifest:
self._extensions = ['','.php','.json','.txt','.gears']
# Already analyzed extensions
self._already_analyzed_ext = disk_list()
def discover(self, fuzzableRequest ):
'''
Get the file and parse it.
@parameter fuzzableRequest: A fuzzableRequest instance that contains
(among other things) the URL to test.
'''
if not self._exec:
raise w3afRunOnce()
else:
# Only run once
self._exec = False
is_404 = kb.kb.getData( 'error404page', '404' )
self._fuzzableRequests = []
dirs = []
base_url = urlParser.baseUrl( fuzzableRequest.getURL() )
for ext in self._extensions:
for word in file(self._wordlist):
manifest_url = urlParser.urlJoin( base_url , word.strip() )
manifest_url = manifest_url + ext
om.out.debug( 'Google Gears Manifest Testing ' + manifest_url )
http_response = self._urlOpener.GET( manifest_url, useCache=True )
if '"entries":' in http_response and not is_404( http_response ):
# Save it to the kb!
i = info.info()
i.setName('Gears Manifest')
i.setURL( manifest_url )
i.setId( http_response.id )
i.setDesc( 'A gears manifest file was found at: "'+ manifest_url +'". Each file should be manually reviewed for sensitive information that may get cached on the client.' )
kb.kb.append( self, manifest_url, i )
om.out.information( i.getDesc() )
for line in http_response.getBody().split('\n'):
if len(line) > 0 and line[0] != '#' and line.upper().find('URL') > 0:
url = line[ line.find(':') + 2 : ]
url = url.replace('"','')
om.out.information( 'Google Gears Cache File ' + url )
url = urlParser.urlJoin( base_url , url )
dirs.append( url )
### CrossDomain.XML
cross_domain_url = urlParser.urlJoin( base_url , 'crossdomain.xml' )
om.out.debug( 'Checking crossdomain.xml file')
om.out.information( 'Checking crossdomain.xml file')
response = self._urlOpener.GET( cross_domain_url, useCache=True )
if not is_404( response ):
self._checkResponse(response, 'crossdomain.xml')
### CrossAccessPolicy.XML
client_access_url = urlParser.urlJoin( base_url , 'clientaccesspolicy.xml' )
om.out.information( 'Checking clientaccesspolicy.xml file')
response = self._urlOpener.GET( client_access_url, useCache=True )
if not is_404( response ):
self._checkResponse(response, 'clientaccesspolicy.xml')
for url in dirs:
http_response = self._urlOpener.GET( url, useCache=True )
fuzz_reqs = self._createFuzzableRequests( http_response )
self._fuzzableRequests.extend( fuzz_reqs )
return self._fuzzableRequests
def _checkResponse(self, response, file ):
om.out.information( 'Checking Response')
try:
dom = xml.dom.minidom.parseString( response.getBody() )
except Exception, e:
# Report this, it may be interesting for the final user
# not a vulnerability per-se... but... it's information after all
if 'allow-access-from' in response.getBody() or \
'cross-domain-policy' in response.getBody() or \
'cross-domain-access' in response.getBody():
i = info.info()
i.setName('Invalid ' + file)
i.setURL( response.getURL() )
i.setMethod( 'GET' )
msg = 'The "' + file + '" file at: "' + response.getURL() + '" is not a valid XML.'
i.setDesc( msg )
i.setId( response.id )
kb.kb.append( self, 'info', i )
om.out.information( i.getDesc() )
else:
if(file == 'crossdomain.xml'):
url_list = dom.getElementsByTagName("allow-access-from")
attribute = 'domain'
if(file == 'clientaccesspolicy.xml'):
url_list = dom.getElementsByTagName("domain")
attribute = 'uri'
for url in url_list:
url = url.getAttribute(attribute)
om.out.information(url)
if url == '*':
v = vuln.vuln()
v.setURL( response.getURL() )
v.setMethod( 'GET' )
v.setName( 'Insecure "' + file + '" settings' )
v.setSeverity(severity.LOW)
msg = 'The "' + file + '" file at "' + response.getURL() + '" allows'
msg += ' flash/silverlight access from any site.'
v.setDesc( msg )
v.setId( response.id )
kb.kb.append( self, 'vuln', v )
om.out.vulnerability( v.getDesc(), severity=v.getSeverity() )
else:
i = info.info()
i.setName('Crossdomain allow ACL')
i.setURL( response.getURL() )
i.setMethod( 'GET' )
i.setDesc( file + '" file allows access from: "' + url + '".')
i.setId( response.id )
kb.kb.append( self, 'info', i )
om.out.information( i.getDesc() )
def getOptions( self ):
'''
@return: A list of option objects for this plugin.
'''
d1 = 'Wordlist to use in the manifest file name bruteforcing process.'
o1 = option('wordlist', self._wordlist , d1, 'string')
d2 = 'File extensions to use when brute forcing Gears Manifest files'
o2 = option('manifestExtensions', self._extensions, d2, 'list')
ol = optionList()
ol.add(o1)
ol.add(o2)
return ol
def setOptions( self, OptionList ):
'''
This method sets all the options that are configured using the user interface
generated by the framework using the result of getOptions().
@parameter OptionList: A dictionary with the options for the plugin.
@return: No value is returned.
'''
wordlist = OptionList['wordlist'].getValue()
if os.path.exists( wordlist ):
self._wordlist = wordlist
self._extensions = OptionList['manifestExtensions'].getValue()
def getPluginDeps( self ):
'''
@return: A list with the names of the plugins that should be runned before the
current one.
'''
return []
def getLongDesc( self ):
'''
@return: A DETAILED description of the plugin functions and features.
'''
return '''
This plugin searches for various Rich Internet Application files. It currently searches for:
Google gears manifests
These files are used to determine which files are locally cached by google gears.
They do not get cleared when the browser cache is cleared and may contain sensitive information.
Flex crossdomain.xml
This file stores domains which are allowed to make cross domain requests to the server.
Silverlight clientaccesspolicy.xml
This file determines which clients can access the server in place of the crossdomain.xml.
Two configurable parameters exists:
- wordlist: The wordlist to be used in the gears bruteforce process.
- manifestExtensions: File extensions to use during manifest bruteforcing.
'''
On Jun 24, 2009, at 2:07 PM, Andres Riancho wrote:
Jon,
On Sat, Jun 20, 2009 at 4:34 PM, Andres Riancho<andres.rian...@gmail.com
> wrote:
Jon,
On Fri, Jun 19, 2009 at 11:34 AM, jrose<jr...@owasp.org> wrote:
Hey,
I extended the CrossDomain.py discovery plugin to also identify
google gears
manifest files and Silverlight files. Check it out and let me
know what you
think.
Excellent work! I just commited this to the trunk, and removed the
crossDomain plugin =)
In the review process, I changed some minimal things, nothing really
important but it could be interesting for you to perform a diff
between your riaEnumerator and the final version I commited.
Here is a link to the information related to the commit, please test
the plugin to see if it's working as expected.
http://w3af.svn.sourceforge.net/viewvc/w3af?view=rev&revision=2917
Thank you so much for your contribution, I hope you mention it at
YSTS
:) See you there tomorrow!
After your talk at YSTS I started to look at some of the RIA things
you mentioned, and I found out that the Google gears manifest file
contains some information that we aren't using in the plugin.
For what I can see here [0], the manifest file contains lines like
this ones:
{ "url": "index.html" },
And we aren't parsing them to return that information to the core.
What if in this file we have one entry that says
"super-secret-access.html" ? I would like the framework to be able to
parse that, and crawl it using the rest of the plugins.
What do you think?
[0] http://code.google.com/apis/gears/tutorial.html
Cheers,
Thanks,
Jon
------------------------------------------------------------------------------
Crystal Reports - New Free Runtime and 30 Day Trial
Check out the new simplified licensing option that enables unlimited
royalty-free distribution of the report engine for externally facing
server and web deployment.
http://p.sf.net/sfu/businessobjects
_______________________________________________
W3af-develop mailing list
W3af-develop@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/w3af-develop
--
Andrés Riancho
Founder, Bonsai - Information Security
http://www.bonsai-sec.com/
http://w3af.sf.net/
--
Andrés Riancho
Founder, Bonsai - Information Security
http://www.bonsai-sec.com/
http://w3af.sf.net/
------------------------------------------------------------------------------
Enter the BlackBerry Developer Challenge
This is your chance to win up to $100,000 in prizes! For a limited time,
vendors submitting new applications to BlackBerry App World(TM) will have
the opportunity to enter the BlackBerry Developer Challenge. See full prize
details at: http://p.sf.net/sfu/Challenge
_______________________________________________
W3af-develop mailing list
W3af-develop@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/w3af-develop