Breaking Down Password Storage Breakdowns

Binary Defense

Binary Defense

Built from the minds of the industry’s top security researchers and continuously evolving to detect next-generation threats, Binary Defense is your company’s security solution.

Written By: Kim McAloon

Hunting for Password Files on Endpoints

As part of the Okta compromise, it was announced that attackers accessed a spreadsheet on Sitel’s internal network called DomAdmins-LastPass.xlsx. The file name suggests that the spreadsheet contained passwords for domain administrator accounts. Users storing passwords in unencrypted documents on company endpoints could expedite post-compromise lateral movement or privilege escalation. Therefore, it is important for enterprise security personnel to detect unsafe password storage incidents and educate end users and administrators about safer ways to store passwords. 

Unfortunately, there is no clear-cut way for defenders to search for these types of files using endpoint security tools, because users can store passwords in many formats and with any file name of their choosing. However, there are many instances where users simply name these files using easy to remember terms like “passwords.txt” that can be discovered using process or file creation event logs.  

Figure 1. Examples of files that may contain passwords 

Binary Defense researchers created queries to discover instances of users saving passwords in this manner. These queries will not be all-inclusive, but they do provide insight into the scope of the issue within an organization. It is highly recommended to provide user awareness training regarding the potential risk of storing passwords this way and to perform a more thorough search using a software management tool. Providing an alternative, more secure solutions, such as a password manager, can assist users with moving away from this behavior.

We recommend deploying active countermeasures using canary token files to identify threat actors accessing these types of documents. These canary token files can be named in a similar fashion to “passwords.txt” or “domain creds.xlsx” and stored in the Documents or Desktop directories of administrators, executives, and users with privileged accounts. Alerts should be created that monitors any activity around these documents as they could be an indicator that a threat actor is on the network and is attempting to collect additional credentials.

Multiple queries were developed across different platforms to search for password-related documents. Each will need to be tuned to remove false positives. These queries should be used as threat hunts to identify potential instances, and not as alerts–as there will be false positives. 

CrowdStrike

To begin the threat hunt, Binary Defense began searching in CrowdStrike for endpoint logs that identify file activity. The “File Written” and “FileCreateInfo” tables indicate when new files are written to disk. There are numerous “File Written”tables, so a wild card needs to be used to capture events from all of them. Additional wild cards are needed in order to search the FileName field. This dramatically decreases the search speed of this query. It also produces numerous false positives as it catches the keywords anywhere in the file name, such as “passdown”, “accounting”, and “accountability”.

(event_simpleName=*FileWritten OR event_simpleName=FileCreateInfo) (FileName=”*password*” OR FileName=”*passwd*” OR FileName=”*pass*” OR FileName=”*pswd*” OR FileName=”*pwd*” OR FileName=”*creds*” OR FileName=”*credential*” OR FileName=”*domain*” OR FileName=”*login*” OR FileName=”*logon*” OR FileName=”*account*” OR FileName=”*admin*”) AND (FileName=”*.txt” OR FileName=”*.doc” OR FileName=”*.docx” OR FileName=”*.xls” OR FileName=”*.xlsx”) FileName!=”*passoff*” FileName!=”*pass off*” FileName!=”*accountability*”FileName!=”*accounting*” FileName!=”*passdown*”

| stats values(FileName) as FileName, Values(FilePath) as FilePath by ComputerName

The “Process” tables are more reliable as a search as they find all file activity being performed on an endpoint. This search focuses on the Microsoft Excel and Word processes, as well as Notepad tools. It then utilizes regex to discover keywords and file extensions in the CommandLine field. This search is faster than the File Written search, but captures even more false positives as the keywords can be anywhere in the file path, such as “Documents\Accounting and Finance\”, “Documents\Admin Assistant\” and “Desktop\Passage Files\”.

index=main (FileName=”excel.exe” OR FileName=”winword.exe” OR FileName=”notepad.exe” OR FileName=”Notepad*.exe”)

| regex CommandLine=”(?i)password|passwd|creds|credentials|pwd|pswd|login|account|domain|logon|admin” 

| regex CommandLine=”(?i)|\.txt|\.doc|\.xls|\.xlsx|\.docx” 

| stats values(FileName) as FileName, Values(CommandLine) as CommandLine by ComputerName

Threat researchers actually found that using a root index search using file names with extensions produced less false positives, improved search speed, and searched both file write activity and process activity. Additional file names can be added based on results of an initial threat hunt. The results of this search are specific to the keyword being directly before the file extension; however, this was found to be a common pattern in the files that were discovered using the other two queries. 

