antiTree | posts and projects
posted by antitree on Jan 25, 2020

It’s been on my list for at least 6 months to start contributing to krew if possible. My first plugin is called net-forward and it’s very simple but confusing if you don’t see what I’m using it for.

Kubectl net-forward

From a user level, net-forward helps you create a forwarding proxy from your machine to an arbitrary IP and port that’s accessible in the cluster. For example if you wanted to connect to another Pod’s service located at 10.0.0.5 on port 80, it would look like this:

kubectl net_forward -i 10.0.0.5 -p 80

You may say this looks a lot like kubectl port-forward, and you’d be right, but there’s a couple of differences that are important.

  1. port-forward only allows you to forward to other Pods/Services in a cluster: This makes sense when you want to play around with other k8s objects but not when you’re debugging or testing other scenarios.
  2. net-forward doesn’t require that you have permission to query other namespaces and services. Unlike port-forward which assume that you’re a privileged user or cluster-admin, net-forward doesn’t do any extra lookup of the service object’s information. This means that if you have a restricted account – such as a compromised service account token or a user account bound to a single namespace – you’ll still be able to make the requests using net-forward.

Example Namespace Isolation

I’ll likely show this in more detail at my Shmoocon talk next week but here’s a scenario that I’ve run into that makes this useful to me. Here’s a diagram of a cluster:

Example Cluster

During a pentest, imagine you’ve compromised the a Pod and you’ve taken over the service account token inside the “secure” namespace shown above. From there you find that you’re able to perform any API function in the context of that namespace but you’re blocked from doing anything in other namespaces such as “default”. But there are no network policies or callico or istio that might restrict networking between those Pods. So if you were to find another service such as the “Webadmin” Pod in the “Default” namespace, you’d like to be able to connect into it.

With port-forward you’d want to execute a command like kubectl port-forward -n default my-pod-name-xxxxx-xxxxxx 8080 which is the Pod name and the port you want to connect into. That doesn’t work here.

In this scenario, you don’t have the name of the Pod, you only have the IP address and port you want to connect to which might be 10.0.0.5:5000. This is where net-forward becomes useful because there are no constraints on what you can connect in with.

You could simply run kubectl net_forward -i 10.0.0.5 -p 5000 and you’ll have a listener created for you on your local machine on port 9999 and you’re now able to target this new service with all your favorite tools from the comfort of your personal laptop that has all your favorite tools on it.

Example Metadata Service

I can make it even simplier. What if you wanted to make a direct connection to your cloud provider’s metadata endpoint. We know that this is a juicy location for pentesters to target because in some cases it lets you access sensitive information such as cloud credentials.

There’s currently no way to do it with kubectl port-forward but you can do it with kubectl net_forward.

$ kubectl net_forward -i 169.254.169.254 -p 80`

This gives you direct access to the metadata endpoint accessible to the cluster you’ve compromised.

Technical Details

This tool works in the same way as port-forward which creates a socat Pod and tells it to redirect to whatever service you tell it. It is equivilent of running the following:

$ kubectl run -n secure --restart=Never \
  --image=alpine/socat socat1 \
  -- -d -d tcp-listen:9999,fork,reuseaddr tcp-connect:10.0.0.5:5000
$ kubectl port-forward -n secure socat1 9999

Krew for pentesters

This is just a simple script that would make me more comfortable going through the Krew review process. I’m definitely pushing the boundaries about what’s worthwhile to include within Krew. Krew is designed for cluster operators to debug and mess around with their cluster. I have different operating constraints. The Krew folks were really helpful and provided questions that I replied to about the intention of the plugin. I plan to put more tools into Krew with kind of specific operating constraints in the future so I hope I don’t piss any of them off.

You can install net-forward today with:

$ kubectl krew install net-forward