~ubuntu-branches/ubuntu/vivid/sqlmap/vivid

« back to all changes in this revision

Viewing changes to plugins/dbms/oracle.py

  • Committer: Bazaar Package Importer
  • Author(s): Bernardo Damele A. G.
  • Date: 2009-02-03 23:30:00 UTC
  • Revision ID: james.westby@ubuntu.com-20090203233000-8gpnwfbih0wnqtv5
Tags: upstream-0.6.4
ImportĀ upstreamĀ versionĀ 0.6.4

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/env python
 
2
 
 
3
"""
 
4
$Id: oracle.py 327 2009-01-12 21:35:38Z inquisb $
 
5
 
 
6
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
 
7
 
 
8
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
 
9
                        and Daniele Bellucci <daniele.bellucci@gmail.com>
 
10
 
 
11
sqlmap is free software; you can redistribute it and/or modify it under
 
12
the terms of the GNU General Public License as published by the Free
 
13
Software Foundation version 2 of the License.
 
14
 
 
15
sqlmap is distributed in the hope that it will be useful, but WITHOUT ANY
 
16
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 
17
FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 
18
details.
 
19
 
 
20
You should have received a copy of the GNU General Public License along
 
21
with sqlmap; if not, write to the Free Software Foundation, Inc., 51
 
22
Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
23
"""
 
24
 
 
25
 
 
26
 
 
27
import re
 
28
 
 
29
from lib.core.agent import agent
 
30
from lib.core.common import formatDBMSfp
 
31
from lib.core.common import formatFingerprint
 
32
from lib.core.common import getHtmlErrorFp
 
33
from lib.core.data import conf
 
34
from lib.core.data import kb
 
35
from lib.core.data import logger
 
36
from lib.core.exception import sqlmapSyntaxException
 
37
from lib.core.session import setDbms
 
38
from lib.core.settings import ORACLE_ALIASES
 
39
from lib.core.settings import ORACLE_SYSTEM_DBS
 
40
from lib.core.unescaper import unescaper
 
41
from lib.request import inject
 
42
from lib.request.connect import Connect as Request
 
43
 
 
44
from plugins.generic.enumeration import Enumeration
 
45
from plugins.generic.filesystem import Filesystem
 
46
from plugins.generic.fingerprint import Fingerprint
 
47
from plugins.generic.takeover import Takeover
 
48
 
 
49
 
 
50
class OracleMap(Fingerprint, Enumeration, Filesystem, Takeover):
 
51
    """
 
52
    This class defines Oracle methods
 
53
    """
 
54
 
 
55
 
 
56
    def __init__(self):
 
57
        self.excludeDbsList = ORACLE_SYSTEM_DBS
 
58
        Enumeration.__init__(self, "Oracle")
 
59
 
 
60
        unescaper.setUnescape(OracleMap.unescape)
 
61
 
 
62
 
 
63
    @staticmethod
 
64
    def unescape(expression, quote=True):
 
65
        if quote:
 
66
            while True:
 
67
                index = expression.find("'")
 
68
                if index == -1:
 
69
                    break
 
70
 
 
71
                firstIndex = index + 1
 
72
                index = expression[firstIndex:].find("'")
 
73
 
 
74
                if index == -1:
 
75
                    raise sqlmapSyntaxException, "Unenclosed ' in '%s'" % expression
 
76
 
 
77
                lastIndex = firstIndex + index
 
78
                old = "'%s'" % expression[firstIndex:lastIndex]
 
79
                #unescaped = "("
 
80
                unescaped = ""
 
81
 
 
82
                for i in range(firstIndex, lastIndex):
 
83
                    unescaped += "CHR(%d)" % (ord(expression[i]))
 
84
                    if i < lastIndex - 1:
 
85
                        unescaped += "||"
 
86
 
 
87
                #unescaped += ")"
 
88
                expression = expression.replace(old, unescaped)
 
89
        else:
 
90
            expression = "||".join("CHR(%d)" % ord(c) for c in expression)
 
91
 
 
92
        return expression
 
93
 
 
94
 
 
95
    @staticmethod
 
96
    def escape(expression):
 
97
        while True:
 
98
            index = expression.find("CHR(")
 
99
            if index == -1:
 
100
                break
 
101
 
 
102
            firstIndex = index
 
103
            index = expression[firstIndex:].find("))")
 
104
 
 
105
            if index == -1:
 
106
                raise sqlmapSyntaxException, "Unenclosed ) in '%s'" % expression
 
107
 
 
108
            lastIndex = firstIndex + index + 1
 
109
            old = expression[firstIndex:lastIndex]
 
110
            oldUpper = old.upper()
 
111
            oldUpper = oldUpper.replace("CHR(", "").replace(")", "")
 
112
            oldUpper = oldUpper.split("||")
 