CrowdStrike Query

index=main (password.txt OR administrator.txt OR domain.txt OR account.txt OR id.txt OR login.txt OR passwd.txt OR pass.txt OR pswd.txt OR pwd.txt OR creds.txt OR credential.txt OR credentials.txt OR logon.txt OR passwords.txt OR accounts.txt OR ids.txt OR logins.txt OR passwds.txt, OR pwds.txt, OR logons.txt OR password.xlsx OR administrator.xlsx OR domain.xlsx OR account.xlsx OR id.xlsx OR login.xlsx OR passwd.xlsx OR pass.xlsx OR pswd.xlsx OR pwd.xlsx OR creds.xlsx OR credential.xlsx OR credentials.xlsx OR logon.xlsx OR passwords.xlsx OR accounts.xlsx OR ids.xlsx OR logins.xlsx OR passwds.xlsx OR pwds.xlsx OR logons.xlsx OR password.docx OR administrator.docx OR domain.docx OR account.docx OR id.docx OR login.docx OR passwd.docx OR pass.docx OR pswd.docx OR pwd.docx OR creds.docx OR credential.docx OR credentials.docx OR logon.docx OR passwords.docx OR accounts.docx OR ids.docx OR logins.docx OR passwds.docx OR pwds.docx OR logons.docx) FileName!=”cat” FileName!=”bash” FileName!=”chmod” FileName!=”sh” FileName!=”chown” FileName!=”cksum” FileName!=”ditto” FileName!=”ls” FileName!=”cmd.exe” FileName!=”java.exe” FileName!=”touch” FileName!=”git”

| stats values(FileName) as FileName, Values(CommandLine) as CommandLine, values(FilePath) as FilePath by ComputerName

Microsoft Sentinel

The DeviceFileEvents table within Microsoft Sentinel (if integrated with Microsoft Defender for Endpoint) can also be used to identify this behavior. Similar to the File Written query above, this query looks for the keywords anywhere within the file name and, therefore, can produce some false positives. Environment-specific keyword patterns can be added to the “where not” portion of this query to eliminate these results. 

Microsoft Sentinel Query

DeviceFileEvents

| where TimeGenerated > ago(30d)

| where FileName contains “pass” or FileName contains “pswd” or FileName contains “pwd” or FileName contains “creds” or FileName contains “credential” or FileName contains “domain” or FileName contains “login” or FileName contains “admin” or FileName contains “logon”

| where FileName matches regex @”(?i).*(\.xls|\.xlsx|\.docx|\.doc|\.txt)\z” 

| where not (FileName has_any (“Time Off”,”Fee”,”bypass”,”credits”, “credit”, “passport”, “backpass”, “administration”, “product”, “payable”, “accounting”, “receivable”, “identity”, “meeting”, “agenda”, “payroll”, “totals”, “accountability”, “policy”, “report”, “passthrough”, “compass”, “administrative”, “Pass On”, “passing”))

//| summarize count() by FileName

//| summarize Locations=make_set(FolderPath) by DeviceName

| summarize Devices=make_set(DeviceName) by FolderPath

SentinelOne

The SentinelOne query works very similarly to the Sentinel query. It discovers all file events with the specified keywords and file extensions within the whole file path. However, SentinelOne does not have the ability to remove duplicates or perform a group by within the SentinelOne interface. Duplicates will need to be manually removed using a spreadsheet and formulas or via the SentinelOne API. To perform the threat hunt, Binary Defense threat researchers exported the results of this query and added a formula to extract the file name from the TargetFilePath field. This allowed analysts to remove duplicates based on EndPoint Name and File Name.

Microsoft Excel Formula

=MID(C2,FIND(“*”,SUBSTITUTE(C2,”\”,”*”,LEN(C2)-LEN(SUBSTITUTE(C2,”\”,””))))+1,LEN(C2))

SentinelOne query

