{ "cells": [ { "cell_type": "code", "execution_count": 1, "id": "9b75c9a1-99f3-42be-913c-2e38e0191a19", "metadata": {}, "outputs": [], "source": [ "from attacktree.models import Action, Block, Detect, Discovery, Edge, Root, Goal\n", "from attacktree.renderer import Renderer\n", "\n", "root = Root(\"Signed up to Azure\")\n", "goal = Goal(\"Access to other tenants data\")" ] }, { "cell_type": "code", "execution_count": 2, "id": "e3e671e0-4f6d-4acf-af95-29bb6029a607", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Goal:4374765040" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Direct path\n", "whoC = root.add(Action(\"Deploy WhoC container to view runtime\"))\n", "omgRunC = whoC.discover(\"OLD runc version 1.0.0-r2\")\n", "exploit = omgRunC.action(\"Deploy exploit container for CVE-2019-5736\")\n", "shell = Root(\"Reverse shell on worker node\")\n", "exploit.add(shell)\n", "creds = shell.discover(\"Read kubelet credentials from disk\")\n", "\n", "describePods = creds.action(\"Call KubeAPI describe pods\")\n", "pods = describePods.discover(\"100+ customer pods on 120 nodes\\nEach customer has their own namespace\")\n", "versions = describePods.discover(\"OLD Kubernetes versions v1.8.4, v1.9.10, v1.10.9\")\n", "anonymousAccess = describePods.discover(\"Kubelets run with anonymous access\")\n", "\n", "otherKubelet = anonymousAccess.action(\"Access another customer's kubelet\")\n", "blockedbyFirewall = otherKubelet.block(\"Blocked by firewall\", implemented=True)\n", "\n", "cve = versions.discover(\"CVE-2018-1002102 kube-api follows 302 redirect\")\n", "exploit2 = cve.action(\"Attempt to redirect to kube-api pod\")\n", "fail = exploit2.block(\"ACI uses a 'bridge' POD which is not impacted by this issue\",implemented=True)\n", "\n", "interesting = exploit2.discover(\"ServiceAccount in 'AuthorizationHeader' of Exec requests\")\n", "bridgeToken = interesting.discover(\"Decoded JWT shows this token belongs to 'bridge' service\")\n", "\n", "accessReview = bridgeToken.action(\"Call SelfSubjectAccessReview with 'bridge' token\")\n", "privs = accessReview.discover(\"Cluster-wide permissions\\npods/exec privilege\")\n", "\n", "gameOver = privs.action(\"Exec into shell on kube-API\")\n", "gameOver.add(goal)\n" ] }, { "cell_type": "code", "execution_count": 3, "id": "34a4cab6-51ec-444e-a286-e979c869e3fb", "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "100be65501814e69952ff4f586e2548c\n", "\n", "Signed up to Azure\n", "\n", "\n", "\n", "22ca9af3cb9f4ebf928389525202540b\n", "\n", "Deploy WhoC container to view runtime\n", "\n", "\n", "\n", "100be65501814e69952ff4f586e2548c->22ca9af3cb9f4ebf928389525202540b\n", "\n", "\n", "Next\n", "\n", "\n", "\n", "329f8a2fe4fa41d7a46f7369644e8a42\n", "\n", "OLD runc version 1.0.0-r2\n", "\n", "\n", "\n", "22ca9af3cb9f4ebf928389525202540b->329f8a2fe4fa41d7a46f7369644e8a42\n", "\n", "\n", "Learn\n", "\n", "\n", "\n", "7797cc26499f40728bc49d61b4ef4672\n", "\n", "Deploy exploit container for CVE-2019-5736\n", "\n", "\n", "\n", "329f8a2fe4fa41d7a46f7369644e8a42->7797cc26499f40728bc49d61b4ef4672\n", "\n", "\n", "Next\n", "\n", "\n", "\n", "7bfd0e4162234ec98266f4c3a2bba654\n", "\n", "Reverse shell on worker node\n", "\n", "\n", "\n", "7797cc26499f40728bc49d61b4ef4672->7bfd0e4162234ec98266f4c3a2bba654\n", "\n", "\n", "\n", "\n", "\n", "b669ca7a2ba64192b6576c8c344a7db3\n", "\n", "Read kubelet credentials from disk\n", "\n", "\n", "\n", "7bfd0e4162234ec98266f4c3a2bba654->b669ca7a2ba64192b6576c8c344a7db3\n", "\n", "\n", "Learn\n", "\n", "\n", "\n", "3575bdd3de2540e9a789795ed78020d8\n", "\n", "Call KubeAPI describe pods\n", "\n", "\n", "\n", "b669ca7a2ba64192b6576c8c344a7db3->3575bdd3de2540e9a789795ed78020d8\n", "\n", "\n", "Next\n", "\n", "\n", "\n", "6f32932f97654639a6be71f020f8472e\n", "\n", "100+ customer pods on 120 nodes\n", "Each customer has their own namespace\n", "\n", "\n", "\n", "3575bdd3de2540e9a789795ed78020d8->6f32932f97654639a6be71f020f8472e\n", "\n", "\n", "Learn\n", "\n", "\n", "\n", "080addb50de6451e8ca9e837296a4aad\n", "\n", "OLD Kubernetes versions v1.8.4, v1.9.10, v1.10.9\n", "\n", "\n", "\n", "3575bdd3de2540e9a789795ed78020d8->080addb50de6451e8ca9e837296a4aad\n", "\n", "\n", "Learn\n", "\n", "\n", "\n", "8df5eeffaa47491da8f05210fae4e053\n", "\n", "Kubelets run with anonymous access\n", "\n", "\n", "\n", "3575bdd3de2540e9a789795ed78020d8->8df5eeffaa47491da8f05210fae4e053\n", "\n", "\n", "Learn\n", "\n", "\n", "\n", "9ac757e6f06b4b9a8df1931c23c4df20\n", "\n", "CVE-2018-1002102 kube-api follows 302 redirect\n", "\n", "\n", "\n", "080addb50de6451e8ca9e837296a4aad->9ac757e6f06b4b9a8df1931c23c4df20\n", "\n", "\n", "Learn\n", "\n", "\n", "\n", "e9485a1a8add4e65891e2c25ad5a21ae\n", "\n", "Attempt to redirect to kube-api pod\n", "\n", "\n", "\n", "9ac757e6f06b4b9a8df1931c23c4df20->e9485a1a8add4e65891e2c25ad5a21ae\n", "\n", "\n", "Next\n", "\n", "\n", "\n", "81fcb88a0c6941afb4d8cff9d209fb01\n", "\n", "ACI uses a 'bridge' POD which is not impacted by this issue\n", "\n", "\n", "\n", "e9485a1a8add4e65891e2c25ad5a21ae->81fcb88a0c6941afb4d8cff9d209fb01\n", "\n", "\n", "Fail\n", "\n", "\n", "\n", "8648efde6dba4f6d824bcc324f1617f3\n", "\n", "ServiceAccount in 'AuthorizationHeader' of Exec requests\n", "\n", "\n", "\n", "e9485a1a8add4e65891e2c25ad5a21ae->8648efde6dba4f6d824bcc324f1617f3\n", "\n", "\n", "Learn\n", "\n", "\n", "\n", "1b3a509adc0f4db89e26536b618c6549\n", "\n", "Decoded JWT shows this token belongs to 'bridge' service\n", "\n", "\n", "\n", "8648efde6dba4f6d824bcc324f1617f3->1b3a509adc0f4db89e26536b618c6549\n", "\n", "\n", "Learn\n", "\n", "\n", "\n", "4fcadf27369840b8bde670010e5499fa\n", "\n", "Call SelfSubjectAccessReview with 'bridge' token\n", "\n", "\n", "\n", "1b3a509adc0f4db89e26536b618c6549->4fcadf27369840b8bde670010e5499fa\n", "\n", "\n", "Next\n", "\n", "\n", "\n", "3a7b49913eb74c44b568b7820bb91c64\n", "\n", "Cluster-wide permissions\n", "pods/exec privilege\n", "\n", "\n", "\n", "4fcadf27369840b8bde670010e5499fa->3a7b49913eb74c44b568b7820bb91c64\n", "\n", "\n", "Learn\n", "\n", "\n", "\n", "b36fe6c46cac485aab7f40d61c3cf78b\n", "\n", "Exec into shell on kube-API\n", "\n", "\n", "\n", "3a7b49913eb74c44b568b7820bb91c64->b36fe6c46cac485aab7f40d61c3cf78b\n", "\n", "\n", "Next\n", "\n", "\n", "\n", "922a555493774a75bd5eb926f516eebd\n", "\n", "Access to other tenants data\n", "\n", "\n", "\n", "b36fe6c46cac485aab7f40d61c3cf78b->922a555493774a75bd5eb926f516eebd\n", "\n", "\n", "\n", "\n", "\n", "c01d3c01085247dc9375700c04e00ea4\n", "\n", "Access another customer's kubelet\n", "\n", "\n", "\n", "8df5eeffaa47491da8f05210fae4e053->c01d3c01085247dc9375700c04e00ea4\n", "\n", "\n", "Next\n", "\n", "\n", "\n", "3e5da008aa3940e6b617239bfb01dffc\n", "\n", "Blocked by firewall\n", "\n", "\n", "\n", "c01d3c01085247dc9375700c04e00ea4->3e5da008aa3940e6b617239bfb01dffc\n", "\n", "\n", "Fail\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Renderer().buildDot22(root)" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.9.5" } }, "nbformat": 4, "nbformat_minor": 5 }