Cybersecurity lessons: Monitoring password manager activity

Tips & tricks
13 mins
Magnifying glass on a password.

Editor’s note: This is the first post in our series for cybersecurity professionals and hobbyists, written by Cherlynn C., a threat hunter on ExpressVPN’s cybersecurity team.

Password managers have become a best practice to help individuals and enterprises to secure their account credentials: They can randomly generate passwords for each account, encrypt and store those passwords securely, and sync the encrypted passwords across multiple devices. 

This convenience comes with a caveat: Any attacker who gains access to a user’s password manager account would also be able to access all of their passwords and compromise all of their accounts at once. 

Unfortunately, there has been limited discussion on how to monitor password manager activity to detect unauthorized access and potential account compromises. This article will cover common issues affecting password managers and ways to detect them, with practical examples using 1Password Business as our case study. (ExpressVPN is not affiliated with 1Password. We’re using 1Password only to illustrate processes that might be adaptable across password management services.)

Security issues when using password managers

While using a password manager is generally considered more secure than manually managing individual passwords, there are still ways things can go wrong. The goal of monitoring password manager logs is to detect and mitigate some of these problems.

Here are some issues that could weaken the security of password managers.

Master password exposure

The most obvious way to compromise a password manager account is to obtain its master password. With this, an attacker gains access to all of the compromised user’s passwords, as well as the passwords in any vault the user has access to.

Lack of MFA

Multi-factor authentication is a straightforward and effective way to prevent someone from accessing an account with the master password alone, hence it may be a good idea to enable that on all organizational accounts. However, this could be seen as an inconvenience by end users, who may decide to disable MFA on their accounts.

Inappropriate permissions

If an attacker compromises an account with privileged access, they can perform other more damaging actions, such as giving themselves access to every user’s passwords, deleting every user’s passwords, or tampering with billing. 1Password’s built-in groups along with their default permissions are documented here.

The principle of least privilege should apply when configuring users’ permissions in an enterprise password manager.

Inappropriate vault access

Any user with access to a vault can read all the passwords stored within the vault, increasing the exposure if an attacker manages to compromise an account with access to sensitive vaults.

As with permissions, we should exercise the principle of least privilege when granting users access to vaults.

Case study: Monitoring 1Password Business

We decided to utilize 1Password Business as our example as we identified potential for constructing monitoring into their logs. It is a popular enterprise password manager solution that produces informative logs, but the ability to monitor those logs effectively is constrained by the limited documentation on its log format.

Hence, in this blog we will examine how to interpret 1Password Business logs, and how to analyze and monitor them to detect suspicious activity.

Jump to…
Sending 1Password activity logs to a SIEM
Understanding activity logs
Analysis and monitoring

Sending 1Password activity logs to a SIEM

Administrators can view 1Password activity logs from their admin console, but in a large enterprise environment the volume of logs would likely be too high for effective manual analysis. To facilitate automated analysis and alerting, we can stream the activity logs to a Security Information and Event Management tool (SIEM). 1Password documents a way to stream its logs to Splunk in this blog post, but since the logs are in JSON format, we can adapt this to any other SIEM that accepts JSON events.

These are the general steps to stream logs from 1Password to a SIEM:

  1. Install the 1Password Command Line Tool (opcli).
  2. Create a 1Password account with the permission to View Administrative Sidebar. This allows the account to view the activity logs.
  3. Pull 1Password events using the 1Password Command Line Tool (details below)
    1. Optional: Enrich the raw events to make it easier to read and analyze. See UUID section below for an example.
  4. Forward those events to the SIEM.

Automation with 1Password Command Line Tool

Since our goal is to automate the analysis of password manager logs, the collection and sending of logs to the SIEM should also be automated. We’ll cover how to do that using 1Password CLI, plus provide some Python code samples to illustrate that. 

Before you can run commands on the 1Password CLI, you’ll need to sign in to your 1Password account. 1Password covers how to do that manually in this article. Here’s an example on how to do it programmatically via Python:

Posting data to SIEM.

This will return a session token, which will need to be included in subsequent commands.

Once you’re signed in, use this command to retrieve 1Password events:

