sqlmap/lib/techniques/brute/use.py

165 lines
4.9 KiB
Python
Raw Normal View History

2010-11-09 12:42:43 +03:00
#!/usr/bin/env python
"""
$Id$
Copyright (c) 2006-2010 sqlmap developers (http://sqlmap.sourceforge.net/)
See the file 'doc/COPYING' for copying permission
"""
2010-12-21 02:21:01 +03:00
import threading
2010-11-09 12:42:43 +03:00
import time
2010-11-24 00:00:42 +03:00
from lib.core.common import clearConsoleLine
2010-11-09 12:42:43 +03:00
from lib.core.common import dataToStdout
from lib.core.common import getFileItems
from lib.core.common import popValue
from lib.core.common import pushValue
from lib.core.common import randomInt
from lib.core.common import safeStringFormat
from lib.core.data import conf
from lib.core.data import kb
2010-11-09 12:42:43 +03:00
from lib.core.data import logger
from lib.core.exception import sqlmapMissingMandatoryOptionException
from lib.core.settings import METADB_SUFFIX
2010-12-09 01:14:42 +03:00
from lib.request import inject
2010-11-09 12:42:43 +03:00
def tableExists(tableFile):
2010-11-09 19:53:33 +03:00
tables = getFileItems(tableFile)
2010-11-09 12:42:43 +03:00
retVal = []
2010-11-09 19:53:33 +03:00
infoMsg = "checking table existence using items from '%s'" % tableFile
2010-11-09 12:42:43 +03:00
logger.info(infoMsg)
2010-12-21 02:21:01 +03:00
count = [0]
2010-11-09 12:42:43 +03:00
length = len(tables)
2010-12-21 02:21:01 +03:00
threads = []
tbllock = threading.Lock()
iolock = threading.Lock()
kb.locks.seqLock = threading.Lock()
kb.threadContinue = True
2010-12-21 02:21:01 +03:00
def tableExistsThread():
while count[0] < length and kb.threadContinue:
tbllock.acquire()
table = tables[count[0]]
count[0] += 1
tbllock.release()
2010-11-09 12:42:43 +03:00
2010-12-21 02:21:01 +03:00
if conf.db and not conf.db.endswith(METADB_SUFFIX):
table = "%s.%s" % (conf.db, table)
result = inject.checkBooleanExpression("%s" % safeStringFormat("EXISTS(SELECT %d FROM %s)", (randomInt(1), table)))
2010-11-09 12:42:43 +03:00
2010-12-21 02:21:01 +03:00
iolock.acquire()
if result:
retVal.append(table)
if conf.verbose in (1, 2):
clearConsoleLine(True)
infoMsg = "\r[%s] [INFO] retrieved: %s\n" % (time.strftime("%X"), table)
dataToStdout(infoMsg, True)
2010-11-09 12:42:43 +03:00
if conf.verbose in (1, 2):
2010-12-21 02:21:01 +03:00
status = '%d/%d items (%d%s)' % (count[0], length, round(100.0*count[0]/length), '%')
dataToStdout("\r[%s] [INFO] tried: %s" % (time.strftime("%X"), status), True)
iolock.release()
2010-12-21 02:21:01 +03:00
# Start the threads
for numThread in range(conf.threads):
thread = threading.Thread(target=tableExistsThread, name=str(numThread))
thread.start()
threads.append(thread)
2010-11-09 12:42:43 +03:00
2010-12-21 02:21:01 +03:00
# And wait for them to all finish
try:
alive = True
while alive:
alive = False
for thread in threads:
if thread.isAlive():
alive = True
thread.join(5)
except KeyboardInterrupt:
kb.threadContinue = False
kb.threadException = True
print
logger.debug("waiting for threads to finish")
try:
while (threading.activeCount() > 1):
pass
except KeyboardInterrupt:
raise sqlmapThreadException, "user aborted"
2010-12-21 02:21:01 +03:00
finally:
kb.locks.seqLock = None
2010-11-09 12:42:43 +03:00
2010-11-24 00:00:42 +03:00
clearConsoleLine(True)
2010-11-09 12:42:43 +03:00
if not retVal:
warnMsg = "no table found"
logger.warn(warnMsg)
else:
for item in retVal:
if not kb.data.cachedTables.has_key(conf.db):
kb.data.cachedTables[conf.db] = [item]
else:
kb.data.cachedTables[conf.db].append(item)
2010-11-09 12:42:43 +03:00
return kb.data.cachedTables
2010-11-09 12:42:43 +03:00
def columnExists(columnFile):
if not conf.tbl:
errMsg = "missing table parameter"
raise sqlmapMissingMandatoryOptionException, errMsg
2010-11-09 19:53:33 +03:00
columns = getFileItems(columnFile)
if conf.db and not conf.db.endswith(METADB_SUFFIX):
2010-11-12 01:26:36 +03:00
table = "%s.%s" % (conf.db, conf.tbl)
else:
table = conf.tbl
2010-11-09 12:42:43 +03:00
retVal = []
2010-11-09 19:53:33 +03:00
infoMsg = "checking column existence using items from '%s'" % columnFile
2010-11-09 12:42:43 +03:00
logger.info(infoMsg)
count = 0
length = len(columns)
2010-11-09 12:42:43 +03:00
for column in columns:
result = inject.checkBooleanExpression("%s" % safeStringFormat("EXISTS(SELECT %s FROM %s)", (column, table)))
2010-11-09 12:42:43 +03:00
if result:
retVal.append(column)
if conf.verbose in (1, 2):
clearConsoleLine(True)
infoMsg = "\r[%s] [INFO] retrieved: %s\n" % (time.strftime("%X"), column)
dataToStdout(infoMsg, True)
2010-11-09 12:42:43 +03:00
count += 1
if conf.verbose in (1, 2):
status = '%d/%d items (%d%s)' % (count, length, round(100.0*count/length), '%')
dataToStdout("\r[%s] [INFO] tried: %s" % (time.strftime("%X"), status), True)
2010-11-09 12:42:43 +03:00
2010-11-24 00:00:42 +03:00
clearConsoleLine(True)
2010-11-09 12:42:43 +03:00
if not retVal:
warnMsg = "no column found"
logger.warn(warnMsg)
else:
columns = {}
2010-11-09 12:42:43 +03:00
for column in retVal:
result = inject.checkBooleanExpression("%s" % safeStringFormat("EXISTS(SELECT %s FROM %s WHERE %s>0)", (column, table, column)))
if result:
columns[column] = 'numeric'
else:
columns[column] = 'non-numeric'
kb.data.cachedColumns[conf.db] = {conf.tbl: columns}
return kb.data.cachedColumns