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.
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.
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.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
.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:
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.
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.
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
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