@@ -60,6 +60,7 @@ def __init__(self, dbms):
6060 kb .data .cachedUsers = []
6161 kb .data .cachedUsersPasswords = {}
6262 kb .data .cachedUsersPrivileges = {}
63+ kb .data .cachedUsersRoles = {}
6364 kb .data .cachedDbs = []
6465 kb .data .cachedTables = {}
6566 kb .data .cachedColumns = {}
@@ -327,9 +328,14 @@ def __isAdminFromPrivileges(self, privileges):
327328 # that the user is DBA
328329 dbaCondition |= ( kb .dbms == "MySQL" and not kb .data .has_information_schema and "super_priv" in privileges )
329330
331+ # In Firebird there is no specific privilege that means
332+ # that the user is DBA
333+ # TODO: confirm
334+ dbaCondition |= ( kb .dbms == "Firebird" and "SELECT" in privileges and "INSERT" in privileges and "UPDATE" in privileges and "DELETE" in privileges and "REFERENCES" in privileges and "EXECUTE" in privileges )
335+
330336 return dbaCondition
331337
332- def getPrivileges (self ):
338+ def getPrivileges (self , query2 = False ):
333339 infoMsg = "fetching database users privileges"
334340
335341 rootQuery = queries [kb .dbms ].privileges
@@ -377,7 +383,7 @@ def getPrivileges(self):
377383 ( 2 , "super" ),
378384 ( 3 , "catupd" ),
379385 )
380-
386+
381387 firebirdPrivs = {
382388 "S" : "SELECT" ,
383389 "I" : "INSERT" ,
@@ -391,37 +397,31 @@ def getPrivileges(self):
391397 if kb .dbms == "MySQL" and not kb .data .has_information_schema :
392398 query = rootQuery ["inband" ]["query2" ]
393399 condition = rootQuery ["inband" ]["condition2" ]
400+ elif kb .dbms == "Oracle" and query2 :
401+ query = rootQuery ["inband" ]["query2" ]
402+ condition = rootQuery ["inband" ]["condition2" ]
394403 else :
395404 query = rootQuery ["inband" ]["query" ]
396405 condition = rootQuery ["inband" ]["condition" ]
397406
398407 if conf .user :
399- if "," in conf .user :
400- users = conf .user .split ("," )
401- query += " WHERE "
402- # NOTE: I assume that the user provided is not in
403- # MySQL >= 5.0 syntax 'user'@'host'
404- if kb .dbms == "MySQL" and kb .data .has_information_schema :
405- queryUser = "%" + conf .user + "%"
406- query += " OR " .join ("%s LIKE '%s'" % (condition , "%" + user + "%" ) for user in users )
407- else :
408- query += " OR " .join ("%s = '%s'" % (condition , user ) for user in users )
408+ users = conf .user .split ("," )
409+ query += " WHERE "
410+ # NOTE: I assume that the user provided is not in
411+ # MySQL >= 5.0 syntax 'user'@'host'
412+ if kb .dbms == "MySQL" and kb .data .has_information_schema :
413+ queryUser = "%" + conf .user + "%"
414+ query += " OR " .join ("%s LIKE '%s'" % (condition , "%" + user + "%" ) for user in users )
409415 else :
410- if kb .dbms == "MySQL" :
411- parsedUser = re .search ("[\047 ]*(.*?)[\047 ]*\@" , conf .user )
416+ query += " OR " .join ("%s = '%s'" % (condition , user ) for user in users )
412417
413- if parsedUser :
414- conf .user = parsedUser .groups ()[0 ]
418+ values = inject .getValue (query , blind = False )
415419
416- # NOTE: I assume that the user provided is not in
417- # MySQL >= 5.0 syntax 'user'@'host'
418- if kb .dbms == "MySQL" and kb .data .has_information_schema :
419- queryUser = "%" + conf .user + "%"
420- query += " WHERE %s LIKE '%s'" % (condition , queryUser )
421- else :
422- query += " WHERE %s = '%s'" % (condition , conf .user )
420+ if not values and kb .dbms == "Oracle" and not query2 :
421+ infoMsg = "trying with table USER_SYS_PRIVS"
422+ logger .info (infoMsg )
423423
424- values = inject . getValue ( query , blind = False )
424+ return self . getPrivileges ( query2 = True )
425425
426426 if values :
427427 for value in values :
@@ -482,13 +482,8 @@ def getPrivileges(self):
482482 conf .user = parsedUser .groups ()[0 ]
483483
484484 users = [ "%" + conf .user + "%" ]
485-
486- elif "," in conf .user :
487- users = conf .user .split ("," )
488-
489485 else :
490- users = [ conf .user ]
491-
486+ users = conf .user .split ("," )
492487 else :
493488 if not len (kb .data .cachedUsers ):
494489 users = self .getUsers ()
@@ -519,11 +514,19 @@ def getPrivileges(self):
519514 query = rootQuery ["blind" ]["count2" ] % queryUser
520515 elif kb .dbms == "MySQL" and kb .data .has_information_schema :
521516 query = rootQuery ["blind" ]["count" ] % (conditionChar , queryUser )
517+ elif kb .dbms == "Oracle" and query2 :
518+ query = rootQuery ["blind" ]["count2" ] % queryUser
522519 else :
523520 query = rootQuery ["blind" ]["count" ] % queryUser
524521 count = inject .getValue (query , inband = False , expected = "int" , charsetType = 2 )
525522
526523 if not count .isdigit () or not len (count ) or count == "0" :
524+ if not count .isdigit () and kb .dbms == "Oracle" and not query2 :
525+ infoMsg = "trying with table USER_SYS_PRIVS"
526+ logger .info (infoMsg )
527+
528+ return self .getPrivileges (query2 = True )
529+
527530 warnMsg = "unable to retrieve the number of "
528531 warnMsg += "privileges for user '%s'" % user
529532 logger .warn (warnMsg )
@@ -545,6 +548,8 @@ def getPrivileges(self):
545548 query = rootQuery ["blind" ]["query2" ] % (queryUser , index )
546549 elif kb .dbms == "MySQL" and kb .data .has_information_schema :
547550 query = rootQuery ["blind" ]["query" ] % (conditionChar , queryUser , index )
551+ elif kb .dbms == "Oracle" and query2 :
552+ query = rootQuery ["blind" ]["query2" ] % (queryUser , index )
548553 elif kb .dbms == "Firebird" :
549554 query = rootQuery ["blind" ]["query" ] % (index , queryUser )
550555 else :
@@ -585,6 +590,8 @@ def getPrivileges(self):
585590 privileges .add (mysqlPriv )
586591
587592 i += 1
593+
594+ # In Firebird we get one letter for each privilege
588595 elif kb .dbms == "Firebird" :
589596 privileges .add (firebirdPrivs [privilege .strip ()])
590597
@@ -613,6 +620,11 @@ def getPrivileges(self):
613620
614621 return ( kb .data .cachedUsersPrivileges , areAdmins )
615622
623+ def getRoles (self , query2 = False ):
624+ warnMsg = "on %s the concept of roles does not " % kb .dbms
625+ warnMsg += "exist. sqlmap will enumerate privileges instead"
626+ self .getPrivileges (query2 )
627+
616628 def getDbs (self ):
617629 if kb .dbms == "MySQL" and not kb .data .has_information_schema :
618630 warnMsg = "information_schema not available, "
0 commit comments