Skip to content

Commit

Permalink
New notebooks - Low Hanging fruits (#235)
Browse files Browse the repository at this point in the history
* Adding new workflow notebooks

* Modifying existing notebook for KHaaS

* PR comments

* Last PR comment

* Update deployments/kubehound/notebook/LowHangingFruit-ContainerEscape.ipynb

Co-authored-by: Simon Maréchal <[email protected]>

* Update deployments/kubehound/notebook/LowHangingFruit-ContainerEscape.ipynb

Co-authored-by: Simon Maréchal <[email protected]>

* Update deployments/kubehound/notebook/LowHangingFruit-ContainerEscape.ipynb

Co-authored-by: Simon Maréchal <[email protected]>

* Update deployments/kubehound/notebook/LowHangingFruit-ContainerEscape.ipynb

Co-authored-by: Simon Maréchal <[email protected]>

* Update deployments/kubehound/notebook/LowHangingFruit-Endpoints.ipynb

Co-authored-by: Simon Maréchal <[email protected]>

* Update deployments/kubehound/notebook/LowHangingFruit-Endpoints.ipynb

Co-authored-by: Simon Maréchal <[email protected]>

* Update deployments/kubehound/notebook/LowHangingFruit-Endpoints.ipynb

Co-authored-by: Simon Maréchal <[email protected]>

* Update deployments/kubehound/notebook/LowHangingFruit-Endpoints.ipynb

Co-authored-by: Simon Maréchal <[email protected]>

---------

Co-authored-by: Simon Maréchal <[email protected]>
  • Loading branch information
jt-dd and Minosity-VR authored Aug 2, 2024
1 parent 99d9e3d commit 358f2b4
Show file tree
Hide file tree
Showing 9 changed files with 1,445 additions and 660 deletions.
129 changes: 68 additions & 61 deletions deployments/kubehound/notebook/BlueTeam.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
},
"outputs": [],
"source": [
"%%capture \"Remove this line to see debug information\"\n",
"%%graph_notebook_vis_options\n",
"{\n",
" \"edges\": {\n",
Expand Down Expand Up @@ -72,12 +73,13 @@
"outputs": [],
"source": [
"%%gremlin\n",
"kh.identities().\n",
" or(\n",
"kh.identities()\n",
" .has(\"runID\", graph.variables().get('runID_yourid').get())\n",
" .or(\n",
" has(\"type\", \"Group\").has(\"name\", within(\"dept-sales\", \"k8s-users\")),\n",
" has(\"type\", \"User\").has(\"name\", \"[email protected]\")).\n",
" hasCriticalPath().\n",
" values(\"name\")"
" has(\"type\", \"User\").has(\"name\", \"[email protected]\"))\n",
" .hasCriticalPath()\n",
" .values(\"name\")"
]
},
{
Expand All @@ -95,13 +97,14 @@
"source": [
"\n",
"%%gremlin -d class -g critical -le 50 -p inv,oute\n",
"kh.identities().\n",
" or(\n",
"kh.identities()\n",
" .has(\"runID\", graph.variables().get('runID_yourid').get())\n",
" .or(\n",
" has(\"type\", \"Group\").has(\"name\", within(\"dept-sales\", \"k8s-users\")),\n",
" has(\"type\", \"User\").has(\"name\", \"[email protected]\")).\n",
" criticalPaths().\n",
" by(elementMap()).\n",
" limit(100) // Limit the number of results for large clusters\n"
" has(\"type\", \"User\").has(\"name\", \"[email protected]\"))\n",
" .criticalPaths()\n",
" .by(elementMap())\n",
" .limit(100) // Limit the number of results for large clusters"
]
},
{
Expand Down Expand Up @@ -129,13 +132,14 @@
"outputs": [],
"source": [
"%%gremlin\n",
"kh.containers().\n",
" or(\n",
"kh.containers()\n",
" .has(\"runID\", graph.variables().get('runID_yourid').get())\n",
" .or(\n",
" has(\"image\", TextP.containing(\"nginx\")), // Replace with your image name\n",
" has(\"image\", TextP.containing(\"cilium\"))). // Replace with your image name\n",
" hasCriticalPath().\n",
" values(\"name\").\n",
" dedup()"
" has(\"image\", TextP.containing(\"cilium\"))) // Replace with your image name\n",
" .hasCriticalPath()\n",
" .values(\"name\")\n",
" .dedup()"
]
},
{
Expand All @@ -152,13 +156,14 @@
"outputs": [],
"source": [
"%%gremlin -d class -g critical -le 50 -p inv,oute\n",
"kh.containers().\n",
" or(\n",
"kh.containers()\n",
" .has(\"runID\", graph.variables().get('runID_yourid').get())\n",
" .or(\n",
" has(\"image\", TextP.containing(\"nginx\")), // Replace with your image name\n",
" has(\"image\", TextP.containing(\"cilium\"))). // Replace with your image name\n",
" criticalPaths().\n",
" by(elementMap()).\n",
" limit(100) // Limit the number of results for large clusters"
" has(\"image\", TextP.containing(\"cilium\"))) // Replace with your image name\n",
" .criticalPaths()\n",
" .by(elementMap())\n",
" .limit(100) // Limit the number of results for large clusters"
]
},
{
Expand Down Expand Up @@ -186,15 +191,17 @@
"outputs": [],
"source": [
"%%gremlin\n",
"kh.containers().\n",
" where(out().hasLabel(\"Node\")).\n",
" or(\n",
"kh.containers()\n",
" .has(\"runID\", graph.variables().get('runID_yourid').get())\n",
" .where(out().hasLabel(\"Node\"))\n",
" .or(\n",
" has(\"image\", TextP.containing(\"nginx\")), // Replace with your image name\n",
" has(\"image\", TextP.containing(\"cilium\"))). // Replace with your image name\n",
"\tproject('image',\"escapes\").\n",
"\tby(values(\"image\")).\n",
"\tby(outE().where(inV().hasLabel(\"Node\")).label().fold()).\n",
"\tdedup()"
" has(\"image\", TextP.containing(\"cilium\")) // Replace with your image name\n",
" ) \n",
" .project('image',\"escapes\")\n",
" .by(values(\"image\"))\n",
" .by(outE().where(inV().hasLabel(\"Node\")).label().fold())\n",
" .dedup()"
]
},
{
Expand All @@ -215,11 +222,12 @@
"outputs": [],
"source": [
"%%gremlin \n",
"kh.containers().\n",
" or(\n",
"kh.containers()\n",
" .has(\"runID\", graph.variables().get('runID_yourid').get())\n",
" .or(\n",
" has(\"image\", TextP.containing(\"nginx\")), // Replace with your image name\n",
" has(\"image\", TextP.containing(\"cilium\"))). // Replace with your image name\n",
" minHopsToCritical()"
" has(\"image\", TextP.containing(\"cilium\"))) // Replace with your image name\n",
" .minHopsToCritical()"
]
},
{
Expand All @@ -236,23 +244,21 @@
"outputs": [],
"source": [
"%%gremlin -d class -g critical -le 50 -p inv,oute\n",
"kh.containers().\n",
" or(\n",
"kh.containers()\n",
" .has(\"runID\", graph.variables().get('runID_yourid').get())\n",
" .or(\n",
" has(\"image\", TextP.containing(\"nginx\")), // Replace with your image name\n",
" has(\"image\", TextP.containing(\"cilium\"))). // Replace with your image name\n",
" \n",
" repeat(\n",
" outE().inV().simplePath()).\n",
" emit().\n",
" until(\n",
" has(\"critical\", true).\n",
" or().\n",
" loops().\n",
" is(4)). // Use result from previous cell\n",
" has(\"critical\", true).\n",
" dedup().\n",
" path().\n",
" by(elementMap())"
" has(\"image\", TextP.containing(\"cilium\"))) // Replace with your image name\n",
" .repeat(\n",
" outE().inV().simplePath())\n",
" .emit()\n",
" .until(\n",
" has(\"critical\", true)\n",
" .or().loops().is(4))\n",
" .has(\"critical\", true)\n",
" .dedup()\n",
" .path()\n",
" .by(elementMap())"
]
},
{
Expand All @@ -271,17 +277,18 @@
"outputs": [],
"source": [
"%%gremlin -d name -g class -le 50 -p inv,oute\n",
"kh.containers().\n",
" or(\n",
"kh.containers()\n",
" .has(\"runID\", graph.variables().get('runID_yourid').get())\n",
" .or(\n",
" has(\"image\", TextP.containing(\"nginx\")),\n",
" has(\"image\", TextP.containing(\"cilium\"))).\n",
" \trepeat(\n",
" outE().inV().simplePath()).\n",
" times(5). // Increase to expand the potential blast radius, but graph size will increase exponentially!\n",
" emit().\n",
" path().\n",
" by(elementMap()).\n",
" limit(100) // Limit the number of results for large clusters"
" has(\"image\", TextP.containing(\"cilium\")))\n",
" \t.repeat(\n",
" outE().inV().simplePath())\n",
" .times(5) // Increase to expand the potential blast radius, but graph size will increase exponentially!\n",
" .emit()\n",
" .path()\n",
" .by(elementMap())\n",
" .limit(100) // Limit the number of results for large clusters"
]
}
],
Expand Down
150 changes: 150 additions & 0 deletions deployments/kubehound/notebook/InitialSetup.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"execution": {
"iopub.execute_input": "2024-07-24T14:46:25.538529Z",
"iopub.status.busy": "2024-07-24T14:46:25.538280Z",
"iopub.status.idle": "2024-07-24T14:46:25.545724Z",
"shell.execute_reply": "2024-07-24T14:46:25.545041Z",
"shell.execute_reply.started": "2024-07-24T14:46:25.538501Z"
},
"frozen": false,
"init_cell": true,
"tags": [
"safe_output"
]
},
"source": [
"# Autoloading\n",
"\n",
"Loading graph visualisation settings."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"init_cell": true
},
"outputs": [],
"source": [
"%%capture \"Remove this line to see debug information\"\n",
"%%graph_notebook_vis_options\n",
"{\n",
" \"edges\": {\n",
" \"smooth\": {\n",
" \"enabled\": true,\n",
" \"type\": \"dynamic\"\n",
" },\n",
" \"arrows\": {\n",
" \"to\": {\n",
" \"enabled\": true,\n",
" \"type\": \"arrow\"\n",
" }\n",
" }\n",
" }\n",
"}"
]
},
{
"cell_type": "markdown",
"metadata": {
"frozen": false,
"tags": [
"unsafe_output"
]
},
"source": [
"# Initial Setup\n",
"\n",
"## Get a view of all Ingested Cluster\n",
"\n",
"Retrieve all the current cluster ingested in KubeHound with the associated runID with the number of nodes. This numbers can be used to get a clue of the size of the cluster and also identify if an ingestion did not complete."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"execution": {
"iopub.execute_input": "2024-07-24T14:46:28.273187Z",
"iopub.status.busy": "2024-07-24T14:46:28.272852Z",
"iopub.status.idle": "2024-07-24T14:46:28.625859Z",
"shell.execute_reply": "2024-07-24T14:46:28.625126Z",
"shell.execute_reply.started": "2024-07-24T14:46:28.273156Z"
},
"frozen": false,
"init_cell": true,
"tags": [
"safe_output"
]
},
"outputs": [],
"source": [
"%%gremlin -d class -g critical -le 50 -p inv,oute\n",
"\n",
"kh.nodes()\n",
" .groupCount()\n",
" .by(project('cluster','runID')\n",
" .by('cluster').by('runID'))\n",
" .unfold()\n",
" .limit(1000)"
]
},
{
"cell_type": "markdown",
"metadata": {
"frozen": false,
"tags": [
"unsafe_output"
]
},
"source": [
"## Setting your run_id/cluster\n",
"\n",
"Set which runID you want to use. The variable are being shared with all users of the instance, so we advise to make a uniq string for your user `runID_yourid` to avoid any conflict."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"frozen": false,
"tags": [
"safe_output"
]
},
"outputs": [],
"source": [
"%%gremlin -d class -g critical -le 50 -p inv,oute\n",
"\n",
"graph.variables()\n",
" .set('runID_yourid','01htdgjj34mcmrrksw4bjy2e94')"
]
}
],
"metadata": {
"celltoolbar": "Initialization Cell",
"kernelspec": {
"display_name": "Python 3 (default)",
"language": "python",
"name": "ipykernel-default"
},
"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.10.13"
}
},
"nbformat": 4,
"nbformat_minor": 4
}
26 changes: 14 additions & 12 deletions deployments/kubehound/notebook/KindCluster_Demo.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
},
"outputs": [],
"source": [
"%%capture \"Remove this line to see debug information\"\n",
"%%graph_notebook_vis_options\n",
"{\n",
" \"edges\": {\n",
Expand Down Expand Up @@ -172,18 +173,19 @@
"outputs": [],
"source": [
"%%gremlin -d label -g class -le 50 -p inv,oute\n",
"kh.endpoints().not(has(\"serviceEndpoint\",\"kube-dns\")).\n",
"\trepeat(\n",
"\t\toutE().inV().\n",
"\t\tsimplePath()).\n",
"\tuntil(\n",
"\t\thasLabel(\"Node\").\n",
"\t\tor().\n",
"\t\tloops().is(5)).\n",
"\thasLabel(\"Node\").\n",
"\tpath().\n",
"\tby(elementMap()).\n",
" limit(100)\t// Limit the number of results for large clusters"
"kh.endpoints().not(has(\"serviceEndpoint\",\"kube-dns\"))\n",
"\t.repeat(\n",
"\t\toutE().inV().simplePath()\n",
"\t)\n",
"\t.until(\n",
"\t\thasLabel(\"Node\")\n",
"\t\t.or()\n",
"\t\t.loops().is(5)\n",
"\t)\n",
"\t.hasLabel(\"Node\")\n",
"\t.path()\n",
"\t.by(elementMap())\n",
"\t.limit(100)\t// Limit the number of results for large clusters"
]
},
{
Expand Down
Loading

0 comments on commit 358f2b4

Please sign in to comment.