Page 1 of 1

not injecting into the system process

Posted: Thu Aug 06, 2020 5:06 am
by Bevan Collins
I would like to inject into all processes except the Windows system process (PID 4), but I am having trouble doing so:

Code: Select all

ULONG exclude_pids[] = {4, 0}; // exclude system process (4), list must finish with 0
BOOL rc = InjectLibraryW(INJECTION_DRIVER_NAME, dll.c_str(), ALL_SESSIONS, INJECT_METRO_APPS | INJECT_SYSTEM_PROCESSES, L"", L"", exclude_pids);
This seems to still attempt to inject into the system process. This can be seen by event ID 5038 audit failure with process id 4 in the system security log. I also tried:

Code: Select all

BOOL rc = InjectLibraryW(INJECTION_DRIVER_NAME, dll.c_str(), ALL_SESSIONS, INJECT_METRO_APPS | INJECT_SYSTEM_PROCESSES, L"", L"ntoskrnl.exe", exclude_pids);
Is there a way I can get this to work? Thanks.

Re: not injecting into the system process

Posted: Thu Aug 06, 2020 5:24 am
by iconic
Hello,

I’ll run some tests later today and see. Worst case we may update the code to dismiss pid 4 (XP and above) or pid 8 (Win2K). They cannot be injected successfully anyhow. What OS are you seeing the audit details in the event viewer? Legacy OSes like XP?

P.S: Can you also try excluding the name "System" instead of "ntoskrnl.exe", the latter won't work, there are multiple forms of the kernel name (due to PAE) so it never resolves to any file on disk regardless of privilege level.

—Iconic

Re: not injecting into the system process

Posted: Thu Aug 06, 2020 7:44 am
by Bevan Collins
Thanks Iconic,

I'm seeing this in Windows 10 1909. I just tried excluding "System" but it didn't help.

Re: not injecting into the system process

Posted: Thu Aug 06, 2020 9:01 pm
by iconic
Hi Bevan,

I ran a few tests and do see that MCH is indeed opening the SYSTEM process when attempting to inject system-wide. Actually, even PID 0 (System Idle Process) is attempted as well. Of course with SYSTEM the return of NtOpenProcess() is (NTSTATUS)0xC0000022 which is STATUS_ACCESS_DENIED. So, I can confirm that this is happening. I wasn't able to reproduce the security audit event information, it's likely because I don't have *all* audit failures displayed within the system policy. I think the easiest solution here and the most logical is to simply not attempt opening the Idle and SYSTEM process. I'm fairly sure that Madshi will agree with this as well since these 2 processes can't be injected anyhow. Would you mind sharing your audit failure entry with us? I'd like to see exactly what it says. Thanks!

--Iconic

Re: not injecting into the system process

Posted: Thu Aug 06, 2020 9:36 pm
by madshi
Well, in order to check if a process is a system process or not, I must first open it, so I can get information about it.

Re: not injecting into the system process

Posted: Thu Aug 06, 2020 9:42 pm
by iconic
Hey Mathias,

I'm talking about the OS hardcoded process ids of 0 and 4, they're static. In Windows 2000 SYSTEM process id is 8 but on XP+ it's always 4. So, by looking at the process id alone it can be determined if it will create a failed security audit entry. That's what I was saying. Neither process can be injected because they're pseudo-processes so there should be no harm in skipping them.

--Iconic

Re: not injecting into the system process

Posted: Thu Aug 06, 2020 9:50 pm
by madshi
Yes, skipping any process ID <= 8 should be fine.

Re: not injecting into the system process

Posted: Thu Aug 06, 2020 10:02 pm
by iconic
Ok, great :D We can add this to the to-do list then.

--Iconic

Re: not injecting into the system process

Posted: Thu Aug 06, 2020 10:12 pm
by Bevan Collins
ok, great.

Here is the event log if you are interested:
Log Name: Security
Source: Microsoft-Windows-Security-Auditing
Date: 8/6/2020 9:39:07 PM
Event ID: 5038
Task Category: System Integrity
Level: Information
Keywords: Audit Failure
User: N/A
Computer: debug-windows10-64
Description:
Code integrity determined that the image hash of a file is not valid. The file could be corrupt due to unauthorized modification or the invalid hash could indicate a potential disk device error.

File Name: \Device\HarddiskVolume2\Program Files (x86)\path to my dll.dll
Event Xml:
<Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
<System>
<Provider Name="Microsoft-Windows-Security-Auditing" Guid="{54849625-5478-4994-a5ba-3e3b0328c30d}" />
<EventID>5038</EventID>
<Version>0</Version>
<Level>0</Level>
<Task>12290</Task>
<Opcode>0</Opcode>
<Keywords>0x8010000000000000</Keywords>
<TimeCreated SystemTime="2020-08-06T21:39:07.8650575Z" />
<EventRecordID>2682</EventRecordID>
<Correlation />
<Execution ProcessID="4" ThreadID="420" />
<Channel>Security</Channel>
<Computer>debug-windows10-64</Computer>
<Security />
</System>
<EventData>
<Data Name="param1">\Device\HarddiskVolume2\Program Files (x86)\path to my dll.dll</Data>
</EventData>
</Event>

Re: not injecting into the system process

Posted: Thu Aug 06, 2020 10:20 pm
by iconic
Thanks for posting your event information. After looking at it I don't think this has anything to do with opening the system process and is specifically a CI error for code integrity of your injected DLL file. SYSTEM just attempts to verify it. So, it sounds more like your signature for your DLL has issues. ci.dll is responsible (partially) for doing this inside the SYSTEM context.

--Iconic

Re: not injecting into the system process

Posted: Thu Aug 06, 2020 11:00 pm
by Bevan Collins
I have tried using /integritycheck linker option along with signtool /ph option as documented here: https://social.technet.microsoft.com/wi ... files.aspx but I still get event ID 5038 or 6281. I think maybe my dll needs to be co-signed by Microsoft.

Since I have no need (even if it is possible) to inject into PID 4, I have been trying to find a way to avoid it while still injecting into Windows services.

Here is another thread about event IDs 5038 and 6281 from 2015: viewtopic.php?f=7&t=28009

Re: not injecting into the system process

Posted: Thu Aug 06, 2020 11:11 pm
by iconic
Hi Bevan,

I'm familiar with those linker flag options, especially /integritycheck. I use a kernel call to ObRegisterCallbacks() a lot in drivers to protect the thread and process object, ObRegisterCallbacks() will completely fail if /integritycheck isn't specified. Definitely appears to be CI related though. But, as Madshi and I talked about, we will ensure that <= 8 PID will never be attempted to inject, to be honest even in the eyes of AV software it can look suspicious any time you're even trying to open SYSTEM (4), so it's best
if we remove this anyhow, regardless of the fact that we never have the access to inject anyhow.

--Iconic