Continuous Intrusion – Why CI tools are an attacker's best friends (2015) [pdf]
blackhat.com
blackhat.com
For all these tools, there is documentation on how to lock down access to the server, and also how to run the agents under various users accounts. On my current engagement, for e.g., I ensure that the various GoCD agents run as low privileged users, with access granted via sudo.
Further, running commands directly is easy. But a better pattern is to push these commands into a script, to check in the script into version control, and to then check out and run that script. At least GoCD is opinionated that way by enforcing that users use "materials" (which could be a checkout from a revision control system).
GoCD enforces something called a "sandbox", where the file references are restricted to only the working directory for that particular job. If one needs to access files outside of this sandbox, then one needs to explicitly invoke a shell - after which point the admin/script owner is responsible for what happens. This is because the GoCD admin/script owner permitted either a command interpreter to be invoked directly, or the script owner did so within their script.
I now-a-days deliver scripts as Ansible playbooks using GPG signed RPMs, the execute the Ansible playbooks in local mode.
The non-salted SHA1 passwords is a good report. GoCD lets uses specify either an htpasswd generated file, or an LDAP source. On enterprise implementations, I always link GoCD to an LDAPs source and manage the credentials there.
In short, if one doesn't read the documentation and just implements distributed orchestrators with zero ops sensibilities, then such WTFs of being able to execute any command would of course be possible.
Good CI/CD processes increase not only security (less crufty servers lying around) but also recovery procedures because they force you to be able to deploy... to new, external, backup or refreshed infrastructure, if necessary.
It's unlikely that the author really believes CI tools are so risky that you should avoid them. On the other hand, it's good to know that your CI infrastructure is part of your attack surface; chances are, the author came up with the idea for this talk after exploiting a CI system on a real pentest (I know that happened at Matasano a couple times).
For every project I've set up CI for, it doesn't matter if someone hacks my CI servers because they don't have access to anything other than dummy data. Sure; you could hack prod systems by building a trojan version of one of the binaries. But even then the binaries just get uploaded to a repository; so with proper code profiling and security testing you would notice the rogue binary before it ever hits a prod server.
It is important to keep CI as a dev process -- deployment should be handled by an orchestration system as it's much more of a tech ops process than a dev process. This is where config management and the like become very important; and those should be left to people who think like operations and security managers rather than hackers who just want to make shit work quickly (there's a place for both inside any good dev org).
And all your source code?
The real trick is owning someone's CI system via the code under test. And it's even more versatile because it works even for projects which keep their executor scripts checked in to source.
1) Check out and gain an understanding of the target's CI scripts
2) Create a pull request (or whatever) which makes some reasonable code change but also introduces a vulnerability into the build/test scripts themselves. For example, curl'ing a domain you control.
3) Kick off pre-commit runs of all the tests to see if your patch should be accepted.
4) Own all the devices testing your patch.
GitLab comes with integrated CI. But all the tests are ran by GitLab Runner on external machines. You can spin up (and down) a new machines per test with Runner Autoscale if you want.
As far as I could see GitLab CI is not vulnerable to the items mentioned in the article (apart from only enforcing password length, not complexity).
But CI security is hard so if you find anything please let us know https://about.gitlab.com/disclosure/
You don't need to own the CI server in order to own a project. You can take over all of the individual executors and replace their linker with your own version that links against an attacker-supplied backdoored fork of openssl (for an extreme and topical example). Doesn't even require constantly-running code which might be detected by a monitoring system, and naturally persists across reboots (but not reimagings).
I'm glad that GitLab is paying attention to these things. The Travis which is tightly integrated with GitHub also seems to do a good job, although I haven't looked into it extensively. But plenty of orgs run self-hosted CI that simply isn't up to proper security standards in this respect.
For a deeper review of security problems we're currently focussed on please see https://gitlab.com/gitlab-org/gitlab-ce/issues/21911 and please feel free to contribute there.
IMO some basic isolation measures like clearing the cache between projects would be good. Killing active processes when a job ends.
Why would just anyone have access to production resources - which would be required to take advantage of any of the things he stated.
Also, dev/QA should be on a separate domain anyway.
It was dramatically obvious how bad this was from a security perspective, so perhaps this article isn't necessary, but certainly it's right on the money.
It baffles me really. Most of the time I do it anyway. But we still have a few major holes I've been slowly patching. There's one last glaring problem: permissions are controlled by teams in an external tool. Anyone has auth to change teams in said tool.
Nevertheless, it's a good reminder to consider build servers as part of the attack surface.
The way it works, Circle pushes the containers built to Google Container Registry and there is a super simple tool I built (https://github.com/crufter/puller) pulls those images. This introduces a couple of minutes of delay but we find that acceptable.
I guess we are still exposed to the possibility of someone breaking into Circle, using the keys there to push to our GCR repos, but at least they won't have full access to our servers...
I am not a security expert by any means, and this workflow was not created with security as a priority in any means, but the latter still rubs me in a worse way. It might be just an ignorant hunch though.
You can do this by using oneway in your docker entry point
https://github.com/muayyad-alsadi/oneway/blob/master/README....
Your ci and registry are locked down (a container).
All that might help.
Multi-Factor into the VPN or SSH bastion is a good idea to look at.
My phrase is that it's the Nerve Center of the company. Don't let it get popped.