Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 3f4c010

Browse files
committed
Merge branch 'master' of github.com:sqlmapproject/sqlmap
2 parents efe26ac + 6a62292 commit 3f4c010

14 files changed

Lines changed: 669 additions & 35 deletions

File tree

extra/shutils/regressiontest.py

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
SMTP_PORT = 25
2727
SMTP_TIMEOUT = 30
2828
29-
29+
3030
SUBJECT = "Regression test results on %s using revision %s" % (TIME, REVISION)
3131

3232
def prepare_email(content):
@@ -87,18 +87,23 @@ def main():
8787

8888
test_counts.append(test_count)
8989

90-
console_output_fd = codecs.open(os.path.join(output_folder, "console_output"), "rb", "utf8")
91-
console_output = console_output_fd.read()
92-
console_output_fd.close()
90+
console_output_file = os.path.join(output_folder, "console_output")
91+
log_file = os.path.join(output_folder, "debiandev", "log")
92+
traceback_file = os.path.join(output_folder, "traceback")
9393

94-
attachments[test_count] = str(console_output)
94+
if os.path.exists(console_output_file):
95+
console_output_fd = codecs.open(console_output_file, "rb", "utf8")
96+
console_output = console_output_fd.read()
97+
console_output_fd.close()
98+
attachments[test_count] = str(console_output)
9599

96-
log_fd = codecs.open(os.path.join(output_folder, "debiandev", "log"), "rb", "utf8")
97-
log = log_fd.read()
98-
log_fd.close()
100+
if os.path.exists(log_file):
101+
log_fd = codecs.open(log_file, "rb", "utf8")
102+
log = log_fd.read()
103+
log_fd.close()
99104

100-
if traceback:
101-
traceback_fd = codecs.open(os.path.join(output_folder, "traceback"), "rb", "utf8")
105+
if os.path.exists(traceback_file):
106+
traceback_fd = codecs.open(traceback_file, "rb", "utf8")
102107
traceback = traceback_fd.read()
103108
traceback_fd.close()
104109

extra/shutils/regressiontest_cronjob.sh

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,18 @@
66
SQLMAP_HOME="/opt/sqlmap"
77
REGRESSION_SCRIPT="${SQLMAP_HOME}/extra/shutils"
88

9+
10+
11+
SUBJECT="Automated regression test failed on $(date)"
12+
913
cd $SQLMAP_HOME
1014
git pull
1115
rm -f output 2>/dev/null
1216

1317
cd $REGRESSION_SCRIPT
14-
python regressiontest.py
18+
python regressiontest.py 1>/tmp/regressiontest.log 2>&1
19+
20+
if [ $? -ne 0 ]
21+
then
22+
cat /tmp/regressiontest.log | mailx -s "${SUBJECT}" -aFrom:${FROM} ${TO}
23+
fi

lib/core/agent.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -535,7 +535,7 @@ def concatQuery(self, query, unpack=True):
535535
elif fieldsNoSelect:
536536
concatenatedQuery = "CONCAT('%s',%s,'%s')" % (kb.chars.start, concatenatedQuery, kb.chars.stop)
537537

538-
elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.ORACLE, DBMS.SQLITE, DBMS.DB2):
538+
elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.ORACLE, DBMS.SQLITE, DBMS.DB2, DBMS.FIREBIRD):
539539
if fieldsExists:
540540
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'||" % kb.chars.start, 1)
541541
concatenatedQuery += "||'%s'" % kb.chars.stop
@@ -822,15 +822,15 @@ def limitQuery(self, num, query, field=None, uniqueField=None):
822822
limitedQuery += " %s" % limitStr
823823

824824
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2):
825-
if " ORDER BY " in limitedQuery and "(SELECT " in limitedQuery:
826-
orderBy = limitedQuery[limitedQuery.index(" ORDER BY "):]
825+
if " ORDER BY " in limitedQuery and "SELECT " in limitedQuery:
827826
limitedQuery = limitedQuery[:limitedQuery.index(" ORDER BY ")]
828827

829828
if query.startswith("SELECT "):
830829
delimiter = queries[Backend.getIdentifiedDbms()].delimiter.query
831830
limitedQuery = "%s FROM (%s,%s" % (untilFrom, untilFrom.replace(delimiter, ','), limitStr)
832831
else:
833832
limitedQuery = "%s FROM (SELECT %s,%s" % (untilFrom, ','.join(f for f in field), limitStr)
833+
834834
limitedQuery = limitedQuery % fromFrom
835835
limitedQuery += "=%d" % (num + 1)
836836

lib/core/dump.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,8 @@ def userSettings(self, header, userSettings, subHeader):
175175
for setting in settings:
176176
self._write(" %s: %s" % (subHeader, setting))
177177

178-
self.singleString("")
178+
if userSettings:
179+
self.singleString("")
179180

180181
def dbs(self, dbs):
181182
self.lister("available databases", dbs)

lib/core/testing.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,9 @@ def liveTest():
167167

168168
result = runCase(switches, parse)
169169