(SrcProcName containscis “Winword.exe” OR SrcProcName ContainsCIS “Excel.exe” OR SrcProcName ContainsCIS “notepad”) AND (TgtFilePath ContainsCIS “password” OR TgtFilePath ContainsCIS “passwd” OR TgtFilePath  ContainsCIS “pass” OR TgtFilePath  ContainsCIS “pswd” OR TgtFilePath  ContainsCIS “pwd” OR TgtFilePath ContainsCIS “cred” OR TgtFilePath ContainsCIS “credential” OR TgtFilePath  ContainsCIS “Domain” OR TgtFilePath  ContainsCIS “logon” OR TgtFilePath ContainsCIS “login”) AND (TgtFileExtension ContainsCIS “txt” OR TgtFileExtension ContainsCIS “doc” OR TgtFileExtension ContainsCIS “xls”) AND (TgtFilePath Does Not ContainCIS “payable” AND TgtFilePath Does Not ContainCIS “receivable” AND TgtFilePath Does Not ContainCIS “webinar” AND TgtFilePath Does Not ContainCIS “zoom” AND TgtFilePath Does Not ContainCIS “payroll” AND TgtFilePath Does Not ContainCIS “administrative”)

Users Sending Plaintext Passwords via Email

In addition to storing files on local machines, it has often been observed that users send plaintext passwords to their home email address. Email accounts can be compromised, resulting in leaked credentials that can be used against an organization. Email logs can be used to search for keywords in subject names or file attachments. For this hypothesis, it is recommended to limit the search results to only recipients outside of the organization. For our queries, we also limited the results to only personal email domains to eliminate potential business to business communications. Other common recipients, such as mobile multimedia addresses, will also need to be removed.

Microsoft Sentinel

Email Subject

let personalEmailDomains = externaldata (personalMailDomain: string)[h@’https://raw.githubusercontent.com/ivolo/personal-email-domains/master/index.json’] with (format=txt, ignoreFirstLine=true)

|extend tempDomain = extract_all(“\”(.*?)\””,personalMailDomain)

|extend ParsedDomain = tostring(tolower(tempDomain[0]))

|project ParsedDomain;

EmailEvents

| where RecipientEmailAddress !endswith “[ORGANIZATIONDOMAIN]” and SenderFromAddress endswith “[ORGANIZATIONDOMAIN]” andRecipientEmailAddress !endswith “txt.att.net” and RecipientEmailAddress !endswith “vtext.com” and RecipientEmailAddress !endswith “mms.att.net” and SenderFromAddress != “postmaster@[ORGANIZATIONDOMAIN]”

| where Subject has_any (“pass”, “pswd”, “pwd”, “creds”, “credential”, “domain”, “login”, “admin”, “logon”)

| where not (Subject has_any (“webinar”, “zoom”))

| summarize make_list(Subject) by SenderFromAddress, RecipientEmailAddress

| project list_Subject, SenderFromAddress, RecipientEmailAddress,RecipientDomainName = tostring(split(RecipientEmailAddress, “@”)[1])

| join (personalEmailDomains) on $left.RecipientDomainName == $right.ParsedDomain

Email Attachment

let personalEmailDomains = externaldata (personalMailDomain: string)[h@’https://raw.githubusercontent.com/ivolo/personal-email-domains/master/index.json’] with (format=txt, ignoreFirstLine=true)

|extend tempDomain = extract_all(“\”(.*?)\””,personalMailDomain)

|extend ParsedDomain = tostring(tolower(tempDomain[0]))

|project ParsedDomain;

EmailAttachmentInfo

| where RecipientEmailAddress !endswith “[ORGANIZATIONDOMAIN]” and SenderFromAddress endswith “[ORGANIZATIONDOMAIN]” andRecipientEmailAddress !endswith “txt.att.net” and RecipientEmailAddress !endswith “vtext.com” and RecipientEmailAddress !endswith “mms.att.net” and SenderFromAddress != “postmaster@[ORGANIZATIONDOMAIN]”

| where FileName has_any (“pass”, “pswd”, “pwd”, “creds”, “credential”, “domain”, “login”, “admin”, “logon”)

| where FileType has_any (“xls”, “doc”, “txt”, “zip”, “xlsx”, “docx”)

| summarize make_list(FileName), make_list(FileType) by SenderFromAddress, RecipientEmailAddress

| project list_FileName, list_FileType, SenderFromAddress, RecipientEmailAddress,RecipientDomainName = tostring(split(RecipientEmailAddress, “@”)[1])

| join (personalEmailDomains) on $left.RecipientDomainName == $right.ParsedDomain

The results of these threat hunts can provide insight into the scope of this issue within your organization. Investing in user awareness training and a secure password management solution can reduce the risk of credentials being leaked or accessed in the case of an infected endpoint and provided greater protection against lateral movement and privilege escalation attacks.

More Articles