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

Skip to content

Commit 7a1d484

Browse files
committed
Implementation for an Issue #340
1 parent 3f84cef commit 7a1d484

5 files changed

Lines changed: 50 additions & 14 deletions

File tree

lib/core/agent.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,12 @@
1515
from lib.core.common import isTechniqueAvailable
1616
from lib.core.common import randomInt
1717
from lib.core.common import randomStr
18+
from lib.core.common import safeSQLIdentificatorNaming
1819
from lib.core.common import singleTimeWarnMessage
1920
from lib.core.data import conf
2021
from lib.core.data import kb
2122
from lib.core.data import queries
23+
from lib.core.dicts import DUMP_DATA_PREPROCESS
2224
from lib.core.dicts import FROM_DUMMY_TABLE
2325
from lib.core.enums import DBMS
2426
from lib.core.enums import PAYLOAD
@@ -463,6 +465,25 @@ def simpleConcatenate(self, first, second):
463465
rootQuery = queries[Backend.getIdentifiedDbms()]
464466
return rootQuery.concatenate.query % (first, second)
465467

468+
def preprocessField(self, table, field):
469+
"""
470+
Does a field preprocessing (if needed) based on it's type (e.g. image to text)
471+
Note: used primarily in dumping of custom tables
472+
"""
473+
474+
retVal = field
475+
if conf.db in table:
476+
table = table.split(conf.db)[-1].strip('.')
477+
try:
478+
columns = kb.data.cachedColumns[safeSQLIdentificatorNaming(conf.db)][safeSQLIdentificatorNaming(table, True)]
479+
for name, type_ in columns.items():
480+
if type_ and type_.upper() in DUMP_DATA_PREPROCESS.get(Backend.getDbms(), {}) and name == field:
481+
retVal = DUMP_DATA_PREPROCESS[Backend.getDbms()][type_.upper()] % name
482+
break
483+
except KeyError:
484+
pass
485+
return retVal
486+
466487
def concatQuery(self, query, unpack=True):
467488
"""
468489
Take in input a query string and return its processed nulled,

lib/core/dicts.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,3 +205,8 @@
205205
DEPRECATED_HINTS = {
206206
"--replicate": "use '--dump-format=SQLITE' instead",
207207
}
208+
209+
DUMP_DATA_PREPROCESS = {
210+
DBMS.ORACLE: {"XMLTYPE": "(%s).getStringVal()"}, # Reference: https://www.tibcommunity.com/docs/DOC-3643
211+
DBMS.MSSQL: {"IMAGE": "CONVERT(VARBINARY(MAX),%s)"},
212+
}

lib/utils/pivotdumptable.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
"""
77

88
from extra.safe2bin.safe2bin import safechardecode
9+
from lib.core.agent import agent
910
from lib.core.bigarray import BigArray
1011
from lib.core.common import Backend
1112
from lib.core.common import isNoneValue
@@ -101,9 +102,9 @@ def pivotDumpTable(table, colList, count=None, blind=True):
101102
for column in colList:
102103
def _(pivotValue):
103104
if column == colList[0]:
104-
query = dumpNode.query.replace("'%s'", "%s") % (column, table, column, unescaper.unescape(pivotValue, False))
105+
query = dumpNode.query.replace("'%s'", "%s") % (agent.preprocessField(table, column), table, agent.preprocessField(table, column), unescaper.unescape(pivotValue, False))
105106
else:
106-
query = dumpNode.query2.replace("'%s'", "%s") % (column, table, colList[0], unescaper.unescape(pivotValue, False))
107+
query = dumpNode.query2.replace("'%s'", "%s") % (agent.preprocessField(table, column), table, agent.preprocessField(table, colList[0]), unescaper.unescape(pivotValue, False))
107108

108109
return unArrayizeValue(inject.getValue(query, blind=blind, time=blind, union=not blind, error=not blind))
109110

