@@ -85,6 +85,7 @@ def __init__(self):
8585 kb .data .cachedDbs = []
8686 kb .data .cachedTables = {}
8787 kb .data .cachedColumns = {}
88+ kb .data .cachedCounts = {}
8889 kb .data .dumpedTable = {}
8990 kb .data .processChar = None
9091 self .alwaysRetrieveSqlOutput = False
@@ -839,6 +840,7 @@ def getTables(self, bruteForce=None):
839840 for db , table in value :
840841 db = safeSQLIdentificatorNaming (db )
841842 table = safeSQLIdentificatorNaming (table , True )
843+
842844 if not kb .data .cachedTables .has_key (db ):
843845 kb .data .cachedTables [db ] = [table ]
844846 else :
@@ -885,6 +887,7 @@ def getTables(self, bruteForce=None):
885887 query = rootQuery .blind .query % index
886888 else :
887889 query = rootQuery .blind .query % (unsafeSQLIdentificatorNaming (db ), index )
890+
888891 table = inject .getValue (query , inband = False , error = False )
889892 kb .hintValue = table
890893 table = safeSQLIdentificatorNaming (table , True )
@@ -1174,6 +1177,56 @@ def getSchema(self):
11741177
11751178 return kb .data .cachedColumns
11761179
1180+ def __tableGetCount (self , db , table ):
1181+ query = "SELECT COUNT(*) FROM %s.%s" % (safeSQLIdentificatorNaming (db ), safeSQLIdentificatorNaming (table , True ))
1182+ count = inject .getValue (query , expected = EXPECTED .INT , charsetType = 2 )
1183+
1184+ if count is not None and isinstance (count , basestring ) and count .isdigit ():
1185+ if unsafeSQLIdentificatorNaming (db ) not in kb .data .cachedCounts :
1186+ kb .data .cachedCounts [unsafeSQLIdentificatorNaming (db )] = {}
1187+
1188+ if int (count ) in kb .data .cachedCounts [unsafeSQLIdentificatorNaming (db )]:
1189+ kb .data .cachedCounts [unsafeSQLIdentificatorNaming (db )][int (count )].append (unsafeSQLIdentificatorNaming (table ))
1190+ else :
1191+ kb .data .cachedCounts [unsafeSQLIdentificatorNaming (db )][int (count )] = [unsafeSQLIdentificatorNaming (table )]
1192+
1193+ def getCount (self ):
1194+ if not conf .tbl :
1195+ warnMsg = "missing table parameter, sqlmap will retrieve "
1196+ warnMsg += "the number of entries for all database "
1197+ warnMsg += "management system databases' tables"
1198+ logger .warn (warnMsg )
1199+
1200+ elif "." in conf .tbl :
1201+ if not conf .db :
1202+ conf .db , conf .tbl = conf .tbl .split ("." )
1203+
1204+ if conf .tbl is not None and conf .db is None :
1205+ warnMsg = "missing database parameter, sqlmap is going to "
1206+ warnMsg += "use the current database to retrieve the "
1207+ warnMsg += "number of entries for table '%s'" % conf .tbl
1208+ logger .warn (warnMsg )
1209+
1210+ conf .db = self .getCurrentDb ()
1211+
1212+ self .forceDbmsEnum ()
1213+
1214+ if conf .db :
1215+ conf .db = safeSQLIdentificatorNaming (conf .db )
1216+
1217+ if conf .tbl :
1218+ for table in conf .tbl .split ("," ):
1219+ table = safeSQLIdentificatorNaming (table , True )
1220+ self .__tableGetCount (conf .db , table )
1221+ else :
1222+ self .getTables ()
1223+
1224+ for db , tables in kb .data .cachedTables .items ():
1225+ for table in tables :
1226+ self .__tableGetCount (db , table )
1227+
1228+ return kb .data .cachedCounts
1229+
11771230 def __pivotDumpTable (self , table , colList , count = None , blind = True ):
11781231 lengths = {}
11791232 entries = {}
@@ -1580,7 +1633,6 @@ def dumpAll(self):
15801633 infoMsg = "skipping table '%s'" % table
15811634 logger .info (infoMsg )
15821635
1583-
15841636 def dumpFoundColumn (self , dbs , foundCols , colConsider ):
15851637 if not dbs :
15861638 warnMsg = "no databases have tables containing any of the "
0 commit comments