mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2025-01-24 00:04:23 +03:00
major refactoring
This commit is contained in:
parent
1bf8939e2f
commit
1e9ae40397
19
extra/xmlobject/__init__.py
Executable file
19
extra/xmlobject/__init__.py
Executable file
|
@ -0,0 +1,19 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
#
|
||||||
|
# Copyright 2007-2008 David McNab
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify it
|
||||||
|
# under the terms of the GNU Lesser General Public License as published
|
||||||
|
# by the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
|
||||||
|
pass
|
534
extra/xmlobject/xmlobject.py
Normal file
534
extra/xmlobject/xmlobject.py
Normal file
|
@ -0,0 +1,534 @@
|
||||||
|
"""
|
||||||
|
Allows XML files to be operated on like Python objects.
|
||||||
|
|
||||||
|
Features:
|
||||||
|
- load XML source from file pathnames, readable file objects or raw strings
|
||||||
|
- add, get and set tag attributes like with python attributes
|
||||||
|
- iterate over nodes
|
||||||
|
- save the modified XMLFile or XMLObject to file
|
||||||
|
|
||||||
|
Example XML file::
|
||||||
|
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<rapsheets>
|
||||||
|
<person name="John Smith" age="42">
|
||||||
|
<!-- John Smith has an appeal in process against his last conviction -->
|
||||||
|
<crime name="Armed robbery" date="March 11, 1994"/>
|
||||||
|
<crime name="Aggravated burglary" date="June 9, 2001"/>
|
||||||
|
</person>
|
||||||
|
<person name="Mary Jones" age="33">
|
||||||
|
<crime name="Prostitution" date="January 8, 1997"/>
|
||||||
|
<crime name="Selling heroin" date="September 4, 2002"/>
|
||||||
|
<crime name="Manslaughter" date="December 21, 2004"/>
|
||||||
|
</person>
|
||||||
|
</rapsheets>
|
||||||
|
|
||||||
|
Example usage::
|
||||||
|
|
||||||
|
>>> from xmlobject import XMLFile
|
||||||
|
|
||||||
|
>>> x = XMLFile(path="sample.xml)
|
||||||
|
|
||||||
|
>>> print x
|
||||||
|
<xmlobj.XMLFile instance at 0xb7ccc52c>
|
||||||
|
|
||||||
|
>>> print x.root
|
||||||
|
<XMLNode: rapsheets>
|
||||||
|
|
||||||
|
>>> print x.root._children
|
||||||
|
[<XMLNode: text>, <XMLNode: person>, <XMLNode: text>,
|
||||||
|
<XMLNode: person>, <XMLNode: text>]
|
||||||
|
|
||||||
|
>>> print x.root.person
|
||||||
|
[<XMLNode: person>, <XMLNode: person>]
|
||||||
|
|
||||||
|
>>> print x.root.person[0].name
|
||||||
|
John Smith
|
||||||
|
|
||||||
|
>>> john = x.root.person[0]
|
||||||
|
|
||||||
|
>>> john.height = 184
|
||||||
|
|
||||||
|
>>> c = john._addNode("crime")
|
||||||
|
|
||||||
|
>>> c.name = "Grand Theft Auto"
|
||||||
|
|
||||||
|
>>> c.date = "4 May, 2005"
|
||||||
|
|
||||||
|
>>> print x.toxml()
|
||||||
|
<?xml version="1.0" ?>
|
||||||
|
<rapsheets>
|
||||||
|
<person age="42" height="184" name="John Smith">
|
||||||
|
<!-- John Smith has an appeal in process against his last conviction -->
|
||||||
|
<crime date="March 11, 1994" name="Armed robbery"/>
|
||||||
|
<crime date="June 9, 2001" name="Aggravated burglary"/>
|
||||||
|
<crime date="4 May, 2005" name="Grand Theft Auto"/></person>
|
||||||
|
<person age="33" name="Mary Jones">
|
||||||
|
<crime date="January 8, 1997" name="Prostitution"/>
|
||||||
|
<crime date="September 4, 2002" name="Selling heroin"/>
|
||||||
|
<crime date="December 21, 2004" name="Manslaughter"/>
|
||||||
|
</person>
|
||||||
|
</rapsheets>
|
||||||
|
|
||||||
|
>>>
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
import sys, os
|
||||||
|
import xml.dom
|
||||||
|
import xml.dom.minidom
|
||||||
|
from xml.dom.minidom import parse, parseString, getDOMImplementation
|
||||||
|
|
||||||
|
impl = getDOMImplementation()
|
||||||
|
|
||||||
|
class MissingRootTag(Exception):
|
||||||
|
"""root tag name was not given"""
|
||||||
|
|
||||||
|
class InvalidXML(Exception):
|
||||||
|
"""failed to parse XML input"""
|
||||||
|
|
||||||
|
class CannotSave(Exception):
|
||||||
|
"""unable to save"""
|
||||||
|
|
||||||
|
class InvalidNode(Exception):
|
||||||
|
"""not a valid minidom node"""
|
||||||
|
|
||||||
|
class XMLFile:
|
||||||
|
"""
|
||||||
|
Allows an xml file to be viewed and operated on
|
||||||
|
as a python object.
|
||||||
|
|
||||||
|
(If you're viewing the epydoc-generated HTML documentation, click the 'show private'
|
||||||
|
link at the top right of this page to see all the methods)
|
||||||
|
|
||||||
|
Holds the root node in the .root attribute, also in an attribute
|
||||||
|
with the same name as this root node.
|
||||||
|
"""
|
||||||
|
def __init__(self, **kw):
|
||||||
|
"""
|
||||||
|
Create an XMLFile
|
||||||
|
|
||||||
|
Keywords:
|
||||||
|
- path - a pathname from which the file can be read
|
||||||
|
- file - an open file object from which the raw xml
|
||||||
|
can be read
|
||||||
|
- raw - the raw xml itself
|
||||||
|
- root - name of root tag, if not reading content
|
||||||
|
|
||||||
|
Usage scenarios:
|
||||||
|
1. Working with existing content - you must supply input in
|
||||||
|
one of the following ways:
|
||||||
|
- 'path' must be an existing file, or
|
||||||
|
- 'file' must be a readable file object, or
|
||||||
|
- 'raw' must contain raw xml as a string
|
||||||
|
2. Creating whole new content - you must give the name
|
||||||
|
of the root tag in the 'root' keyword
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
- Keyword precedence governing existing content is:
|
||||||
|
1. path (if existing file)
|
||||||
|
2. file
|
||||||
|
3. raw
|
||||||
|
- If working with existing content:
|
||||||
|
- if the 'root' is given, then the content's toplevel tag
|
||||||
|
MUST match the value given for 'root'
|
||||||
|
- trying to _save will raise an exception unless 'path'
|
||||||
|
has been given
|
||||||
|
- if not working with existing content:
|
||||||
|
- 'root' must be given
|
||||||
|
- _save() will raise an exception unless 'path' has been given
|
||||||
|
"""
|
||||||
|
path = kw.get("path", None)
|
||||||
|
fobj = kw.get("file", None)
|
||||||
|
raw = kw.get("raw", None)
|
||||||
|
root = kw.get("root", None)
|
||||||
|
|
||||||
|
if path:
|
||||||
|
self.path = path
|
||||||
|
try:
|
||||||
|
fobj = file(path)
|
||||||
|
except IOError:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
self.path = None
|
||||||
|
|
||||||
|
if fobj:
|
||||||
|
raw = fobj.read()
|
||||||
|
|
||||||
|
if raw:
|
||||||
|
self.dom = xml.dom.minidom.parseString(raw)
|
||||||
|
else:
|
||||||
|
# could not source content, so create a blank slate
|
||||||
|
if not root:
|
||||||
|
# in which case, must give a root node name
|
||||||
|
raise MissingRootTag(
|
||||||
|
"No existing content, so must specify root")
|
||||||
|
|
||||||
|
# ok, create a blank dom
|
||||||
|
self.dom = impl.createDocument(None, root, None)
|
||||||
|
|
||||||
|
# get the root node, save it as attributes 'root' and name of node
|
||||||
|
rootnode = self.dom.documentElement
|
||||||
|
|
||||||
|
# now validate root tag
|
||||||
|
if root:
|
||||||
|
if rootnode.nodeName != root:
|
||||||
|
raise IncorrectRootTag("Gave root='%s', input has root='%s'" % (
|
||||||
|
root, rootnode.nodeName))
|
||||||
|
|
||||||
|
# need this for recursion in XMLNode
|
||||||
|
self._childrenByName = {}
|
||||||
|
self._children = []
|
||||||
|
|
||||||
|
# add all the child nodes
|
||||||
|
for child in self.dom.childNodes:
|
||||||
|
childnode = XMLNode(self, child)
|
||||||
|
#print "compare %s to %s" % (rootnode, child)
|
||||||
|
if child == rootnode:
|
||||||
|
#print "found root"
|
||||||
|
self.root = childnode
|
||||||
|
setattr(self, rootnode.nodeName, self.root)
|
||||||
|
|
||||||
|
def save(self, where=None, obj=None):
|
||||||
|
"""
|
||||||
|
Saves the document.
|
||||||
|
|
||||||
|
If argument 'where' is given, saves to it, otherwise
|
||||||
|
tries to save to the original given 'path' (or barfs)
|
||||||
|
|
||||||
|
Value can be a string (taken to be a file path), or an open
|
||||||
|
file object.
|
||||||
|
"""
|
||||||
|
obj = obj or self.dom
|
||||||
|
|
||||||
|
if not where:
|
||||||
|
if self._root.path:
|
||||||
|
where = self._root.path
|
||||||
|
|
||||||
|
if isinstance(where, str):
|
||||||
|
where = file(where, "w")
|
||||||
|
|
||||||
|
if not where:
|
||||||
|
raise CannotSave("No save destination, and no original path")
|
||||||
|
|
||||||
|
where.write(obj.toxml())
|
||||||
|
where.flush()
|
||||||
|
|
||||||
|
def saveAs(self, path):
|
||||||
|
"""
|
||||||
|
save this time, and all subsequent times, to filename 'path'
|
||||||
|
"""
|
||||||
|
self.path = path
|
||||||
|
self.save()
|
||||||
|
|
||||||
|
def toxml(self):
|
||||||
|
return self.dom.toxml()
|
||||||
|
|
||||||
|
def __len__(self):
|
||||||
|
"""
|
||||||
|
returns number of child nodes
|
||||||
|
"""
|
||||||
|
return len(self._children)
|
||||||
|
|
||||||
|
def __getitem__(self, idx):
|
||||||
|
if isinstance(idx, int):
|
||||||
|
return self._children[idx]
|
||||||
|
else:
|
||||||
|
return self._childrenByName[idx]
|
||||||
|
|
||||||
|
|
||||||
|
class XMLNode:
|
||||||
|
"""
|
||||||
|
This is the workhorse for the xml object interface
|
||||||
|
|
||||||
|
(If you're viewing the epydoc-generated HTML documentation, click the 'show private'
|
||||||
|
link at the top right of this page to see all the methods)
|
||||||
|
|
||||||
|
"""
|
||||||
|
def __init__(self, parent, node):
|
||||||
|
"""
|
||||||
|
You shouldn't need to instantiate this directly
|
||||||
|
"""
|
||||||
|
self._parent = parent
|
||||||
|
if isinstance(parent, XMLFile):
|
||||||
|
self._root = parent
|
||||||
|
else:
|
||||||
|
self._root = parent._root
|
||||||
|
self._node = node
|
||||||
|
self._childrenByName = {}
|
||||||
|
self._children = []
|
||||||
|
|
||||||
|
# add ourself to parent's children registry
|
||||||
|
parent._children.append(self)
|
||||||
|
|
||||||
|
# the deal with named subtags is that we store the first instance
|
||||||
|
# as itself, and with second and subsequent instances, we make a list
|
||||||
|
parentDict = self._parent._childrenByName
|
||||||
|
nodeName = node.nodeName
|
||||||
|
if not parentDict.has_key(nodeName):
|
||||||
|
parentDict[nodeName] = parent.__dict__[nodeName] = self
|
||||||
|
else:
|
||||||
|
if isinstance(parentDict[nodeName], XMLNode):
|
||||||
|
# this is the second child node of a given tag name, so convert
|
||||||
|
# the instance to a list
|
||||||
|
parentDict[nodeName] = parent.__dict__[nodeName] = [parentDict[nodeName]]
|
||||||
|
parentDict[nodeName].append(self)
|
||||||
|
|
||||||
|
# figure out our type
|
||||||
|
self._value = None
|
||||||
|
if isinstance(node, xml.dom.minidom.Text):
|
||||||
|
self._type = "text"
|
||||||
|
self._value = node.nodeValue
|
||||||
|
elif isinstance(node, xml.dom.minidom.Element):
|
||||||
|
self._type = "node"
|
||||||
|
elif isinstance(node, xml.dom.minidom.Comment):
|
||||||
|
self._type = "comment"
|
||||||
|
self._value = node.nodeValue
|
||||||
|
else:
|
||||||
|
raise InvalidNode("node class %s" % node.__class__)
|
||||||
|
|
||||||
|
# and wrap all the child nodes
|
||||||
|
for child in node.childNodes:
|
||||||
|
XMLNode(self, child)
|
||||||
|
|
||||||
|
def _render(self):
|
||||||
|
"""
|
||||||
|
Produces well-formed XML of this node's contents,
|
||||||
|
indented as required
|
||||||
|
"""
|
||||||
|
return self._node.toxml()
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
if self._type == "node":
|
||||||
|
return "<XMLNode: %s>" % self._node.nodeName
|
||||||
|
else:
|
||||||
|
return "<XMLNode: %s>" % self._type
|
||||||
|
|
||||||
|
def __getattr__(self, attr):
|
||||||
|
"""
|
||||||
|
Fetches an attribute or child node of this tag
|
||||||
|
|
||||||
|
If it's an attribute, then returns the attribute value as a string.
|
||||||
|
|
||||||
|
If a child node, then:
|
||||||
|
- if there is only one child node of that name, return it
|
||||||
|
- if there is more than one child node of that name, return a list
|
||||||
|
of child nodes of that tag name
|
||||||
|
|
||||||
|
Supports some magic attributes:
|
||||||
|
- _text - the value of the first child node of type text
|
||||||
|
"""
|
||||||
|
#print "%s: __getattr__: attr=%s" % (self, attr)
|
||||||
|
|
||||||
|
if attr == '_text':
|
||||||
|
# magic attribute to return text
|
||||||
|
tnode = self['#text']
|
||||||
|
if isinstance(tnode, list):
|
||||||
|
tnode = tnode[0]
|
||||||
|
return tnode._value
|
||||||
|
|
||||||
|
if self._type in ['text', 'comment']:
|
||||||
|
if attr == '_value':
|
||||||
|
return self._node.nodeValue
|
||||||
|
else:
|
||||||
|
raise AttributeError(attr)
|
||||||
|
|
||||||
|
if self._node.hasAttribute(attr):
|
||||||
|
return self._node.getAttribute(attr)
|
||||||
|
elif self._childrenByName.has_key(attr):
|
||||||
|
return self._childrenByName[attr]
|
||||||
|
|
||||||
|
#elif attr == 'value':
|
||||||
|
# magic attribute
|
||||||
|
|
||||||
|
else:
|
||||||
|
raise AttributeError(attr)
|
||||||
|
|
||||||
|
|
||||||
|
def __setattr__(self, attr, val):
|
||||||
|
"""
|
||||||
|
Change the value of an attribute of this tag
|
||||||
|
|
||||||
|
The magic attribute '_text' can be used to set the first child
|
||||||
|
text node's value
|
||||||
|
|
||||||
|
For example::
|
||||||
|
|
||||||
|
Consider:
|
||||||
|
|
||||||
|
<somenode>
|
||||||
|
<child>foo</child>
|
||||||
|
</somenode>
|
||||||
|
|
||||||
|
>>> somenode
|
||||||
|
<XMLNODE: somenode>
|
||||||
|
>>> somenode.child
|
||||||
|
<XMLNODE: child>
|
||||||
|
>>> somenode.child._text
|
||||||
|
'foo'
|
||||||
|
>>> somenode._toxml()
|
||||||
|
u'<somenode><child>foo</child></somenode>'
|
||||||
|
>>> somenode.child._text = 'bar'
|
||||||
|
>>> somenode.child._text
|
||||||
|
'bar'
|
||||||
|
>>> somenode.child._toxml()
|
||||||
|
u'<somenode><child>bar/child></somenode>'
|
||||||
|
|
||||||
|
"""
|
||||||
|
if attr.startswith("_"):
|
||||||
|
|
||||||
|
# magic attribute for setting _text
|
||||||
|
if attr == '_text':
|
||||||
|
tnode = self['#text']
|
||||||
|
if isinstance(tnode, list):
|
||||||
|
tnode = tnode[0]
|
||||||
|
tnode._node.nodeValue = val
|
||||||
|
tnode._value = val
|
||||||
|
return
|
||||||
|
|
||||||
|
self.__dict__[attr] = val
|
||||||
|
elif self._type in ['text', 'comment']:
|
||||||
|
self._node.nodeValue = val
|
||||||
|
else:
|
||||||
|
# discern between attribute and child node
|
||||||
|
if self._childrenByName.has_key(attr):
|
||||||
|
raise Exception("Attribute Exists")
|
||||||
|
self._node.setAttribute(attr, str(val))
|
||||||
|
|
||||||
|
def _keys(self):
|
||||||
|
"""
|
||||||
|
Return a list of attribute names
|
||||||
|
"""
|
||||||
|
return self._node.attributes.keys()
|
||||||
|
|
||||||
|
def _values(self):
|
||||||
|
"""
|
||||||
|
Returns a list of (attrname, attrval) tuples for this tag
|
||||||
|
"""
|
||||||
|
return [self._node.getAttribute(k) for k in self._node.attributes.keys()]
|
||||||
|
|
||||||
|
def _items(self):
|
||||||
|
"""
|
||||||
|
returns a list of attribute values for this tag
|
||||||
|
"""
|
||||||
|
return [(k, self._node.getAttribute(k)) for k in self._node.attributes.keys()]
|
||||||
|
|
||||||
|
def _has_key(self, k):
|
||||||
|
"""
|
||||||
|
returns True if this tag has an attribute of the given name
|
||||||
|
"""
|
||||||
|
return self._node.hasAttribute(k) or self._childrenByName.has_key(k)
|
||||||
|
|
||||||
|
def _get(self, k, default=None):
|
||||||
|
"""
|
||||||
|
returns the value of attribute k, or default if no such attribute
|
||||||
|
"""
|
||||||
|
if self._has_key(k):
|
||||||
|
return getattr(self, k)
|
||||||
|
else:
|
||||||
|
return default
|
||||||
|
def __len__(self):
|
||||||
|
"""
|
||||||
|
returns number of child nodes
|
||||||
|
"""
|
||||||
|
return len(self._children)
|
||||||
|
|
||||||
|
def __getitem__(self, idx):
|
||||||
|
"""
|
||||||
|
if given key is numeric, return the nth child, otherwise
|
||||||
|
try to return the child tag (or list of child tags) having
|
||||||
|
the key as the tag name
|
||||||
|
"""
|
||||||
|
#print "__getitem__: idx=%s" % str(idx)
|
||||||
|
|
||||||
|
if isinstance(idx, slice) or isinstance(idx, int):
|
||||||
|
return self._children[idx]
|
||||||
|
elif isinstance(idx, str):
|
||||||
|
return self._childrenByName[idx]
|
||||||
|
else:
|
||||||
|
raise IndexError(idx)
|
||||||
|
|
||||||
|
def _addNode(self, child):
|
||||||
|
"""
|
||||||
|
Tries to append a child node to the tree, and returns it
|
||||||
|
|
||||||
|
Value of 'child' must be one of:
|
||||||
|
- a string (in which case it is taken to be the name
|
||||||
|
of the new node's tag)
|
||||||
|
- a dom object, in which case it will be wrapped and added
|
||||||
|
- an XMLNode object, in which case it will be added without
|
||||||
|
wrapping
|
||||||
|
"""
|
||||||
|
|
||||||
|
if isinstance(child, XMLNode):
|
||||||
|
|
||||||
|
# add it to our children registry
|
||||||
|
self._children.append(child)
|
||||||
|
|
||||||
|
parentDict = self._childrenByName
|
||||||
|
nodeName = child._node.nodeName
|
||||||
|
|
||||||
|
if not parentDict.has_key(nodeName):
|
||||||
|
parentDict[nodeName] = parent.__dict__[nodeName] = child
|
||||||
|
else:
|
||||||
|
if isinstance(parentDict[nodeName], XMLNode):
|
||||||
|
# this is the second child node of a given tag name, so convert
|
||||||
|
# the instance to a list
|
||||||
|
parentDict[nodeName] = self.__dict__[nodeName] = [parentDict[nodeName]]
|
||||||
|
parentDict[nodeName].append(child)
|
||||||
|
|
||||||
|
# and stick it in the dom
|
||||||
|
self._node.appendChild(child._node)
|
||||||
|
|
||||||
|
return child
|
||||||
|
|
||||||
|
elif isinstance(child, str):
|
||||||
|
childNode = self._root.dom.createElement(child)
|
||||||
|
self._node.appendChild(childNode)
|
||||||
|
|
||||||
|
elif isinstance(child, xml.dom.minidom.Element):
|
||||||
|
childNode = child
|
||||||
|
child = childNode.nodeName
|
||||||
|
self._node.appendChild(childNode)
|
||||||
|
|
||||||
|
|
||||||
|
return XMLNode(self, childNode)
|
||||||
|
|
||||||
|
def _addText(self, value):
|
||||||
|
"""
|
||||||
|
Tries to append a child text node, with the given text, to the tree,
|
||||||
|
and returns the created node object
|
||||||
|
"""
|
||||||
|
childNode = self._root.dom.createTextNode(value)
|
||||||
|
self._node.appendChild(childNode)
|
||||||
|
return XMLNode(self, childNode)
|
||||||
|
|
||||||
|
def _addComment(self, comment):
|
||||||
|
"""
|
||||||
|
Tries to append a child comment node (with the given text value)
|
||||||
|
to the tree, and returns the create node object
|
||||||
|
"""
|
||||||
|
childNode = self._root.dom.createCommentNode(comment)
|
||||||
|
self._node.appendChild(childNode)
|
||||||
|
return XMLNode(self, childNode)
|
||||||
|
|
||||||
|
def _save(self, where=None):
|
||||||
|
"""
|
||||||
|
Generates well-formed XML from just this node, and saves it
|
||||||
|
to a file.
|
||||||
|
|
||||||
|
Argument 'where' is either an open file object, or a pathname
|
||||||
|
|
||||||
|
If 'where' is not given, then saves the entire document tree.
|
||||||
|
"""
|
||||||
|
if not where:
|
||||||
|
self._root.save()
|
||||||
|
else:
|
||||||
|
self._root.save(where, self._node)
|
||||||
|
|
||||||
|
def _toxml(self):
|
||||||
|
"""
|
||||||
|
renders just this node out to raw xml code
|
||||||
|
"""
|
||||||
|
return self._node.toxml()
|
||||||
|
|
|
@ -31,7 +31,6 @@ from lib.core.common import getUnicode
|
||||||
from lib.core.common import preparePageForLineComparison
|
from lib.core.common import preparePageForLineComparison
|
||||||
from lib.core.common import randomInt
|
from lib.core.common import randomInt
|
||||||
from lib.core.common import randomStr
|
from lib.core.common import randomStr
|
||||||
from lib.core.common import readXmlFile
|
|
||||||
from lib.core.common import DynamicContentItem
|
from lib.core.common import DynamicContentItem
|
||||||
from lib.core.convert import md5hash
|
from lib.core.convert import md5hash
|
||||||
from lib.core.data import conf
|
from lib.core.data import conf
|
||||||
|
@ -67,41 +66,30 @@ def checkSqlInjection(place, parameter, value, parenthesis):
|
||||||
if conf.postfix:
|
if conf.postfix:
|
||||||
postfix = conf.postfix
|
postfix = conf.postfix
|
||||||
|
|
||||||
injections = readXmlFile(paths.INJECTIONS_XML)
|
for case in kb.injections.root.case:
|
||||||
|
positive = case.test.positive
|
||||||
|
negative = case.test.negative
|
||||||
|
|
||||||
for case in injections.getElementsByTagName("case"):
|
if not prefix and not postfix and case.name == "custom":
|
||||||
tag = case.getAttribute("tag")
|
|
||||||
desc = case.getAttribute("desc")
|
|
||||||
|
|
||||||
positive = case.getElementsByTagName("positive")[0]
|
|
||||||
negative = case.getElementsByTagName("negative")[0]
|
|
||||||
|
|
||||||
params = positive.getAttribute("params")
|
|
||||||
format = positive.getAttribute("format")
|
|
||||||
|
|
||||||
if not prefix and not postfix and tag == "custom":
|
|
||||||
continue
|
continue
|
||||||
|
|
||||||
infoMsg = "testing %s injection " % desc
|
infoMsg = "testing %s injection " % case.desc
|
||||||
infoMsg += "on %s parameter '%s'" % (place, parameter)
|
infoMsg += "on %s parameter '%s'" % (place, parameter)
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
payload = agent.payload(place, parameter, value, format % eval(params))
|
payload = agent.payload(place, parameter, value, positive.format % eval(positive.params))
|
||||||
|
|
||||||
trueResult = Request.queryPage(payload, place)
|
trueResult = Request.queryPage(payload, place)
|
||||||
|
|
||||||
if trueResult:
|
if trueResult:
|
||||||
params = negative.getAttribute("params")
|
payload = agent.payload(place, parameter, value, negative.format % eval(negative.params))
|
||||||
format = negative.getAttribute("format")
|
|
||||||
payload = agent.payload(place, parameter, value, format % eval(params))
|
|
||||||
|
|
||||||
falseResult = Request.queryPage(payload, place)
|
falseResult = Request.queryPage(payload, place)
|
||||||
|
|
||||||
if not falseResult:
|
if not falseResult:
|
||||||
infoMsg = "%s parameter '%s' is %s injectable " % (place, parameter, desc)
|
infoMsg = "%s parameter '%s' is %s injectable " % (place, parameter, case.desc)
|
||||||
infoMsg += "with %d parenthesis" % parenthesis
|
infoMsg += "with %d parenthesis" % parenthesis
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
return tag
|
return case.name
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@ import re
|
||||||
|
|
||||||
from xml.etree import ElementTree as ET
|
from xml.etree import ElementTree as ET
|
||||||
|
|
||||||
|
from lib.core.common import getInjectionCase
|
||||||
from lib.core.common import randomInt
|
from lib.core.common import randomInt
|
||||||
from lib.core.common import randomStr
|
from lib.core.common import randomStr
|
||||||
from lib.core.common import replaceSpaces
|
from lib.core.common import replaceSpaces
|
||||||
|
@ -142,19 +143,19 @@ class Agent:
|
||||||
if conf.direct:
|
if conf.direct:
|
||||||
return self.payloadDirect(string)
|
return self.payloadDirect(string)
|
||||||
|
|
||||||
query = ""
|
query = str()
|
||||||
|
case = getInjectionCase(kb.injType)
|
||||||
|
|
||||||
|
if case is None:
|
||||||
|
raise sqlmapNoneDataException, "unsupported injection type"
|
||||||
|
|
||||||
if conf.prefix:
|
if conf.prefix:
|
||||||
query = conf.prefix
|
query = conf.prefix
|
||||||
else:
|
else:
|
||||||
if kb.injType == "numeric" or conf.postfix:
|
if case.usage.prefix._has_key('value'):
|
||||||
pass
|
query = case.usage.prefix.value
|
||||||
elif kb.injType in ( "stringsingle", "likesingle" ):
|
elif case.usage.prefix._has_key('format'):
|
||||||
query = "'"
|
query = case.usage.prefix.format % eval(case.usage.prefix.params)
|
||||||
elif kb.injType in ( "stringdouble", "likedouble" ):
|
|
||||||
query = "\""
|
|
||||||
else:
|
|
||||||
raise sqlmapNoneDataException, "unsupported injection type"
|
|
||||||
|
|
||||||
if kb.parenthesis not in ( None, 0 ):
|
if kb.parenthesis not in ( None, 0 ):
|
||||||
query += "%s " % (")" * kb.parenthesis)
|
query += "%s " % (")" * kb.parenthesis)
|
||||||
|
@ -172,6 +173,11 @@ class Agent:
|
||||||
if conf.direct:
|
if conf.direct:
|
||||||
return self.payloadDirect(string)
|
return self.payloadDirect(string)
|
||||||
|
|
||||||
|
case = getInjectionCase(kb.injType)
|
||||||
|
|
||||||
|
if case is None:
|
||||||
|
raise sqlmapNoneDataException, "unsupported injection type"
|
||||||
|
|
||||||
randInt = randomInt()
|
randInt = randomInt()
|
||||||
randStr = randomStr()
|
randStr = randomStr()
|
||||||
|
|
||||||
|
@ -186,18 +192,10 @@ class Agent:
|
||||||
else:
|
else:
|
||||||
raise sqlmapNoneDataException, "unable to get the number of parenthesis"
|
raise sqlmapNoneDataException, "unable to get the number of parenthesis"
|
||||||
|
|
||||||
if kb.injType == "numeric":
|
if case.usage.postfix._has_key('value'):
|
||||||
string += "%d=%d" % (randInt, randInt)
|
string += case.usage.postfix.value
|
||||||
elif kb.injType == "stringsingle":
|
elif case.usage.postfix._has_key('format'):
|
||||||
string += "'%s'='%s" % (randStr, randStr)
|
string += case.usage.postfix.format % eval(case.usage.postfix.params)
|
||||||
elif kb.injType == "likesingle":
|
|
||||||
string += "'%s' LIKE '%s" % (randStr, randStr)
|
|
||||||
elif kb.injType == "stringdouble":
|
|
||||||
string += "\"%s\"=\"%s" % (randStr, randStr)
|
|
||||||
elif kb.injType == "likedouble":
|
|
||||||
string += "\"%s\" LIKE \"%s" % (randStr, randStr)
|
|
||||||
else:
|
|
||||||
raise sqlmapNoneDataException, "unsupported injection type"
|
|
||||||
|
|
||||||
return replaceSpaces(string)
|
return replaceSpaces(string)
|
||||||
|
|
||||||
|
|
|
@ -1241,6 +1241,14 @@ def calculateDeltaSeconds(start, epsilon=0.05):
|
||||||
"""
|
"""
|
||||||
return int(time.time() - start + epsilon)
|
return int(time.time() - start + epsilon)
|
||||||
|
|
||||||
|
def getInjectionCase(name):
|
||||||
|
retVal = None
|
||||||
|
for case in kb.injections.root.case:
|
||||||
|
if case.name == name:
|
||||||
|
retVal = case
|
||||||
|
break
|
||||||
|
return retVal
|
||||||
|
|
||||||
def initCommonOutputs():
|
def initCommonOutputs():
|
||||||
kb.commonOutputs = {}
|
kb.commonOutputs = {}
|
||||||
key = None
|
key = None
|
||||||
|
|
|
@ -34,6 +34,7 @@ import urllib2
|
||||||
import urlparse
|
import urlparse
|
||||||
|
|
||||||
from extra.keepalive import keepalive
|
from extra.keepalive import keepalive
|
||||||
|
from extra.xmlobject import xmlobject
|
||||||
from lib.core.common import getConsoleWidth
|
from lib.core.common import getConsoleWidth
|
||||||
from lib.core.common import getFileType
|
from lib.core.common import getFileType
|
||||||
from lib.core.common import normalizePath
|
from lib.core.common import normalizePath
|
||||||
|
@ -1010,6 +1011,7 @@ def __setKnowledgeBaseAttributes():
|
||||||
kb.injParameter = None
|
kb.injParameter = None
|
||||||
kb.injPlace = None
|
kb.injPlace = None
|
||||||
kb.injType = None
|
kb.injType = None
|
||||||
|
kb.injections = xmlobject.XMLFile(path=paths.INJECTIONS_XML)
|
||||||
kb.hintValue = None
|
kb.hintValue = None
|
||||||
kb.nullConnection = None
|
kb.nullConnection = None
|
||||||
|
|
||||||
|
|
|
@ -1,28 +1,64 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
<root>
|
<root>
|
||||||
<case tag="custom" desc="custom">
|
<case name="custom" desc="custom">
|
||||||
|
<test>
|
||||||
<positive format="%s%s%s AND %s%d=%d %s" params="value, prefix, ")" * parenthesis, "(" * parenthesis, randInt, randInt, postfix"/>
|
<positive format="%s%s%s AND %s%d=%d %s" params="value, prefix, ")" * parenthesis, "(" * parenthesis, randInt, randInt, postfix"/>
|
||||||
<negative format="%s%s%s AND %s%d=%d %s" params="value, prefix, ")" * parenthesis, "(" * parenthesis, randInt, randInt + 1, postfix"/>
|
<negative format="%s%s%s AND %s%d=%d %s" params="value, prefix, ")" * parenthesis, "(" * parenthesis, randInt, randInt + 1, postfix"/>
|
||||||
|
</test>
|
||||||
|
<usage>
|
||||||
|
<prefix/>
|
||||||
|
<postfix/>
|
||||||
|
</usage>
|
||||||
</case>
|
</case>
|
||||||
<case tag="numeric" desc="unescaped numeric">
|
<case name="numeric" desc="unescaped numeric">
|
||||||
|
<test>
|
||||||
<positive format="%s%s AND %s%d=%d" params="value, ")" * parenthesis, "(" * parenthesis, randInt, randInt"/>
|
<positive format="%s%s AND %s%d=%d" params="value, ")" * parenthesis, "(" * parenthesis, randInt, randInt"/>
|
||||||
<negative format="%s%s AND %s%d=%d" params="value, ")" * parenthesis, "(" * parenthesis, randInt, randInt + 1"/>
|
<negative format="%s%s AND %s%d=%d" params="value, ")" * parenthesis, "(" * parenthesis, randInt, randInt + 1"/>
|
||||||
|
</test>
|
||||||
|
<usage>
|
||||||
|
<prefix/>
|
||||||
|
<postfix format="%d=%d" params="randInt, randInt"/>
|
||||||
|
</usage>
|
||||||
</case>
|
</case>
|
||||||
<case tag="stringsingle" desc="single quoted string">
|
<case name="stringsingle" desc="single quoted string">
|
||||||
|
<test>
|
||||||
<positive format="%s'%s AND %s'%s'='%s" params="value, ")" * parenthesis, "(" * parenthesis, randStr, randStr"/>
|
<positive format="%s'%s AND %s'%s'='%s" params="value, ")" * parenthesis, "(" * parenthesis, randStr, randStr"/>
|
||||||
<negative format="%s'%s AND %s'%s'='%s" params="value, ")" * parenthesis, "(" * parenthesis, randStr, randStr + randomStr(1)"/>
|
<negative format="%s'%s AND %s'%s'='%s" params="value, ")" * parenthesis, "(" * parenthesis, randStr, randStr + randomStr(1)"/>
|
||||||
|
</test>
|
||||||
|
<usage>
|
||||||
|
<prefix value="'"/>
|
||||||
|
<postfix format="'%s'='%s" params="randStr, randStr"/>
|
||||||
|
</usage>
|
||||||
</case>
|
</case>
|
||||||
<case tag="likesingle" desc="LIKE single quoted string">
|
<case name="likesingle" desc="LIKE single quoted string">
|
||||||
|
<test>
|
||||||
<positive format="%s'%s AND %s'%s' LIKE '%s" params="value, ")" * parenthesis, "(" * parenthesis, randStr, randStr"/>
|
<positive format="%s'%s AND %s'%s' LIKE '%s" params="value, ")" * parenthesis, "(" * parenthesis, randStr, randStr"/>
|
||||||
<negative format="%s'%s AND %s'%s' LIKE '%s" params="value, ")" * parenthesis, "(" * parenthesis, randStr, randStr + randomStr(1)"/>
|
<negative format="%s'%s AND %s'%s' LIKE '%s" params="value, ")" * parenthesis, "(" * parenthesis, randStr, randStr + randomStr(1)"/>
|
||||||
|
</test>
|
||||||
|
<usage>
|
||||||
|
<prefix value="'"/>
|
||||||
|
<postfix format="'%s' LIKE '%s" params="randStr, randStr"/>
|
||||||
|
</usage>
|
||||||
</case>
|
</case>
|
||||||
<case tag="stringdouble" desc="double quoted string">
|
<case name="stringdouble" desc="double quoted string">
|
||||||
|
<test>
|
||||||
<positive format="%s\"%s AND %s\"%s\"=\"%s" params="value, ")" * parenthesis, "(" * parenthesis, randStr, randStr"/>
|
<positive format="%s\"%s AND %s\"%s\"=\"%s" params="value, ")" * parenthesis, "(" * parenthesis, randStr, randStr"/>
|
||||||
<negative format="%s\"%s AND %s\"%s\"=\"%s" params="value, ")" * parenthesis, "(" * parenthesis, randStr, randStr + randomStr(1)"/>
|
<negative format="%s\"%s AND %s\"%s\"=\"%s" params="value, ")" * parenthesis, "(" * parenthesis, randStr, randStr + randomStr(1)"/>
|
||||||
|
</test>
|
||||||
|
<usage>
|
||||||
|
<prefix value="""/>
|
||||||
|
<postfix format="\"%s\"=\"%s" params="randStr, randStr"/>
|
||||||
|
</usage>
|
||||||
</case>
|
</case>
|
||||||
<case tag="likedouble" desc="LIKE double quoted string">
|
<case name="likedouble" desc="LIKE double quoted string">
|
||||||
|
<test>
|
||||||
<positive format="%s\"%s AND %s\"%s\" LIKE \"%s" params="value, ")" * parenthesis, "(" * parenthesis, randStr, randStr"/>
|
<positive format="%s\"%s AND %s\"%s\" LIKE \"%s" params="value, ")" * parenthesis, "(" * parenthesis, randStr, randStr"/>
|
||||||
<negative format="%s\"%s AND %s\"%s\" LIKE \"%s" params="value, ")" * parenthesis, "(" * parenthesis, randStr, randStr + randomStr(1)"/>
|
<negative format="%s\"%s AND %s\"%s\" LIKE \"%s" params="value, ")" * parenthesis, "(" * parenthesis, randStr, randStr + randomStr(1)"/>
|
||||||
|
</test>
|
||||||
|
<usage>
|
||||||
|
<prefix value="""/>
|
||||||
|
<postfix format="\"%s\" LIKE \"%s" params="randStr, randStr"/>
|
||||||
|
</usage>
|
||||||
</case>
|
</case>
|
||||||
</root>
|
</root>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user