Analyzing Linux Authentication Files

Alfredo Pardo

Analyzing Linux Authentication Files


October 11, 2023

When auditing Unix-based systems, particularly some Linux flavors, some requirements arise regarding the authentication files.

These systems have two main files: `/etc/passwd` contains user information like username, main group, home directory and shell being used; and `/etc/shadow`, which contains the user’s hashed password, settings and related data.

We will be using these files from the box containing the OWASP Broken Web Applications Project.

Analyzing /etc/passwd file

This file contains 7 distinct fields:

  • User ID: it is used when the user logs in, and it is compared to the `/etc/shadow` file. Its maximum length is 32 characters.
  • Password: it indicates with an “x” that the real password is stored in another file; `/etc/shadow` in this case.
  • UID: it is the unique identifier assigned to a user. 0 is used for root, and every other predefined account uses the range 1-99. For system accounts, the commonly used range is 100-999.
  • GID: it is the primary user group. More details can be found in the `/etc/group` file.
  • User Info: it is usually used to save the user’s full name and other relevant data.
  • Home Dir: it is the absolute path of the user’s home directory.
  • Shell: it is the absolute path of the user’s default shell.

This is the content we are going to analyze:

We are interested in extracting group and shell information from this file. If you need additional information about user groups please use the groups <username> command or, for a group perspective, you can look in the `/etc/group` file. Let’s start working on it. 

First, we will be importing some python libraries we need and define the base structure:

The following function will iterate the content of our `/etc/passwd` file and return the information to be analyzed. We will be counting the number of users with a particular group membership and the shells they are using. We will also be ignoring those lines that are commented.

Assuming we saved this information in a data/passwd.txt file, we may want to capture the file content in the following way:

And to complement this, let’s draw some graphics. For that, we will be using the following function:

So, our main function will now be this:

And this is the resulting picture:

With a few small changes to our main function, we can draw the shells being used as well:

Analyzing /etc/shadow file

These are the fields of the `/etc/shadow` file:

  • User ID: it is the same identifier used in the `/etc/passwd` file.
  • Encrypted Password: it is the encrypted password and its format is usually `$id$salt$hashed`.
  • Last Chg Days: this is an integer value indicating the number of days since Jan 1, 1970, when the password was last changed.
  • Min Days: this is the minimum number of days after which a user is authorized to change the password.
  • Max Days: this is the maximum number of days in which a password is valid. Exceeded this period, the user will be forced to change the password.
  • Warn Days: this number indicates a notification of the number of days before the user password expires.
  • Inactive Days: this is the number of days after the password expiration date, in which the account will be disabled.
  • Disabled Days: it is an integer value that indicates the number of days since Jan 1, 1970, when the account will no longer be used.
  • Not Used: this field is not currently being used.

And this is how the content looks:

We will add another dictionary to save our data:

And we will be using a similar function to complete this information:

Finally, we will be adding this function to our main function using a `data/shadow.txt` file and, with minimal changes, we should be able to see when users changed their password.


With this, you may be able to answer questions like:

  • Do accounts that don’t need interactive logon have a false shell in place?
  • Are the users assigned to the correct group considering the least privilege principle? You may need to perform additional work to have a complete answer to this question, as previously mentioned
  • Have the users recently changed their password?
  • Are the expiration settings properly configured?
  • Is the user being asked to change his password with proper anticipation?

Thanks for reading!

You can see a full version of the code here.

Alfredo Pardo

To learn more contact us

Continue reading

Ready to connect?