113
 
 
114
            escaped = "'%s'" % "".join([chr(int(char)) for char in oldUpper])
 
115
            expression = expression.replace(old, escaped)
 
116
 
 
117
        return expression
 
118
 
 
119
 
 
120
    def getFingerprint(self):
 
121
        value  = ""
 
122
        wsOsFp = formatFingerprint("web server", kb.headersFp)
 
123
 
 
124
        if wsOsFp:
 
125
            value += "%s\n" % wsOsFp
 
126
 
 
127
        if self.banner:
 
128
            dbmsOsFp = formatFingerprint("back-end DBMS", kb.bannerFp)
 
129
 
 
130
            if dbmsOsFp:
 
131
                value += "%s\n" % dbmsOsFp
 
132
 
 
133
        value += "back-end DBMS: "
 
134
 
 
135
        if not conf.extensiveFp:
 
136
            value += "Oracle"
 
137
            return value
 
138
 
 
139
        actVer      = formatDBMSfp()
 
140
        blank       = " " * 15
 
141
        value      += "active fingerprint: %s" % actVer
 
142
 
 
143
        if kb.bannerFp:
 
144
            banVer = kb.bannerFp["dbmsVersion"]
 
145
            banVer = formatDBMSfp([banVer])
 
146
            value += "\n%sbanner parsing fingerprint: %s" % (blank, banVer)
 
147
 
 
148
        htmlErrorFp = getHtmlErrorFp()
 
149
 
 
150
        if htmlErrorFp:
 
151
            value += "\n%shtml error message fingerprint: %s" % (blank, htmlErrorFp)
 
152
 
 
153
        return value
 
154
 
 
155
 
 
156
    def checkDbms(self):
 
157
        if conf.dbms in ORACLE_ALIASES:
 
158
            setDbms("Oracle")
 
159
 
 
160
            self.getPrematureBanner("SELECT banner FROM v$version WHERE ROWNUM=1")
 
161
 
 
162
            if not conf.extensiveFp:
 
163
                return True
 
164
 
 
165
        logMsg = "testing Oracle"
 
166
        logger.info(logMsg)
 
167
 
 
168
        payload = agent.fullPayload(" AND ROWNUM=ROWNUM")
 
169
        result  = Request.queryPage(payload)
 
170
 
 
171
        if result == True:
 
172
            logMsg = "confirming Oracle"
 
173
            logger.info(logMsg)
 
174
 
 
175
            payload = agent.fullPayload(" AND LENGTH(SYSDATE)=LENGTH(SYSDATE)")
 
176
            result  = Request.queryPage(payload)
 
177
 
 
178
            if result != True:
 
179
                warnMsg = "the back-end DMBS is not Oracle"
 
180
                logger.warn(warnMsg)
 
181
 
 
182
                return False
 
183
 
 
184
            setDbms("Oracle")
 
185
 
 
186
            self.getPrematureBanner("SELECT banner FROM v$version WHERE ROWNUM=1")
 
187
 
 
188
            if not conf.extensiveFp:
 
189
                return True
 
190
 
 
191
            query = "SELECT SUBSTR((VERSION), 1, 2) FROM SYS.PRODUCT_COMPONENT_VERSION WHERE ROWNUM=1"
 
192
            version = inject.getValue(query)
 
193
 
 
194
            if re.search("^11", version):
 
195
                kb.dbmsVersion = ["11i"]
 
196
            elif re.search("^10", version):
 
197
                kb.dbmsVersion = ["10g"]
 
198
            elif re.search("^9", version):
 
199
                kb.dbmsVersion = ["9i"]
 
200
            elif re.search("^8", version):
 
201
                kb.dbmsVersion = ["8i"]
 
202
 
 
203
            return True
 
204
        else:
 
205
            warnMsg = "the back-end DMBS is not Oracle"
 
206
            logger.warn(warnMsg)
 
207
 
 
208
            return False
 
209
 
 
210
 
 
211
    def forceDbmsEnum(self):
 
212
        if conf.db:
 
213
            conf.db = conf.db.upper()
 
214
        else:
 
215
            conf.db = "USERS"
 
216
 
 
217
            warnMsg  = "on Oracle it is only possible to enumerate "
 
218
            warnMsg += "if you provide a TABLESPACE_NAME as database "
 
219
            warnMsg += "name. sqlmap is going to use 'USERS' as database "
 
220
            warnMsg += "name"
 
221
            logger.warn(warnMsg)
 
222
 
 
223
        if conf.tbl:
 
224
            conf.tbl = conf.tbl.upper()
 
225
 
 
226
 
 
227
    def getDbs(self):
 
228
        warnMsg = "on Oracle it is not possible to enumerate databases"
 
229
        logger.warn(warnMsg)
 
230
 
 
231
        return []