170+
test_case_fd = codecs.open(os.path.join(paths.SQLMAP_OUTPUT_PATH, "test_case"), "wb", UNICODE_ENCODING)
171+
test_case_fd.write("%s\n" % name)
172+
170173
if result:
171174
logger.info("test passed")
172175
cleanCase()
@@ -183,6 +186,7 @@ def liveTest():
183186
errMsg += " - SQL injection not detected"
184187

185188
logger.error(errMsg)
189+
test_case_fd.write("%s\n" % errMsg)
186190

187191
if failedParseOn:
188192
console_output_fd = codecs.open(os.path.join(paths.SQLMAP_OUTPUT_PATH, "console_output"), "wb", UNICODE_ENCODING)
@@ -199,6 +203,7 @@ def liveTest():
199203
if conf.stopFail is True:
200204
return retVal
201205

206+
test_case_fd.close()
202207
retVal &= bool(result)
203208

204209
dataToStdout("\n")

lib/techniques/error/use.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
from lib.core.common import initTechnique
2424
from lib.core.common import isListLike
2525
from lib.core.common import isNumPosStrValue
26+
from lib.core.common import isTechniqueAvailable
2627
from lib.core.common import listToStrValue
2728
from lib.core.common import readInput
2829
from lib.core.common import unArrayizeValue
@@ -34,6 +35,7 @@
3435
from lib.core.data import queries
3536
from lib.core.dicts import FROM_DUMMY_TABLE
3637
from lib.core.enums import DBMS
38+
from lib.core.enums import PAYLOAD
3739
from lib.core.settings import CHECK_ZERO_COLUMNS_THRESHOLD
3840
from lib.core.settings import MYSQL_ERROR_CHUNK_LENGTH
3941
from lib.core.settings import MSSQL_ERROR_CHUNK_LENGTH
@@ -180,6 +182,9 @@ def _errorFields(expression, expressionFields, expressionFieldsList, num=None, e
180182
else:
181183
expressionReplaced = expression.replace(expressionFields, field, 1)
182184

185+
if kb.technique == PAYLOAD.TECHNIQUE.QUERY and Backend.isDbms(DBMS.FIREBIRD) and expressionReplaced.startswith("SELECT "):
186+
expressionReplaced = "SELECT %s" % agent.concatQuery(expressionReplaced)
187+
183188
output = NULL if emptyFields and field in emptyFields else _oneShotErrorUse(expressionReplaced, field)
184189

185190
if not kb.threadContinue:

plugins/dbms/firebird/fingerprint.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ def _sysTablesCheck(self):
7474
("1.5", ("NULLIF(%d,%d) IS NULL", "EXISTS(SELECT CURRENT_TRANSACTION FROM RDB$DATABASE)")),
7575
("2.0", ("EXISTS(SELECT CURRENT_TIME(0) FROM RDB$DATABASE)", "BIT_LENGTH(%d)>0", "CHAR_LENGTH(%d)>0")),
7676
("2.1", ("BIN_XOR(%d,%d)=0", "PI()>0.%d", "RAND()<1.%d", "FLOOR(1.%d)>=0")),
77+
# TODO: add test for Firebird 2.5
7778
)
7879

7980
for i in xrange(len(table)):
@@ -122,7 +123,7 @@ def checkDbms(self):
122123
logger.info(infoMsg)
123124

124125
randInt = randomInt()
125-
result = inject.checkBooleanExpression("EXISTS(SELECT * FROM RDB$DATABASE WHERE %d=%d)" % (randInt, randInt))
126+
result = inject.checkBooleanExpression("(SELECT COUNT(*) FROM RDB$DATABASE WHERE %d=%d)>0" % (randInt, randInt))
126127

127128
if result:
128129
infoMsg = "confirming %s" % DBMS.FIREBIRD

plugins/dbms/firebird/syntax.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ def __init__(self):
1616
@staticmethod
1717
def escape(expression, quote=True):
1818
if isDBMSVersionAtLeast('2.1'):
19+
if expression == u"'''":
20+
return "ASCII_CHAR(%d)" % (ord("'"))
21+
1922
if quote:
2023
while True:
2124
index = expression.find("'")

plugins/dbms/mssqlserver/connector.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ def connect(self):
4141

4242
try:
4343
self.connector = pymssql.connect(host="%s:%d" % (self.hostname, self.port), user=self.user, password=self.password, database=self.db, login_timeout=conf.timeout, timeout=conf.timeout)
44-
except pymssql.OperationalError, msg:
44+
except (pymssql.InterfaceError, pymssql.OperationalError), msg:
4545
raise SqlmapConnectionException(msg)
4646

4747
self.initCursor()

