-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Process SE DEBUG mode is not set on Windows #1429
Conversation
…id we ever set SE DEBUG at all?) - if SE DEBUG can't be set we now raise an exception on import; that's bad - I'll change it later, and I will probably replace it with a warning
Confirmed SE DEBUG was not set. I tested with a limited user and it seems we get slightly less AD exceptions . |
X-post from gopsutil with just the relevant part:
|
As the code comment says, the rationale is getting less access denied exceptions for non-admin users. This was added at the inception of the project, around 15 years ago, so I don't recall the exact circumstance that led to this decision. It may be possibile that this was necessary on windows XP and it's not longer necessary today. |
The additional problem is actually this PR, which escalated the use of the privilege from a narrow use case (process.kill API) to now always run with the dangerous SE_DEBUG_NAME privilege all the time. I think that the limited use case is actually somewhat acceptable:
The above would be acceptable. On the contrary, constantly running with the dangerous token all the time is causing problems:
|
Point is I'm not sure whether SE_DEBUG_NAME was added only because of Can you provide some links / literature that recommends against using SE_DEBUG_NAME for security reasons? |
The documentation from Microsoft words it in a somewhat passive manner here: https://learn.microsoft.com/en-us/windows/win32/secauthz/enabling-and-disabling-privileges-in-c--
I am still in the process of creating a minimal example that will actually trigger an alert in an EDR system, in my case using Microsoft Defender for Endpoint as the EDR tool. I can successfully trigger a 'Credential access' false positive alert in Defender for Endpoints when using a large Golang program that uses gopsutil. Once I have managed to write a very small Golang program with gopsutil that also triggers the problematic scenario, I will try and also port that to python psutil. |
The way I interpret it, it was added for I haven't specifically looked for another commit between 2009 and 2019 that would have broadened the use of the Debug privilege prior to this PR.
Yes, I'm pretty confident that it will. I would have to look it up, but I wouldn't be surprised if even some everyday tools from Microsoft that ship together with Windows OS would probably have used this privilege in the past. With Windows 10 and later though, I don't think this would be the case anymore. |
I believe based on the history in 434950a
<434950a>
and what little I remember from code all the way back then, this was
originally used early on for killing a process but also turned out to be
necessary for a number of other operations to retrieve commandline
arguments and all sorts of other process information for processes NOT
owned by the user initiating psutil.
https://learn.microsoft.com/en-us/windows/win32/procthread/process-security-and-access-rights
"To open a handle to another process and obtain full access rights, you
must enable the *SeDebugPrivilege* privilege"
We initially tried setting SeDebug only when it was needed and then
unsetting it each time, but judging by the check-in for 434950a that seems
to have created other problems for us at the time stepping on other
functions that still needed the privilege to be set.
This is analogous to ps on Linux using setuid privileges to retrieve
process information for other processes even when run as a non-root user.
I've not kept up with Windows programming at all since the last work I did
on psutil, so I don't know if any of this will have changed substantively.
I suspect that you would still have the same issues with granting psutil
read permissions to other processes, but if there's a better and more
secure way to do this that doesn't create deployment issues or break a lot
of backwards compatibility, it's worth reviewing.
One option might be to have a non-privilege escalation mode that can be
enabled at the module level and that does not set SeDebug mode at all, for
cases where users only need to query their own processes and where SeDebug
mode will raise security concerns.
…-Jay
On Wed, Nov 29, 2023 at 4:03 PM cwegener ***@***.***> wrote:
Point is I'm not sure whether SE_DEBUG_NAME was added only because of
kill().
The way I interpret it, it was added for kill() only in 2009 in the early
days of psutil 4a9678b
<4a9678b>
I haven't specifically looked for another commit between 2009 and 2019
that would have broadened the use of the Debug privilege prior to this PR.
It's possible it reduces access denied also for other APIs, hence why it's
enabled for the whole lifetime of the (python) process.
Yes, I'm pretty confident that it will. I would have to look it up, but I
wouldn't be surprised if even some everyday tools from Microsoft that ship
together with Windows OS would probably have used this privilege in the
past. With Windows 10 and later though, I don't think this would be the
case anymore.
—
Reply to this email directly, view it on GitHub
<#1429 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AB23S76NZCMSOXMZPP3NCDDYG6PLLAVCNFSM4GZ3JDQKU5DIOJSWCZC7NNSXTN2JONZXKZKDN5WW2ZLOOQ5TCOBTGI3DSNRXGYYQ>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
Thanks Jay! Really appreciate the feedback and the time taken.
This was my original intention, but I fear that it would be substantial work involved in it. And also I believe that even some Microsoft built-in Windows tooling itself (e.g. taskmgr.exe) probably has long been using this way of obtaining handles. At this stage, I'm still in the research and experimentation phase to gain a full understanding of the situation, including:
|
Looking into this a bit more today, it looks to me like this has not
fundamentally changed; SeDebug stil exists as a privilege and is still used
the same way when needed to allow access to other processes' memory space.
By default the SeDebug privilege would only be available to local
Administrator group users, or users that have had it explicitly granted.
The way we are using it in psutil appears to still be an appropriate use
case, as one of the exceptions where your process legitimately needs to
read data from other processes to perform a useful function.
I'm not sure from your description if the issue with triggering credential
access alerts from Defender for Endpoints has anything to do with psutil
using SeDebug privilege. Do you get an ID with the alerts? Those types of
alerts are seemingly triggered from other types of scenarios; looking at
the Microsoft reference docs, none of the "Credential access" events look
like they would be relevant to that use case.
Ref:
https://learn.microsoft.com/en-us/defender-for-identity/credential-access-alerts
I'm wondering if your Go application is actually tripping the Defender
alert for a different reason altogether. I can see other security vendors
do consider reading lsass.exe process memory as a potential 'credential
access' vulnerability, but not specifically Microsoft Defender for
Endpoints (ex: https://attack.mitre.org/techniques/T1003/001/)
Can you reproduce this with a specific use case in Python + psutil
directly? E.g. reading lsass.exe process specifics from pustil, or listing
all processes with their commandline details etc. ?
…-Jay
On Thu, Nov 30, 2023 at 4:31 PM cwegener ***@***.***> wrote:
Thanks Jay! Really appreciate the feedback and the time taken.
I suspect that you would still have the same issues with granting psutil
read permissions to other processes, but if there's a better and more
secure way to do this that doesn't create deployment issues or break a lot
of backwards compatibility, it's worth reviewing.
This was my original intention, but I fear that it would be substantial
work involved in it.
And also I believe that even some Microsoft built-in Windows tooling
itself (e.g. taskmgr.exe) probably has long been using this way of
obtaining handles.
At this stage, I'm still in the research and experimentation phase to gain
a full understanding of the situation, including:
1. Impact on the whole EDR situation, which triggered my investigation
in the first place => I'm not even 100% certain yet that a process with
SE_DEBUG_NAME opening handles to other processes (which are considered
security-critical processes like lsass.exe ) is the main issue that
I'm chasing here, but it looks very likely to be true. example scenarios:
[1]
2. What is Microsoft doing in their own tooling and API landscape?
I.e. how does latest taskmgr.exe work on Win10/Win11? Are different
Win32 APIs being used now by Microsoft's own tools?
3. Better understanding of the Win32 security model as it relates to
default security principals (users) and their default privileges in Win32
(e.g. NT AUHTORITY\SYSTEM would have always had some sort of SE_DEBUG
enabled by default in many versions of Windows)
[1]
https://niiconsulting.com/checkmate/2019/11/token-manipulation-attacks-part-2-process-of-impersonation/
—
Reply to this email directly, view it on GitHub
<#1429 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AB23S7ZYFTBQRDLGRSKE7FDYHD3KZAVCNFSM4GZ3JDQKU5DIOJSWCZC7NNSXTN2JONZXKZKDN5WW2ZLOOQ5TCOBTGQ2TSMRQGEZA>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
From the code:
^ that is what we are supposed to do on module import. While I was refactoring this function I realized that the code which uses it never checks return code/error, so
possiblySE DEBUG has never been set(or it has been broken at some point, I wouldn't know). Now it's set and will raise exception on import in case of error (not what I want - will change it later). Perhaps this means we're now gonna get less AccessDenied exceptions for PIDs owned by other/system users?@jloden - you wrote this code 10 years ago - brings back memories =)
UPDATE: confirmed SE DEBUG was not set. I tested with a limited user and it seems we get slightly less AD exceptions .