Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BUG/ISSUE : DLL Hijacking Vulnerability in Unyo v0.6.7 | Responsible Disclosure #58

Open
riftsandroses opened this issue Jan 1, 2025 · 3 comments

Comments

@riftsandroses
Copy link

riftsandroses commented Jan 1, 2025

Description
I have discovered a DLL Hijacking vulnerability in Unyo v.0.6.7 running on Windows 10 Pro 2H22.

The application searches for the following DLLs during runtime but fails to locate them:

  • DWriteCore.dll
  • vulkan-1.dll

Since the application does not verify the integrity of these DLLs before loading, an attacker can craft malicious DLLs with these names. When Unyo is launched, the malicious DLLs can be executed, potentially allowing arbitrary code execution.


Environment

  • Application Version: Unyo v0.6.7
  • Operating System: Windows 10 Pro 2H22

Steps to Reproduce

  1. Identify the missing DLLs by monitoring the application's runtime behavior (e.g., using Process Monitor).
  2. Craft malicious DLLs with the same names as the missing DLLs (DWriteCore.dll or vulkan-1.dll).
  3. Place the malicious DLLs in a directory within the application’s search path (C:\Users<username>\AppData\Local\Microsoft\WindowsApps).
  4. Launch Unyo and observe that the malicious DLLs are loaded and executed.

Impact
Successful exploitation allows an attacker to execute arbitrary code in the context of the application, potentially leading to:

  • Remote code execution
  • System compromise
  • Further attacks depending on the privileges of the application

Expected Behavior
The application should verify the integrity of DLLs before loading them (e.g., by using digital signatures or specifying absolute paths).

@K3vinb5
Copy link
Owner

K3vinb5 commented Jan 2, 2025

Hi, will look into it :(. I honestly haven't being making updates but this seems serious enough for me to do some research and release a fix, I can't guarantee I will be able to do so fast since it's been a while since I've done some progress due to lack of time and the state of my personal life right now, worst case scenario I'll put a warning on the readme and on launching the app warning people.

Really appreciate the issue man, thank u, and if you have any tips on how I could tackle this or know other flutter apps that have solved this issue please let me know.

Best regards, Kevin Borges.

@riftsandroses
Copy link
Author

Take your time buddy, since you have to ensure that fixing this issue does not introduce any new vulnerabilities haha. I hope your personal life gets sorted out enough for you to find time to dedicate to this project since we really appreciate the work that you have put into it.

I don't know a lot about Flutter apps but from what I have gathered, in Flutter the direct control over which DLLs are loaded is limited, as most of the lower-level system operations are managed by the underlying engine (written in C++). However, you can prevent certain libraries from being loaded by disabling specific backends or by modifying the native Windows code generated by Flutter.

Here's how you can ensure DWriteCore.dll and vulkan-1.dll are not loaded:


1. Modify flutter_windows.cpp

The flutter_windows.cpp file is part of the generated Windows Flutter runner. You can customize it to avoid loading Vulkan or DirectWriteCore-related features.

  • Locate the File:
    This file is generated in your project directory:
    windows\runner\flutter_windows.cpp

  • Modify the Code:
    Add conditions to ensure specific backends or DLLs are excluded. For Vulkan, explicitly disable it as a rendering backend.

#include <flutter/flutter_view_controller.h>
#include <flutter/plugin_registry.h>
#include <windows.h>

// Prevent loading unwanted DLLs.
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {
  if (fdwReason == DLL_PROCESS_ATTACH) {
    // Block loading specific DLLs.
    if (GetModuleHandle(L"DWriteCore.dll") || GetModuleHandle(L"vulkan-1.dll")) {
      MessageBox(NULL, L"Blocked untrusted DLLs from loading.", L"Security Warning", MB_OK | MB_ICONERROR);
      ExitProcess(1);
    }
  }
  return TRUE;
}

int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE prev, wchar_t* command_line, int show_command) {
  // Disable Vulkan explicitly by setting the backend to OpenGL or DirectX.
  flutter::DartProject project(L"data");
  project.SetArgument("--disable-vulkan");

  flutter::FlutterViewController controller(800, 600, project);

  HWND window_handle = controller.GetNativeWindow();

  // Customize window properties here if needed.

  MSG msg;
  while (GetMessage(&msg, nullptr, 0, 0)) {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
  }

  return 0;
}

2. Add Command-Line Arguments in Dart

Flutter provides the ability to pass arguments to the engine during initialization. You can disable Vulkan or DirectWriteCore features.

  • Add the following code in your main.dart:
void main() {
  WidgetsFlutterBinding.ensureInitialized();

  // Pass arguments to the Flutter engine.
  DartPluginRegistrant.ensureInitialized();
  PlatformDispatcher.instance.onPlatformMessage = (name, data, callback) {
    if (name == 'flutter/settings') {
      const disableVulkan = ['--disable-vulkan'];
      data = utf8.encode(jsonEncode({'args': disableVulkan}));
    }
    return PlatformDispatcher.instance.defaultBinaryMessenger.handlePlatformMessage(name, data, callback);
  };

  runApp(MyApp());
}

3. Use Safe DLL Loading Practices

Ensure your app doesn't load DLLs from untrusted paths by enabling safe DLL search mode globally.

import 'dart:ffi';
import 'dart:io';

void main() {
  if (Platform.isWindows) {
    final kernel32 = DynamicLibrary.open("kernel32.dll");
    final setDllDirectory = kernel32.lookupFunction<
        Int32 Function(Pointer<Utf16>),
        int Function(Pointer<Utf16>)>("SetDllDirectoryW");

    // Set an empty DLL search path.
    final result = setDllDirectory(nullptr.cast());
    if (result == 0) {
      print("Failed to set safe DLL search mode.");
    }
  }

  runApp(MyApp());
}

4. Rebuild the Project

After making these changes, clean and rebuild your project:

flutter clean
flutter build windows

Apart from this you might have to do some research at your end as well to figure out how to implement them in this application. Take care!

@K3vinb5
Copy link
Owner

K3vinb5 commented Jan 13, 2025

Hi, not a lot of progress but I looked into it once, once I have more updates I'll let you know, I will add this to known issues though

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants