nil0x42/phpsploit

View on GitHub
src/core/session/compat_session.py

Summary

Maintainability
A
1 hr
Test Coverage
"""Backwards compatible session loader.

This module loads a phpsploit session file which
have been generated by old phpsploit versions
which uses different format.

"""
# pylint: disable=no-self-use
# pylint: disable=invalid-name

import copy
import pickle

from core import encoding


def rename_key(dictionnary, old_keyname, new_keyname):
    """If `old_keyname` exists in `dictionnary`, rename
    the key to `new_keyname`

    """
    if old_keyname in dictionnary:
        dictionnary[new_keyname] = dictionnary.pop(old_keyname)


def remove_key(dictionnary, keyname):
    """Remove `keyname` from `dictionnary` if it exists.

    """
    if keyname in dictionnary.keys():
        del dictionnary[keyname]


# pylint: disable=too-few-public-methods
class AbstractSessionLoader:
    """Abstract class for loading session files
    which have been generated by a deprecated
    phpsploit framework version.

    """
    # empty raw session template (const)
    _template = {"Conf": {},
                 "Env": {},
                 "Alias": {},
                 "Hist": {},
                 "Compat": {},
                 "File": None
                }

    def __init__(self):
        pass

    def __call__(self, session_path):
        """Get raw session object from `session_path`.
        """
        new_session = copy.deepcopy(self._template)
        session_keys = new_session.keys()
        old_session = self._load_file(session_path)
        for attribute in dir(self):
            if attribute.startswith("set_"):
                target = attribute[4:].capitalize()
                if target not in session_keys:
                    raise ValueError("Invalid attribute: %r" % attribute)
                function = getattr(self, attribute)
                new_session[target] = function(old_session)
        return new_session

    def _load_file(self, session_path):
        """default file loader
        """
        with open(session_path, 'rb') as file:
            return pickle.load(file,
                               encoding=encoding.default_encoding,
                               errors=encoding.default_errors)


class Loader_V2_1_4(AbstractSessionLoader):
    """Load session file from phpsploit <= 2.1.4

    """
    def _load_file(self, session_path):
        """load file & check PSCOREVER"""
        old_session = super()._load_file(session_path)
        if int(old_session["PSCOREVER"]) != 2:
            raise ValueError("PSCOREVER must be 2")
        return old_session

    def set_conf(self, old_session):
        """Conf object setter"""
        result = old_session["SET"]

        # $EDITOR
        rename_key(result, "TEXTEDITOR", "EDITOR")

        # $BROWSER
        rename_key(result, "WEBBROWSER", "BROWSER")

        # $HTTP_USER_AGENT
        if "HTTP_USER_AGENT" in result.keys():
            old_defaults = ["file://misc/http/User-Agent.lst",
                            "file://framework/misc/http_user_agents.lst"]
            if result["HTTP_USER_AGENT"] in old_defaults:
                del result["HTTP_USER_AGENT"]

        # $SAVEFILE
        remove_key(result, "SAVEFILE")

        return result

    def set_env(self, old_session):
        """Env object setter"""
        result = old_session["ENV"]

        rename_key(result, "CWD", "PWD")
        rename_key(result, "WRITE_TMPDIR", "WRITEABLE_TMPDIR")
        rename_key(result, "WRITE_WEBDIR", "WRITEABLE_WEBDIR")

        remove_key(result, "TEXTEDITOR")

        # Add some environment variables from old "SRV" object.
        result["ADDR"] = old_session["SRV"]["addr"]
        result["HOME"] = old_session["SRV"]["home"]
        result["HOST"] = old_session["SRV"]["host"]
        result["PHP_VERSION"] = old_session["SRV"]["phpver"]
        result["PATH_SEP"] = old_session["SRV"]["separator"]
        result["HTTP_SOFTWARE"] = old_session["SRV"]["soft"]
        result["USER"] = old_session["SRV"]["user"]
        result["WEB_ROOT"] = old_session["SRV"]["webroot"]
        result["CLIENT_ADDR"] = old_session["SRV"]["client_addr"]

        # $PLATFORM
        result["PLATFORM"] = old_session["SRV"]["os"].split()[0].lower()
        if result["PLATFORM"] in ["unknow", "unknown", ""]:
            if result["PATH_SEP"] == "\\":
                result["PLATFORM"] = "windows"
            else:
                result["PLATFORM"] = "unix"

        return result


def load(session_path):
    """Successively try to load session file
    with the list of compat session loaders.

    The list `compat_loaders` must be sorted starting
    with most recent loader
    """
    compat_loaders = [Loader_V2_1_4()]

    for old_session_load in compat_loaders:
        try:
            return old_session_load(session_path)
        except BaseException:
            pass