Keyloggers are spyware that monitor and record user keystrokes on endpoints. Some variants relay the recorded data to an external party or attacker, enabling threat actors to exfiltrate user credentials or other sensitive information.
This blog post focuses on detecting Indicators of Compromise (IoC) for keyloggers that utilize living-off-the-land (LOTL) techniques. LOTL is an attack technique where adversaries leverage existing legitimate tools on the victim’s endpoint to perform malicious activities. The MITRE ATT&CK framework labels this attack tactic as Input Capture (T1056.001), since it allows attackers to discreetly intercept the victim’s keystrokes without being detected.
How adversaries leverage LOTL techniques to log keystrokes on Linux endpoints
- Pluggable Authentication Module (PAM) abuse to log keystrokes: PAM is a modular system of configuration files and libraries that manages authentication for multiple services in Linux. Since the values exchanged with PAM are in plain-text, adversaries may infect PAM resources with malicious code to harvest user credentials. Adversaries can also deactivate PAM modules to tamper with the SSHD configuration to capture the keystrokes in a Linux endpoint.
- Logging shell history to the system log file: Threat actors may use the
PROMPT_COMMAND
bash variable or other similar shell variables to configure commands that execute whenever a user runs a shell command. Adversaries can also modify shell configuration to save every new command in shell history to the system’s log file. The log is usually located in/var/log/syslog
or/var/log/messages
, depending on the Linux distribution.
Infrastructure
We use the following infrastructure to demonstrate the detection of keyloggers using Wazuh.
- A pre-built, ready-to-use Wazuh OVA 4.7.0 that includes the Wazuh central components (Wazuh server, Wazuh indexer, and Wazuh dashboard). Follow the Virtual Machine (OVA) – Installation guide to download and set up the Wazuh virtual machine.
- Any Linux endpoint with Wazuh agent 4.7.0 installed and enrolled to the Wazuh server. We use Amazon Linux 2 to simulate the attack and test the SCA policies we create in this blog post. Refer to the Wazuh agent installation guide to install the Wazuh agent.
Configuration
In this section, we show how to configure the Wazuh server and the Wazuh agent to detect Linux keyloggers that utilize LOTL techniques.
Amazon Linux endpoint
The Wazuh Security Configuration Assessment (SCA) module performs checks that validate configuration policies by detecting when legitimate programs on monitored endpoints are poorly configured. We utilize the Wazuh SCA module to detect when legitimate programs are logging keystrokes on Linux endpoints.
We create the SCA policy on the monitored endpoint to detect when adversaries are capturing keystrokes with the use of LOTL techniques.
1. Create a new policy file /var/ossec/etc/sca_detect_linux_keylogger.yml
and add the content below to the file:
policy: id: "detect_linux_keylogger" file: "sca_detect_linux_keylogger.yml" name: "System audit to detect keylogger on Linux endpoints" description: "Scans to detect potential keyloggers on Linux endpoints." references: - https://attack.mitre.org/techniques/T1056/001/ requirements: title: "Check that the SSH service and password-related files are present on the system" description: "Requirements for running the SCA scan against the Unix based systems policy." condition: any rules: - "f:$sshd_file" - "f:/etc/passwd" - "f:/etc/shadow" variables: $sshd_file: /etc/ssh/sshd_config $pam_d_files: /etc/pam.d/common-password /etc/pam.d/passwd-auth /etc/pam.d/system-auth /etc/pam.d/system-auth-ac /etc/pam.d/passwd /etc/pam.d/sshd $bash_cfg_files: /root/.bashrc /root/.bash_profile /root/.bash_aliases /home/*/.bashrc /home/*/.bash_profile /home/*/.bash_aliases /etc/skel/.bashrc $zsh_cfg_files: /root/.zshrc /root/.zprofile /root/.zsh_aliases /home/*/.zshrc,/home/*/.zprofile /home/*/.zsh_aliases /etc/zsh/zshrc $tcsh_cfg_files: /root/.tcshrc /root/.login /root/.cshrc /home/*/.tcshrc /home/*/.login /home/*/.cshrc /etc/csh.cshrc $fish_cfg_files: /root/.config/fish/config.fish /root/.config/fish/functions/*.fish /home/*/.config/fish/config.fish /home/*/.config/fish/functions/*.fish /etc/fish/config.fish $ksh_cfg_files: /root/.profile /root/.kshrc /home/*/.profile /home/*/.kshrc /etc/profile /etc/kshrc checks: - id: 10030 title: "PAM abuse to log keystrokes" description: "Threat actors may enable the PAM auditing feature to log keystrokes." rationale: "By adding the line 'pam_tty_audit.so enable=' to the PAM configuration files, the system is configured to require the pam_tty_audit.so module to log TTY sessions." remediation: "Edit the /etc/pam.d/password-auth and /etc/pam.d/system-auth files, to disable the PAM TTY auditing feature." compliance: - pci_dss: ["2.2.4"] - nist_800_53: ["CM.1"] condition: none rules: - 'c:cat $pam_d_files 2>/dev/null -> r:^session \.*pam_tty_audit.so \.*enable=' - id: 10031 title: "PAM abuse to log passwords" description: "Threat actors may enable the PAM auditing feature to log password." rationale: "By a line similar to 'pam_tty_audit.so enable=* log_password' to the PAM configuration files, the system is configured to require the pam_tty_audit.so module to log passwords in TTY sessions." remediation: "Edit the /etc/pam.d/password-auth and /etc/pam.d/system-auth files, to disable the PAM TTY password auditing feature." compliance: - pci_dss: ["2.2.4"] - nist_800_53: ["CM.1"] condition: none rules: - 'c:cat $pam_d_files 2>/dev/null -> r:^session \.*pam_tty_audit.so \.*enable=\.*log_password' - id: 10032 title: "Logging shell history to file" description: "Threat actors may log shell history to a file they can easily read from, most commonly a log file." rationale: "Threat actors utilize shell prompts such as the PROMPT_COMMAND variable, the precmd() function or some other shell feature to log every command executed." remediation: "Edit your shell configuration files, and remove configuration lines that attempt to write shell history to another file different from the default shell history file." compliance: - pci_dss: ["2.2.4"] - nist_800_53: ["CM.1"] condition: none rules: - 'c:cat $bash_cfg_files -> r:^PROMPT_COMMAND=\.*history -a' - 'c:cat $zsh_cfg_files -> r:^precmd\.*\(\)\.*history -a' - 'c:cat $tcsh_cfg_files -> r:^alias precmd\.*history -S' - 'c:cat $fish_cfg_files -> r:^function fish_prompt\.*history -h' - 'c:cat $ksh_cfg_files -> r:^PS1=\.*history -a' - id: 10033 title: "Known keylogger process" description: "Threat actors may utilize known keylogging applications." rationale: "Threat actors may use off-the-shelf keylogging applications to log user keystrokes." remediation: "Investigate the endpoint, kill the running process, remove the persistence of the keylogger." compliance: - pci_dss: ["2.2.4"] - nist_800_53: ["CM.1"] condition: none rules: - 'c:ps -e -o comm= -> r:^logkeys|^lkl|^uberkey|^thc-vlogger' - 'c:ps aux -> r:py.*keylogger'
Where:
- SCA check ID
10030
determines if adversaries have enabled the PAM auditing feature in a Linux endpoint to log keystrokes. - SCA check ID
10031
determines if adversaries have enabled the PAM auditing feature in a Linux endpoint, specifically to log the victim’s password. - SCA check ID
10032
determines if adversaries have logged the shell history of a Linux endpoint in the system log file. - SCA check ID
10033
determines if adversaries are using any known keylogging application to capture keystrokes in a Linux endpoint.
2. Change the owner and group of the sca_detect_linux_keylogger.yml
file to wazuh
:
# chown wazuh:wazuh /var/ossec/etc/sca_detect_linux_keylogger.yml
3. Enable the policy by appending the following configuration to the /var/ossec/etc/ossec.conf
file on the monitored endpoint:
<ossec_config> <sca> <enabled>yes</enabled> <scan_on_start>yes</scan_on_start> <interval>24h</interval> <skip_nfs>yes</skip_nfs> <policies> <policy>/var/ossec/etc/sca_detect_linux_keylogger.yml</policy> </policies> </sca> </ossec_config>
4. Restart the Wazuh agent to apply the changes:
# systemctl restart wazuh-agent
Simulating attacks on the Linux endpoint
We use the following PoC to simulate the LOTL attack of capturing keystrokes. Perform the following steps on the victim endpoint:
Note: Run the commands below with root privileges.
1. PAM abuse to log keystrokes and passwords
Run the following commands that configure the system to log the victim’s password and keyboard activities in terminal sessions (TTY).
# if sudo test -f /etc/pam.d/password-auth; then sudo cp /etc/pam.d/password-auth /tmp/password-auth.bk; fi; # if sudo test -f /etc/pam.d/system-auth; then sudo cp /etc/pam.d/system-auth /tmp/system-auth.bk; fi; # sudo echo "session required pam_tty_audit.so enable=* log_password" >> /etc/pam.d/password-auth # sudo echo "session required pam_tty_audit.so enable=* log_password" >> /etc/pam.d/system-auth
- By adding the line
session required pam_tty_audit.so enable=* log_password
to the PAM configuration files (password-auth
andsystem-auth
), the system is configured to require thepam_tty_audit.so
module for auditing every TTY session. - The
enable=*
parameter specifies that auditing should be enabled for all users, and thelog_password
parameter indicates that passwords entered during the session should also be logged.
2. Logging shell history to log file
Run the following command to configure bash shell to save every new command in shell history to the specific Linux distribution log file:
# echo 'PROMPT_COMMAND="history -a >(tee -a ~/.bash_history | logger -t \"$USER[$$] $SSH_CONNECTION \")"' >> ~/.bashrc
- The
PROMPT_COMMAND
variable is usually defined in files such as~/.bashrc
for persistence. - The
history -a
command is used to append the current session’s command history to the file~/.bash_history
. - The
tee -a ~/.bash_history
command takes the input from the previous command and appends it to~/.bash_history
while also allowing it to be passed to the next command. - The
logger -t "$USER[$$] $SSH_CONNECTION"
command logs the input received fromtee
to the system log file with the specified tag.
To start the simulation test, open a new terminal as root
and execute the following commands:
# echo "$PROMPT_COMMAND"; echo "testing the simulation" # cat /var/log/{syslog,messages} | grep "testing the simulation"
3. Known keylogger processes
Attackers frequently use common keyloggers alongside LOTL attack techniques in Linux to stealthily capture sensitive data while leveraging trusted system utilities, thereby avoiding detection.
Some common keyloggers that are widely recognized in Linux endpoints are:
- LKL captures hardware keyboard port data and converts keycodes to ASCII using a keymap file.
- Uberkey captures keystrokes directly from the keyboard controller and performs a simple translation.
- THC-vlogger gives the ability to log keystrokes from all administrator/user sessions via remote sessions and transfer the logged data to a centralized remote server.
- PyKeylogger is a free open source keylogger designed for personal backup purposes, offering a universal backup solution for all keystrokes.
- Logkeys keylogger captures all characters and function keys and does not repeat any keys.
Run the following commands to simulate one of the known keylogger processes (LKL):
# cp /usr/bin/sleep ~/lkl; ~/lkl 600 &
Detection results
To view the results immediately, restart the Wazuh agent to trigger the SCA scan which will detect the keylogger IoCs:
# systemctl restart wazuh-agent
Below is an image of SCA results in the Security configuration assessment tab of the Wazuh dashboard when Wazuh detects keylogging activities in a Linux endpoint.
Cleanup commands
At the end of the simulation, follow the steps below to clean up the Linux endpoint:
1. Run the following commands to clean up the simulation of PAM abuse to log keystrokes and passwords from the Linux endpoint:
# if sudo test -f /tmp/password-auth.bk; then sudo cp /tmp/password-auth.bk /etc/pam.d/password-auth; else rm /etc/pam.d/password-auth; fi; # if sudo test -f /tmp/system-auth.bk; then sudo cp /tmp/system-auth.bk /etc/pam.d/system-auth; else rm /etc/pam.d/system-auth; fi;
2. Run the following commands to clean up the simulation of logging shell history to the system log files from the Linux endpoint:
# unset PROMPT_COMMAND # sed -i '/PROMPT_COMMAND="history -a >(tee -a ~\/.bash_history \| logger -t \"$USER[$$] $SSH_CONNECTION \")"/d' ~/.bashrc
3. Run the following command to clean up the simulation of the known keylogger process (LKL) from the Linux endpoint:
# rm ~/lkl
4. Restart the Wazuh agent to manually run the SCA scan:
# systemctl restart wazuh-agent
Check the SCA module on the Wazuh dashboard to verify that the cleanup actions are successful.
Conclusion
Keyloggers are a common type of spyware that attackers use to capture their victim’s keystrokes, potentially exposing sensitive information such as credentials. In this blog post, we demonstrated how to create custom SCA policies in Wazuh to detect multiple keyloggers in a Linux endpoint using LOTL techniques.
Wazuh is a free, open source SIEM and XDR solution that can monitor and detect malicious activities. To learn more about Wazuh capabilities, check out our documentation, blog posts, and our community for support and updates.
Reference