mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2025-12-07 21:21:33 +00:00
Merge branch 'master' of github.com:sqlmapproject/sqlmap
This commit is contained in:
@@ -742,7 +742,7 @@ def setColor(message, bold=False):
|
||||
|
||||
return retVal
|
||||
|
||||
def dataToStdout(data, forceOutput=False, bold=False):
|
||||
def dataToStdout(data, forceOutput=False, bold=False, content_type=None, status=None):
|
||||
"""
|
||||
Writes text to the stdout (console) stream
|
||||
"""
|
||||
@@ -754,8 +754,15 @@ def dataToStdout(data, forceOutput=False, bold=False):
|
||||
if kb.get("multiThreadMode"):
|
||||
logging._acquireLock()
|
||||
|
||||
message = stdoutencode(data)
|
||||
sys.stdout.write(setColor(message, bold))
|
||||
if isinstance(data, basestring):
|
||||
message = stdoutencode(data)
|
||||
else:
|
||||
message = data
|
||||
|
||||
if hasattr(conf, "api"):
|
||||
sys.stdout.write(message, status=status, content_type=content_type)
|
||||
else:
|
||||
sys.stdout.write(setColor(message, bold))
|
||||
|
||||
try:
|
||||
sys.stdout.flush()
|
||||
|
||||
@@ -104,3 +104,6 @@ def stdoutencode(data):
|
||||
|
||||
def jsonize(data):
|
||||
return json.dumps(data, sort_keys=False, indent=4)
|
||||
|
||||
def dejsonize(data):
|
||||
return json.loads(data)
|
||||
|
||||
@@ -26,6 +26,8 @@ from lib.core.data import conf
|
||||
from lib.core.data import kb
|
||||
from lib.core.data import logger
|
||||
from lib.core.dicts import DUMP_REPLACEMENTS
|
||||
from lib.core.enums import API_CONTENT_STATUS
|
||||
from lib.core.enums import API_CONTENT_TYPE
|
||||
from lib.core.enums import DBMS
|
||||
from lib.core.enums import DUMP_FORMAT
|
||||
from lib.core.exception import SqlmapGenericException
|
||||
@@ -52,8 +54,13 @@ class Dump(object):
|
||||
self._outputFP = None
|
||||
self._lock = threading.Lock()
|
||||
|
||||
def _write(self, data, newline=True, console=True):
|
||||
def _write(self, data, newline=True, console=True, content_type=None):
|
||||
if hasattr(conf, "api"):
|
||||
dataToStdout(data, content_type=content_type, status=API_CONTENT_STATUS.COMPLETE)
|
||||
return
|
||||
|
||||
text = "%s%s" % (data, "\n" if newline else " ")
|
||||
|
||||
if console:
|
||||
dataToStdout(text)
|
||||
|
||||
@@ -81,7 +88,7 @@ class Dump(object):
|
||||
def singleString(self, data):
|
||||
self._write(data)
|
||||
|
||||
def string(self, header, data, sort=True):
|
||||
def string(self, header, data, content_type=None, sort=True):
|
||||
kb.stickyLevel = None
|
||||
|
||||
if isListLike(data):
|
||||
@@ -92,18 +99,19 @@ class Dump(object):
|
||||
if _ and _[-1] == '\n':
|
||||
_ = _[:-1]
|
||||
|
||||
if "\n" in _:
|
||||
if hasattr(conf, "api"):
|
||||
self._write(data, content_type=content_type)
|
||||
elif "\n" in _:
|
||||
self._write("%s:\n---\n%s\n---" % (header, _))
|
||||
else:
|
||||
self._write("%s: %s" % (header, ("'%s'" % _) if isinstance(data, basestring) else _))
|
||||
elif hasattr(conf, "api"):
|
||||
self._write(data, content_type=content_type)
|
||||
else:
|
||||
self._write("%s:\tNone" % header)
|
||||
|
||||
def lister(self, header, elements, sort=True):
|
||||
if elements:
|
||||
self._write("%s [%d]:" % (header, len(elements)))
|
||||
|
||||
if sort:
|
||||
def lister(self, header, elements, content_type=None, sort=True):
|
||||
if elements and sort:
|
||||
try:
|
||||
elements = set(elements)
|
||||
elements = list(elements)
|
||||
@@ -111,6 +119,13 @@ class Dump(object):
|
||||
except:
|
||||
pass
|
||||
|
||||
if hasattr(conf, "api"):
|
||||
self._write(elements, content_type=content_type)
|
||||
return
|
||||
|
||||
if elements:
|
||||
self._write("%s [%d]:" % (header, len(elements)))
|
||||
|
||||
for element in elements:
|
||||
if isinstance(element, basestring):
|
||||
self._write("[*] %s" % element)
|
||||
@@ -121,29 +136,29 @@ class Dump(object):
|
||||
self._write("")
|
||||
|
||||
def banner(self, data):
|
||||
self.string("banner", data)
|
||||
self.string("banner", data, content_type=API_CONTENT_TYPE.BANNER)
|
||||
|
||||
def currentUser(self, data):
|
||||
self.string("current user", data)
|
||||
self.string("current user", data, content_type=API_CONTENT_TYPE.CURRENT_USER)
|
||||
|
||||
def currentDb(self, data):
|
||||
if Backend.isDbms(DBMS.MAXDB):
|
||||
self.string("current database (no practical usage on %s)" % Backend.getIdentifiedDbms(), data)
|
||||
self.string("current database (no practical usage on %s)" % Backend.getIdentifiedDbms(), data, content_type=API_CONTENT_TYPE.CURRENT_DB)
|
||||
elif Backend.isDbms(DBMS.ORACLE):
|
||||
self.string("current schema (equivalent to database on %s)" % Backend.getIdentifiedDbms(), data)
|
||||
self.string("current schema (equivalent to database on %s)" % Backend.getIdentifiedDbms(), data, content_type=API_CONTENT_TYPE.CURRENT_DB)
|
||||
else:
|
||||
self.string("current database", data)
|
||||
self.string("current database", data, content_type=API_CONTENT_TYPE.CURRENT_DB)
|
||||
|
||||
def hostname(self, data):
|
||||
self.string("hostname", data)
|
||||
self.string("hostname", data, content_type=API_CONTENT_TYPE.HOSTNAME)
|
||||
|
||||
def dba(self, data):
|
||||
self.string("current user is DBA", data)
|
||||
self.string("current user is DBA", data, content_type=API_CONTENT_TYPE.IS_DBA)
|
||||
|
||||
def users(self, users):
|
||||
self.lister("database management system users", users)
|
||||
self.lister("database management system users", users, content_type=API_CONTENT_TYPE.USERS)
|
||||
|
||||
def userSettings(self, header, userSettings, subHeader):
|
||||
def userSettings(self, header, userSettings, subHeader, content_type=None):
|
||||
self._areAdmins = set()
|
||||
|
||||
if userSettings:
|
||||
@@ -179,9 +194,9 @@ class Dump(object):
|
||||
self.singleString("")
|
||||
|
||||
def dbs(self, dbs):
|
||||
self.lister("available databases", dbs)
|
||||
self.lister("available databases", dbs, content_type=API_CONTENT_TYPE.DBS)
|
||||
|
||||
def dbTables(self, dbTables):
|
||||
def dbTables(self, dbTables, content_type=API_CONTENT_TYPE.TABLES):
|
||||
if isinstance(dbTables, dict) and len(dbTables) > 0:
|
||||
maxlength = 0
|
||||
|
||||
@@ -219,7 +234,7 @@ class Dump(object):
|
||||
else:
|
||||
self.string("tables", dbTables)
|
||||
|
||||
def dbTableColumns(self, tableColumns):
|
||||
def dbTableColumns(self, tableColumns, content_type=API_CONTENT_TYPE.COLUMNS):
|
||||
if isinstance(tableColumns, dict) and len(tableColumns) > 0:
|
||||
for db, tables in tableColumns.items():
|
||||
if not db:
|
||||
@@ -286,7 +301,7 @@ class Dump(object):
|
||||
else:
|
||||
self._write("+%s+\n" % lines1)
|
||||
|
||||
def dbTablesCount(self, dbTables):
|
||||
def dbTablesCount(self, dbTables, content_type=API_CONTENT_TYPE.COUNT):
|
||||
if isinstance(dbTables, dict) and len(dbTables) > 0:
|
||||
maxlength1 = len("Table")
|
||||
maxlength2 = len("Entries")
|
||||
@@ -328,7 +343,7 @@ class Dump(object):
|
||||
else:
|
||||
logger.error("unable to retrieve the number of entries for any table")
|
||||
|
||||
def dbTableValues(self, tableValues):
|
||||
def dbTableValues(self, tableValues, content_type=API_CONTENT_TYPE.DUMP_TABLE):
|
||||
replication = None
|
||||
rtable = None
|
||||
dumpFP = None
|
||||
@@ -534,7 +549,7 @@ class Dump(object):
|
||||
dumpFP.close()
|
||||
logger.info("table '%s.%s' dumped to %s file '%s'" % (db, table, conf.dumpFormat, dumpFileName))
|
||||
|
||||
def dbColumns(self, dbColumnsDict, colConsider, dbs):
|
||||
def dbColumns(self, dbColumnsDict, colConsider, dbs, content_type=API_CONTENT_TYPE.COLUMNS):
|
||||
for column in dbColumnsDict.keys():
|
||||
if colConsider == "1":
|
||||
colConsiderStr = "s like '" + column + "' were"
|
||||
@@ -565,13 +580,13 @@ class Dump(object):
|
||||
self.dbTableColumns(_)
|
||||
|
||||
def query(self, query, queryRes):
|
||||
self.string(query, queryRes)
|
||||
self.string(query, queryRes, content_type=API_CONTENT_TYPE.SQL_QUERY)
|
||||
|
||||
def rFile(self, fileData):
|
||||
self.lister("files saved to", fileData, sort=False)
|
||||
self.lister("files saved to", fileData, sort=False, content_type=API_CONTENT_TYPE.FILE_READ)
|
||||
|
||||
def registerValue(self, registerData):
|
||||
self.string("Registry key value data", registerData, sort=False)
|
||||
def registerValue(self):
|
||||
self.string("Registry key value data", registerData, registerData, content_type=API_CONTENT_TYPE.REG_READ, sort=False)
|
||||
|
||||
# object to manage how to print the retrieved queries output to
|
||||
# standard output and sessions file
|
||||
|
||||
@@ -243,3 +243,33 @@ class WEB_API:
|
||||
ASP = "asp"
|
||||
ASPX = "aspx"
|
||||
JSP = "jsp"
|
||||
|
||||
class API_CONTENT_TYPE:
|
||||
TECHNIQUES = 0
|
||||
BANNER = 1
|
||||
CURRENT_USER = 2
|
||||
CURRENT_DB = 3
|
||||
HOSTNAME = 4
|
||||
IS_DBA = 5
|
||||
USERS = 6
|
||||
PASSWORDS = 7
|
||||
PRIVILEGES = 8
|
||||
ROLES = 9
|
||||
DBS = 10
|
||||
TABLES = 11
|
||||
COLUMNS = 12
|
||||
SCHEMA = 13
|
||||
COUNT = 14
|
||||
DUMP_TABLE = 15
|
||||
SEARCH = 16
|
||||
SQL_QUERY = 17
|
||||
COMMON_TABLES = 18
|
||||
COMMON_COLUMNS = 19
|
||||
FILE_READ = 20
|
||||
FILE_WRITE = 21
|
||||
OS_CMD = 22
|
||||
REG_READ = 23
|
||||
|
||||
class API_CONTENT_STATUS:
|
||||
IN_PROGRESS = 0
|
||||
COMPLETE = 1
|
||||
|
||||
@@ -87,7 +87,6 @@ from lib.core.exception import SqlmapSyntaxException
|
||||
from lib.core.exception import SqlmapUnsupportedDBMSException
|
||||
from lib.core.exception import SqlmapUserQuitException
|
||||
from lib.core.log import FORMATTER
|
||||
from lib.core.log import LOGGER_HANDLER
|
||||
from lib.core.optiondict import optDict
|
||||
from lib.core.purge import purge
|
||||
from lib.core.settings import ACCESS_ALIASES
|
||||
@@ -137,6 +136,7 @@ from lib.request.httpshandler import HTTPSHandler
|
||||
from lib.request.rangehandler import HTTPRangeHandler
|
||||
from lib.request.redirecthandler import SmartRedirectHandler
|
||||
from lib.request.templates import getPageTemplate
|
||||
from lib.utils.api import setRestAPILog
|
||||
from lib.utils.crawler import crawl
|
||||
from lib.utils.deps import checkDependencies
|
||||
from lib.utils.google import Google
|
||||
@@ -1795,25 +1795,6 @@ def _mergeOptions(inputOptions, overrideOptions):
|
||||
if hasattr(conf, key) and conf[key] is None:
|
||||
conf[key] = value
|
||||
|
||||
class LogRecorder(logging.StreamHandler):
|
||||
def emit(self, record):
|
||||
"""
|
||||
Record emitted events to temporary database for asynchronous I/O
|
||||
communication with the parent process
|
||||
"""
|
||||
connection = sqlite3.connect(conf.ipc, isolation_level=None)
|
||||
cursor = connection.cursor()
|
||||
cursor.execute("INSERT INTO logs VALUES(NULL, ?, ?, ?)",
|
||||
(time.strftime("%X"), record.levelname, record.msg % record.args if record.args else record.msg))
|
||||
cursor.close()
|
||||
connection.close()
|
||||
|
||||
def _setRestAPILog():
|
||||
if hasattr(conf, "ipc"):
|
||||
logger.removeHandler(LOGGER_HANDLER)
|
||||
LOGGER_RECORDER = LogRecorder()
|
||||
logger.addHandler(LOGGER_RECORDER)
|
||||
|
||||
def _setTrafficOutputFP():
|
||||
if conf.trafficFile:
|
||||
infoMsg = "setting file for logging HTTP traffic"
|
||||
@@ -2085,7 +2066,7 @@ def init(inputOptions=AttribDict(), overrideOptions=False):
|
||||
_mergeOptions(inputOptions, overrideOptions)
|
||||
_useWizardInterface()
|
||||
setVerbosity()
|
||||
_setRestAPILog()
|
||||
setRestAPILog()
|
||||
_saveCmdline()
|
||||
_setRequestFromFile()
|
||||
_cleanupOptions()
|
||||
|
||||
@@ -265,7 +265,7 @@ def runCase(switches=None, parse=None):
|
||||
try:
|
||||
result = start()
|
||||
except KeyboardInterrupt:
|
||||
raise
|
||||
pass
|
||||
except SqlmapBaseException, e:
|
||||
handled_exception = e
|
||||
except Exception, e:
|
||||
|
||||
Reference in New Issue
Block a user