plugins/generic/entries.py

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
See the file 'doc/COPYING' for copying permission
66
"""
77

8+
import re
9+
10+
from lib.core.agent import agent
811
from lib.core.bigarray import BigArray
912
from lib.core.common import Backend
1013
from lib.core.common import clearConsoleLine
@@ -117,17 +120,23 @@ def dumpTable(self, foundData=None):
117120

118121
continue
119122

120-
colList = sorted(filter(None, kb.data.cachedColumns[safeSQLIdentificatorNaming(conf.db)][safeSQLIdentificatorNaming(tbl, True)].keys()))
121-
colString = ", ".join(column for column in colList)
123+
columns = kb.data.cachedColumns[safeSQLIdentificatorNaming(conf.db)][safeSQLIdentificatorNaming(tbl, True)]
124+
colList = sorted(filter(None, columns.keys()))
125+
colNames = colString = ", ".join(column for column in colList)
122126
rootQuery = queries[Backend.getIdentifiedDbms()].dump_table
123127

124128
infoMsg = "fetching entries"
125129
if conf.col:
126-
infoMsg += " of column(s) '%s'" % colString
130+
infoMsg += " of column(s) '%s'" % colNames
127131
infoMsg += " for table '%s'" % unsafeSQLIdentificatorNaming(tbl)
128132
infoMsg += " in database '%s'" % unsafeSQLIdentificatorNaming(conf.db)
129133
logger.info(infoMsg)
130134

135+
for column in colList:
136+
_ = agent.preprocessField(tbl, column)
137+
if _ != column:
138+
colString = re.sub(r"\b%s\b" % column, _, colString)
139+
131140
entriesCount = 0
132141

133142
if any(isTechniqueAvailable(_) for _ in (PAYLOAD.TECHNIQUE.UNION, PAYLOAD.TECHNIQUE.ERROR, PAYLOAD.TECHNIQUE.QUERY)) or conf.direct:
@@ -190,7 +199,7 @@ def dumpTable(self, foundData=None):
190199
if not kb.data.dumpedTable and isInferenceAvailable() and not conf.direct:
191200
infoMsg = "fetching number of "
192201
if conf.col:
193-
infoMsg += "column(s) '%s' " % colString
202+
infoMsg += "column(s) '%s' " % colNames
194203
infoMsg += "entries for table '%s' " % unsafeSQLIdentificatorNaming(tbl)
195204
infoMsg += "in database '%s'" % unsafeSQLIdentificatorNaming(conf.db)
196205
logger.info(infoMsg)
@@ -224,7 +233,7 @@ def dumpTable(self, foundData=None):
224233
elif not isNumPosStrValue(count):
225234
warnMsg = "unable to retrieve the number of "
226235
if conf.col:
227-
warnMsg += "column(s) '%s' " % colString
236+
warnMsg += "column(s) '%s' " % colNames
228237
warnMsg += "entries for table '%s' " % unsafeSQLIdentificatorNaming(tbl)
229238
warnMsg += "in database '%s'" % unsafeSQLIdentificatorNaming(conf.db)
230239
logger.warn(warnMsg)
@@ -269,16 +278,16 @@ def dumpTable(self, foundData=None):
269278
entries[column] = BigArray()
270279

271280
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL):
272-
query = rootQuery.blind.query % (column, conf.db, conf.tbl, sorted(colList, key=len)[0], index)
281+
query = rootQuery.blind.query % (agent.preprocessField(tbl, column), conf.db, conf.tbl, sorted(colList, key=len)[0], index)
273282
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2):
274-
query = rootQuery.blind.query % (column, column,
283+
query = rootQuery.blind.query % (agent.preprocessField(tbl, column),
275284
tbl.upper() if not conf.db else ("%s.%s" % (conf.db.upper(), tbl.upper())),
276285
index)
277286
elif Backend.isDbms(DBMS.SQLITE):
278-
query = rootQuery.blind.query % (column, tbl, index)
287+
query = rootQuery.blind.query % (agent.preprocessField(tbl, column), tbl, index)
279288

280289
elif Backend.isDbms(DBMS.FIREBIRD):
281-
query = rootQuery.blind.query % (index, column, tbl)
290+
query = rootQuery.blind.query % (index, agent.preprocessField(tbl, column), tbl)
282291

283292
value = NULL if column in emptyColumns else inject.getValue(query, union=False, error=False, dump=True)
284293
value = '' if value is None else value
@@ -302,7 +311,7 @@ def dumpTable(self, foundData=None):
302311
if len(kb.data.dumpedTable) == 0 or (entriesCount == 0 and kb.permissionFlag):
303312
warnMsg = "unable to retrieve the entries "
304313
if conf.col:
305-
warnMsg += "of columns '%s' " % colString
314+
warnMsg += "of columns '%s' " % colNames
306315
warnMsg += "for table '%s' " % unsafeSQLIdentificatorNaming(tbl)
307316
warnMsg += "in database '%s'%s" % (unsafeSQLIdentificatorNaming(conf.db), " (permission denied)" if kb.permissionFlag else "")
308317
logger.warn(warnMsg)

xml/queries.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@
274274
</columns>
275275
<dump_table>
276276
<inband query="SELECT %s FROM %s"/>
277-
<blind query="SELECT %s FROM (SELECT %s,ROWNUM AS LIMIT FROM %s) WHERE LIMIT=%d" count="SELECT COUNT(*) FROM %s"/>
277+
<blind query="SELECT ENTRY_VALUE FROM (SELECT %s AS ENTRY_VALUE,ROWNUM AS LIMIT FROM %s) WHERE LIMIT=%d" count="SELECT COUNT(*) FROM %s"/>
278278
</dump_table>
279279
<!-- NOTE: in Oracle schema names are the counterpart to database names on other DBMSes -->
280280
<search_db>
@@ -608,7 +608,7 @@
608608
</columns>
609609
<dump_table>
610610
<inband query="SELECT %s FROM %s"/>
611-
<blind query="SELECT %s FROM (SELECT ROW_NUMBER() OVER () AS LIMIT,%s FROM %s) AS foobar WHERE LIMIT=%d" count="SELECT COUNT(*) FROM %s"/>
611+
<blind query="SELECT ENTRY_VALUE FROM (SELECT ROW_NUMBER() OVER () AS LIMIT,%s AS ENTRY_VALUE FROM %s) AS foobar WHERE LIMIT=%d" count="SELECT COUNT(*) FROM %s"/>
612612
</dump_table>
613613
<search_db>
614614
<inband query="SELECT schemaname FROM syscat.schemata WHERE " condition="schemaname"/>

0 commit comments

Comments
 (0)