11#!/usr/bin/env python
22
33"""
4- $Id: oracle.py 1003 2010-01-02 02:02:12Z inquisb $
4+ $Id$
55
66This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
77
2222Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
2323"""
2424
25- import re
26-
27- from lib .core .agent import agent
28- from lib .core .common import formatDBMSfp
29- from lib .core .common import formatFingerprint
30- from lib .core .common import getHtmlErrorFp
31- from lib .core .common import randomInt
32- from lib .core .data import conf
33- from lib .core .data import kb
34- from lib .core .data import logger
35- from lib .core .exception import sqlmapSyntaxException
36- from lib .core .exception import sqlmapUnsupportedFeatureException
37- from lib .core .session import setDbms
38- from lib .core .settings import ACCESS_ALIASES
3925from lib .core .settings import ACCESS_SYSTEM_DBS
4026from lib .core .unescaper import unescaper
41- from lib .request import inject
42- from lib .request .connect import Connect as Request
4327
44- from plugins .generic .enumeration import Enumeration
45- from plugins .generic .filesystem import Filesystem
46- from plugins .generic .fingerprint import Fingerprint
28+ from plugins .dbms .access .enumeration import Enumeration
29+ from plugins .dbms .access .filesystem import Filesystem
30+ from plugins .dbms .access .fingerprint import Fingerprint
31+ from plugins .dbms .access .syntax import Syntax
32+ from plugins .dbms .access .takeover import Takeover
4733from plugins .generic .misc import Miscellaneous
48- from plugins .generic .takeover import Takeover
49-
5034
51- class AccessMap (Fingerprint , Enumeration , Filesystem , Miscellaneous , Takeover ):
35+ class AccessMap (Syntax , Fingerprint , Enumeration , Filesystem , Miscellaneous , Takeover ):
5236 """
53- This class defines Access methods
37+ This class defines Microsoft Access methods
5438 """
5539
5640 def __init__ (self ):
5741 self .excludeDbsList = ACCESS_SYSTEM_DBS
5842
59- Enumeration .__init__ (self , "Microsoft Access" )
43+ Syntax .__init__ (self )
44+ Fingerprint .__init__ (self )
45+ Enumeration .__init__ (self )
6046 Filesystem .__init__ (self )
47+ Miscellaneous .__init__ (self )
6148 Takeover .__init__ (self )
62-
63- unescaper .setUnescape (AccessMap .unescape )
64-
65- @staticmethod
66- def unescape (expression , quote = True ):
67- if quote :
68- while True :
69- index = expression .find ("'" )
70- if index == - 1 :
71- break
72-
73- firstIndex = index + 1
74- index = expression [firstIndex :].find ("'" )
75-
76- if index == - 1 :
77- raise sqlmapSyntaxException , "Unenclosed ' in '%s'" % expression
78-
79- lastIndex = firstIndex + index
80- old = "'%s'" % expression [firstIndex :lastIndex ]
81- unescaped = ""
82-
83- for i in range (firstIndex , lastIndex ):
84- unescaped += "CHR(%d)" % (ord (expression [i ]))
85- if i < lastIndex - 1 :
86- unescaped += "&"
87-
88- expression = expression .replace (old , unescaped )
89- else :
90- unescaped = "" .join ("CHR(%d)&" % ord (c ) for c in expression )
91- if unescaped [- 1 ] == "&" :
92- unescaped = unescaped [:- 1 ]
93-
94- expression = unescaped
95-
96- return expression
97-
98- @staticmethod
99- def escape (expression ):
100- while True :
101- index = expression .find ("CHR(" )
102- if index == - 1 :
103- break
104-
105- firstIndex = index
106- index = expression [firstIndex :].find (")" )
107-
108- if index == - 1 :
109- raise sqlmapSyntaxException , "Unenclosed ) in '%s'" % expression
110-
111- lastIndex = firstIndex + index + 1
112- old = expression [firstIndex :lastIndex ]
113- oldUpper = old .upper ()
114- oldUpper = oldUpper .lstrip ("CHR(" ).rstrip (")" )
115- oldUpper = oldUpper .split ("&" )
116-
117- escaped = "'%s'" % "" .join ([chr (int (char )) for char in oldUpper ])
118- expression = expression .replace (old , escaped ).replace ("'&'" , "" )
119-
120- return expression
121-
122- def __sandBoxCheck (self ):
123- # Reference: http://milw0rm.com/papers/198
124- retVal = None
125- table = None
126- if kb .dbmsVersion and len (kb .dbmsVersion ) > 0 :
127- if kb .dbmsVersion [0 ] in ("97" , "2000" ):
128- table = "MSysAccessObjects"
129- elif kb .dbmsVersion [0 ] in ("2002-2003" , "2007" ):
130- table = "MSysAccessStorage"
131- if table :
132- query = agent .prefixQuery (" AND EXISTS(SELECT CURDIR() FROM %s)" % table )
133- query = agent .postfixQuery (query )
134- payload = agent .payload (newValue = query )
135- result = Request .queryPage (payload )
136- retVal = "not sandboxed" if result else "sandboxed"
137-
138- return retVal
139-
140- def __sysTablesCheck (self ):
141- infoMsg = "executing system table(s) existance fingerprint"
142- logger .info (infoMsg )
143-
144- # Microsoft Access table reference updated on 01/2010
145- sysTables = {
146- "97" : ("MSysModules2" , "MSysAccessObjects" ),
147- "2000" : ("!MSysModules2" , "MSysAccessObjects" ),
148- "2002-2003" : ("MSysAccessStorage" , "!MSysNavPaneObjectIDs" ),
149- "2007" : ("MSysAccessStorage" , "MSysNavPaneObjectIDs" )
150- }
151- # MSysAccessXML is not a reliable system table because it doesn't always exist
152- # ("Access through Access", p6, should be "normally doesn't exist" instead of "is normally empty")
153-
154- for version , tables in sysTables .items ():
155- exist = True
156- for table in tables :
157- negate = False
158- if table [0 ] == '!' :
159- negate = True
160- table = table [1 :]
161- randInt = randomInt ()
162- query = agent .prefixQuery (" AND EXISTS(SELECT * FROM %s WHERE %d=%d)" % (table , randInt , randInt ))
163- query = agent .postfixQuery (query )
164- payload = agent .payload (newValue = query )
165- result = Request .queryPage (payload )
166- if negate :
167- result = not result
168- exist &= result
169- if not exist :
170- break
171- if exist :
172- return version
173-
174- return None
175-
176- def getFingerprint (self ):
177- value = ""
178- wsOsFp = formatFingerprint ("web server" , kb .headersFp )
179-
180- if wsOsFp :
181- value += "%s\n " % wsOsFp
182-
183- if kb .data .banner :
184- dbmsOsFp = formatFingerprint ("back-end DBMS" , kb .bannerFp )
185-
186- if dbmsOsFp :
187- value += "%s\n " % dbmsOsFp
188-
189- value += "back-end DBMS: "
19049
191- if not conf .extensiveFp :
192- value += "Microsoft Access"
193- return value
194-
195- actVer = formatDBMSfp () + " (%s)" % (self .__sandBoxCheck ())
196- blank = " " * 15
197- value += "active fingerprint: %s" % actVer
198-
199- if kb .bannerFp :
200- banVer = kb .bannerFp ["dbmsVersion" ]
201-
202- if re .search ("-log$" , kb .data .banner ):
203- banVer += ", logging enabled"
204-
205- banVer = formatDBMSfp ([banVer ])
206- value += "\n %sbanner parsing fingerprint: %s" % (blank , banVer )
207-
208- htmlErrorFp = getHtmlErrorFp ()
209-
210- if htmlErrorFp :
211- value += "\n %shtml error message fingerprint: %s" % (blank , htmlErrorFp )
212-
213- return value
214-
215- def checkDbms (self ):
216- if conf .dbms in ACCESS_ALIASES :
217- setDbms ("Microsoft Access" )
218- if not conf .extensiveFp :
219- return True
220-
221- logMsg = "testing Microsoft Access"
222- logger .info (logMsg )
223-
224- payload = agent .fullPayload (" AND VAL(CVAR(1))=1" )
225- result = Request .queryPage (payload )
226-
227- if result :
228- logMsg = "confirming Microsoft Access"
229- logger .info (logMsg )
230-
231- payload = agent .fullPayload (" AND IIF(ATN(2)>0,1,0) BETWEEN 2 AND 0" )
232- result = Request .queryPage (payload )
233-
234- if not result :
235- warnMsg = "the back-end DMBS is not Microsoft Access"
236- logger .warn (warnMsg )
237- return False
238-
239- setDbms ("Microsoft Access" )
240-
241- if not conf .extensiveFp :
242- return True
243-
244- kb .dbmsVersion = [self .__sysTablesCheck ()]
245-
246- return True
247- else :
248- warnMsg = "the back-end DMBS is not Microsoft Access"
249- logger .warn (warnMsg )
250-
251- return False
252-
253- def getPasswordHashes (self ):
254- warnMsg = "on Microsoft Access it is not possible to enumerate the user password hashes"
255- logger .warn (warnMsg )
256-
257- return {}
258-
259- def readFile (self , rFile ):
260- errMsg = "on Microsoft Access it is not possible to read files"
261- raise sqlmapUnsupportedFeatureException , errMsg
262-
263- def writeFile (self , wFile , dFile , fileType = None , confirm = True ):
264- errMsg = "on Microsoft Access it is not possible to write files"
265- raise sqlmapUnsupportedFeatureException , errMsg
266-
267- def osCmd (self ):
268- errMsg = "on Microsoft Access it is not possible to execute commands"
269- raise sqlmapUnsupportedFeatureException , errMsg
270-
271- def osShell (self ):
272- errMsg = "on Microsoft Access it is not possible to execute commands"
273- raise sqlmapUnsupportedFeatureException , errMsg
274-
275- def osPwn (self ):
276- errMsg = "on Microsoft Access it is not possible to establish an "
277- errMsg += "out-of-band connection"
278- raise sqlmapUnsupportedFeatureException , errMsg
279-
280- def osSmb (self ):
281- errMsg = "on Microsoft Access it is not possible to establish an "
282- errMsg += "out-of-band connection"
283- raise sqlmapUnsupportedFeatureException , errMsg
284-
285- def getBanner (self ):
286- errMsg = "on Microsoft Access it is not possible to get a banner"
287- raise sqlmapUnsupportedFeatureException , errMsg
50+ unescaper .setUnescape (AccessMap .unescape )
0 commit comments