HEX
Server: Apache
System: Linux 244.240.109.208.host.secureserver.net 5.14.0-611.11.1.el9_7.x86_64 #1 SMP PREEMPT_DYNAMIC Wed Dec 3 09:47:37 EST 2025 x86_64
User: icsla (1002)
PHP: 8.1.34
Disabled: NONE
Upload Files
File: /home/icsla/public_html/wp-content/plugins/chatbot/includes/class-wpbot-gc-download.php
<?php
if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

class WPBotGCDownload
{
    private $download_url = 'https://github.com/qcloud/gc/raw/master/wpbotgc.zip';
    private $filename = 'wpbotgc.zip';

    public function __construct() {
        add_action( 'wp_ajax_qcld_wp_chatbot_gc_client_download', array( $this, 'downloadgc' ) );
        add_action( 'wp_ajax_qcld_wp_chatbot_gc_client_extract',  array( $this, 'extractgc' ) );
    }

    /**
     * Initialise WP_Filesystem and return the global instance.
     */
    private function get_filesystem() {
        global $wp_filesystem;
        if ( empty( $wp_filesystem ) ) {
            require_once ABSPATH . 'wp-admin/includes/file.php';
            WP_Filesystem();
        }
        return $wp_filesystem;
    }

    /**
     * Create a directory using WP_Filesystem.
     */
    public function create_folder( $gcdirectory ) {
        $fs = $this->get_filesystem();
        if ( ! $fs->is_dir( $gcdirectory ) ) {
            return $fs->mkdir( $gcdirectory, FS_CHMOD_DIR );
        }
        return true;
    }

    /**
     * Create a blank index.php guard file using WP_Filesystem.
     */
    public function create_file( $filename ) {
        $fs = $this->get_filesystem();
        if ( $fs->exists( $filename ) ) {
            return true;
        }
        return $fs->put_contents( $filename, '<?php //silence is golden', FS_CHMOD_FILE );
    }

    public function downloadgc() {
        if ( ! current_user_can( 'manage_options' ) ) {
            wp_send_json( array( 'success' => false, 'msg' => esc_html__( 'Unauthorized access', 'chatbot' ) ) );
            wp_die();
        }

        $nonce = sanitize_text_field( wp_unslash( $_POST['nonce'] ?? '' ) );
        if ( ! wp_verify_nonce( $nonce, 'wp_chatbot' ) ) {
            wp_send_json( array( 'success' => false, 'msg' => esc_html__( 'Failed in Security check', 'chatbot' ) ) );
            wp_die();
        }

        $fs           = $this->get_filesystem();
        $gcdirectory  = QCLD_wpCHATBOT_GC_DIRNAME;

        if ( ! $fs->is_dir( $gcdirectory ) ) {
            $this->create_folder( $gcdirectory );
        }

        if ( ! $fs->exists( $gcdirectory . '/index.php' ) ) {
            $this->create_file( $gcdirectory . '/index.php' );
        }

        if ( ! $fs->is_dir( $gcdirectory ) ) {
            wp_send_json( array( 'status' => 'error', 'content' => esc_html__( 'Server does not allow creating files and folders.', 'chatbot' ) ) );
            wp_die();
        }

        $zip_file = $gcdirectory . '/' . $this->filename;

        $remote_response = wp_remote_get( $this->download_url, array(
            'timeout'  => 60,
            'stream'   => true,
            'filename' => $zip_file,
        ) );

        if ( is_wp_error( $remote_response ) ) {
            wp_send_json( array( 'status' => 'error', 'content' => esc_html( $remote_response->get_error_message() ) ) );
            wp_die();
        }

        $http_code = wp_remote_retrieve_response_code( $remote_response );
        if ( 200 !== $http_code ) {
            wp_send_json( array( 'status' => 'error', 'content' => esc_html__( 'Remote server returned an unexpected response.', 'chatbot' ) ) );
            wp_die();
        }

        wp_send_json( array( 'status' => 'success', 'content' => esc_html__( 'File downloaded successfully.', 'chatbot' ) ) );
        wp_die();
    }

    public function extractgc() {
        if ( ! current_user_can( 'manage_options' ) ) {
            wp_send_json( array( 'success' => false, 'msg' => esc_html__( 'Unauthorized access', 'chatbot' ) ) );
            wp_die();
        }

        $nonce = sanitize_text_field( wp_unslash( $_POST['nonce'] ?? '' ) );
        if ( ! wp_verify_nonce( $nonce, 'wp_chatbot' ) ) {
            wp_send_json( array( 'success' => false, 'msg' => esc_html__( 'Failed in Security check', 'chatbot' ) ) );
            wp_die();
        }

        $fs          = $this->get_filesystem();
        $gcdirectory = QCLD_wpCHATBOT_GC_DIRNAME;
        $gcfilename  = $gcdirectory . '/' . $this->filename;

        // Verify the zip exists before attempting to open it.
        if ( ! $fs->exists( $gcfilename ) ) {
            wp_send_json( array( 'status' => 'error', 'content' => esc_html__( 'File not found.', 'chatbot' ) ) );
            wp_die();
        }

        $zip = new ZipArchive();
        if ( true !== $zip->open( $gcfilename ) ) {
            wp_send_json( array( 'status' => 'error', 'content' => esc_html__( 'Could not open zip archive.', 'chatbot' ) ) );
            wp_die();
        }

        // Validate every entry: block path traversal and absolute paths.
        $real_dest = realpath( $gcdirectory );
        for ( $i = 0; $i < $zip->numFiles; $i++ ) {
            $stat     = $zip->statIndex( $i );
            $entry    = $stat['name'];

            if (
                strpos( $entry, '../' ) !== false ||
                strpos( $entry, '..' . DIRECTORY_SEPARATOR ) !== false ||
                '/' === substr( $entry, 0, 1 )
            ) {
                $zip->close();
                $fs->delete( $gcfilename );
                wp_send_json( array( 'status' => 'error', 'content' => esc_html__( 'Invalid zip structure — path traversal detected.', 'chatbot' ) ) );
                wp_die();
            }

            // Ensure resolved path stays within the destination directory.
            $resolved = realpath( $real_dest . DIRECTORY_SEPARATOR . $entry );
            if ( $resolved !== false && strpos( $resolved, $real_dest ) !== 0 ) {
                $zip->close();
                $fs->delete( $gcfilename );
                wp_send_json( array( 'status' => 'error', 'content' => esc_html__( 'Invalid zip structure — entry escapes destination.', 'chatbot' ) ) );
                wp_die();
            }
        }

        $zip->extractTo( $gcdirectory );
        $zip->close();

        // Remove the zip after successful extraction.
        $fs->delete( $gcfilename );

        wp_send_json( array( 'status' => 'success', 'content' => esc_html__( 'Files extracted successfully.', 'chatbot' ) ) );
        wp_die();
    }
}

new WPBotGCDownload();