Exetools

Exetools (https://forum.exetools.com/index.php)
-   General Discussion (https://forum.exetools.com/forumdisplay.php?f=2)
-   -   Patch in memory .net app (https://forum.exetools.com/showthread.php?t=18830)

taos 07-03-2018 19:00

Patch in memory .net app
 
Hi, I have an obfuscated .net app. This app use WMI (Select * From Win32_processor) to get motherboard serial numer and CPUID. I don't want to patch directly EXE (it has several checks to avoid this) so I got 2 vectors of attack:

a) Patch WMI to return always the same values in different hardware

Anyone has info about this?

b) Patch in memory using a loader for .net

Anyone has info too?
(I have seen how to hook functions but it always make changes at EXE so is not valid for me)

Thanks

user1 07-03-2018 20:49

you mean in ring0 kernel driver that replace data in OS and give what you need? in x64 need WQHL signature for last 10, rest test mode need be used.
was done, not remember name. but some guru's here can maybe show us how to clone entire PC hardware iD?
anyone alive from real guru's @ here?

cachito 07-03-2018 23:31

This one seems to be the solution to your case
https://forum.exetools.com/showthread.php?t=14432

taos 07-04-2018 01:28

Quote:

Originally Posted by cachito (Post 113858)
This one seems to be the solution to your case
https://forum.exetools.com/showthread.php?t=14432

Not working in W10 64bits.

ketan 07-04-2018 06:19

In the end it calls NtQuerySystemInformation

So you can hook it any way you like and filter data returned as desired.

SinaDiR 07-04-2018 08:03

What about dll proxy(dll hijacking) instead of loader ?

TechLord 07-04-2018 08:49

Quote:

Originally Posted by taos (Post 113854)
Hi, I have an obfuscated .net app. This app use WMI (Select * From Win32_processor) to get motherboard serial numer and CPUID. I don't want to patch directly EXE (it has several checks to avoid this) so I got 2 vectors of attack:

a) Patch WMI to return always the same values in different hardware

Anyone has info about this?

b) Patch in memory using a loader for .net

Anyone has info too?
(I have seen how to hook functions but it always make changes at EXE so is not valid for me)

Thanks

Sounds interesting :D
Please share the target with me (PM is fine if its a private one).

You can join the SLACK channel while you are at it (invite attached there), as this could be done much faster by CHAT than by sending out a PM, waiting for a day and then replying etc.

Anyways, just share the target first :)

Cheers

cachito 07-04-2018 11:34

I made this loader/debugger long ago for a simple target, but never finished it. It worked for native x64 targets. I don't know if setting 0x01 (bp il opcode) will fire up the ExceptionCode.STATUS_BREAKPOINT. I tried to follow here https://github.com/dotnet/coreclr/blob/master/src/vm/excep.cpp but I am a very bad coder...


Code:

using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
using Microsoft.Samples.Debugging.Native;

