sqlmap/plugins/generic/custom.py

141 lines
4.4 KiB
Python
Raw Normal View History

2019-03-21 16:00:09 +03:00
#!/usr/bin/env python2
2012-07-20 22:17:35 +04:00
"""
2019-01-05 23:38:52 +03:00
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
2017-10-11 15:50:46 +03:00
See the file 'LICENSE' for copying permission
2012-07-20 22:17:35 +04:00
"""
2019-01-22 03:28:24 +03:00
from __future__ import print_function
2012-07-20 22:17:35 +04:00
import re
2014-11-11 13:53:51 +03:00
import sys
2012-07-20 22:17:35 +04:00
from lib.core.common import Backend
from lib.core.common import dataToStdout
from lib.core.common import getSQLSnippet
2014-11-11 13:53:51 +03:00
from lib.core.common import getUnicode
from lib.core.common import isStackingAvailable
2012-07-20 22:17:35 +04:00
from lib.core.data import conf
from lib.core.data import logger
2012-08-21 13:19:15 +04:00
from lib.core.dicts import SQL_STATEMENTS
2014-09-16 11:07:31 +04:00
from lib.core.enums import AUTOCOMPLETE_TYPE
2015-11-23 11:20:35 +03:00
from lib.core.exception import SqlmapNoneDataException
from lib.core.settings import NULL
2012-07-20 22:17:35 +04:00
from lib.core.settings import PARAMETER_SPLITTING_REGEX
from lib.core.shell import autoCompletion
from lib.request import inject
2019-05-02 01:45:44 +03:00
from thirdparty.six.moves import input as _input
2012-07-20 22:17:35 +04:00
class Custom:
"""
This class defines custom enumeration functionalities for plugins.
"""
def __init__(self):
pass
def sqlQuery(self, query):
output = None
sqlType = None
query = query.rstrip(';')
2015-11-23 11:20:35 +03:00
try:
for sqlTitle, sqlStatements in SQL_STATEMENTS.items():
for sqlStatement in sqlStatements:
if query.lower().startswith(sqlStatement):
sqlType = sqlTitle
break
2012-07-20 22:17:35 +04:00
2015-11-23 11:20:35 +03:00
if not any(_ in query.upper() for _ in ("OPENROWSET", "INTO")) and (not sqlType or "SELECT" in sqlType):
infoMsg = "fetching %s query output: '%s'" % (sqlType if sqlType is not None else "SQL", query)
logger.info(infoMsg)
2012-07-20 22:17:35 +04:00
2015-11-23 11:20:35 +03:00
output = inject.getValue(query, fromUser=True)
2012-07-20 22:17:35 +04:00
2015-11-23 11:20:35 +03:00
return output
elif not isStackingAvailable() and not conf.direct:
2017-04-17 00:32:58 +03:00
warnMsg = "execution of non-query SQL statements is only "
2015-11-23 11:20:35 +03:00
warnMsg += "available when stacked queries are supported"
logger.warn(warnMsg)
2012-07-20 22:17:35 +04:00
2015-11-23 11:20:35 +03:00
return None
2012-07-20 22:17:35 +04:00
else:
2015-11-23 11:20:35 +03:00
if sqlType:
debugMsg = "executing %s query: '%s'" % (sqlType if sqlType is not None else "SQL", query)
else:
debugMsg = "executing unknown SQL type query: '%s'" % query
logger.debug(debugMsg)
2012-07-20 22:17:35 +04:00
2015-11-23 11:20:35 +03:00
inject.goStacked(query)
2012-07-20 22:17:35 +04:00
2015-11-23 11:20:35 +03:00
debugMsg = "done"
logger.debug(debugMsg)
2012-07-20 22:17:35 +04:00
2015-11-23 11:20:35 +03:00
output = NULL
2019-01-22 02:40:48 +03:00
except SqlmapNoneDataException as ex:
2015-11-23 11:20:35 +03:00
logger.warn(ex)
2012-07-20 22:17:35 +04:00
return output
def sqlShell(self):
infoMsg = "calling %s shell. To quit type " % Backend.getIdentifiedDbms()
infoMsg += "'x' or 'q' and press ENTER"
logger.info(infoMsg)
2014-09-16 11:07:31 +04:00
autoCompletion(AUTOCOMPLETE_TYPE.SQL)
2012-07-20 22:17:35 +04:00
while True:
query = None
try:
2019-05-02 01:45:44 +03:00
query = _input("sql-shell> ")
2014-11-11 13:53:51 +03:00
query = getUnicode(query, encoding=sys.stdin.encoding)
query = query.strip("; ")
2012-07-20 22:17:35 +04:00
except KeyboardInterrupt:
2019-01-22 03:28:24 +03:00
print()
2012-07-20 22:17:35 +04:00
errMsg = "user aborted"
logger.error(errMsg)
except EOFError:
2019-01-22 03:28:24 +03:00
print()
2012-07-20 22:17:35 +04:00
errMsg = "exit"
logger.error(errMsg)
break
if not query:
continue
if query.lower() in ("x", "q", "exit", "quit"):
break
output = self.sqlQuery(query)
if output and output != "Quit":
2019-04-30 15:04:39 +03:00
conf.dumper.sqlQuery(query, output)
2012-07-20 22:17:35 +04:00
elif not output:
pass
elif output != "Quit":
dataToStdout("No output\n")
def sqlFile(self):
infoMsg = "executing SQL statements from given file(s)"
logger.info(infoMsg)
2016-12-20 01:47:39 +03:00
for filename in re.split(PARAMETER_SPLITTING_REGEX, conf.sqlFile):
filename = filename.strip()
2012-07-20 22:17:35 +04:00
2016-12-20 01:47:39 +03:00
if not filename:
2012-07-20 22:17:35 +04:00
continue
2016-12-20 01:47:39 +03:00
snippet = getSQLSnippet(Backend.getDbms(), filename)
2012-07-20 22:17:35 +04:00
if snippet and all(query.strip().upper().startswith("SELECT") for query in (_ for _ in snippet.split(';' if ';' in snippet else '\n') if _)):
for query in (_ for _ in snippet.split(';' if ';' in snippet else '\n') if _):
2015-08-23 23:54:08 +03:00
query = query.strip()
if query:
2019-04-30 15:04:39 +03:00
conf.dumper.sqlQuery(query, self.sqlQuery(query))
2015-08-23 23:54:08 +03:00
else:
2019-04-30 15:04:39 +03:00
conf.dumper.sqlQuery(snippet, self.sqlQuery(snippet))