op list events <event ID> newer –session <session token>

This pulls up to 100 events that are newer than the event identified by <event ID>. If there are more than 100 events, you’ll need to run this multiple times. For each run, input the event ID of the latest event that has been retrieved so far. Event IDs are integers assigned in chronological order, so just take the highest event ID in all the retrieved events. Repeat until no more events are returned. 

Translating that into code, we have:

Event ID code.

This will give us a list of events in 1Password activity logs generated after the event designated by event_id. Take note that the above function also returns the latest event_id that has been retrieved. Store this somewhere, as you’ll need it the next time you retrieve logs using 1Password CLI.

After retrieving the events (and possibly enriching it), we can send it off to our SIEM of choice. This can be as simple as making a POST request to the SIEM’s webhook, or installing a dedicated forwarder on the machine (such as Splunk Universal Forwarder).

Here’s an example on posting the data to the SIEM, but note that the method can vary wildly depending on the SIEM’s requirements:

Posting data to SIEM.

Putting it together, we can combine the above parts into a single script, which we can then schedule to run periodically as a cron job to get automated log collection and forwarding to the SIEM.

Understanding activity logs

First, let’s go through how to read 1Password activity logs. As noted in this 1Password post, events in the activity log follow this general format:

{
 “eid”: 392879,
 “time”: “2018-01-23T15:50:49Z”,
 “actorUuid”: “YJTZ3RWWFRBNTF4M2YEEY3EPOQ”,
 “action”: “join”,
 “objectType”: “gm”,
 “objectUuid”: “hd22y2bob6qdpap2ge6d7nn4yy”,
 “auxInfo”: “A”,
 “auxUUID”: “YJTZ3RWWFRBNTF4M2YEEY3EPOQ”
}

We’ll go through each field one by one.

FieldDescription
eidThe event ID. Each event in the activity log has a unique event ID.
timeTime the event was generated.
actorUuidID of the actor who performed the action on 1Password.
actionThe action that was performed.
objectTypeThe type of object that the action was performed on.
auxInfoAuxiliary info on the action being performed.
auxUUIDThe UUID of the user targeted by the action, if any.

Actions

These are some notable actions that are logged in 1Password activity logs in the action field.

ActionDescription
createUser invited another user into the 1Password team.
beginrUser initiated account recovery for an account (This allows someone to log into their account in case they have lost their master password).
completrAccount recovery has been completed.
joinUser added another account to a group.
grantUser granted another account access to a vault.
roleUser changed the role of another account in a group.
disblmfaUser disabled an account’s Multi-Factor Authentication.
updatmfaUser modified an account’s Multi-Factor Authentication.
patchUser modified a vault.
deleteUser deleted an item from a vault.

Auxiliary fields

auxInfo and auxUUID contain additional information about the action. Whether these fields are present and what information is recorded depends on the action performed.

auxUUID

auxUUID is only present if the action is performed on a target user, and shows the UUID of the target user. For example:

Action join – auxUUID tells us which user was added into a group.

Action grant – auxUUID tells us which user was granted access to a vault.

Action role – auxUUID tells us which user’s role was changed.

auxInfo

auxInfo is present in certain actions, and gives additional information on what was performed in the action. Here are some actions and their associated auxiliary information:

Action patch

auxInfo tells us what kind of changes have been made to a vault:

  • 1,0,0,0,0 – New entry in vault was created
  • 0,1,0,0,0 – Entry in vault was edited
  • 0,0,1,0,0 – Entry in vault was deleted

The number reflects the number of items involved in the action, e.g., 0,0,2,0,0 means that two items have been deleted.

Action create – auxInfo tells us which user was invited into the team.

Action delete – auxInfo tells us how many items were deleted from the vault.

UUID

As showcased in the sample log message, we see that UUIDs of users and objects (actorUuid, objectUuid, auxUUID) are logged instead of their names. We can use the 1Password command line tool to retrieve lists of objects and their associated UUIDs using op list (users | groups | vaults | items | documents | templates)

To make reading the events easier, we can retrieve these lists, map each object’s UUIDs to their names in those lists, and add the mapped names as additional fields in the events before forwarding them to the SIEM. We’ll cover an example below.

This is a sample raw event from 1Password activity logs:

{
 “eid”: 123456,
 “time”: “2021-01-01T00:00:00Z”,
 “actorUuid”: “ALICE_UUID”,
 “action”: “join”,
 “objectType”: “gm”,
 “objectUuid”: “hd22y2bob6qdpap2ge6d7nn4yy”,
 “auxInfo”: “A”,
 “auxUUID”: “BOB_UUID”
}

actorUuid and auxUUID are both UUIDs of 1Password users. So we’ll run the op list users command to get the mapping for UUID to user names, which gives us an output like this:

[
  {
    “uuid”: “ALICE_UUID”,
    “firstName”: “Alice”,
    “lastName”: “A”,
    “name”: “Alice A”,
    “email”: “alice@example.com”,
    “avatar”: “”,
    “state”: “A”,
    “type”: “R”
  },
  {
    “uuid”: “BOB_UUID”,
    “firstName”: “Bob”,
    “lastName”: “B”,
    “name”: “Bob B”,
    “email”: “bob@example.com”,
    “avatar”: “”,
    “state”: “A”,
    “type”: “R”
  }
]

The output is an array of JSON objects, each representing one user. Look up the actorUuid and auxUUID in this array to find the corresponding user entry. Then, create two new fields, actorName and auxName, and assign them the names of the users corresponding to actorUuid and auxUUID respectively.

Here, we find that actorUuid ALICE_UUID corresponds to user with name “Alice A”, and auxUUID BOB_UUID corresponds to user with name “Bob B”. So we’ll set actorName to “Alice A”, and auxName to “Bob B”.

Add those fields to our original activity log event, and we get:

{
 “eid”: 123456,
 “time”: “2021-01-01T00:00:00Z”,
 “actorUuid”: “ALICE_UUID”,
 “actorName”: “Alice A”, //added field
 “action”: “join”,
 “objectType”: “gm”,
 “objectUuid”: “hd22y2bob6qdpap2ge6d7nn4yy”,
 “auxInfo”: “A”,
 “auxUUID”: “BOB_UUID”,
 “auxName”:“Bob B” //added field
}

We can then send this modified event to the SIEM instead of the raw event from the activity logs.

Alternatively, the above list of UUIDs and users can be stored in some easily accessible database, lookup table, or spreadsheet for easy correlation.

Analysis and monitoring

Now that we’ve established the problems that could undermine the security of password managers, we can start considering ways to identify the presence of such problems from the activity logs, and formulate rules to detect these problems automatically in a SIEM.

We’ll cover a few examples below, with sample events and rule logic.

Disabled MFA

Accounts without MFA are at greater risk of compromise, since attackers would only need the master password to access the account.

If the company policy is to enable MFA, we could look out for events where MFA is disabled.

Sample event

{
 “eid”: 12345,
 “time”: “2000-01-01T00:00:00Z”,
 “actorUuid”: “*”,
 “action”: “disablmfa”,
 “objectType”: “gm”,
 “objectUuid”: “*”,
}

Rule logic

Generalizing this to a rule, we can simply alert on events where action = disablmfa.

Privileged activity from non-privileged user

The list of users who are 1Password administrators in an organization should be tightly controlled and clearly documented. If we see activities that only administrators can perform coming from a user that is not a known 1Password admin, it suggests a potential misconfiguration or compromise granting admin permissions to a user that is not supposed to have them.

Examples of privileged activity:

  • Inviting another user into the 1Password team.
  • Initiating account recovery for another account.
  • Adding another account into a privileged group.
  • Granting another account access to a privileged vault.

Sample events

Inviting another user into the 1Password team.

{
 “eid”: 12345,
 “time”: “2000-01-01T00:00:00Z”,
 “actorUuid”: “<Non-admin UUID>”,
 “action”: “create”,
 “objectType”: “invite”,
 “objectUuid”: “*”,
 “auxInfo”: “A”,
 “auxUUID”: “*”
}

Initiating account recovery for another account.

