Skip to content

Commit 12d33c7

Browse files
committed
Fix for Issue sqlmapproject#180 and sqlmapproject#181 (missing module from an Issue sqlmapproject#179)
1 parent 959225a commit 12d33c7

File tree

1 file changed

+148
-0
lines changed

1 file changed

+148
-0
lines changed

lib/utils/pivotdumptable.py

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
#!/usr/bin/env python
2+
3+
"""
4+
Copyright (c) 2006-2012 sqlmap developers (http://sqlmap.org/)
5+
See the file 'doc/COPYING' for copying permission
6+
"""
7+
8+
from extra.safe2bin.safe2bin import safechardecode
9+
from lib.core.bigarray import BigArray
10+
from lib.core.common import Backend
11+
from lib.core.common import decodeIntToUnicode
12+
from lib.core.common import isNoneValue
13+
from lib.core.common import isNumPosStrValue
14+
from lib.core.common import singleTimeWarnMessage
15+
from lib.core.common import unArrayizeValue
16+
from lib.core.common import unsafeSQLIdentificatorNaming
17+
from lib.core.data import conf
18+
from lib.core.data import logger
19+
from lib.core.data import queries
20+
from lib.core.enums import CHARSET_TYPE
21+
from lib.core.enums import EXPECTED
22+
from lib.core.exception import sqlmapConnectionException
23+
from lib.core.exception import sqlmapNoneDataException
24+
from lib.core.settings import MAX_INT
25+
from lib.request import inject
26+
27+
def pivotDumpTable(table, colList, count=None, blind=True):
28+
lengths = {}
29+
entries = {}
30+
31+
dumpNode = queries[Backend.getIdentifiedDbms()].dump_table.blind
32+
33+
validColumnList = False
34+
validPivotValue = False
35+
36+
if count is None:
37+
query = dumpNode.count % table
38+
count = inject.getValue(query, inband=False, error=False, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS) if blind else inject.getValue(query, blind=False, expected=EXPECTED.INT)
39+
40+
if isinstance(count, basestring) and count.isdigit():
41+
count = int(count)
42+
43+
if count == 0:
44+
infoMsg = "table '%s' appears to be empty" % unsafeSQLIdentificatorNaming(table)
45+
logger.info(infoMsg)
46+
47+
for column in colList:
48+
lengths[column] = len(column)
49+
entries[column] = []
50+
51+
return entries, lengths
52+
53+
elif not isNumPosStrValue(count):
54+
return None
55+
56+
for column in colList:
57+
lengths[column] = 0
58+
entries[column] = BigArray()
59+
60+
colList = filter(None, sorted(colList, key=lambda x: len(x) if x else MAX_INT))
61+
62+
for column in colList:
63+
infoMsg = "fetching number of distinct "
64+
infoMsg += "values for column '%s'" % column
65+
logger.info(infoMsg)
66+
67+
query = dumpNode.count2 % (column, table)
68+
value = inject.getValue(query, blind=blind, inband=not blind, error=not blind, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS)
69+
70+
if isNumPosStrValue(value):
71+
validColumnList = True
72+
73+
if value == count:
74+
infoMsg = "using column '%s' as a pivot " % column
75+
infoMsg += "for retrieving row data"
76+
logger.info(infoMsg)
77+
78+
validPivotValue = True
79+
80+
colList.remove(column)
81+
colList.insert(0, column)
82+
break
83+
84+
if not validColumnList:
85+
errMsg = "all column name(s) provided are non-existent"
86+
raise sqlmapNoneDataException, errMsg
87+
88+
if not validPivotValue:
89+
warnMsg = "no proper pivot column provided (with unique values)."
90+
warnMsg += " It won't be possible to retrieve all rows"
91+
logger.warn(warnMsg)
92+
93+
pivotValue = " "
94+
breakRetrieval = False
95+
96+
try:
97+
for i in xrange(count):
98+
if breakRetrieval:
99+
break
100+
101+
for column in colList:
102+
# Correction for pivotValues with unrecognized/problematic chars
103+
for char in ('\'', '?'):
104+
if pivotValue and char in pivotValue and pivotValue[0] != char:
105+
pivotValue = pivotValue.split(char)[0]
106+
pivotValue = pivotValue[:-1] + decodeIntToUnicode(ord(pivotValue[-1]) + 1)
107+
break
108+
if column == colList[0]:
109+
query = dumpNode.query % (column, table, column, pivotValue)
110+
else:
111+
query = dumpNode.query2 % (column, table, colList[0], pivotValue)
112+
113+
value = inject.getValue(query, blind=blind, inband=not blind, error=not blind)
114+
115+
if column == colList[0]:
116+
if isNoneValue(value):
117+
breakRetrieval = True
118+
break
119+
else:
120+
pivotValue = safechardecode(value)
121+
122+
if conf.limitStart or conf.limitStop:
123+
if conf.limitStart and (i + 1) < conf.limitStart:
124+
warnMsg = "skipping first %d pivot " % conf.limitStart
125+
warnMsg += "point values"
126+
singleTimeWarnMessage(warnMsg)
127+
break
128+
elif conf.limitStop and (i + 1) > conf.limitStop:
129+
breakRetrieval = True
130+
break
131+
132+
value = "" if isNoneValue(value) else unArrayizeValue(value)
133+
134+
lengths[column] = max(lengths[column], len(value) if value else 0)
135+
entries[column].append(value)
136+
137+
except KeyboardInterrupt:
138+
warnMsg = "user aborted during enumeration. sqlmap "
139+
warnMsg += "will display partial output"
140+
logger.warn(warnMsg)
141+
142+
except sqlmapConnectionException, e:
143+
errMsg = "connection exception detected. sqlmap "
144+
errMsg += "will display partial output"
145+
errMsg += "'%s'" % e
146+
logger.critical(errMsg)
147+
148+
return entries, lengths

0 commit comments

Comments
 (0)