Skip to content

Commit be118e8

Browse files
committed
Implements option --union-values (#5508)
1 parent 4f2a883 commit be118e8

File tree

7 files changed

+30
-3
lines changed

7 files changed

+30
-3
lines changed

lib/core/agent.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
from lib.core.settings import BOUNDED_BASE64_MARKER
4646
from lib.core.settings import BOUNDARY_BACKSLASH_MARKER
4747
from lib.core.settings import BOUNDED_INJECTION_MARKER
48+
from lib.core.settings import CUSTOM_INJECTION_MARK_CHAR
4849
from lib.core.settings import DEFAULT_COOKIE_DELIMITER
4950
from lib.core.settings import DEFAULT_GET_POST_DELIMITER
5051
from lib.core.settings import GENERIC_SQL_COMMENT
@@ -890,11 +891,16 @@ def forgeUnionQuery(self, query, position, count, comment, prefix, suffix, char,
890891
if element > 0:
891892
unionQuery += ','
892893

893-
if element == position:
894+
if conf.uValues:
895+
unionQuery += conf.uValues.split(',')[element]
896+
elif element == position:
894897
unionQuery += query
895898
else:
896899
unionQuery += char
897900

901+
if conf.uValues:
902+
unionQuery = unionQuery.replace(CUSTOM_INJECTION_MARK_CHAR, query)
903+
898904
if fromTable and not unionQuery.endswith(fromTable):
899905
unionQuery += fromTable
900906

lib/core/option.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1801,6 +1801,9 @@ def _cleanupOptions():
18011801
conf.dbms = dbms if conf.dbms and ',' not in conf.dbms else None
18021802
break
18031803

1804+
if conf.uValues:
1805+
conf.uCols = "%d-%d" % (1 + conf.uValues.count(','), 1 + conf.uValues.count(','))
1806+
18041807
if conf.testFilter:
18051808
conf.testFilter = conf.testFilter.strip('*+')
18061809
conf.testFilter = re.sub(r"([^.])([*+])", r"\g<1>.\g<2>", conf.testFilter)
@@ -2582,6 +2585,10 @@ def _basicOptionValidation():
25822585
errMsg = "switch '--text-only' is incompatible with switch '--null-connection'"
25832586
raise SqlmapSyntaxException(errMsg)
25842587

2588+
if conf.uValues and conf.uChar:
2589+
errMsg = "option '--union-values' is incompatible with option '--union-char'"
2590+
raise SqlmapSyntaxException(errMsg)
2591+
25852592
if conf.base64Parameter and conf.tamper:
25862593
errMsg = "option '--base64' is incompatible with option '--tamper'"
25872594
raise SqlmapSyntaxException(errMsg)
@@ -2804,6 +2811,11 @@ def _basicOptionValidation():
28042811
errMsg = "option '--dump-format' accepts one of following values: %s" % ", ".join(getPublicTypeMembers(DUMP_FORMAT, True))
28052812
raise SqlmapSyntaxException(errMsg)
28062813

2814+
if conf.uValues and (not re.search(r"\A['\w\s.,()%s-]+\Z" % CUSTOM_INJECTION_MARK_CHAR, conf.uValues) or conf.uValues.count(CUSTOM_INJECTION_MARK_CHAR) != 1):
2815+
errMsg = "option '--union-values' must contain valid UNION column values, along with the injection position "
2816+
errMsg += "(e.g. 'NULL,1,%s,NULL')" % CUSTOM_INJECTION_MARK_CHAR
2817+
raise SqlmapSyntaxException(errMsg)
2818+
28072819
if conf.skip and conf.testParameter:
28082820
if intersect(conf.skip, conf.testParameter):
28092821
errMsg = "option '--skip' is incompatible with option '-p'"

lib/core/optiondict.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@
118118
"uCols": "string",
119119
"uChar": "string",
120120
"uFrom": "string",
121+
"uValues": "string",
121122
"dnsDomain": "string",
122123
"secondUrl": "string",
123124
"secondReq": "string",

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.six import unichr as _unichr
2121

2222
# sqlmap version (<major>.<minor>.<month>.<monthly commit>)
23-
VERSION = "1.7.8.11"
23+
VERSION = "1.7.9.0"
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/parse/cmdline.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,9 @@ def cmdLineParser(argv=None):
414414
techniques.add_argument("--union-from", dest="uFrom",
415415
help="Table to use in FROM part of UNION query SQL injection")
416416

417+
techniques.add_argument("--union-values", dest="uValues",
418+
help="Column values to use for UNION query SQL injection")
419+
417420
techniques.add_argument("--dns-domain", dest="dnsDomain",
418421
help="Domain name used for DNS exfiltration attack")
419422

lib/techniques/union/test.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ def _unionTestByCharBruteforce(comment, place, parameter, value, prefix, suffix)
340340
warnMsg = "if UNION based SQL injection is not detected, "
341341
warnMsg += "please consider "
342342

343-
if not conf.uChar and count > 1 and kb.uChar == NULL:
343+
if not conf.uChar and count > 1 and kb.uChar == NULL and conf.uValues is None:
344344
message = "injection not exploitable with NULL values. Do you want to try with a random integer value for option '--union-char'? [Y/n] "
345345

346346
if not readInput(message, default='Y', boolean=True):

sqlmap.conf

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,11 @@ uChar =
412412
# Example: INFORMATION_SCHEMA.COLLATIONS
413413
uFrom =
414414

415+
# Column values to use for UNION query SQL injection.
416+
# Valid: string
417+
# Example: NULL,1,*,NULL
418+
uChar =
419+
415420
# Domain name used for DNS exfiltration attack.
416421
# Valid: string
417422
dnsDomain =

0 commit comments

Comments
 (0)