Skip to content

Commit 8bc0f47

Browse files
committed
Fixes #5933
1 parent 567e051 commit 8bc0f47

3 files changed

Lines changed: 25 additions & 2 deletions

File tree

lib/core/settings.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
from thirdparty import six
2121

2222
# sqlmap version (<major>.<minor>.<month>.<monthly commit>)
23-
VERSION = "1.10.7.76"
23+
VERSION = "1.10.7.77"
2424
TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable"
2525
TYPE_COLORS = {"dev": 33, "stable": 90, "pip": 34}
2626
VERSION_STRING = "sqlmap/%s#%s" % ('.'.join(VERSION.split('.')[:-1]) if VERSION.count('.') > 2 and VERSION.split('.')[-1] == '0' else VERSION, TYPE)

lib/core/target.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,22 @@ def process(match, repl):
214214
conf.data = conf.data.replace(kb.customInjectionMark, ASTERISK_MARKER)
215215
conf.data = re.sub(r"(<(?P<name>[^>]+)( [^<]*)?>)([^<]+)(</\2)", functools.partial(process, repl=r"\g<1>\g<4>%s\g<5>" % kb.customInjectionMark), conf.data)
216216

217+
# Also expose XML attribute values (e.g. <item id="1">) as injection points, not just
218+
# element text (Reference: https://github.com/sqlmapproject/sqlmap/issues/5993). Done per
219+
# opening tag (skipping <?...?> declarations, <!...> and closing tags) so every attribute
220+
# is covered while the XML declaration/namespaces are left intact.
221+
def processAttributes(match):
222+
def _attr(m):
223+
name = m.group("name")
224+
if name == "xmlns" or name.startswith("xmlns:"): # namespace declarations are not injection points
225+
return m.group(0)
226+
if conf.testParameter and name not in (removePostHintPrefix(_) for _ in conf.testParameter):
227+
return m.group(0)
228+
hintNames.append(("%s%s%s" % (m.group(1), m.group(3), m.group(4)), name))
229+
return "%s%s%s%s%s" % (m.group(1), m.group(3), m.group(4), kb.customInjectionMark, m.group(5))
230+
return re.sub(r'(\s(?P<name>[\w:.-]+)\s*=\s*)(["\'])([^"\'<>]*)(["\'])', _attr, match.group(0))
231+
conf.data = re.sub(r"(?s)<[^>?!/][^>]*>", processAttributes, conf.data)
232+
217233
elif re.search(MULTIPART_RECOGNITION_REGEX, conf.data):
218234
message = "Multipart-like data found in %s body. " % conf.method
219235
message += "Do you want to process it? [Y/n/q] "

tests/test_payload_marking.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,10 +175,17 @@ def mark(self, data):
175175

176176
CASES = [
177177
("<a>x</a>", "<a>x*</a>"),
178-
('<a id="1">x</a>', '<a id="1">x*</a>'),
178+
# attribute values are now marked too, not just element text (issue #5993)
179+
('<a id="1">x</a>', '<a id="1*">x*</a>'),
179180
("<user><name>bob</name><id>5</id></user>", "<user><name>bob*</name><id>5*</id></user>"),
180181
("<ns:tag>v</ns:tag>", "<ns:tag>v*</ns:tag>"),
181182
("<soap:Body><q>1</q></soap:Body>", "<soap:Body><q>1*</q></soap:Body>"),
183+
# multiple attributes and single-quoted attribute values
184+
('<a id="1" role="x">y</a>', '<a id="1*" role="x*">y*</a>'),
185+
("<a id='1'>y</a>", "<a id='1*'>y*</a>"),
186+
# XML declaration and namespace declarations are left intact (not injection points)
187+
('<?xml version="1.0"?><a>y</a>', '<?xml version="1.0"?><a>y*</a>'),
188+
('<a xmlns="urn:x" id="1">y</a>', '<a xmlns="urn:x" id="1*">y*</a>'),
182189
]
183190

184191
def test_cases(self):

0 commit comments

Comments
 (0)