@@ -228,93 +228,95 @@ def columnExists(columnFile, regex=None):
228
228
columns .extend (_addPageTextWords ())
229
229
columns = filterListValue (columns , regex )
230
230
231
- table = safeSQLIdentificatorNaming (conf .tbl , True )
231
+ for table in conf .tbl .split (',' ):
232
+ table = safeSQLIdentificatorNaming (table , True )
232
233
233
- if conf .db and METADB_SUFFIX not in conf .db and Backend .getIdentifiedDbms () not in (DBMS .SQLITE , DBMS .ACCESS , DBMS .FIREBIRD ):
234
- table = "%s.%s" % (safeSQLIdentificatorNaming (conf .db ), table )
234
+ if conf .db and METADB_SUFFIX not in conf .db and Backend .getIdentifiedDbms () not in (DBMS .SQLITE , DBMS .ACCESS , DBMS .FIREBIRD ):
235
+ table = "%s.%s" % (safeSQLIdentificatorNaming (conf .db ), table )
235
236
236
- kb .threadContinue = True
237
- kb .bruteMode = True
238
-
239
- threadData = getCurrentThreadData ()
240
- threadData .shared .count = 0
241
- threadData .shared .limit = len (columns )
242
- threadData .shared .files = []
237
+ kb .threadContinue = True
238
+ kb .bruteMode = True
243
239
244
- def columnExistsThread ():
245
240
threadData = getCurrentThreadData ()
241
+ threadData .shared .count = 0
242
+ threadData .shared .limit = len (columns )
243
+ threadData .shared .files = []
246
244
247
- while kb .threadContinue :
248
- kb .locks .count .acquire ()
249
- if threadData .shared .count < threadData .shared .limit :
250
- column = safeSQLIdentificatorNaming (columns [threadData .shared .count ])
251
- threadData .shared .count += 1
252
- kb .locks .count .release ()
253
- else :
254
- kb .locks .count .release ()
255
- break
245
+ def columnExistsThread ():
246
+ threadData = getCurrentThreadData ()
256
247
257
- if Backend .isDbms (DBMS .MCKOI ):
258
- result = inject .checkBooleanExpression (safeStringFormat ("0<(SELECT COUNT(%s) FROM %s)" , (column , table )))
259
- else :
260
- result = inject .checkBooleanExpression (safeStringFormat (BRUTE_COLUMN_EXISTS_TEMPLATE , (column , table )))
248
+ while kb .threadContinue :
249
+ kb .locks .count .acquire ()
261
250
262
- kb .locks .io .acquire ()
251
+ if threadData .shared .count < threadData .shared .limit :
252
+ column = safeSQLIdentificatorNaming (columns [threadData .shared .count ])
253
+ threadData .shared .count += 1
254
+ kb .locks .count .release ()
255
+ else :
256
+ kb .locks .count .release ()
257
+ break
263
258
264
- if result :
265
- threadData .shared .files .append (column )
259
+ if Backend .isDbms (DBMS .MCKOI ):
260
+ result = inject .checkBooleanExpression (safeStringFormat ("0<(SELECT COUNT(%s) FROM %s)" , (column , table )))
261
+ else :
262
+ result = inject .checkBooleanExpression (safeStringFormat (BRUTE_COLUMN_EXISTS_TEMPLATE , (column , table )))
266
263
267
- if conf .verbose in (1 , 2 ) and not conf .api :
268
- clearConsoleLine (True )
269
- infoMsg = "[%s] [INFO] retrieved: %s\n " % (time .strftime ("%X" ), unsafeSQLIdentificatorNaming (column ))
270
- dataToStdout (infoMsg , True )
264
+ kb .locks .io .acquire ()
271
265
272
- if conf .verbose in (1 , 2 ):
273
- status = "%d/%d items (%d%%)" % (threadData .shared .count , threadData .shared .limit , round (100.0 * threadData .shared .count / threadData .shared .limit ))
274
- dataToStdout ("\r [%s] [INFO] tried %s" % (time .strftime ("%X" ), status ), True )
266
+ if result :
267
+ threadData .shared .files .append (column )
275
268
276
- kb .locks .io .release ()
269
+ if conf .verbose in (1 , 2 ) and not conf .api :
270
+ clearConsoleLine (True )
271
+ infoMsg = "[%s] [INFO] retrieved: %s\n " % (time .strftime ("%X" ), unsafeSQLIdentificatorNaming (column ))
272
+ dataToStdout (infoMsg , True )
277
273
278
- try :
279
- runThreads (conf .threads , columnExistsThread , threadChoice = True )
280
- except KeyboardInterrupt :
281
- warnMsg = "user aborted during column existence "
282
- warnMsg += "check. sqlmap will display partial output"
283
- logger .warning (warnMsg )
284
- finally :
285
- kb .bruteMode = False
274
+ if conf .verbose in (1 , 2 ):
275
+ status = "%d/%d items (%d%%)" % (threadData .shared .count , threadData .shared .limit , round (100.0 * threadData .shared .count / threadData .shared .limit ))
276
+ dataToStdout ("\r [%s] [INFO] tried %s" % (time .strftime ("%X" ), status ), True )
286
277
287
- clearConsoleLine (True )
288
- dataToStdout ("\n " )
278
+ kb .locks .io .release ()
289
279
290
- if not threadData .shared .files :
291
- warnMsg = "no column(s) found"
292
- logger .warning (warnMsg )
293
- else :
294
- columns = {}
295
-
296
- for column in threadData .shared .files :
297
- if Backend .getIdentifiedDbms () in (DBMS .MYSQL ,):
298
- result = not inject .checkBooleanExpression ("%s" % safeStringFormat ("EXISTS(SELECT %s FROM %s WHERE %s REGEXP '[^0-9]')" , (column , table , column )))
299
- elif Backend .getIdentifiedDbms () in (DBMS .SQLITE ,):
300
- result = inject .checkBooleanExpression ("%s" % safeStringFormat ("EXISTS(SELECT %s FROM %s WHERE %s NOT GLOB '*[^0-9]*')" , (column , table , column )))
301
- elif Backend .getIdentifiedDbms () in (DBMS .MCKOI ,):
302
- result = inject .checkBooleanExpression ("%s" % safeStringFormat ("0=(SELECT MAX(%s)-MAX(%s) FROM %s)" , (column , column , table )))
303
- else :
304
- result = inject .checkBooleanExpression ("%s" % safeStringFormat ("EXISTS(SELECT %s FROM %s WHERE ROUND(%s)=ROUND(%s))" , (column , table , column , column )))
280
+ try :
281
+ runThreads (conf .threads , columnExistsThread , threadChoice = True )
282
+ except KeyboardInterrupt :
283
+ warnMsg = "user aborted during column existence "
284
+ warnMsg += "check. sqlmap will display partial output"
285
+ logger .warning (warnMsg )
286
+ finally :
287
+ kb .bruteMode = False
305
288
306
- if result :
307
- columns [column ] = "numeric"
308
- else :
309
- columns [column ] = "non-numeric"
289
+ clearConsoleLine (True )
290
+ dataToStdout ("\n " )
291
+
292
+ if not threadData .shared .files :
293
+ warnMsg = "no column(s) found"
294
+ logger .warning (warnMsg )
295
+ else :
296
+ columns = {}
297
+
298
+ for column in threadData .shared .files :
299
+ if Backend .getIdentifiedDbms () in (DBMS .MYSQL ,):
300
+ result = not inject .checkBooleanExpression ("%s" % safeStringFormat ("EXISTS(SELECT %s FROM %s WHERE %s REGEXP '[^0-9]')" , (column , table , column )))
301
+ elif Backend .getIdentifiedDbms () in (DBMS .SQLITE ,):
302
+ result = inject .checkBooleanExpression ("%s" % safeStringFormat ("EXISTS(SELECT %s FROM %s WHERE %s NOT GLOB '*[^0-9]*')" , (column , table , column )))
303
+ elif Backend .getIdentifiedDbms () in (DBMS .MCKOI ,):
304
+ result = inject .checkBooleanExpression ("%s" % safeStringFormat ("0=(SELECT MAX(%s)-MAX(%s) FROM %s)" , (column , column , table )))
305
+ else :
306
+ result = inject .checkBooleanExpression ("%s" % safeStringFormat ("EXISTS(SELECT %s FROM %s WHERE ROUND(%s)=ROUND(%s))" , (column , table , column , column )))
307
+
308
+ if result :
309
+ columns [column ] = "numeric"
310
+ else :
311
+ columns [column ] = "non-numeric"
310
312
311
- kb .data .cachedColumns [conf .db ] = {conf . tbl : columns }
313
+ kb .data .cachedColumns [conf .db ] = {table : columns }
312
314
313
- for _ in ((conf .db , conf . tbl , item [0 ], item [1 ]) for item in columns .items ()):
314
- if _ not in kb .brute .columns :
315
- kb .brute .columns .append (_ )
315
+ for _ in ((conf .db , table , item [0 ], item [1 ]) for item in columns .items ()):
316
+ if _ not in kb .brute .columns :
317
+ kb .brute .columns .append (_ )
316
318
317
- hashDBWrite (HASHDB_KEYS .KB_BRUTE_COLUMNS , kb .brute .columns , True )
319
+ hashDBWrite (HASHDB_KEYS .KB_BRUTE_COLUMNS , kb .brute .columns , True )
318
320
319
321
return kb .data .cachedColumns
320
322
0 commit comments