Crafting Malicious Pluggable Authentication Modules for Persistence, Privilege Escalation, and Lateral Movement

Since its inception in 1997, PAM (Pluggable Authentication Modules) have served as a library for enabling local system administrators to choose how individual applications authenticate users. In this guide, we will discuss how these modules can be harnessed to create malicious binaries for capturing credentials to use in persistence, privilege escalation, and lateral movement.

Synopsis:

Since its inception in 1997, PAM (Pluggable Authentication Modules) have served as a library for enabling local system administrators to choose how individual applications authenticate users. A PAM module is a single executable binary file that can be loaded by the PAM interface library, which is configured locally with a system file, /etc/pam.conf, to authenticate a user request via the locally available authentication modules. The modules themselves will usually be located in the directory /lib/security or the /usr/lib64/security directory depending on architecture and operating system, and take the form of dynamically loadable object files. In this guide, we will discuss how these modules can be harnessed to create malicious binaries for capturing credentials to use in persistence, privilege escalation, and lateral movement.

PAM Components:

As we manipulate authentication programs, here are the useful file locations for different PAM components:

/usr/lib64/security


A collection of PAM libraries that perform various checks. Most of these modules have man pages to explain the use case and options available.

/etc/pam.d


A collection of configuration files for applications that call libpam. These files define which modules are checked, with what options, in which order, and how to handle the result. These files may be added to the system when an application is installed and are frequently edited by other utilities.

/etc/security

A collection of additional configuration files for specific modules. Some modules, such as pam_access and pam_time, allow additional granularity for checks. When an application configuration file calls these modules, the checks are completed using the additional information from its corresponding supplemental configuration files. Other modules, like pam_pwquality, make it easier for other utilities to modify the configuration by placing all the options in a separate file instead of on the module line in the application configuration file.

/var/log/secure

Most security and authentication errors are reported in this log file. Permissions are configured on this file to restrict access.

Developing the Malicious Module:

For this demonstration, imagine that you have gained access to a Linux system, discovering a misconfigured cronjob that allowed you to escalate privileges to root. To laterally move throughout the network, you want to capture the credentials of legitimate users who occasionally log in to the system. To achieve this, we will craft a PAM to capture and output the credentials of the user to a tmp file.

After conducting initial reconnaissance, we identified that the system is running Ubuntu 22.04.

Because this device is x86_64 and running Ubuntu, research reveals that the modules are located within the /usr/lib/x86_64-linux-gnu/security/ directory. With this in mind, we can begin to craft our executable using C. The following code captures and outputs credentials to a tmp file:

To compile the binary, we can make use of gcc and libpam0g-dev to build the PAM module:

gcc -fPIC -fno-stack-protector -c pam_su.c

Now that we have created the binary, we can link it with PAM without having to restart the system:

ld -x --shared -o /usr/lib/x86_64-linux-gnu/security/pam_su.so pam_su.o

Now that the binary is created and linked, we will edit the PAM configuration file /etc/pam.d/common-auth to include our malicious module. This specific file is used to define authentication-related PAM modules and settings that are common across multiple services, whether this be SSH, LDAP, or even VNC. Instead of duplicating authentication configurations in each service file, administrators centralize common authentication settings in this file.

Within this file, we can inconspicuously add our optional authentication module as it is not required to succeed for authentication to occur. With this in place, we can monitor the /tmp/pam_su.tmp for new logins. To test the module, I created a new user named `sysadmin` and logged in via SSH:

Conclusion:

I hope that this guide was an informative journey to improving your penetration testing and red-teaming skills. The code in this article can be found here, and if you have any questions, enjoyed the content, or would like to check out more of our research, feel free to visit our GitHub.