plugins/generic/databases.py

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -513,22 +513,24 @@ def getColumns(self, onlyColNames=False, colTuple=None, bruteForce=None):
513513
query = rootQuery.inband.query % (unsafeSQLIdentificatorNaming(tbl), unsafeSQLIdentificatorNaming(conf.db))
514514
query += condQuery
515515
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2):
516-
query = rootQuery.inband.query % unsafeSQLIdentificatorNaming(tbl.upper())
516+
query = rootQuery.inband.query % (unsafeSQLIdentificatorNaming(tbl.upper()), unsafeSQLIdentificatorNaming(conf.db.upper()))
517517
query += condQuery
518518
elif Backend.isDbms(DBMS.MSSQL):
519519
query = rootQuery.inband.query % (conf.db, conf.db, conf.db, conf.db,
520520
conf.db, conf.db, conf.db, unsafeSQLIdentificatorNaming(tbl).split(".")[-1])
521521
query += condQuery.replace("[DB]", conf.db)
522-
elif Backend.isDbms(DBMS.SQLITE):
522+
elif Backend.getIdentifiedDbms() in (DBMS.SQLITE, DBMS.FIREBIRD):
523523
query = rootQuery.inband.query % tbl
524524

525525
values = inject.getValue(query, blind=False, time=False)
526526

527527
if Backend.isDbms(DBMS.MSSQL) and isNoneValue(values):
528528
index, values = 1, []
529+
529530
while True:
530531
query = rootQuery.inband.query2 % (conf.db, tbl, index)
531532
value = unArrayizeValue(inject.getValue(query, blind=False, time=False))
533+
532534
if isNoneValue(value) or value == " ":
533535
break
534536
else:
@@ -591,7 +593,7 @@ def getColumns(self, onlyColNames=False, colTuple=None, bruteForce=None):
591593
query += condQuery
592594

593595
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2):
594-
query = rootQuery.blind.count % unsafeSQLIdentificatorNaming(tbl.upper())
596+
query = rootQuery.blind.count % (unsafeSQLIdentificatorNaming(tbl.upper()), unsafeSQLIdentificatorNaming(conf.db.upper()))
595597
query += condQuery
596598

597599
elif Backend.isDbms(DBMS.MSSQL):
@@ -639,7 +641,7 @@ def getColumns(self, onlyColNames=False, colTuple=None, bruteForce=None):
639641
query += condQuery
640642
field = None
641643
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2):
642-
query = rootQuery.blind.query % unsafeSQLIdentificatorNaming(tbl.upper())
644+
query = rootQuery.blind.query % (unsafeSQLIdentificatorNaming(tbl.upper()), unsafeSQLIdentificatorNaming(conf.db.upper()))
643645
query += condQuery
644646
field = None
645647
elif Backend.isDbms(DBMS.MSSQL):
@@ -659,7 +661,7 @@ def getColumns(self, onlyColNames=False, colTuple=None, bruteForce=None):
659661
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL):
660662
query = rootQuery.blind.query2 % (unsafeSQLIdentificatorNaming(tbl), column, unsafeSQLIdentificatorNaming(conf.db))
661663
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2):
662-
query = rootQuery.blind.query2 % (unsafeSQLIdentificatorNaming(tbl.upper()), column)
664+
query = rootQuery.blind.query2 % (unsafeSQLIdentificatorNaming(tbl.upper()), column, unsafeSQLIdentificatorNaming(conf.db.upper()))
663665
elif Backend.isDbms(DBMS.MSSQL):
664666
query = rootQuery.blind.query2 % (conf.db, conf.db, conf.db, conf.db, column, conf.db,
665667
conf.db, conf.db, unsafeSQLIdentificatorNaming(tbl).split(".")[-1])
@@ -736,7 +738,11 @@ def _tableGetCount(self, db, table):
736738
db = db.upper()
737739
table = table.upper()
738740

739-
query = "SELECT %s FROM %s.%s" % (queries[Backend.getIdentifiedDbms()].count.query % '*', safeSQLIdentificatorNaming(db), safeSQLIdentificatorNaming(table, True))
741+
if Backend.getIdentifiedDbms() in (DBMS.SQLITE, DBMS.ACCESS, DBMS.FIREBIRD):
742+
query = "SELECT %s FROM %s" % (queries[Backend.getIdentifiedDbms()].count.query % '*', safeSQLIdentificatorNaming(table, True))
743+
else:
744+
query = "SELECT %s FROM %s.%s" % (queries[Backend.getIdentifiedDbms()].count.query % '*', safeSQLIdentificatorNaming(db), safeSQLIdentificatorNaming(table, True))
745+
740746
count = inject.getValue(query, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS)
741747

742748
if isNumPosStrValue(count):
@@ -759,7 +765,7 @@ def getCount(self):
759765
if not conf.db:
760766
conf.db, conf.tbl = conf.tbl.split(".")
761767

762-
if conf.tbl is not None and conf.db is None:
768+
if conf.tbl is not None and conf.db is None and Backend.getIdentifiedDbms() not in (DBMS.SQLITE, DBMS.ACCESS, DBMS.FIREBIRD):
763769
warnMsg = "missing database parameter. sqlmap is going to "
764770
warnMsg += "use the current database to retrieve the "
765771
warnMsg += "number of entries for table '%s'" % unsafeSQLIdentificatorNaming(conf.tbl)

0 commit comments

Comments
 (0)