On November 1st, Dropbox disclosed a security breach where the attackers stole over 130 code repositories after gaining access to one of the employee’s GitHub accounts using the stolen credentials of that employee via a well-designed phishing attack.
If the attacker gains access to Dropbox engineer’s GitHub login details by pretending to be CircleCI (via a sophisticated phishing attack whereby they spoofed a circleci.com email address), they can use that information to get into the Dropbox GitHub organization, and then exfiltrate data from those private Git repos.
The Dropbox employees use their GitHub accounts to access Dropbox’s private code repos, and their GitHub login details also get them into CircleCI.
It’s important to note that this is not a brand new occurrence of CircleCI phishing attempts. Three weeks prior to the attack, GitHub warned of phishing campaigns that involved impersonation of CircleCI. Dropbox was a victim of this existing campaign where the phishing emails masqueraded as real CircleCI emails.
Known threat attack – phishing
While education around phishing emails is important to prevent another Dropbox-style breach from happening to your business or organization, there are many other ways that adversaries can gain access to your Github accounts. With open source Falco, the cloud-native runtime security project, we can address some of the GitHub security flaws that lead to a breach. We can extend Falco’s threat detection across cloud environments and 3rd party services, like GitHub, by use of Falco Plugins.
Github plugin for Falco
The Falco libraries and Falco itself can be extended by using Plugins.
Plugins are shared libraries that conform to a documented API and allow for:
- Adding new event sources that can be evaluated using filtering expressions/Falco rules.
- Adding the ability to define new fields that can extract information from events.
The recently announced GitHub plugin for Falco should address the below security flaws that usually lead to common breaches, including but not limited to the Dropbox attack. Before we discuss the attack vectors commonly used against GitHub, it makes sense to quickly explain how the plugin operates.
Integrating Falco with GitHub is rather simple. The below steps play out:
- Falco is given a GitHub token.
It uses the token to set up a webhook for each of the repositories that you specify. - It then listens to every message sent by GitHub on those webhooks.
Falco filters and interprets the message’s data, and sends you meaningful alerts when something bad happens, in a matter of seconds. - You can route these alerts to your favorite notification channels (email, Slack, a SIEM tool) or you can leverage them in a response engine to automatically remediate the issue.
Note: Falco operates in true streaming fashion: it doesn’t copy, store or index any data.
This makes it inexpensive, easy to run, and super responsive.
Detect pushing secrets into Git repos
While the employee credentials in the Dropbox case were stolen via a phishing attack, in many breaches the secrets are simply pushed into Git repositories without even thinking about it. In cloud-native applications, secrets are objects that contain a small amount of sensitive data such as a password, a token, or a key.
Using a Secret means that you don’t need to include confidential data in your application code. However, secrets should not be accessible within public or private repositories. Since this is usually done unintentionally, or without any thoughts as to the risk it could cause, security teams should be notified when secrets are pushed to public/private Git repos.
Below is a Falco rule that can detect when secrets are pushed to a public repository. Immediately, you should notice the source: github
used for the Github plugin. When the condition
in one of the rules is met, Falco will send you a message formatted as specified by the output
field, which includes a bunch of useful contexts.
- rule: Secret pushed into a public repository
desc: A secret (AWS keys, github token...) was committed into a public repository
condition: >
github.type=push
and github.diff.has_secrets = true
and github.repo.public=true
output: >
One or more secrets were pushed into a public repository
(repository=%github.repo repo_owner=%github.owner org=%github.org
user=%github.user secret_types=%github.diff.committed_secrets.desc
file=%github.diff.committed_secrets.files
line=%github.diff.committed_secrets.lines
url=%github.diff.committed_secrets.links)
priority: CRITICAL
source: github
Code language: JavaScript (javascript)
As you can see above, Falco rules provide a somewhat humanly-readable YAML format. As such, it is rather simple for security teams to customize these YAML files, or create new ones that fit your specific business needs.
To build a Falco rule for instances where secrets are pushed to private repos, the rule is only slightly modified.
- rule: Secret pushed into a private repository
desc: A secret (AWS keys, github token...) was committed into a private repository
condition: github.type=push and github.diff.has_secrets = true and github.repo.public=false
output: One or more secrets were pushed into a private repository (repository=%github.repo repo_owner=%github.owner org=%github.org user=%github.user secret_types=%github.diff.committed_secrets.desc file=%github.diff.committed_secrets.files line=%github.diff.committed_secrets.lines url=%github.diff.committed_secrets.links)
priority: CRITICAL
source: github
Code language: JavaScript (javascript)
In the case of the Dropbox breach, 130 private repos are now accessible to the adversaries. If secrets were pushed to those private repos, again, intentional or not – the attackers could now scrape those sensitive credentials which could give them access to additional services or infrastructure.
That’s why it’s important to monitor these insecure behaviors, so that even if we are breached, we are doing our best to limit the blast radius.
The only difference between the public and private Falco rules was changing the github.repo.public
condition from ‘true’ to ‘false’.
Similar to how easy it was to build Falco rules, Falco Plugins are rather straightforward to develop. The Falco community team organized a useful session on YouTube, showing how to build a Hashicorp Nomad plugin for Falco or you can also investigate more in the article about the Okta plugin to detect MFA spam attacks.
Adding/Removing collaborators from GitHub
While the Dropbox breach involved the use of stolen credentials from an employee, they likely performed all actions in GitHub as the impersonated user. Assuming we are dealing with an insider threat, or someone who gained access to a user account with elevated permissions, they could attempt to add additional collaborators to the project and evade detection as a “legitimate” user on the project.
We can create 2 simple Falco rules to detect when a collaborator is added (whether legitimate or not), as well as when collaborators have been removed. If an attacker wants to take over the account, they could try removing the existing collaborators. The below Falco rule will detect those attempts:
- rule: Remove Collaborator from Repository
desc: Detect the removal of a collaborator from a repository
condition: github.type=member and github.action=removed
output: A collaborator was removed from a repository (repository=%github.repo repo_owner=%github.owner org=%github.org user=%github.user collaborator=%github.collaborator.name)
priority: INFO
source: github
Code language: JavaScript (javascript)
If they were attempting to add a non-corporate email address to the project – ie: [email protected], we should see this under the collaborator
field of the Falco rule output.
While most of these alerts are considered to be priority “informational”, you should these INFO alerts as some of the earliest possible Indicator of Compromise (IoC) for Github:
- rule: Add Collaborator to Repository
desc: Detect the addition of a collaborator to a repository
condition: github.type=member and github.action=added
output: A collaborator was added to a repository (repository=%github.repo repo_owner=%github.owner org=%github.org user=%github.user collaborator=%github.collaborator.name role=%github.collaborator.role)
priority: INFO
source: github
Code language: JavaScript (javascript)
Private repository becoming public
In the case of the Dropbox incident, after the attacker stole the employee credentials, they gained access to one of Dropbox’s GitHub organizations and were able to steal the 130+ code repositories.
It’s worth noting that Github “did not include code for our core apps or infrastructure. Access to those repositories is even more limited and strictly controlled,” the company added.
In this scenario the Dropbox team had repos with different levels of restrictions that were not subject to data exfiltration. Unfortunately, just like the secrets being made public, many organizations do the same to their private repositories. Thankfully, this exact behavior did not happen to Dropbox!
- rule: Private Repository Becoming Public
desc: Detect changing the visibility of a repository to public
condition: >
github.type=repository and github.action=publicized
output: >
A repository went from private to public
(repository=%github.repo repo_owner=%github.owner
org=%github.org user=%github.user)
priority: CRITICAL
source: github
Code language: JavaScript (javascript)
Again, having a private repository does not make your code safe if the credentials to access that private repo are already stolen. But to keep with the analogy of security in houses, having a public repository with company code in it is like having a house without a door. It’s critical that we do not make the repository public, however, we also need to be able to prevent potential data exfiltration from services like Github.
GitHub confirms that they detected content exfiltration from the private repositories almost immediately after the compromise, with the threat actors using VPN or proxy services to make tracing them more difficult. Any attempt to perform Git Clone, or change the visibility of the repository to ‘public’ should be treated with ‘critical’ priority.
Crypto mining through GitHub Actions
Again, as bad as the Dropbox breach was – and the loss of confidential business information is a major concern for any organization – the attack surface in Github could have caused additional head-aches.
In Github, a feature known as GitHub Actions offer the ability to run arbitrary code in response to selected GitHub events (for example, merging a PR). Github Actions is a great way to extend code repositories with automation and integrations.
Recently, the Sysdig Threat Research Team uncovered a massive cryptomining operation leveraging GitHub Actions. The activity observed is known as “freejacking,” which is the abuse of compute allocated for free trial accounts on CI/CD platforms. While this freejacking is not new, the frequency of these attacks has been increasing in-line with the rate that new cloud services are created and offered for free.
The increase of cryptocurrency mining holds especially true in situations that allow malicious actors to scale their attacks, so much so that even a few hours here or there can be quite profitable. The below Falco rule can detect specifically when Github actions are being used with miners.
- rule: Github action with miners
desc: a github action containing crypto miners was executed
condition: >
github.type=workflow_run and github.workflow.has_miners=true
output: >
a github action containing crypto miners was executed
(repository=%github.repo repo_owner=%github.owner org=%github.org
user=%github.user file=%github.workflow.filename)
priority: CRITICAL
source: github
Code language: JavaScript (javascript)
Note how the condition field filters for webhook messages of type workflow_run that point to the execution of miners. Github.workflow.has_miners is a separate macro that fetches the workflow’s definition file and scans it line by line, looking for patterns that identify the execution of one of the well known miner binaries such as xmrig.
Conclusion
Despite the problem of pushing secrets to public git repos is fairly well known at this point, many high-profile data breaches happened over the years because of secret leaks, including a very recent one at Toyota. With the Github plugin for Falco, we can alert on this kind of misconfiguration before we make additional mistakes like it.
We mentioned how cryptomining gangs are abusing free cloud computing platforms. The list of services that have been abused this way includes the likes of GitLab, Microsoft Azure, TravisCI, LayerCI, CircleCI, Render, CloudBees CodeShip, Sourcehut, and Okteto. It’s not uniquely a GitHub problem. There are endless opportunities for Falco plugins in the cloud-native ecosystem that can detect crypto-mining abuse within services.
In the case of the recent Dropbox GitHub breach, like all other breaches, it started with an employee’s credentials being accessed via a sophisticated phishing attack. Once in, we need to monitor the extent of the damage. With Falco plugins we can detect post explorations attempts to gain persistence adding or removing collaborators from a project.
Since Falco ruleset is customizable, it is easy to build security rules specifically around newly-discovered threats in Github – not just the example of cryptomining. We currently identify a bunch of common secrets types that could be exposed within your Git repos. However, adding a new secret detection is simply a matter of adding a new entry in the secretsChecks array in secrets.go.
If you would like to create your own Falco plugin, visit the Falco plugin development guide.