{
 “eid”: 12345,
 “time”: “2000-01-01T00:00:00Z”,
 “actorUuid”: “<Non-admin UUID>”,
 “action”: “beginr”,
 “objectType”: “user”,
 “objectUuid”: “*”,
}

Adding another account into a privileged group.

{
 “eid”: 12345,
 “time”: “2000-01-01T00:00:00Z”,
 “actorUuid”: “<Non-admin UUID>”,
 “action”: “join”,
 “objectType”: “gm”,
 “objectUuid”: “<privileged group UUID>”,
 “auxInfo”: “A”,
 “auxUUID”: “*”
}

Granting another account access to a privileged vault.

{
 “eid”: 12345,
 “time”: “2000-01-01T00:00:00Z”,
 “actorUuid”: “<Non-admin UUID>”,
 “action”: “grant”,
 “objectType”: “uva”,
 “objectUuid”: “<privileged vault UUID>”,
 “auxInfo”: “A”,
 “auxUUID”: “*”
}

Rule logic

There should be a documented list of privileged groups, vaults, and admin users in the organization. Retrieve their UUIDs; see the UUID section for how to get the UUID mappings.

Alert on events where actorUuid is not in the list of admin user UUIDs and where any of following is true:

  • action=create, OR
  • action=beginr, OR
  • (action=join AND objectUuid is in the list of privileged group UUIDs), OR
  • (action=grant AND objectUuid is in the list of privileged vault UUIDs).

User granted exclusive access

There may be highly sensitive and exclusive 1Password groups in an organization where the membership is expected to be fairly small (e.g., administrator group). Similarly, there may be certain vaults holding passwords for sensitive/critical systems that should only be accessible to a select few. While not necessarily a sign of malicious activity, if a user is granted membership to the administrator group or access to a sensitive vault, we should do some validation to ensure that the action is expected.

Sample events

User added to exclusive group.

{
 “eid”: 12345,
 “time”: “2000-01-01T00:00:00Z”,
 “actorUuid”: “*”,
 “action”: “join”,
 “objectType”: “gm”,
 “objectUuid”: “<exclusive group UUID>”,
 “auxInfo”: “A”,
 “auxUUID”: “*”
}

User granted access to an exclusive vault.

{
 “eid”: 12345,
 “time”: “2000-01-01T00:00:00Z”,
 “actorUuid”: “*”,
 “action”: “grant”,
 “objectType”: “uva”,
 “objectUuid”: “<exclusive vault UUID>”,
 “auxInfo”: “A”,
 “auxUUID”: “*”
}

Rule logic

Document a list of highly sensitive/exclusive groups and vaults in the organization and retrieve their UUIDs – See the UUID section for how to get the UUID mappings.

Alert on events where objectUuid is in the list of UUIDs of sensitive groups and vaults.

Abnormal timing of admin activity

Assuming that an organization’s 1Password administrators work under some regular schedule, we can profile their usual active hours and flag out activities performed using their accounts outside those times.

Naturally, this does not work if the administrators are expected to be on-call for ad-hoc requests or if they work in irregular shifts, but if their working hours are mostly consistent it may be an indicator that an attacker has obtained access to an admin’s account and is performing activities in their stead.

Sample event

{
 “eid”: 12345,
 “time”: “2000-01-01T03:00:00Z”,
 “actorUuid”: “<Administrator’s UUID>”,
 “action”: “*”,
 “objectType”: “*”,
 “objectUuid”: “*”,
 “auxInfo”: “A”,
 “auxUUID”: “*”
}

Rule logic

This requires an initial profiling of each administrator’s regular working hours. This could be 9 a.m. to 5 p.m. in the admin’s local time zone, or their shift hours.

Alert on any event where the actorUuid belongs to an admin account, and where time is outside the regular working hours of the admin.

Conclusion

The examples we have discussed are by no means an exhaustive list but simply a starting point to catch some suspicious activities. With more in-depth knowledge of the environment, we can create more granular rules that take specific organizational policies and user behavior into account to catch a wider range of abnormalities.

ExpressVPN's Security Team contributes articles with the aim of benefiting the cybersecurity community at large.