Using Crowstrike Real Time Response, we're able to deploy Canarytokens onto various endpoints. Below we'll walk through the configuration required to execute a Powershell script onto an endpoint configured with the Falcon agent.
The script will perform the following:
- Create a new AWS API key Canarytoken
- Download an enticing MS Word document from a private Github repository
- Tokenise the downloaded MS Word document
- Embed the AWS API key into the document
- Perform Timestomping on the newly placed stacked Canarytoken
There's no need to go this complex, a simple token would do, but we figured we'd experiment with automated token stacking.
Github
Personal access token
We'll create a personal access token on Github. The purpose of the token is to allow us to download an MS Word template from a private Github repository. The template can contain some enticing information and should include some text which the script will replace with an AWS API key Canarytoken.
Head over to your Github account, go to "settings" and finally "Developer settings" (Or click on the link here). Create a new token by clicking the "Generate new token" button. You can set the lifetime of the token to a little as possible and reduce the scope of the token to "repo" only.
Private repository
Create a new private repository where you will host your MS Word template. Head over to https://github.com/new, select the private repository radio button and click on "Create repository".
Template MS Word document
Next, we'll create an MS Word document (sample.docx) containing some enticing text as well as two placeholders. This can be any unique text ("meep", "sheep") that we'll replace with an AWS API key.
Upload the document to your private repository either using git cli or by simply clicking the "add file" button on the user interface.
Now we're ready to configure Crowdstrike and make some final adjustments to the tokenisation script.
Crowdstrike Configuration
Host Group
In your Crowdstrike Console, head over to "Host setup and management" then select "Host groups" and create a group of hosts you would like to deploy Canarytokens onto.
The new Host group will be empty, and we'll need to assign hosts and a response policy to the group. Click "Add Hosts" and select the applicable hosts.
Response Policy
In your Crowdstrike Console head over to "Host setup and management" then select "Response Policies" and create your policy.
Next select "Real Time Response" and enable "Custom Scripts" on the policy. Subsequently "Enable" and "Save" the policy.
Click on the "ASSIGNED HOST GROUPS" tab and select the host group created above.
Response Scripts and Files
Now that we've configured the relevant hosts and permissions to execute scripts, we need to upload the script to CrowdStrike. We'll need to make some modifications to the script and upload it.
Download Invoke-EmbedWordwithAWS.ps1 and modify the following variables:
Replace the empty "Domain" and "FactoryAuth" variables with your applicable values.
(Get-Content .\Invoke-EmbedWordwithAWS.ps1) | %{ $_ -replace "Domain = '1234abc.canary.tools'", "Domain = 'xxxxyyyy.canary.tools'"} | Set-Content .\Invoke-EmbedWordwithAWS.ps1
(Get-Content .\Invoke-EmbedWordwithAWS.ps1) | %{ $_ -replace "FactoryAuth = 'a1bc3e769fg832hij3'", "FactoryAuth = 'aaaaaaaaaaaaaaabbbbbbbbbbbbbbbbb'"} | Set-Content .\Invoke-EmbedWordwithAWS.ps1
Substitute the value within the "pathToTemplateFile" with your newly created repository and template file. Private Repo's use the github API and it's URL should should follow the format of https://api.github.com/repos/repo_owner/private_repo_name/contents/sample.docx
(Get-Content .\Invoke-EmbedWordwithAWS.ps1) | %{ $_ -replace "pathToTemplateFile = 'https://api.github.com/repos/repo_owner/private_repo_name/contents/sample.docx'", "pathToTemplateFile = 'https://api.github.com/repos/tkempheks/vigilant-chainsaw/contents/sample.docx'"} | Set-Content .\Invoke-EmbedWordwithAWS.ps1
Substitute the values within the "FindText" and "FindText2" variables. In the document above these values were set to "meep" and "sheep". The script will replace meep and sheep with valid AWS API key credentials.
(Get-Content .\Invoke-EmbedWordwithAWS.ps1) | %{ $_ -replace "FindText = 'AKIASJ2WZMVFQGNWG4HA'",
"FindText = 'meep'"} | Set-Content .\Invoke-EmbedWordwithAWS.ps1
(Get-Content .\Invoke-EmbedWordwithAWS.ps1) | %{ $_ -replace "FindText2 = 'zXqAw2NlqNdha1IVCBNkIdv74AdfPw6MMb6xKBw5'",
"FindText2 = 'sheep'"} | Set-Content .\Invoke-EmbedWordwithAWS.ps1
Substitute the "Personal_Access_Token" variable with the token created in Github.
(Get-Content .\Invoke-EmbedWordwithAWS.ps1) | %{ $_ -replace "Personal_Access_Token = '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'",
"Personal_Access_Token = 'ghp_9Ue8C5uaaaaaBmW8yf3HbbbbbGiX90SWEaa'"} | Set-Content .\Invoke-EmbedWordwithAWS.ps1
Finally, substitute the values in the "mainFolder" and "randomCanaryToken" array. This will create a randomised folder structure and filename for your stacked Canarytoken.
(Get-Content .\Invoke-EmbedWordwithAWS.ps1) | %{ $_ -replace "'Application1','Application2','Application3'",
"'VMware','Cisco','Splunk'"} | Set-Content .\Invoke-EmbedWordwithAWS.ps1
(Get-Content .\Invoke-EmbedWordwithAWS.ps1) | %{ $_ -replace "'doc1.docx', 'doc2.docx'",
"'backup_credentials.docx', 'access_information.docx'"} | Set-Content .\Invoke-EmbedWordwithAWS.ps1
Head over to "Host setup and management" then select the "CUSTOM SCRIPTS" tab and hit the "Create script" button.
Give the script a name, copy the modified contents into the "SCRIPT" text box and hit "CREATE".
Now we can execute the script using Crowdstrike Falcon and confirm that our template document has been tokenised and embedded with an AWS API Key Canarytoken.
Real Time Response
Using Real Time Response we can now establish a shell onto our endpoint and execute the script we uploaded. Navigate to your host under Host Management and hit the "Connect to Host" button.
With the interactive shell on the host execute the script. This can be achieved by typing out the full command "runscript -CloudFile="deploy_stacked_canary_token" or by clicking on the "SCRIPT NAME" under the "Custom scripts" tab. This will automatically type out the above mentioned command. Click on the "RUN" button.
Real Time Response (Optional)
It's also possible to automate the deployment leveraging the Crowdstrike Falcon API. Below are the steps to execute the script using the API. In your Crowdstrike Console, head over to "Support and resources" then select "API clients and keys" and create a new API client.
Enter a "CLIENT NAME", "DESCRIPTION" and select the necessary permissions as indicated below.
Creating the API now provides a client_id and client_secret which are required in the API calls below.
The following API calls can be made to execute the script onto various endpoints. Replace the "client_id" and "client_secret" with your applicable values to obtain a valid bearer token.
curl -X POST \
--data-binary 'client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET' \
https://api.us-2.crowdstrike.com/oauth2/token
The command produces a bearer token required in the subsequent API calls:
eyJhbGciOiJSUzI1NiIsImtpZCI6InB1YmxpYzo3ODdlZjkxZC01YzMxLTQ3YzktYjg0Ni1kNDIzNTk1M2FmYWEiLCJ0eXAiOiJKV1QifQ.eyJhdWQiOltdLCJjbGllbnRfaWQiOiI5ZGRiYjYwZThiM2I0ODI3OWFlNWRiOWUwZTgyMGM5MSIsImV4cCI6MTY1NzU2MDMxOSwiZXh0Ijp7fSwiaWF0IjoxNjU3NTU4NTE5LCJpc3MiOiJodHRwczovL2FwaS5jcm93ZHN0cmlrZS5jb20udG9kby8iLCJqdGkiOiJlNDM1YmNiMi1jNmIzLTRkMTctOTkyMy0zOWFiNWQwYzE0YjIiLCJuYmYiOjE2NTc1NTg1MTksInNjcCI6W10sInN1YiI6IjlkZGJiNjBlOGIzYjQ4Mjc5YWU1ZGI5ZTBlODIwYzkxIiwic3ViX3R5cGUiOm51bGx9.iILADwruTaLsVvihVqFBN5p_ctBRuWb_xYp07uXkokI8xFrCNaLu41bzxu2r4l-qi1760P6oTfyGcoJTU3PHzQZ9wwKfvu42JBsXQunNbZhsL6ME_1MdL6R56gPA9_5z567q8Jcp70MGHmtPlNdQWTiSxp2hhxFNqcgKRZ1iee6mZsTq6KAoT34luMhG-TES_Kx2O2m646IAyYqvR93iDdGenNu3LvWDPfRim-bmOspxOQzyagMMG4J-WI5nDvQzauNczh3GuX1y80AoddqepbskaaC5ijNhKyIhA2lLcS9tYdrqBO3JKb_TR4wc4b1ntWCSXOM_pJ5dUfJjLNkl9aLaVUkZAcCkJWtqL6vcgrcb9scaM5zeSTuh-cm-DKtzuhiayxI1Rm5xeShVIZ2z7UUGFcS2isGzglxI3v2czbZdu0UVDh3OY00kvz1zx4wO9Sjz1dVtJA33OdegQAzdYmnl7FSarJvaztOIiacB9Of6mxY8VEGGHoAqwdfSf5F_lGWgJDFbpf9exUzUHSTCFaFiEvJl2mOeNw_usAEh18c0SK7M-TjdUZtyvc26cUJjFlWzkBgmlUEPxZ9UCMDEyXAQLCWIKg3beOhp1L28POo4PeMbzUcMTRvFNi9y-YWKvwJQcoHBwF5khsdalSGH0-vuCh_rRqAiFiRyEVlR_mY
Using the above bearer token grab the host ID you want to deploy the tokens onto.
curl -X GET "https://api.us-2.crowdstrike.com/devices/queries/devices/v1" -H "authorization: Bearer YOUR_BEARER_TOKEN"
The command produces host id's and we'll grab the host ID we want to deploy the token onto.
11355ed91zzz471d8b7fdccac6933096
The next step is to open a real-time-response session and thereafter we'll use the session to execute the same script as above.
curl -X POST "https://api.us-2.crowdstrike.com/real-time-response/combined/batch-init-session/v1?timeout=30&timeout_duration=30s" -H "authorization: Bearer YOUR_BEARER_TOKEN" -H "Content-Type: application/json" -d "{ \"host_ids\": [ \"YOUR_HOST_ID\" ], \"queue_offline\": true}"
The command produces a session_id which is required to execute a command on the endpoint.
c589edf2-1362-4b3c-a444-71630a67d508
Now we have all the information required to execute the runscript command via the API.
curl -X POST \
-H 'Authorization: Bearer YOUR_BEARER_TOKEN' -H $'Content-Type: application/json' \
--data-binary $'{ \"base_command\": \"runscript\", \"command_string\":\"runscript -CloudFile=\\\"deploy_stacked_canarytoken\\\" -CommandLine=\\\"\\\"\", \"device_id\": \"YOUR_DEVICE_ID\", \"id\": 0, \"persist\": true, \"session_id\": \"YOUR_SESSION_ID\"}' \
https://api.us-2.crowdstrike.com/real-time-response/entities/active-responder-command/v1
Now you've deployed the tokens onto the endpoint manually, or by performing a couple API calls mentioned above. Next step, have a look at the alerts.
Canary Alerts
The result is an MS Word Canarytoken dropped in the "C:\ProgramData\Splunk\Backup" folder containing an embedded AWS API key Canarytoken. We'll open up the document which triggers the initial alert and subsequently perform an AWS API call to verify that they key triggers an alert as expected.
Opening up the document above produces the following alert:
The subsequent AWS API call produces the following alert: