diff --git a/doc/THANKS b/doc/THANKS index f5059f0fb..7140d15fb 100644 --- a/doc/THANKS +++ b/doc/THANKS @@ -294,6 +294,9 @@ Jason Swan for reporting a bug when enumerating columns on Microsoft SQL Server for suggesting a couple of improvements +Chilik Tamir + for providing a patch for initial support SOAP requests + Alessandro Tanasi for extensively beta-testing sqlmap for suggesting many features and reporting some bugs diff --git a/lib/core/agent.py b/lib/core/agent.py index d86c73f4a..e530f75e6 100644 --- a/lib/core/agent.py +++ b/lib/core/agent.py @@ -24,6 +24,8 @@ Franklin St, Fifth Floor, Boston, MA 02110-1301 USA import re +from xml.etree import ElementTree as ET + from lib.core.common import randomInt from lib.core.common import randomStr from lib.core.convert import urlencode @@ -33,7 +35,6 @@ from lib.core.data import queries from lib.core.data import temp from lib.core.exception import sqlmapNoneDataException - class Agent: """ This class defines the SQL agent methods. @@ -82,16 +83,36 @@ class Agent: paramString = conf.parameters[kb.injPlace] paramDict = conf.paramDict[kb.injPlace] value = paramDict[kb.injParameter] - retValue = paramString.replace("%s=%s" % (kb.injParameter, value), - "%s=%s%s" % (kb.injParameter, negValue, value + falseValue + newValue)) + + if "POSTxml" in conf.paramDict and kb.injPlace == "POST": + root = ET.XML(paramString) + iterator = root.getiterator(kb.injParameter) + + for child in iterator: + child.text = "%s%s" % (negValue, value + falseValue + newValue) + + retValue = ET.tostring(root) + else: + retValue = paramString.replace("%s=%s" % (kb.injParameter, value), + "%s=%s%s" % (kb.injParameter, negValue, value + falseValue + newValue)) # Before identifing the injectable parameter elif parameter == "User-Agent": retValue = value.replace(value, newValue) else: paramString = conf.parameters[place] - retValue = paramString.replace("%s=%s" % (parameter, value), - "%s=%s" % (parameter, newValue)) + + if "POSTxml" in conf.paramDict and place == "POST": + root = ET.XML(paramString) + iterator = root.getiterator(parameter) + + for child in iterator: + child.text = newValue + + retValue = ET.tostring(root) + else: + retValue = paramString.replace("%s=%s" % (parameter, value), + "%s=%s" % (parameter, newValue)) return retValue diff --git a/lib/core/common.py b/lib/core/common.py index 25010b7af..91fad5560 100644 --- a/lib/core/common.py +++ b/lib/core/common.py @@ -44,6 +44,7 @@ from subprocess import PIPE from subprocess import Popen as execute from tempfile import NamedTemporaryFile from tempfile import mkstemp +from xml.etree import ElementTree as ET from xml.sax import parse from extra.cloak.cloak import decloak @@ -96,25 +97,36 @@ def paramToDict(place, parameters=None): if conf.parameters.has_key(place) and not parameters: parameters = conf.parameters[place] - parameters = parameters.replace(", ", ",") + if place is not "POSTxml": + parameters = parameters.replace(", ", ",") - if place == "Cookie": - splitParams = parameters.split(";") + if place == "Cookie": + splitParams = parameters.split(";") + else: + splitParams = parameters.split("&") + + for element in splitParams: + elem = element.split("=") + + if len(elem) == 2: + parameter = elem[0].replace(" ", "") + + condition = not conf.testParameter + condition |= parameter in conf.testParameter + + if condition: + testableParameters[parameter] = elem[1] else: - splitParams = parameters.split("&") + root = ET.XML(parameters) + iterator = root.getiterator() - for element in splitParams: - elem = element.split("=") - - if len(elem) == 2: - parameter = elem[0].replace(" ", "") - - condition = not conf.testParameter - condition |= parameter in conf.testParameter + for child in iterator: + parameter = child.tag + condition = not conf.testParameter + condition |= parameter.split("}")[1] in conf.testParameter if condition: - value = elem[1] - testableParameters[parameter] = value + testableParameters[parameter] = child.text if conf.testParameter and not testableParameters: paramStr = ", ".join(test for test in conf.testParameter) diff --git a/lib/core/convert.py b/lib/core/convert.py index 351b2b0f8..bf2a7435e 100644 --- a/lib/core/convert.py +++ b/lib/core/convert.py @@ -86,7 +86,7 @@ def urldecode(string): return result def urlencode(string, safe=":/?%&=", convall=False): - if conf.direct: + if conf.direct or "POSTxml" in conf.paramDict: return string result = None @@ -95,7 +95,7 @@ def urlencode(string, safe=":/?%&=", convall=False): return result if convall: - result = urllib.quote(utf8encode(string)) #Reference: http://old.nabble.com/Re:-Problem:-neither-urllib2.quote-nor-urllib.quote-encode-the--unicode-strings-arguments-p19823144.html + result = urllib.quote(utf8encode(string)) # Reference: http://old.nabble.com/Re:-Problem:-neither-urllib2.quote-nor-urllib.quote-encode-the--unicode-strings-arguments-p19823144.html else: result = urllib.quote(utf8encode(string), safe) diff --git a/lib/core/target.py b/lib/core/target.py index 686f58b06..8e5abd83b 100644 --- a/lib/core/target.py +++ b/lib/core/target.py @@ -24,6 +24,7 @@ Franklin St, Fifth Floor, Boston, MA 02110-1301 USA import codecs import os +import re import time from lib.core.common import dataToSessionFile @@ -66,8 +67,15 @@ def __setRequestParams(): raise sqlmapSyntaxException, errMsg if conf.data: + conf.data = conf.data.replace("\n", " ") conf.parameters["POST"] = conf.data - __paramDict = paramToDict("POST", conf.data) + + # Check if POST data is in xml syntax + if re.match("[\n]*<(\?xml |soap\:|ns).*>", conf.data): + conf.paramDict["POSTxml"] = True + __paramDict = paramToDict("POSTxml", conf.data) + else: + __paramDict = paramToDict("POST", conf.data) if __paramDict: conf.paramDict["POST"] = __paramDict