How to find long-lost passwords in your clipboard history

Inspecting the 'Paste' database.
Featured image

generated using DALL·E 3

I was able to find a lost password in my clipboard history using creativity, some SQL, and command line tools. A lesson in problem-solving for me.

After setting up a new, I tried to build an Android project and discovered that the release signing key was missing. I use Bitwarden as my password manager, so the signing key must be saved there – or so I thought – there was an entry for the signing key, but it was empty. It seemed like I had forgotten to paste the password when creating the entry.

After some despair, I remembered where the key might be found: in my clipboard.
I use the Paste app to easily copy & paste multiple items at a time and keep a history of all my clipboard items.

The signing key I generated in Bitwarden must still be in my clipboard history! But how do I find it?

Paste allows fuzzy search for all my clipboard history, which works okay. But of course it can’t be used to find an unknown string, so I needed a different approach. I knew when the key was generated, thanks to the creation date of the entry in Bitwarden, but manually scrolling through thousands of items I had copied in the past months was not an option. There has to be another way, right?

# Searching the data

The app must have a database somewhere containing all copied snippets. I was able to find it by inspecting the process in the Activity Monitor. The “Open Files and Ports” tab contains an interesting file handle: Paste.db.

The Paste app's open files and ports, in the macOS Activity Monitor.
The Paste app’s open files and ports, in the macOS Activity Monitor.

At first, I was unsure whether I’d be able to easily read the database’s contents, but my first hunch turned out to be correct. It’s simply SQLite. Using the command line to browse through an unknown database is pretty cumbersome, so I used DB Browser for SQLite, which makes it easy to explore SQLite databases. There are a dozen tables, but the interesting one is ZSNIPPET.

The ZSNIPPET table in Paste's database.
The ZSNIPPET table in Paste’s database. Blob of a snippet shown in the top right.

This table contains everything I copied in the past 6 months. My first instinct was to use the timestamp to quickly jump to the time the Bitwarden note was created. However, for some reason, Paste’s timestamps do not match usual Unix timestamps. I also tried using a known timestamp to calculate the offset between the two, but this didn’t work either.

# Brute force

The next-best solution that came to my mind, was to search through all data.

Before generating the release signing key, I had also copied the command to create the keystore. So I’d just need to find this snippet and go from there.

keytool -genkey -v -keystore ~/upload-keystore.jks -keyalg RSA -keysize 2048 -validity 10000 -alias upload

However, I couldn’t just search it using SQLite, since copied text is stored as a binary blob in the database. Using the blob header bplist00, I found it to use Apple’s “Information Property List” format. And, after dusting off my SQL, I was able to extract all blobs and convert them from ‘plist’ to XML.

$ mkdir bins && cd bins

$ sqlite3 Paste.db "select writefile('object' || ZTIMESTAMP || '.bin', ZPREVIEW2) FROM ZSNIPPET;"

$ ls . |  awk '{print $1}' | xargs plutil -convert xml1

After that, I used the excellent tool ripgrep to search through all XML files for the known string keytool.

$ rg "keytool"

27:		<string>  keytool -genkey -v -keystore ~/upload-keystore.jks -keyalg RSA -keysize 2048 -validity 10000 -alias upload

Now it was just a matter of querying the database using a range around the timestamp 701805006.782251. And there it was, the keystore password!

# Final thoughts

Don’t be an idiot, make sure to save your passwords.

But the interesting detail here might be security. Any application could find the Paste database and extract all passwords, tokens & keys I’ve ever copied. No sudo required. A password might even have some additional context thanks to other nearby clipboard items like URLs or email addresses.

# More

Hi, I’m Filippo. A software engineer living in Graz, Austria. On this blog I write about my programming projects and other interests. Learn more about me.