Merge branch 'master' of github.com:sqlmapproject/sqlmap

This commit is contained in:
Miroslav Stampar
2013-01-29 15:35:01 +01:00
11 changed files with 361 additions and 193 deletions

View File

@@ -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()

View File

@@ -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)

View File

@@ -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

View 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

View File

@@ -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()

View File

@@ -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: