Executing Shellcode In C#

2 minute read

This was a topic that was brought up on Tuts4You here:

https://forum.tuts4you.com/topic/39503-getting-peb-in-c/

I Google’d around and could not find a single instance of doing this in C# within the parameters given by the poster so I took to some ideas in mind of how I could allocate memory without any imports.

Some ideas that came to mind were:

  • Marshal.AllocHGlobal
  • Marshal.AllocCoTaskMem
  • MemoryStream

Sadly, all three of these options only allocate the memory that have protection flags of PAGE_READ and PAGE_WRITE with no ability to execute.

Next, I thought of memory mapped files, these are a way to share memory between processes. This API allows you to specify the access type of the file, including execution permissions. C# has this built-in via the ‘System.IO.MemoryMappedFiles’ namespace within the System.Core.dll module.

Using this namespace, we can create a mapped file in memory, write our shellcode to it, create a function delegate to the function and invoke it. Here’s an example of doing this, getting the PEB of the process (32bit):

/**
 * C# Shellcode Example
 * (c) 2017 atom0s [atom0s@live.com]
 *
 * Demonstrates how to invoke shellcode within C# using a memory mapped file.
 */
 
namespace ShellcodeExample
{
    using System;
    using System.IO.MemoryMappedFiles;
    using System.Runtime.InteropServices;
 
    class Program
    {
        /// <summary>
        /// Function delegate to invoke the shellcode.
        /// </summary>
        /// <returns></returns>
        private delegate IntPtr GetPebDelegate();
 
        /// <summary>
        /// Shellcode function used to obtain the PEB of the process.
        /// </summary>
        /// <returns></returns>
        private unsafe static IntPtr GetPeb()
        {
            var shellcode = new byte[]
                {
                    0x64, 0xA1, 0x30, 0x00, 0x00, 0x00,         // mov eax, dword ptr fs:[30]
                    0xC3                                        // ret
                };
 
            MemoryMappedFile mmf = null;
            MemoryMappedViewAccessor mmva = null;
 
            try
            {
                // Create a read/write/executable memory mapped file to hold our shellcode..
                mmf = MemoryMappedFile.CreateNew("__shellcode", shellcode.Length, MemoryMappedFileAccess.ReadWriteExecute);
 
                // Create a memory mapped view accessor with read/write/execute permissions..
                mmva = mmf.CreateViewAccessor(0, shellcode.Length, MemoryMappedFileAccess.ReadWriteExecute);
 
                // Write the shellcode to the MMF..
                mmva.WriteArray(0, shellcode, 0, shellcode.Length);
 
                // Obtain a pointer to our MMF..
                var pointer = (byte*)0;
                mmva.SafeMemoryMappedViewHandle.AcquirePointer(ref pointer);
 
                // Create a function delegate to the shellcode in our MMF..
                var func = (GetPebDelegate)Marshal.GetDelegateForFunctionPointer(new IntPtr(pointer), typeof(GetPebDelegate));
 
                // Invoke the shellcode..
                return func();
            }
            catch
            {
                return IntPtr.Zero;
            }
            finally
            {
                mmva?.Dispose();
                mmf?.Dispose();
            }
        }
 
        /// <summary>
        /// Entry point.
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {
            var peb = GetPeb();
            Console.WriteLine("PEB is located at: {0:X8}", peb.ToInt32());
        }
    }
}

Comments