osquery-extensions
osquery-extensions copied to clipboard
Blocked users extension
WORK IN PROGRESS
A simple extension to allow locking and unlocking of linux local user accounts.
Uses "usermod --lock --expiredate 1
Example usage:
// Add a test user
adduser test
// In osqueryi, lock the user
INSERT INTO blocked_users (username) VALUES("test");
or
INSERT INTO blocked_users (uid) VALUES("<uid>");
// List locked users
SELECT * FROM blocked_users;
// Unlock test user
DELETE FROM blocked_users WHERE username="test";
or
DELETE FROM blocked_users WHERE uid="<uid>";
Interesting; I assume the use case is in incident management, to contain the impact of a compromised endpoint.
Some questions:
- Does
usermod --lock
immediately log out the user if they are currently logged in? - Does it disable all methods of authenticating (e.g., ssh public key) or just password authentication? I have read contradictory information on this.
- Can the user be left with a message of some kind to explain why they are locked out?
- Would something similar be possible on macOS, with
dscl
maybe?
This would be a powerful capability, so we'd want to test to make sure it is safe and always reversible with osquery.
Interesting; I assume the use case is in incident management, to contain the impact of a compromised endpoint.
That was the intention yes :).
Some questions:
- Does
usermod --lock
immediately log out the user if they are currently logged in?
usermod doesn't, as discussed on Slack a kill of all the user processes is needed.
- Does it disable all methods of authenticating (e.g., ssh public key) or just password authentication? I have read contradictory information on this.
usermod --lock alone will only block the password login. It works by prepending the encrypted password in the shadow file with '!' character, which can never appear in an encrypted password. Adding --expiredate 1 expires the account, which also blocks ssh logins.
- Can the user be left with a message of some kind to explain why they are locked out?
The system to lock the user out is pretty raw and basic, so I don't think so. Maybe with PAM something can be done, but this will probably mean requiring a custom module/config.
- Would something similar be possible on macOS, with
dscl
maybe?
Unfortunately don't have a Mac to test this ^^'.
- Does
usermod --lock
immediately log out the user if they are currently logged in?usermod doesn't, as discussed on Slack a kill of all the user processes is needed.
I think to complete the feature in this PR, that we ought to also support the ability to immediately logout the user.
Perhaps you could kill the user's session (via its parent process) rather than kill each individual process of the user? If I was using a CLI and I were in the sudoers group, I could logout the user named "bob" with $ sudo pkill -KILL -u bob
(pkill
is wrapping the kill
system call (called through libc
, as we would too)).
Adding --expiredate 1 expires the account, which also blocks ssh logins.
👍 Blocking SSH logins this way (expiring the account) sounds good to me. Also, it seems that this is the only way to ensure that the account is locked out for all configurations of PAM.
- Can the user be left with a message of some kind to explain why they are locked out?
The system to lock the user out is pretty raw and basic, so I don't think so. Maybe with PAM something can be done, but this will probably mean requiring a custom module/config.
Ok, disregard my suggestion.
- Would something similar be possible on macOS, with
dscl
maybe?Unfortunately don't have a Mac to test this ^^'.
@alessandrogario said he could look into that later after this PR is merged. 😁
I think to complete the feature in this PR, that we ought to also support the ability to immediately logout the user.
That was my thought too :). I also have a raw list of other things to do like:
- Make the code thread safe
- Cleanup error logic and input checking
- Do not accept root user in the queries, as suggested by @alessandrogario
- Add a readonly column to inform about which kind of lock the account has (maybe only the password got locked, manually/externally)
Perhaps you could kill the user's session (via its parent process) rather than kill each individual process of the user? If I was using a CLI and I were in the sudoers group, I could logout the user named "bob" with
$ sudo pkill -KILL -u bob
(pkill
is wrapping thekill
system call (called throughlibc
, as we would too)).
So i tried a bit more with a graphical installation (Ubuntu 18.04) by killing the /var/lib/systemd --user
process which is owned by the user I want to logout, but it has nasty side effects which are to also logout the current user.. and apparently break its log in.
No idea why it does that, but I've found a way which works cleanly, using loginctl, which is a tool from systemd to manage sessions. It uses sdbus internally, so I can try to dlopen the relevant libraries (to avoid and do the same call loginctl does to terminate the session (which seems pretty straightforward). Then if this doesn't terminate the user processes, resort to a fallback method, which kills processes individually using libproc.
Beyond having no dependencies with dlopen, I think I could also check for the presence of the systemd libraries, if there's some distro that has to be supported that doesn't have them; in that case I could use the fallback method only.