namespace Test2
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }


        #region WinNT Definitions
        private const uint CONTEXT_FULL = 0x10007;
        private const ushort IMAGE_DOS_SIGNATURE = 0x5A4D; // MZ
        private const uint IMAGE_NT_SIGNATURE = 0x00004550; // PE00

        private static short SW_SHOWNORMAL = 1;
        private const uint STARTF_USESTDHANDLES = 0x00000100;
        private const uint STARTF_USESHOWWINDOW = 0x00000001;
        private CreateProcessFlags flags;
        #endregion

        private void button1_Click(object sender, EventArgs e)
        {
            // PART 1 !!!!!
            STARTUPINFO si = new STARTUPINFO();
            si.cb = Marshal.SizeOf(si);

            flags = CreateProcessFlags.DEBUG_ONLY_THIS_PROCESS | CreateProcessFlags.CREATE_SUSPENDED;

            PROCESS_INFORMATION pi = new PROCESS_INFORMATION();
            CreateProcess(@"test.exe", null, IntPtr.Zero, IntPtr.Zero, false, flags, IntPtr.Zero, null, si, pi);

            // Taken from Kao's solution in part 1 :)

            PROCESS_BASIC_INFORMATION pbi = new PROCESS_BASIC_INFORMATION();
            int d;
            NtQueryInformationProcess(pi.hProcess, 0, ref pbi, Marshal.SizeOf(pbi), out d);

            byte[] dummy2 = new byte[8];
            int dummy;
            // in 64bit OS, main module imagebase is at PEB+0x10
            ReadProcessMemory(pi.hProcess, new IntPtr((Int64)pbi.PebBaseAddress + 0x10), dummy2, (UIntPtr)8, out dummy);
            Int64 realImageBase = BitConverter.ToInt64(dummy2, 0);

            textBox1.Text = realImageBase.ToString("X2");

            // STARTUPINFO
            STARTUPINFO StartupInfo = new STARTUPINFO();
            StartupInfo.dwFlags = (int)(STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW);
            StartupInfo.wShowWindow = SW_SHOWNORMAL;

            /*var IMAGE_SECTION_HEADER = new byte[0x28]; // pish
            var IMAGE_NT_HEADERS = new byte[0xf8]; // pinh
            var IMAGE_DOS_HEADER = new byte[0x40]; // pidh
            var PROCESS_INFO = new int[0x4]; // pi

            byte* pish;
            fixed (byte* p = &IMAGE_SECTION_HEADER[0]) pish = p;

            byte* pinh;
            fixed (byte* p = &IMAGE_NT_HEADERS[0]) pinh = p;

            byte* pidh;
            fixed (byte* p = &IMAGE_DOS_HEADER[0]) pidh = p;

            // Get the DOS header of the EXE.
            ReadProcessMemory(pi.hProcess, new IntPtr(realImageBase), IMAGE_DOS_HEADER, (UIntPtr)IMAGE_DOS_HEADER.Length, out dummy);

            // Sanity check:  See if we have MZ header.
            if (*(ushort*)(pidh + 0x0) != IMAGE_DOS_SIGNATURE)
                MessageBox.Show("Bad MZ header");

            var e_lfanew = *(int*)(pidh + 0x3c);

            textBox2.Text = e_lfanew.ToString("X2");

            // Get the NT header of the EXE.
            ReadProcessMemory(pi.hProcess, new IntPtr(realImageBase + e_lfanew), IMAGE_NT_HEADERS, (UIntPtr)IMAGE_NT_HEADERS.Length, out dummy);

            // Sanity check: See if we have PE00 header.
            if (*(uint*)(pinh + 0x0) != IMAGE_NT_SIGNATURE)
                MessageBox.Show("Bad PE00 header");

            var AddressOfEntryPoint = *(int*)(pinh + 0x28);

            textBox3.Text = AddressOfEntryPoint.ToString("X2");

            byte[] OEPData = new byte[9];
            ReadProcessMemory(pi.hProcess, new IntPtr(realImageBase + AddressOfEntryPoint), OEPData, (UIntPtr)9, out dummy);

            textBox4.Text = BitConverter.ToString(OEPData).Replace("-", "");*/

            // PART 2 !!!!!

            var buffer = new byte[1] { 0xCC };
            var origIN_OUT = new byte[1] { 0x48 };
            var dummy4 = new UIntPtr();
            byte[] buffer2 = new byte[5];

            WriteProcessMemory(pi.hProcess, new IntPtr(realImageBase + 0x1B1AA4), buffer, (UIntPtr)1, out dummy4);
            WriteProcessMemory(pi.hProcess, new IntPtr(realImageBase + 0x1B1AA9), buffer, (UIntPtr)1, out dummy4);

            ContinueStatus dwContinueStatus = ContinueStatus.DBG_CONTINUE;
            DebugEvent64 event64 = new DebugEvent64();

            ResumeThread(pi.hThread);

            bool continuar = true;
            while (continuar)
            {
                if (!WaitForDebugEvent64(ref event64, -1))
                {
                    MessageBox.Show("Debug loop aborted");
                    return;
                }

                switch (event64.header.dwDebugEventCode)
                {
                    case NativeDebugEventCode.EXIT_PROCESS_DEBUG_EVENT:
                        CloseHandle(pi.hThread);
                        CloseHandle(pi.hProcess);
                        return;

                    case NativeDebugEventCode.EXCEPTION_DEBUG_EVENT:
                        {
                            EXCEPTION_DEBUG_INFO exception = event64.union.Exception;

                            switch (exception.ExceptionRecord.ExceptionCode)
                            {
                                case ExceptionCode.STATUS_BREAKPOINT:
                                    {
                                        SuspendThread(pi.hThread); // Always suspend target before getting context or you will get bad data

                                        CONTEXT64 context = new CONTEXT64(); // Create a new Context64 struct.
                                        context.ContextFlags = ContextFlags.AMD64ContextAll;

                                        if (!GetThreadContext(pi.hThread, ref context)) // Read thread context
                                            MessageBox.Show("There was a problem getting context");

                                        if (context.Rip == (ulong)(realImageBase + 0x1B1AA4 + 1)) // Compare in BP
                                        {
                                            context.Rip -= 1; // Change EIP to -1
                                            if (!SetThreadContext(pi.hThread, ref context)) // Update changed context
                                                MessageBox.Show("There was a problem setting context");

                                            // Do the stuff
                                            MessageBox.Show("Message box open");

                                            WriteProcessMemory(pi.hProcess, new IntPtr(realImageBase + 0x1B1AA4), origIN_OUT, (UIntPtr)1, out dummy4); // Set original bytes to resume process

                                        }
                                        if (context.Rip == (ulong)(realImageBase + 0x1B1AA9 + 1)) // Compare out BP
                                        {
                                            context.Rip -= 1; // Change EIP to -1
                                            if (!SetThreadContext(pi.hThread, ref context)) // Update changed context
                                                MessageBox.Show("There was a problem setting context");

                                            // Do the stuff
                                            MessageBox.Show("Message box closed");

                                            WriteProcessMemory(pi.hProcess, new IntPtr(realImageBase + 0x1B1AA9), origIN_OUT, (UIntPtr)1, out dummy4); // Set original bytes to resume process
                                        }

                                        ResumeThread(pi.hThread); // Resume target

                                        await Task.Delay(200); // Small delay before putting BPs back or they might get hit more than once
                                        break;
                                    }

                                default:
                                    {
                                        dwContinueStatus = ContinueStatus.DBG_EXCEPTION_NOT_HANDLED;
                                        break;
                                    }
                            }
                            break;
                        }

                }
                if (!ContinueDebugEvent(event64.header.dwProcessId, event64.header.dwThreadId, dwContinueStatus))
                    MessageBox.Show("Error continuing debug event");

                // Reset
                dwContinueStatus = ContinueStatus.DBG_CONTINUE;

                // Set BPs again
                WriteProcessMemory(pi.hProcess, new IntPtr(realImageBase + 0x1B1AA4), buffer, (UIntPtr)1, out dummy4);
                WriteProcessMemory(pi.hProcess, new IntPtr(realImageBase + 0x1B1AA9), buffer, (UIntPtr)1, out dummy4);
            }
        }

    }
}


taos 07-04-2018 16:16

Did it! Thanks

Quote:

Originally Posted by TechLord (Post 113865)
Sounds interesting :D
Please share the target with me (PM is fine if its a private one).

You can join the SLACK channel while you are at it (invite attached there), as this could be done much faster by CHAT than by sending out a PM, waiting for a day and then replying etc.

Anyways, just share the target first :)

Cheers


TechLord 07-04-2018 17:27

Quote:

Originally Posted by taos (Post 113876)
Did it! Thanks

Great ! That's what counts :D

Shub-Nigurrath 07-04-2018 19:42

among the ARTEam tutorials there was one where we did a .net loader.

cachito 07-05-2018 01:06

@Shub-Nigurrath
Can you provide the link?
I downloaded all the tutorials with the word "loader" in the title but it wasn't any of them.
Or maybe if you remember the target title it will be easier for searching.
Thanks!

Kurapica 07-05-2018 01:39

another try from the far past : .

https://board.b-at-s.info/index.php?app=blog&module=display&section=blog&blogid=5&showentry=7


All times are GMT +8. The time now is 01:30.

Powered by vBulletin® Version 3.8.8
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Always Your Best Friend: Aaron, JMI, ahmadmansoor, ZeNiX