Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sqlmapproject
GitHub Repository: sqlmapproject/sqlmap
Path: blob/master/plugins/dbms/oracle/enumeration.py
2992 views
1
#!/usr/bin/env python
2
3
"""
4
Copyright (c) 2006-2025 sqlmap developers (https://sqlmap.org)
5
See the file 'LICENSE' for copying permission
6
"""
7
8
from lib.core.common import getLimitRange
9
from lib.core.common import isAdminFromPrivileges
10
from lib.core.common import isInferenceAvailable
11
from lib.core.common import isNoneValue
12
from lib.core.common import isNumPosStrValue
13
from lib.core.common import isTechniqueAvailable
14
from lib.core.compat import xrange
15
from lib.core.data import conf
16
from lib.core.data import kb
17
from lib.core.data import logger
18
from lib.core.data import queries
19
from lib.core.enums import CHARSET_TYPE
20
from lib.core.enums import DBMS
21
from lib.core.enums import EXPECTED
22
from lib.core.enums import PAYLOAD
23
from lib.core.exception import SqlmapNoneDataException
24
from lib.core.settings import CURRENT_USER
25
from lib.request import inject
26
from plugins.generic.enumeration import Enumeration as GenericEnumeration
27
28
class Enumeration(GenericEnumeration):
29
def getRoles(self, query2=False):
30
infoMsg = "fetching database users roles"
31
32
rootQuery = queries[DBMS.ORACLE].roles
33
34
if conf.user == CURRENT_USER:
35
infoMsg += " for current user"
36
conf.user = self.getCurrentUser()
37
38
logger.info(infoMsg)
39
40
# Set containing the list of DBMS administrators
41
areAdmins = set()
42
43
if any(isTechniqueAvailable(_) for _ in (PAYLOAD.TECHNIQUE.UNION, PAYLOAD.TECHNIQUE.ERROR, PAYLOAD.TECHNIQUE.QUERY)) or conf.direct:
44
if query2:
45
query = rootQuery.inband.query2
46
condition = rootQuery.inband.condition2
47
else:
48
query = rootQuery.inband.query
49
condition = rootQuery.inband.condition
50
51
if conf.user:
52
users = conf.user.split(',')
53
query += " WHERE "
54
query += " OR ".join("%s = '%s'" % (condition, user) for user in sorted(users))
55
56
values = inject.getValue(query, blind=False, time=False)
57
58
if not values and not query2:
59
infoMsg = "trying with table 'USER_ROLE_PRIVS'"
60
logger.info(infoMsg)
61
62
return self.getRoles(query2=True)
63
64
if not isNoneValue(values):
65
for value in values:
66
user = None
67
roles = set()
68
69
for count in xrange(0, len(value or [])):
70
# The first column is always the username
71
if count == 0:
72
user = value[count]
73
74
# The other columns are the roles
75
else:
76
role = value[count]
77
78
# In Oracle we get the list of roles as string
79
roles.add(role)
80
81
if user in kb.data.cachedUsersRoles:
82
kb.data.cachedUsersRoles[user] = list(roles.union(kb.data.cachedUsersRoles[user]))
83
else:
84
kb.data.cachedUsersRoles[user] = list(roles)
85
86
if not kb.data.cachedUsersRoles and isInferenceAvailable() and not conf.direct:
87
if conf.user:
88
users = conf.user.split(',')
89
else:
90
if not len(kb.data.cachedUsers):
91
users = self.getUsers()
92
else:
93
users = kb.data.cachedUsers
94
95
retrievedUsers = set()
96
97
for user in users:
98
unescapedUser = None
99
100
if user in retrievedUsers:
101
continue
102
103
infoMsg = "fetching number of roles "
104
infoMsg += "for user '%s'" % user
105
logger.info(infoMsg)
106
107
if unescapedUser:
108
queryUser = unescapedUser
109
else:
110
queryUser = user
111
112
if query2:
113
query = rootQuery.blind.count2 % queryUser
114
else:
115
query = rootQuery.blind.count % queryUser
116
count = inject.getValue(query, union=False, error=False, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS)
117
118
if not isNumPosStrValue(count):
119
if count != 0 and not query2:
120
infoMsg = "trying with table 'USER_SYS_PRIVS'"
121
logger.info(infoMsg)
122
123
return self.getPrivileges(query2=True)
124
125
warnMsg = "unable to retrieve the number of "
126
warnMsg += "roles for user '%s'" % user
127
logger.warning(warnMsg)
128
continue
129
130
infoMsg = "fetching roles for user '%s'" % user
131
logger.info(infoMsg)
132
133
roles = set()
134
135
indexRange = getLimitRange(count, plusOne=True)
136
137
for index in indexRange:
138
if query2:
139
query = rootQuery.blind.query2 % (queryUser, index)
140
else:
141
query = rootQuery.blind.query % (queryUser, index)
142
role = inject.getValue(query, union=False, error=False)
143
144
# In Oracle we get the list of roles as string
145
roles.add(role)
146
147
if roles:
148
kb.data.cachedUsersRoles[user] = list(roles)
149
else:
150
warnMsg = "unable to retrieve the roles "
151
warnMsg += "for user '%s'" % user
152
logger.warning(warnMsg)
153
154
retrievedUsers.add(user)
155
156
if not kb.data.cachedUsersRoles:
157
errMsg = "unable to retrieve the roles "
158
errMsg += "for the database users"
159
raise SqlmapNoneDataException(errMsg)
160
161
for user, privileges in kb.data.cachedUsersRoles.items():
162
if isAdminFromPrivileges(privileges):
163
areAdmins.add(user)
164
165
return kb.data.cachedUsersRoles, areAdmins
166
167