Beispiel #1
0
        /////////////////////////////////////////////////////
        //                                                 //
        // DoKernelModeHeuristics()                        //
        //                                                 //
        /////////////////////////////////////////////////////
        //Description:  Communicates with kernel-mode driver
        //              to perform advanced heuristic analysis.
        //              (oooo...aaaahhh)
        //
        //Returns:      true if successful
        //////////////////////////////////////////////////////
        private unsafe bool DoKernelModeHeuristics()
        {
            AgentHeuristicMatches.KernelModeMatches = new CwXML.KernelModeHeuristicMatches();

            AgentScanLog.AppendLine("");
            AgentScanLog.AppendLine("*********************************************");
            AgentScanLog.AppendLine("          KERNEL-MODE HEURISTICS             ");
            AgentScanLog.AppendLine("*********************************************");
            AgentScanLog.AppendLine("");

            //----------------------------------------------
            //
            //                  SSDT HOOKS
            //
            //----------------------------------------------
            #region SSDT HOOKS

            if (AgentSettings["KernelHeuristics_SSDT_DetectHooks"] == "True")
            {
                AgentScanLog.AppendLine("------------------------");
                AgentScanLog.AppendLine("    SSDT HOOKS       ");
                AgentScanLog.AppendLine("------------------------");

                CwStructures.HOOKED_SSDT_TABLE HookTable = new CwStructures.HOOKED_SSDT_TABLE();

                try
                {
                    HookTable = HeuristicsKernelModeHelper.GetSSDTHooks();
                }
                catch (Exception ex)
                {
                    AgentScanLog.AppendLine("SCAN:  Error checking for SSDT hooks:  " + ex.Message);
                }

                //save the hook table to return object.
                AgentHeuristicMatches.KernelModeMatches.SSDTHookTable = HookTable;
            }
            else
            {
                AgentHeuristicMatches.KernelModeMatches.SSDTHookTable = new CwStructures.HOOKED_SSDT_TABLE();
            }
            #endregion

            //----------------------------------------------
            //
            //                  SSDT DETOURS
            //
            //----------------------------------------------
            #region SSDT DETOURS

            if (AgentSettings["KernelHeuristics_SSDT_DetectDetours"] == "True")
            {
                AgentScanLog.AppendLine("------------------------");
                AgentScanLog.AppendLine("    SSDT DETOURS       ");
                AgentScanLog.AppendLine("------------------------");

                CwStructures.DETOURED_SSDT_TABLE DetourTable = new CwStructures.DETOURED_SSDT_TABLE();

                try
                {
                    DetourTable = HeuristicsKernelModeHelper.GetSSDTDetours();
                }
                catch (Exception ex)
                {
                    AgentScanLog.AppendLine("SCAN:  Error checking for SSDT detours:  " + ex.Message);
                }

                //save the hook table to return object.
                AgentHeuristicMatches.KernelModeMatches.SSDTDetourTable = DetourTable;
            }
            else
            {
                AgentHeuristicMatches.KernelModeMatches.SSDTDetourTable = new CwStructures.DETOURED_SSDT_TABLE();
            }

            #endregion

            //----------------------------------------------
            //
            //                  WIN32 API DETOURS
            //
            //----------------------------------------------
            //
            //TODO:  this functionality is disabled until fixed.
            //
            #region WIN32 API DETOURS
            /*
            if (AgentSettings["KernelHeuristics_Win32Api_CheckExportsForDetours"] == "True")
            {
                AgentScanLog.AppendLine("------------------------");
                AgentScanLog.AppendLine("    WIN32 API DETOURS   ");
                AgentScanLog.AppendLine("------------------------");

                string[] DirtyDlls = new string[] { "ntdll.dll","kernel32.dll","user32.dll","advapi32.dll",
                                                       "gdi32.dll","comdlg32.dll","comctl32.dll","commctrl.dll",
                                                       "shell.dll","shlwapi.dll","mshtml.dll","urlmon.dll"}; //ntdll.dll??

                //initialize return object to 12 items
                AgentHeuristicMatches.KernelModeMatches.Win32DetourTable = new CwStructures.WIN32API_DETOUR_TABLE[12];

                //loop through DLLs we care about
                for (int i = 0; i < DirtyDlls.Length; i++)
                {
                    CwStructures.WIN32API_DETOUR_TABLE ModuleDetourTable = new CwStructures.WIN32API_DETOUR_TABLE();
                    string thisDLL = DirtyDlls[i];

                    try
                    {
                        ModuleDetourTable = HeuristicsKernelModeHelper.GetModuleDetours(thisDLL);
                    }
                    catch (Exception ex)
                    {
                        AgentScanLog.AppendLine("SCAN:  Error checking for detours in module '" + thisDLL + "':  " + ex.Message);
                        continue;
                    }

                    //save the hook table to return object.
                    AgentHeuristicMatches.KernelModeMatches.Win32DetourTable[i] = ModuleDetourTable;
                }
            }
            else
            {
                AgentHeuristicMatches.KernelModeMatches.Win32DetourTable = new CwStructures.WIN32API_DETOUR_TABLE[0];
            }
            */
            #endregion

            //----------------------------------------------
            //
            //                  IRP HOOKS
            //
            //----------------------------------------------
            #region IRP HOOOKS

            if (AgentSettings["DriversHeuristics_DetectIRPHooks"] == "True" && AgentSettings.ContainsKey("AddDriverListview"))
            {
                //get the list of driver names and objects
                //it is stored in the settings variable "AddDriverListview"
                //as a comma-separated list:
                //      string[]=  {driver1,device1,driver2,device2,..}
                string drivers = AgentSettings["AddDriverListview"];

                if (drivers.IndexOf(",") != -1)
                {
                    //values were stored as comma-separated list
                    string[] items = drivers.Split(new char[] { ',' });
                    //get DRIVER_CHECK_INFO structs from the driver/device pairs
                    ArrayList driversToCheck = DriverHelper.GetDriverInfoStructs(items);

                    //bail completely
                    if (driversToCheck == null)
                    {
                        AgentHeuristicMatches.KernelModeMatches.DriverIrpHooksTable = new CwStructures.HOOKED_DISPATCH_FUNCTIONS_TABLE[0];
                        return false;
                    }
                    AgentScanLog.AppendLine("------------------------");
                    AgentScanLog.AppendLine("        IRP HOOKS       ");
                    AgentScanLog.AppendLine("------------------------");
                    AgentHeuristicMatches.KernelModeMatches.DriverIrpHooksTable = new CwStructures.HOOKED_DISPATCH_FUNCTIONS_TABLE[driversToCheck.Count];
                    int count = 0;

                    //loop through all drivers/device name combinations supplied by user and check for IRP hooks
                    foreach (CwStructures.DRIVER_CHECK_INFO thisDriver in (CwStructures.DRIVER_CHECK_INFO[])driversToCheck.ToArray(typeof(CwStructures.DRIVER_CHECK_INFO)))
                    {
                        CwStructures.HOOKED_DISPATCH_FUNCTIONS_TABLE DriverHookTable = new CwStructures.HOOKED_DISPATCH_FUNCTIONS_TABLE();

                        try
                        {
                            DriverHookTable = HeuristicsKernelModeHelper.GetHookedDispatchFunctionsInDriver(thisDriver);
                        }
                        catch (Exception ex)
                        {
                            AgentScanLog.AppendLine("SCAN:  Error checking for IRP hooks:  " + ex.Message);
                        }
                        AgentHeuristicMatches.KernelModeMatches.DriverIrpHooksTable[count] = DriverHookTable;
                        count++;
                    }
                }
                else
                {
                    AgentHeuristicMatches.KernelModeMatches.DriverIrpHooksTable = new CwStructures.HOOKED_DISPATCH_FUNCTIONS_TABLE[0];
                }
            }
            else
            {
                AgentHeuristicMatches.KernelModeMatches.DriverIrpHooksTable = new CwStructures.HOOKED_DISPATCH_FUNCTIONS_TABLE[0];
            }

            #endregion

            //----------------------------------------------
            //
            //                  IRP DETOURS
            //
            //----------------------------------------------
            #region IRP DETOURS

            if (AgentSettings["DriversHeuristics_CheckDispatchRoutinesForDetours"] == "True" && AgentSettings.ContainsKey("AddDriverListview"))
            {
                //get the list of driver names and objects
                //it is stored in the settings variable "AddDriverListview"
                //as a comma-separated list:
                //      string[]=  {driver1,device1,driver2,device2,..}
                string drivers = AgentSettings["AddDriverListview"];

                if (drivers.IndexOf(",") != -1)
                {
                    //values were stored as comma-separated list
                    string[] items = drivers.Split(new char[] { ',' });
                    //get DRIVER_CHECK_INFO structs from the driver/device pairs
                    ArrayList driversToCheck = DriverHelper.GetDriverInfoStructs(items);

                    //bail completely
                    if (driversToCheck == null)
                    {
                        AgentHeuristicMatches.KernelModeMatches.DriverIrpHooksTable = new CwStructures.HOOKED_DISPATCH_FUNCTIONS_TABLE[0];
                        return false;
                    }

                    AgentScanLog.AppendLine("------------------------");
                    AgentScanLog.AppendLine("      IRP DETOURS       ");
                    AgentScanLog.AppendLine("------------------------");

                    AgentHeuristicMatches.KernelModeMatches.DriverIrpDetoursTable = new CwStructures.DETOURED_DISPATCH_FUNCTIONS_TABLE[driversToCheck.Count];
                    int count = 0;

                    //loop through all drivers/device name combinations supplied by user and check for IRP hooks
                    foreach (CwStructures.DRIVER_CHECK_INFO thisDriver in (CwStructures.DRIVER_CHECK_INFO[])driversToCheck.ToArray(typeof(CwStructures.DRIVER_CHECK_INFO)))
                    {
                        CwStructures.DETOURED_DISPATCH_FUNCTIONS_TABLE DriverDetoursTable = new CwStructures.DETOURED_DISPATCH_FUNCTIONS_TABLE();

                        try
                        {
                            DriverDetoursTable = HeuristicsKernelModeHelper.GetDetouredDispatchFunctionsInDriver(thisDriver);
                        }
                        catch (Exception ex)
                        {
                            AgentScanLog.AppendLine("SCAN:  Error checking for IRP hooks:  " + ex.Message);
                        }

                        AgentHeuristicMatches.KernelModeMatches.DriverIrpDetoursTable[count] = DriverDetoursTable;
                        count++;
                    }
                }
                else
                {
                    AgentHeuristicMatches.KernelModeMatches.DriverIrpDetoursTable = new CwStructures.DETOURED_DISPATCH_FUNCTIONS_TABLE[0];
                }
            }
            else
            {
                AgentHeuristicMatches.KernelModeMatches.DriverIrpDetoursTable = new CwStructures.DETOURED_DISPATCH_FUNCTIONS_TABLE[0];
            }

            #endregion

            return true;
        }
            /////////////////////////////////////////////////////
            //                                                 //
            // GetDetouredDispatchFunctionsInDriver()          //
            //                                                 //
            /////////////////////////////////////////////////////
            //Description:  Attempts to detect any detoured dispatch functions in the
            //              given driver by examining those funcs' prologues.
            //
            //Returns:      a DETOURED_DISPATCH_FUNCTIONS_TABLE structure
            /////////////////////////////////////////////////////
            internal static CwStructures.DETOURED_DISPATCH_FUNCTIONS_TABLE GetDetouredDispatchFunctionsInDriver(CwStructures.DRIVER_CHECK_INFO driverInfoStruct)
            {
                //-----------------------------
                //      SEND COMMAND
                //-----------------------------
                //build the IOCTL to send to driver
                uint ioctl = Win32Helper.GetIOCTL(CwConstants.CW_DRIVER_IRP_DETOUR_DETECTION, Win32Helper.METHOD_OUT_DIRECT);

                //build our buffers
                int InBufSize = Marshal.SizeOf(typeof(CwStructures.DRIVER_CHECK_INFO));
                int OutBufSize = Marshal.SizeOf(typeof(CwStructures.DETOURED_DISPATCH_FUNCTIONS_TABLE));
                IntPtr lpInBuf = Marshal.AllocHGlobal(InBufSize);
                Marshal.StructureToPtr(driverInfoStruct, lpInBuf, true);
                IntPtr lpOutBuf = Marshal.AllocHGlobal(OutBufSize);
                int bytesReturned = 0;

                //send the IOCTL
                try
                {
                    bytesReturned = DriverHelper.SendDriverCommand(ioctl, lpInBuf, InBufSize, ref lpOutBuf, OutBufSize);
                }
                catch (Exception ex)
                {
                    Marshal.FreeHGlobal(lpInBuf);
                    throw new Exception("SendDriverCommand() failed:  " + ex.Message);
                }

                Marshal.FreeHGlobal(lpInBuf);

                if (bytesReturned == 0)
                    throw new Exception("A 0-length buffer was returned from the driver.");

                //-----------------------------
                //      PROCESS RESULTS
                //-----------------------------
                CwStructures.DETOURED_DISPATCH_FUNCTIONS_TABLE DriverDetourTable = new CwStructures.DETOURED_DISPATCH_FUNCTIONS_TABLE();

                //try to marshal the ptr
                try
                {
                    DriverDetourTable = (CwStructures.DETOURED_DISPATCH_FUNCTIONS_TABLE)Marshal.PtrToStructure(lpOutBuf, typeof(CwStructures.DETOURED_DISPATCH_FUNCTIONS_TABLE));
                }
                catch (Exception ex)
                {
                    throw new Exception("Failed to marshal lpOutBuf pointer to DriverDetourTable structure:  " + ex.Message);
                }

                Marshal.FreeHGlobal(lpOutBuf);

                AgentScanLog.AppendLine("SCAN:  Detected " + DriverDetourTable.NumDetours + " IRP detours.");

                //loop through hooks and print them out in our log
                for (int i = 0; i < DriverDetourTable.NumDetours; i++)
                {
                    CwStructures.DETOURED_DISPATCH_FUNCTION_ENTRY de = new CwStructures.DETOURED_DISPATCH_FUNCTION_ENTRY();
                    de = DriverDetourTable.DetouredEntries[i];
                    AgentScanLog.AppendLine("SCAN:       " + de.DispatchFunctionName + "()'s prologue is detoured to function at address 0x" + de.TargetAddress.ToString("x"));
                }

                return DriverDetourTable;
            }