4040from lib .core .exception import sqlmapUndefinedMethod
4141from lib .core .exception import sqlmapUnsupportedFeatureException
4242from lib .core .shell import autoCompletion
43+ from lib .core .unescaper import unescaper
4344from lib .request import inject
4445from lib .request .connect import Connect as Request
4546
@@ -346,19 +347,19 @@ def getPrivileges(self):
346347 if "," in conf .user :
347348 users = conf .user .split ("," )
348349 query += " WHERE "
349- # NOTE: we need this here only for MySQL 5.0 because
350- # of a known issue explained in queries.xml
350+ # NOTE: I assume that the user provided is not in
351+ # MySQL >= 5.0 syntax 'user'@'host'
351352 if kb .dbms == "MySQL" and self .has_information_schema :
352- likeUser = "%" + conf .user + "%"
353+ queryUser = "%" + conf .user + "%"
353354 query += " OR " .join ("%s LIKE '%s'" % (condition , "%" + user + "%" ) for user in users )
354355 else :
355356 query += " OR " .join ("%s = '%s'" % (condition , user ) for user in users )
356357 else :
357- # NOTE: we need this here only for MySQL 5.0 because
358- # of a known issue explained in queries.xml
358+ # NOTE: I assume that the user provided is not in
359+ # MySQL >= 5.0 syntax 'user'@'host'
359360 if kb .dbms == "MySQL" and self .has_information_schema :
360- likeUser = "%" + conf .user + "%"
361- query += " WHERE %s LIKE '%s'" % (condition , likeUser )
361+ queryUser = "%" + conf .user + "%"
362+ query += " WHERE %s LIKE '%s'" % (condition , queryUser )
362363 else :
363364 query += " WHERE %s = '%s'" % (condition , conf .user )
364365
@@ -406,11 +407,25 @@ def getPrivileges(self):
406407 self .cachedUsersPrivileges [user ] = list (privileges )
407408
408409 if not self .cachedUsersPrivileges :
410+ conditionChar = "="
411+
409412 if conf .user :
410- if "," in conf .user :
413+ if kb .dbms == "MySQL" and self .has_information_schema :
414+ conditionChar = " LIKE "
415+
416+ if "," in conf .user :
417+ users = set ()
418+ for user in conf .user .split ("," ):
419+ users .add ("%" + user + "%" )
420+ else :
421+ users = [ "%" + conf .user + "%" ]
422+
423+ elif "," in conf .user :
411424 users = conf .user .split ("," )
425+
412426 else :
413- users = [conf .user ]
427+ users = [ conf .user ]
428+
414429 else :
415430 if not len (self .cachedUsers ):
416431 users = self .getUsers ()
@@ -420,11 +435,10 @@ def getPrivileges(self):
420435 retrievedUsers = set ()
421436
422437 for user in users :
423- if kb .dbms == "MySQL" :
424- parsedUser = re .search ("\047 (.*?)\047 @'" , user )
438+ unescapedUser = None
425439
426- if parsedUser :
427- user = parsedUser . groups ()[ 0 ]. replace ( "'" , "" )
440+ if kb . dbms == "MySQL" and self . has_information_schema :
441+ unescapedUser = unescaper . unescape ( user , quote = False )
428442
429443 if user in retrievedUsers :
430444 continue
@@ -433,38 +447,42 @@ def getPrivileges(self):
433447 logMsg += "for user '%s'" % user
434448 logger .info (logMsg )
435449
436- if kb . dbms == "MySQL" and self . has_information_schema :
437- likeUser = "%" + user + "%"
450+ if unescapedUser :
451+ queryUser = unescapedUser
438452 else :
439- likeUser = user
453+ queryUser = user
440454
441455 if kb .dbms == "MySQL" and not self .has_information_schema :
442- query = rootQuery ["blind" ]["count2" ] % likeUser
456+ query = rootQuery ["blind" ]["count2" ] % queryUser
457+ elif kb .dbms == "MySQL" and self .has_information_schema :
458+ query = rootQuery ["blind" ]["count" ] % (conditionChar , queryUser )
443459 else :
444- query = rootQuery ["blind" ]["count" ] % likeUser
460+ query = rootQuery ["blind" ]["count" ] % queryUser
445461 count = inject .getValue (query , inband = False )
446462
447463 if not len (count ) or count == "0" :
448464 warnMsg = "unable to retrieve the number of "
449- warnMsg += "privileges for user '%s'" % likeUser
465+ warnMsg += "privileges for user '%s'" % user
450466 logger .warn (warnMsg )
451467 continue
452468
453- logMsg = "fetching privileges for user '%s'" % likeUser
469+ logMsg = "fetching privileges for user '%s'" % user
454470 logger .info (logMsg )
455471
456472 privileges = set ()
457473 indexRange = getRange (count )
458474
459475 for index in indexRange :
460476 if kb .dbms == "MySQL" and not self .has_information_schema :
461- query = rootQuery ["blind" ]["query2" ] % (likeUser , index )
477+ query = rootQuery ["blind" ]["query2" ] % (queryUser , index )
478+ elif kb .dbms == "MySQL" and self .has_information_schema :
479+ query = rootQuery ["blind" ]["query" ] % (conditionChar , queryUser , index )
462480 else :
463- query = rootQuery ["blind" ]["query" ] % (likeUser , index )
481+ query = rootQuery ["blind" ]["query" ] % (queryUser , index )
464482 privilege = inject .getValue (query , inband = False )
465483
466- # In PostgreSQL we return 1 if the privilege
467- # if True, otherwise 0
484+ # In PostgreSQL we get 1 if the privilege is True,
485+ # 0 otherwise
468486 if kb .dbms == "PostgreSQL" and ", " in privilege :
469487 privilege = privilege .replace (", " , "," )
470488 privs = privilege .split ("," )
@@ -501,6 +519,12 @@ def getPrivileges(self):
501519 if self .__isAdminFromPrivileges (privileges ):
502520 areAdmins .add (user )
503521
522+ # In MySQL < 5.0 we break the cycle after the first
523+ # time we get the user's privileges otherwise we
524+ # duplicate the same query
525+ if kb .dbms == "MySQL" and not self .has_information_schema :
526+ break
527+
504528 if privileges :
505529 self .cachedUsersPrivileges [user ] = list (privileges )
506530 else :
0 commit comments