bbot 2.3.2.5915rc0__py3-none-any.whl → 2.3.2.5938rc0__py3-none-any.whl

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.

Potentially problematic release.


This version of bbot might be problematic. Click here for more details.

bbot/__init__.py CHANGED
@@ -1,4 +1,4 @@
1
1
  # version placeholder (replaced by poetry-dynamic-versioning)
2
- __version__ = "v2.3.2.5915rc"
2
+ __version__ = "v2.3.2.5938rc"
3
3
 
4
4
  from .scanner import Scanner, Preset
bbot/cli.py CHANGED
@@ -161,8 +161,11 @@ async def _main():
161
161
  all_modules = list(preset.module_loader.preloaded())
162
162
  scan.helpers.depsinstaller.force_deps = True
163
163
  succeeded, failed = await scan.helpers.depsinstaller.install(*all_modules)
164
- log.info("Finished installing module dependencies")
165
- return False if failed else True
164
+ if failed:
165
+ log.hugewarning(f"Failed to install dependencies for the following modules: {', '.join(failed)}")
166
+ return False
167
+ log.hugesuccess(f"Successfully installed dependencies for the following modules: {', '.join(succeeded)}")
168
+ return True
166
169
 
167
170
  scan_name = str(scan.name)
168
171
 
@@ -96,7 +96,7 @@ class DepsInstaller:
96
96
  self.ensure_root_lock = Lock()
97
97
 
98
98
  async def install(self, *modules):
99
- self.install_core_deps()
99
+ await self.install_core_deps()
100
100
  succeeded = []
101
101
  failed = []
102
102
  try:
@@ -386,13 +386,14 @@ class DepsInstaller:
386
386
  else:
387
387
  log.warning("Incorrect password")
388
388
 
389
- def install_core_deps(self):
389
+ async def install_core_deps(self):
390
390
  to_install = set()
391
391
  to_install_friendly = set()
392
392
  playbook = []
393
393
  self._install_sudo_askpass()
394
394
  # ensure tldextract data is cached
395
395
  self.parent_helper.tldextract("evilcorp.co.uk")
396
+ # install any missing commands
396
397
  for command, package_name_or_playbook in self.CORE_DEPS.items():
397
398
  if not self.parent_helper.which(command):
398
399
  to_install_friendly.add(command)
@@ -400,6 +401,19 @@ class DepsInstaller:
400
401
  to_install.add(package_name_or_playbook)
401
402
  else:
402
403
  playbook.extend(package_name_or_playbook)
404
+ # install ansible community.general collection
405
+ if not self.setup_status.get("ansible:community.general", False):
406
+ log.info("Installing Ansible Community General Collection")
407
+ try:
408
+ command = ["ansible-galaxy", "collection", "install", "community.general"]
409
+ await self.parent_helper.run(command, check=True)
410
+ self.setup_status["ansible:community.general"] = True
411
+ log.info("Successfully installed Ansible Community General Collection")
412
+ except CalledProcessError as err:
413
+ log.warning(
414
+ f"Failed to install Ansible Community.General Collection (return code {err.returncode}): {err.stderr}"
415
+ )
416
+ # construct ansible playbook
403
417
  if to_install:
404
418
  playbook.append(
405
419
  {
@@ -408,6 +422,7 @@ class DepsInstaller:
408
422
  "become": True,
409
423
  }
410
424
  )
425
+ # run playbook
411
426
  if playbook:
412
427
  log.info(f"Installing core BBOT dependencies: {','.join(sorted(to_install_friendly))}")
413
428
  self.ensure_root()
@@ -594,7 +594,6 @@ names = [
594
594
  "rachel",
595
595
  "radagast",
596
596
  "ralph",
597
- "rambunctious",
598
597
  "randy",
599
598
  "raymond",
600
599
  "rebecca",
@@ -31,6 +31,10 @@ class RegexHelper:
31
31
  self.ensure_compiled_regex(compiled_regex)
32
32
  return await self.parent_helper.run_in_executor(compiled_regex.search, *args, **kwargs)
33
33
 
34
+ async def sub(self, compiled_regex, *args, **kwargs):
35
+ self.ensure_compiled_regex(compiled_regex)
36
+ return await self.parent_helper.run_in_executor(compiled_regex.sub, *args, **kwargs)
37
+
34
38
  async def findall(self, compiled_regex, *args, **kwargs):
35
39
  self.ensure_compiled_regex(compiled_regex)
36
40
  return await self.parent_helper.run_in_executor(compiled_regex.findall, *args, **kwargs)
@@ -83,6 +83,7 @@ class BBOTAsyncClient(httpx.AsyncClient):
83
83
  # TODO: re-enable this
84
84
  if self._target.in_scope(str(request.url)):
85
85
  for hk, hv in self._web_config.get("http_headers", {}).items():
86
+ hv = str(hv)
86
87
  # don't clobber headers
87
88
  if hk not in request.headers:
88
89
  request.headers[hk] = hv
bbot/modules/git.py CHANGED
@@ -5,7 +5,7 @@ from bbot.modules.base import BaseModule
5
5
 
6
6
  class git(BaseModule):
7
7
  watched_events = ["URL"]
8
- produced_events = ["FINDING"]
8
+ produced_events = ["FINDING", "CODE_REPOSITORY"]
9
9
  flags = ["active", "safe", "web-basic", "code-enum"]
10
10
  meta = {
11
11
  "description": "Check for exposed .git repositories",
@@ -37,3 +37,10 @@ class git(BaseModule):
37
37
  event,
38
38
  context="{module} detected {event.type}: {description}",
39
39
  )
40
+ await self.emit_event(
41
+ {"url": url.rstrip("config")},
42
+ "CODE_REPOSITORY",
43
+ event,
44
+ tags="git_directory",
45
+ context="{module} detected {event.type}: {description}",
46
+ )
@@ -0,0 +1,270 @@
1
+ import regex as re
2
+ from pathlib import Path
3
+ from subprocess import CalledProcessError
4
+ from bbot.modules.base import BaseModule
5
+
6
+
7
+ class gitdumper(BaseModule):
8
+ watched_events = ["CODE_REPOSITORY"]
9
+ produced_events = ["FILESYSTEM"]
10
+ flags = ["passive", "safe", "slow", "code-enum"]
11
+ meta = {
12
+ "description": "Download a leaked .git folder recursively or by fuzzing common names",
13
+ "created_date": "2025-02-11",
14
+ "author": "@domwhewell-sage",
15
+ }
16
+ options = {
17
+ "output_folder": "",
18
+ "fuzz_tags": False,
19
+ "max_semanic_version": 10,
20
+ }
21
+ options_desc = {
22
+ "output_folder": "Folder to download repositories to",
23
+ "fuzz_tags": "Fuzz for common git tag names (v0.0.1, 0.0.2, etc.) up to the max_semanic_version",
24
+ "max_semanic_version": "Maximum version number to fuzz for (default < v10.10.10)",
25
+ }
26
+
27
+ scope_distance_modifier = 2
28
+
29
+ async def setup(self):
30
+ self.urls_downloaded = set()
31
+ output_folder = self.config.get("output_folder")
32
+ if output_folder:
33
+ self.output_dir = Path(output_folder) / "git_repos"
34
+ else:
35
+ self.output_dir = self.scan.home / "git_repos"
36
+ self.helpers.mkdir(self.output_dir)
37
+ self.unsafe_regex = self.helpers.re.compile(r"^\s*fsmonitor|sshcommand|askpass|editor|pager", re.IGNORECASE)
38
+ self.ref_regex = self.helpers.re.compile(r"ref: refs/heads/([a-zA-Z\d_-]+)")
39
+ self.obj_regex = self.helpers.re.compile(r"[a-f0-9]{40}")
40
+ self.pack_regex = self.helpers.re.compile(r"pack-([a-f0-9]{40})\.pack")
41
+ self.git_files = [
42
+ "HEAD",
43
+ "description",
44
+ "config",
45
+ "COMMIT_EDITMSG",
46
+ "index",
47
+ "packed-refs",
48
+ "info/refs",
49
+ "info/exclude",
50
+ "refs/stash",
51
+ "refs/wip/index/refs/heads/master",
52
+ "refs/wip/wtree/refs/heads/master",
53
+ "logs/HEAD",
54
+ "objects/info/packs",
55
+ ]
56
+ self.info("Compiling fuzz list with common branch names")
57
+ branch_names = [
58
+ "bugfix",
59
+ "daily",
60
+ "dev",
61
+ "develop",
62
+ "development",
63
+ "feat",
64
+ "feature",
65
+ "fix",
66
+ "hotfix",
67
+ "integration",
68
+ "issue",
69
+ "main",
70
+ "master",
71
+ "ng",
72
+ "prod",
73
+ "production",
74
+ "qa",
75
+ "quickfix",
76
+ "release",
77
+ "stable",
78
+ "stage",
79
+ "staging",
80
+ "test",
81
+ "testing",
82
+ "wip",
83
+ ]
84
+ url_patterns = [
85
+ "logs/refs/heads/{branch}",
86
+ "logs/refs/remotes/origin/{branch}",
87
+ "refs/remotes/origin/{branch}",
88
+ "refs/heads/{branch}",
89
+ ]
90
+ for branch in branch_names:
91
+ for pattern in url_patterns:
92
+ self.git_files.append(pattern.format(branch=branch))
93
+ self.fuzz_tags = self.config.get("fuzz_tags", "10")
94
+ self.max_semanic_version = self.config.get("max_semanic_version", "10")
95
+ if self.fuzz_tags:
96
+ self.info("Adding symantec version tags to fuzz list")
97
+ for major in range(self.max_semanic_version):
98
+ for minor in range(self.max_semanic_version):
99
+ for patch in range(self.max_semanic_version):
100
+ self.verbose(f"{major}.{minor}.{patch}")
101
+ self.git_files.append(f"refs/tags/{major}.{minor}.{patch}")
102
+ self.verbose(f"v{major}.{minor}.{patch}")
103
+ self.git_files.append(f"refs/tags/v{major}.{minor}.{patch}")
104
+ else:
105
+ self.info("Adding symantec version tags to fuzz list (v0.0.1, 0.0.1, v1.0.0, 1.0.0)")
106
+ for path in ["refs/tags/v0.0.1", "refs/tags/0.0.1", "refs/tags/v1.0.0", "refs/tags/1.0.0"]:
107
+ self.git_files.append(path)
108
+ return await super().setup()
109
+
110
+ async def filter_event(self, event):
111
+ if event.type == "CODE_REPOSITORY":
112
+ if "git-directory" not in event.tags:
113
+ return False, "event is not a leaked .git directory"
114
+ return True
115
+
116
+ async def handle_event(self, event):
117
+ repo_url = event.data.get("url")
118
+ self.info(f"Processing leaked .git directory at {repo_url}")
119
+ repo_folder = self.output_dir / self.helpers.tagify(repo_url)
120
+ self.helpers.mkdir(repo_folder)
121
+ dir_listing = await self.directory_listing_enabled(repo_url)
122
+ if dir_listing:
123
+ urls = await self.recursive_dir_list(dir_listing)
124
+ result = await self.download_files(urls, repo_folder)
125
+ else:
126
+ result = await self.git_fuzz(repo_url, repo_folder)
127
+ if result:
128
+ await self.sanitize_config(repo_folder)
129
+ await self.git_checkout(repo_folder)
130
+ codebase_event = self.make_event({"path": str(repo_folder)}, "FILESYSTEM", tags=["git"], parent=event)
131
+ await self.emit_event(
132
+ codebase_event,
133
+ context=f"{{module}} cloned git repo at {repo_url} to {{event.type}}: {str(repo_folder)}",
134
+ )
135
+ else:
136
+ self.helpers.rm_rf(repo_folder)
137
+
138
+ async def directory_listing_enabled(self, repo_url):
139
+ response = await self.helpers.request(repo_url)
140
+ if "<title>Index of" in getattr(response, "text", ""):
141
+ self.info(f"Directory listing enabled at {repo_url}")
142
+ return response
143
+ return None
144
+
145
+ async def recursive_dir_list(self, dir_listing):
146
+ file_list = []
147
+ soup = self.helpers.beautifulsoup(dir_listing.text, "html.parser")
148
+ links = soup.find_all("a")
149
+ for link in links:
150
+ href = link["href"]
151
+ if href == "../" or href == "/":
152
+ continue
153
+ if href.endswith("/"):
154
+ folder_url = self.helpers.urljoin(str(dir_listing.url), href)
155
+ response = await self.helpers.request(folder_url)
156
+ if getattr(response, "status_code", 0) == 200:
157
+ file_list.extend(await self.recursive_dir_list(response))
158
+ else:
159
+ file_url = self.helpers.urljoin(str(dir_listing.url), href)
160
+ # Ensure the file is in the same domain as the directory listing
161
+ if file_url.startswith(str(dir_listing.url)):
162
+ url = self.helpers.urlparse(file_url)
163
+ file_list.append(url)
164
+ return file_list
165
+
166
+ async def git_fuzz(self, repo_url, repo_folder):
167
+ self.info("Directory listing not enabled, fuzzing common git files")
168
+ url_list = []
169
+ for file in self.git_files:
170
+ url_list.append(self.helpers.urlparse(self.helpers.urljoin(repo_url, file)))
171
+ result = await self.download_files(url_list, repo_folder)
172
+ if result:
173
+ await self.download_current_branch(repo_url, repo_folder)
174
+ await self.download_git_objects(repo_url, repo_folder)
175
+ await self.download_git_packs(repo_url, repo_folder)
176
+ return True
177
+ else:
178
+ return False
179
+
180
+ async def download_current_branch(self, repo_url, repo_folder):
181
+ for branch in await self.regex_files(self.ref_regex, file=repo_folder / ".git/HEAD"):
182
+ await self.download_files(
183
+ [self.helpers.urlparse(self.helpers.urljoin(repo_url, f"refs/heads/{branch}"))], repo_folder
184
+ )
185
+
186
+ async def download_git_objects(self, url, folder):
187
+ for object in await self.regex_files(self.obj_regex, folder=folder):
188
+ await self.download_object(object, url, folder)
189
+
190
+ async def download_git_packs(self, url, folder):
191
+ url_list = []
192
+ for sha1 in await self.regex_files(self.pack_regex, file=folder / ".git/objects/info/packs"):
193
+ url_list.append(self.helpers.urlparse(self.helpers.urljoin(url, f"objects/pack/pack-{sha1}.idx")))
194
+ url_list.append(self.helpers.urlparse(self.helpers.urljoin(url, f"objects/pack/pack-{sha1}.pack")))
195
+ if url_list:
196
+ await self.download_files(url_list, folder)
197
+
198
+ async def regex_files(self, regex, folder=Path(), file=Path(), files=[]):
199
+ results = []
200
+ if folder:
201
+ if folder.is_dir():
202
+ for file_path in folder.rglob("*"):
203
+ if file_path.is_file():
204
+ results.extend(await self.regex_file(regex, file_path))
205
+ if files:
206
+ for file in files:
207
+ results.extend(await self.regex_file(regex, file))
208
+ if file:
209
+ results.extend(await self.regex_file(regex, file))
210
+ return results
211
+
212
+ async def regex_file(self, regex, file=Path()):
213
+ if file.exists() and file.is_file():
214
+ with file.open("r", encoding="utf-8", errors="ignore") as file:
215
+ content = file.read()
216
+ matches = await self.helpers.re.findall(regex, content)
217
+ if matches:
218
+ return matches
219
+ return []
220
+
221
+ async def download_object(self, object, repo_url, repo_folder):
222
+ await self.download_files(
223
+ [self.helpers.urlparse(self.helpers.urljoin(repo_url, f"objects/{object[:2]}/{object[2:]}"))], repo_folder
224
+ )
225
+ output = await self.git_catfile(object, option="-p", folder=repo_folder)
226
+ for obj in await self.helpers.re.findall(self.obj_regex, output):
227
+ await self.download_object(obj, repo_url, repo_folder)
228
+
229
+ async def download_files(self, urls, folder):
230
+ for url in urls:
231
+ git_index = url.path.find(".git")
232
+ file_url = url.geturl()
233
+ filename = folder / url.path[git_index:]
234
+ self.helpers.mkdir(filename.parent)
235
+ if hash(str(file_url)) not in self.urls_downloaded:
236
+ self.verbose(f"Downloading {file_url} to {filename}")
237
+ await self.helpers.download(file_url, filename=filename, warn=False)
238
+ self.urls_downloaded.add(hash(str(file_url)))
239
+ if any(folder.rglob("*")):
240
+ return True
241
+ else:
242
+ self.debug(f"Unable to download git files to {folder}")
243
+ return False
244
+
245
+ async def sanitize_config(self, folder):
246
+ config_file = folder / ".git/config"
247
+ if config_file.exists():
248
+ with config_file.open("r", encoding="utf-8", errors="ignore") as file:
249
+ content = file.read()
250
+ sanitized = await self.helpers.re.sub(self.unsafe_regex, r"# \g<0>", content)
251
+ with config_file.open("w", encoding="utf-8") as file:
252
+ file.write(sanitized)
253
+
254
+ async def git_catfile(self, hash, option="-t", folder=Path()):
255
+ command = ["git", "cat-file", option, hash]
256
+ try:
257
+ output = await self.run_process(command, env={"GIT_TERMINAL_PROMPT": "0"}, cwd=folder, check=True)
258
+ except CalledProcessError:
259
+ return ""
260
+
261
+ return output.stdout
262
+
263
+ async def git_checkout(self, folder):
264
+ self.verbose(f"Running git checkout to reconstruct the git repository at {folder}")
265
+ command = ["git", "checkout", "."]
266
+ try:
267
+ await self.run_process(command, env={"GIT_TERMINAL_PROMPT": "0"}, cwd=folder, check=True)
268
+ except CalledProcessError as e:
269
+ # Still emit the event even if the checkout fails
270
+ self.debug(f"Error running git checkout in {folder}. STDERR: {repr(e.stderr)}")
@@ -2,7 +2,7 @@ from bbot.modules.base import BaseInterceptModule
2
2
 
3
3
 
4
4
  class portfilter(BaseInterceptModule):
5
- watched_events = ["OPEN_TCP_PORT"]
5
+ watched_events = ["OPEN_TCP_PORT", "URL_UNVERIFIED", "URL"]
6
6
  flags = ["passive", "safe"]
7
7
  meta = {
8
8
  "description": "Filter out unwanted open ports from cloud/CDN targets",
@@ -0,0 +1,385 @@
1
+ from pathlib import Path
2
+ from .base import ModuleTestBase
3
+
4
+
5
+ class TestGitDumper_Dirlisting(ModuleTestBase):
6
+ targets = [
7
+ "http://127.0.0.1:8888/test",
8
+ ]
9
+
10
+ modules_overrides = ["git", "gitdumper", "httpx"]
11
+
12
+ index_html = """<html>
13
+ <head>
14
+ <title>Index of /.git</title>
15
+ </head>
16
+ <body>
17
+ <h1>Index of /.git</h1>
18
+ <table>
19
+ <tr><th>Name</th><th>Size</th></tr>
20
+ <tr><td><a href='/test/.git/branches/'>&lt;branches&gt;</a></td><td></td></tr>
21
+ <tr><td><a href='/test/.git/COMMIT_EDITMSG'>COMMIT_EDITMSG</a></td><td>157B</td></tr>
22
+ <tr><td><a href='/test/.git/config'>config</a></td><td>157B</td></tr>
23
+ <tr><td><a href='/test/.git/description'>description</a></td><td>73B</td></tr>
24
+ <tr><td><a href='/test/.git/HEAD'>HEAD</a></td><td>23B</td></tr>
25
+ <tr><td><a href='/test/.git/hooks/'>&lt;hooks&gt;</a></td><td></td></tr>
26
+ <tr><td><a href='/test/.git/info/'>&lt;info&gt;</a></td><td></td></tr>
27
+ <tr><td><a href='/test/.git/objects/'>&lt;objects&gt;</a></td><td></td></tr>
28
+ <tr><td><a href='/test/.git/index'>index</a></td><td></td></tr>
29
+ <tr><td><a href='/test/.git/refs/'>&lt;refs&gt;</a></td><td></td></tr>
30
+ <tr><td><a href='/test/.git/logs/'>&lt;logs&gt;</a></td><td></td></tr>
31
+ </table>
32
+ </body>
33
+ </html>"""
34
+
35
+ info_index = """<html>
36
+ <head>
37
+ <title>Index of /.git/info</title>
38
+ </head>
39
+ <body>
40
+ <h1>Index of /.git/info</h1>
41
+ <table>
42
+ <tr><th>Name</th><th>Size</th></tr>
43
+ <tr><td><a href='../'>[..]</a></td><td></td></tr>
44
+ <tr><td><a href='/test/.git/info/exclude'>exclude</a></td><td>240B</td></tr>
45
+ <tr><td><a href='http://exclude.com/excludeme'>excludeme</a></td><td>0B</td></tr>
46
+ </table>
47
+ </body>
48
+ </html>"""
49
+
50
+ objects_index = """<html>
51
+ <head>
52
+ <title>Index of /.git/objects</title>
53
+ </head>
54
+ <body>
55
+ <h1>Index of /.git/objects</h1>
56
+ <table>
57
+ <tr><th>Name</th><th>Size</th></tr>
58
+ <tr><td><a href='../'>[..]</a></td><td></td></tr>
59
+ <tr><td><a href='/test/.git/objects/05/'>&lt;05&gt;</a></td><td></td></tr>
60
+ <tr><td><a href='/test/.git/objects/34/'>&lt;34&gt;</a></td><td></td></tr>
61
+ <tr><td><a href='/test/.git/objects/c2/'>&lt;c2&gt;</a></td><td></td></tr>
62
+ <tr><td><a href='/test/.git/objects/pack/'>&lt;pack&gt;</a></td><td></td></tr>
63
+ <tr><td><a href='/test/.git/objects/info/'>&lt;info&gt;</a></td><td></td></tr>
64
+ </table>
65
+ </body>
66
+ </html>"""
67
+
68
+ objects_o5_index = """<html>
69
+ <head>
70
+ <title>Index of /.git/objects/05</title>
71
+ </head>
72
+ <body>
73
+ <h1>Index of /.git/objects/05</h1>
74
+ <table>
75
+ <tr><th>Name</th><th>Size</th></tr>
76
+ <tr><td><a href='../'>[..]</a></td><td></td></tr>
77
+ <tr><td><a href='/test/.git/objects/05/27e6bd2d76b45e2933183f1b506c7ac49f5872'>27e6bd2d76b45e2933183f1b506c7ac49f5872</a></td><td></td></tr>
78
+ </table>
79
+ </body>
80
+ </html>"""
81
+
82
+ objects_34_index = """<html>
83
+ <head>
84
+ <title>Index of /.git/objects/34</title>
85
+ </head>
86
+ <body>
87
+ <h1>Index of /.git/objects/34</h1>
88
+ <table>
89
+ <tr><th>Name</th><th>Size</th></tr>
90
+ <tr><td><a href='../'>[..]</a></td><td></td></tr>
91
+ <tr><td><a href='/test/.git/objects/34/dc86f0247798892a89553e7c5c2d5aa06c2c5b'>dc86f0247798892a89553e7c5c2d5aa06c2c5b</a></td><td></td></tr>
92
+ </table>
93
+ </body>
94
+ </html>"""
95
+
96
+ objects_c2_index = """<html>
97
+ <head>
98
+ <title>Index of /.git/objects/c2</title>
99
+ </head>
100
+ <body>
101
+ <h1>Index of /.git/objects/c2</h1>
102
+ <table>
103
+ <tr><th>Name</th><th>Size</th></tr>
104
+ <tr><td><a href='../'>[..]</a></td><td></td></tr>
105
+ <tr><td><a href='/test/.git/objects/c2/69d751b8e2fd0be0d0dc7a6437a4dce4ec0200'>69d751b8e2fd0be0d0dc7a6437a4dce4ec0200</a></td><td></td></tr>
106
+ </table>
107
+ </body>
108
+ </html>"""
109
+
110
+ refs_index = """<html>
111
+ <head>
112
+ <title>Index of /.git/refs</title>
113
+ </head>
114
+ <body>
115
+ <h1>Index of /.git/refs</h1>
116
+ <table>
117
+ <tr><th>Name</th><th>Size</th></tr>
118
+ <tr><td><a href='../'>[..]</a></td><td></td></tr>
119
+ <tr><td><a href='/test/.git/refs/heads/'>&lt;heads&gt;</a></td><td></td></tr>
120
+ <tr><td><a href='/test/.git/refs/tags/'>&lt;tags&gt;</a></td><td></td></tr>
121
+ </table>
122
+ </body>
123
+ </html>
124
+ """
125
+
126
+ refs_heads_index = """<html>
127
+ <head>
128
+ <title>Index of /.git/refs/heads</title>
129
+ </head>
130
+ <body>
131
+ <h1>Index of /.git/refs/heads</h1>
132
+ <table>
133
+ <tr><th>Name</th><th>Size</th></tr>
134
+ <tr><td><a href='../'>[..]</a></td><td></td></tr>
135
+ <tr><td><a href='/test/.git/refs/heads/master'>master</a></td><td></td></tr>
136
+ </table>
137
+ </body>
138
+ </html>
139
+ """
140
+
141
+ logs_index = """<html>
142
+ <head>
143
+ <title>Index of /.git/logs</title>
144
+ </head>
145
+ <body>
146
+ <h1>Index of /.git/logs</h1>
147
+ <table>
148
+ <tr><th>Name</th><th>Size</th></tr>
149
+ <tr><td><a href='../'>[..]</a></td><td></td></tr>
150
+ <tr><td><a href='/test/.git/logs/HEAD'>HEAD</a></td><td></td></tr>
151
+ <tr><td><a href='/test/.git/logs/refs/'>&lt;tags&gt;</a></td><td></td></tr>
152
+ </table>
153
+ </body>
154
+ </html>
155
+ """
156
+
157
+ logs_refs_index = """<html>
158
+ <head>
159
+ <title>Index of /.git/logs/refs</title>
160
+ </head>
161
+ <body>
162
+ <h1>Index of /.git/logs/refs</h1>
163
+ <table>
164
+ <tr><th>Name</th><th>Size</th></tr>
165
+ <tr><td><a href='../'>[..]</a></td><td></td></tr>
166
+ <tr><td><a href='/test/.git/logs/refs/heads/'>&lt;heads&gt;</a></td><td></td></tr>
167
+ </table>
168
+ </body>
169
+ </html>
170
+ """
171
+
172
+ logs_refs_heads_index = """<html>
173
+ <head>
174
+ <title>Index of /.git/logs/refs/heads</title>
175
+ </head>
176
+ <body>
177
+ <h1>Index of /.git/logs/refs/heads</h1>
178
+ <table>
179
+ <tr><th>Name</th><th>Size</th></tr>
180
+ <tr><td><a href='../'>[..]</a></td><td></td></tr>
181
+ <tr><td><a href='/test/.git/logs/refs/heads/master'>master</a></td><td></td></tr>
182
+ </table>
183
+ </body>
184
+ </html>
185
+ """
186
+
187
+ empty_index = """<html>
188
+ <head>
189
+ <title>Index of /.git/...</title>
190
+ </head>
191
+ <body>
192
+ <h1>Index of /.git/...</h1>
193
+ <table>
194
+ <tr><th>Name</th><th>Size</th></tr>
195
+ <tr><td><a href='../'>[..]</a></td><td></td></tr>
196
+ </table>
197
+ </body>
198
+ </html>"""
199
+
200
+ git_head = "ref: refs/heads/master"
201
+
202
+ refs_head = "34dc86f0247798892a89553e7c5c2d5aa06c2c5b"
203
+
204
+ logs_head = "0000000000000000000000000000000000000000 34dc86f0247798892a89553e7c5c2d5aa06c2c5b Test <test@test.com> 1738516534 +0000 commit (initial): Initial commit"
205
+
206
+ logs_master_head = "0000000000000000000000000000000000000000 34dc86f0247798892a89553e7c5c2d5aa06c2c5b Test <test@test.com> 1738516534 +0000 commit (initial): Initial commit"
207
+
208
+ git_description = "Unnamed repository; edit this file 'description' to name the repository."
209
+
210
+ git_commit_editmsg = "Initial commit"
211
+
212
+ git_config = """[core]
213
+ repositoryformatversion = 0
214
+ filemode = true
215
+ bare = false
216
+ logallrefupdates = true"""
217
+
218
+ git_exclude = """# git ls-files --others --exclude-from=.git/info/exclude
219
+ # Lines that start with '#' are comments.
220
+ # For a project mostly in C, the following would be a good set of
221
+ # exclude patterns (uncomment them if you want to use them):
222
+ # *.[oa]
223
+ # *~"""
224
+
225
+ filebytes_gitindex = b"DIRC\x00\x00\x00\x02\x00\x00\x00\x01g\x9f\xbe\x04\x14\xfcb\xd1g\x9f\xbe\x04\x14\xfcb\xd1\x00\x00\x08 \x00\x04aD\x00\x00\x81\xa4\x00\x00\x03\xe8\x00\x00\x03\xe8\x00\x00\x00\x0f\x05'\xe6\xbd-v\xb4^)3\x18?\x1bPlz\xc4\x9fXr\x00\x08test.txt\x00\x00TREE\x00\x00\x00\x19\x001 0\n\xc2i\xd7Q\xb8\xe2\xfd\x0b\xe0\xd0\xdczd7\xa4\xdc\xe4\xec\x02\x00\xe8m|iw\xbb\xd6\x88;f\xdbW\x10yY\xd2\xb0G\xcfJ"
226
+ filebytes_27e6bd2d76b45e2933183f1b506c7ac49f5872 = (
227
+ b"x\x01K\xca\xc9OR04e\x08\xc9\xc8,V\x00\xa2D\x85\x92\xd4\xe2\x12.\x00U\xab\x07%"
228
+ )
229
+ filebytes_dc86f0247798892a89553e7c5c2d5aa06c2c5b = b"x\x01\x9d\x8dK\n\x021\x10D]\xe7\x14\xbd\x17\x86\xce?\x82\x88\x0b7\x9e\xc0u\xa6\xd3:\x81\xc4\xc0\x18\x99\xeb\x1b\x98\x1bX\xbbzP\xaf\xa8\xd5\x9a;\xc8\xa0\x0f}e\x06R\xee\x94\xbc\x95s`\xf5L83&L\xe4\xa33\xdaG\x93\x88\r\x13*D\x11\xbf}i+\xdcZ\x85\xc7\xc2\x1b\x97\x02\xe7\xd4\xea\xb4\xed\xe5\xfa\x89/\x9e\xa8\xd5\x0bH\xaf\x83\x95\xcej\x03G\x1c\x11\x83\x8e\xcf\xce\xff\xad\xc5\xfd\x9d{\x8e\x05v\x8d\xf8\x01\xfaF<\x05"
230
+ filebytes_69d751b8e2fd0be0d0dc7a6437a4dce4ec0200 = b"x\x01+)JMU06c040031Q(I-.\xd1+\xa9(a`U\x7f\xb6W\xb7lK\x9c\xa6\xb1\x84\xbdt@N\xd5\x91\xf9\x11E\x00*\x05\x0e\x8c"
231
+
232
+ async def setup_after_prep(self, module_test):
233
+ module_test.set_expect_requests(
234
+ expect_args={"uri": "/test/.git/"}, respond_args={"response_data": self.index_html}
235
+ )
236
+ module_test.set_expect_requests(
237
+ expect_args={"uri": "/test/.git/index"}, respond_args={"response_data": self.filebytes_gitindex}
238
+ )
239
+ module_test.set_expect_requests(
240
+ expect_args={"uri": "/test/.git/COMMIT_EDITMSG"}, respond_args={"response_data": self.git_commit_editmsg}
241
+ )
242
+ module_test.set_expect_requests(
243
+ expect_args={"uri": "/test/.git/config"}, respond_args={"response_data": self.git_config}
244
+ )
245
+ module_test.set_expect_requests(
246
+ expect_args={"uri": "/test/.git/branches/"}, respond_args={"response_data": self.empty_index}
247
+ )
248
+ module_test.set_expect_requests(
249
+ expect_args={"uri": "/test/.git/description"}, respond_args={"response_data": self.git_description}
250
+ )
251
+ module_test.set_expect_requests(
252
+ expect_args={"uri": "/test/.git/HEAD"}, respond_args={"response_data": self.git_head}
253
+ )
254
+ module_test.set_expect_requests(
255
+ expect_args={"uri": "/test/.git/hooks/"}, respond_args={"response_data": self.empty_index}
256
+ )
257
+ module_test.set_expect_requests(
258
+ expect_args={"uri": "/test/.git/info/"}, respond_args={"response_data": self.info_index}
259
+ )
260
+ module_test.set_expect_requests(
261
+ expect_args={"uri": "/test/.git/info/exclude"}, respond_args={"response_data": self.git_exclude}
262
+ )
263
+ module_test.set_expect_requests(
264
+ expect_args={"uri": "/test/.git/objects/"}, respond_args={"response_data": self.objects_index}
265
+ )
266
+ module_test.set_expect_requests(
267
+ expect_args={"uri": "/test/.git/objects/05/"}, respond_args={"response_data": self.objects_o5_index}
268
+ )
269
+ module_test.set_expect_requests(
270
+ expect_args={"uri": "/test/.git/objects/05/27e6bd2d76b45e2933183f1b506c7ac49f5872"},
271
+ respond_args={"response_data": self.filebytes_27e6bd2d76b45e2933183f1b506c7ac49f5872},
272
+ )
273
+ module_test.set_expect_requests(
274
+ expect_args={"uri": "/test/.git/objects/34/"}, respond_args={"response_data": self.objects_34_index}
275
+ )
276
+ module_test.set_expect_requests(
277
+ expect_args={"uri": "/test/.git/objects/34/dc86f0247798892a89553e7c5c2d5aa06c2c5b"},
278
+ respond_args={"response_data": self.filebytes_dc86f0247798892a89553e7c5c2d5aa06c2c5b},
279
+ )
280
+ module_test.set_expect_requests(
281
+ expect_args={"uri": "/test/.git/objects/c2/"}, respond_args={"response_data": self.objects_c2_index}
282
+ )
283
+ module_test.set_expect_requests(
284
+ expect_args={"uri": "/test/.git/objects/c2/69d751b8e2fd0be0d0dc7a6437a4dce4ec0200"},
285
+ respond_args={"response_data": self.filebytes_69d751b8e2fd0be0d0dc7a6437a4dce4ec0200},
286
+ )
287
+ module_test.set_expect_requests(
288
+ expect_args={"uri": "/test/.git/objects/info/"}, respond_args={"response_data": self.empty_index}
289
+ )
290
+ module_test.set_expect_requests(
291
+ expect_args={"uri": "/test/.git/objects/pack/"}, respond_args={"response_data": self.empty_index}
292
+ )
293
+ module_test.set_expect_requests(
294
+ expect_args={"uri": "/test/.git/refs/"}, respond_args={"response_data": self.refs_index}
295
+ )
296
+ module_test.set_expect_requests(
297
+ expect_args={"uri": "/test/.git/refs/heads/"}, respond_args={"response_data": self.refs_heads_index}
298
+ )
299
+ module_test.set_expect_requests(
300
+ expect_args={"uri": "/test/.git/refs/heads/master"}, respond_args={"response_data": self.refs_head}
301
+ )
302
+ module_test.set_expect_requests(
303
+ expect_args={"uri": "/test/.git/refs/tags/"}, respond_args={"response_data": self.empty_index}
304
+ )
305
+ module_test.set_expect_requests(
306
+ expect_args={"uri": "/test/.git/logs/"}, respond_args={"response_data": self.logs_index}
307
+ )
308
+ module_test.set_expect_requests(
309
+ expect_args={"uri": "/test/.git/logs/refs/"}, respond_args={"response_data": self.logs_refs_index}
310
+ )
311
+ module_test.set_expect_requests(
312
+ expect_args={"uri": "/test/.git/logs/refs/heads/"},
313
+ respond_args={"response_data": self.logs_refs_heads_index},
314
+ )
315
+ module_test.set_expect_requests(
316
+ expect_args={"uri": "/test/.git/logs/refs/heads/master"},
317
+ respond_args={"response_data": self.logs_master_head},
318
+ )
319
+ module_test.set_expect_requests(
320
+ expect_args={"uri": "/test/.git/logs/HEAD"}, respond_args={"response_data": self.logs_head}
321
+ )
322
+
323
+ def check(self, module_test, events):
324
+ assert any(
325
+ e.type == "CODE_REPOSITORY"
326
+ and "git-directory" in e.tags
327
+ and e.data["url"] == "http://127.0.0.1:8888/test/.git/"
328
+ for e in events
329
+ )
330
+ filesystem_events = [
331
+ e
332
+ for e in events
333
+ if e.type == "FILESYSTEM" and "http-127-0-0-1-8888-test-git" in e.data["path"] and "git" in e.tags
334
+ ]
335
+ assert 1 == len(filesystem_events), "Failed to git clone CODE_REPOSITORY"
336
+ filesystem_event = filesystem_events[0]
337
+ folder = Path(filesystem_event.data["path"])
338
+ assert folder.is_dir(), "Destination folder doesn't exist"
339
+ with open(folder / "test.txt") as f:
340
+ content = f.read()
341
+ assert content == "This is a test\n", "File content doesn't match"
342
+
343
+
344
+ class TestGitDumper_NoDirlisting(TestGitDumper_Dirlisting):
345
+ async def setup_after_prep(self, module_test):
346
+ module_test.set_expect_requests(
347
+ expect_args={"uri": "/test/.git/index"}, respond_args={"response_data": self.filebytes_gitindex}
348
+ )
349
+ module_test.set_expect_requests(
350
+ expect_args={"uri": "/test/.git/COMMIT_EDITMSG"}, respond_args={"response_data": self.git_commit_editmsg}
351
+ )
352
+ module_test.set_expect_requests(
353
+ expect_args={"uri": "/test/.git/config"}, respond_args={"response_data": self.git_config}
354
+ )
355
+ module_test.set_expect_requests(
356
+ expect_args={"uri": "/test/.git/description"}, respond_args={"response_data": self.git_description}
357
+ )
358
+ module_test.set_expect_requests(
359
+ expect_args={"uri": "/test/.git/HEAD"}, respond_args={"response_data": self.git_head}
360
+ )
361
+ module_test.set_expect_requests(
362
+ expect_args={"uri": "/test/.git/info/exclude"}, respond_args={"response_data": self.git_exclude}
363
+ )
364
+ module_test.set_expect_requests(
365
+ expect_args={"uri": "/test/.git/objects/05/27e6bd2d76b45e2933183f1b506c7ac49f5872"},
366
+ respond_args={"response_data": self.filebytes_27e6bd2d76b45e2933183f1b506c7ac49f5872},
367
+ )
368
+ module_test.set_expect_requests(
369
+ expect_args={"uri": "/test/.git/objects/34/dc86f0247798892a89553e7c5c2d5aa06c2c5b"},
370
+ respond_args={"response_data": self.filebytes_dc86f0247798892a89553e7c5c2d5aa06c2c5b},
371
+ )
372
+ module_test.set_expect_requests(
373
+ expect_args={"uri": "/test/.git/objects/c2/69d751b8e2fd0be0d0dc7a6437a4dce4ec0200"},
374
+ respond_args={"response_data": self.filebytes_69d751b8e2fd0be0d0dc7a6437a4dce4ec0200},
375
+ )
376
+ module_test.set_expect_requests(
377
+ expect_args={"uri": "/test/.git/refs/heads/master"}, respond_args={"response_data": self.refs_head}
378
+ )
379
+ module_test.set_expect_requests(
380
+ expect_args={"uri": "/test/.git/logs/refs/heads/master"},
381
+ respond_args={"response_data": self.logs_master_head},
382
+ )
383
+ module_test.set_expect_requests(
384
+ expect_args={"uri": "/test/.git/logs/HEAD"}, respond_args={"response_data": self.logs_head}
385
+ )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: bbot
3
- Version: 2.3.2.5915rc0
3
+ Version: 2.3.2.5938rc0
4
4
  Summary: OSINT automation for hackers.
5
5
  License: GPL-3.0
6
6
  Keywords: python,cli,automation,osint,threat-intel,intelligence,neo4j,scanner,python-library,hacking,recursion,pentesting,recon,command-line-tool,bugbounty,subdomains,security-tools,subdomain-scanner,osint-framework,attack-surface,subdomain-enumeration,osint-tool
@@ -15,7 +15,7 @@ Classifier: Programming Language :: Python :: 3.11
15
15
  Classifier: Programming Language :: Python :: 3.12
16
16
  Classifier: Programming Language :: Python :: 3.13
17
17
  Classifier: Topic :: Security
18
- Requires-Dist: ansible (>=7.3,<9.0)
18
+ Requires-Dist: ansible-core (>=2.15.13,<3.0.0)
19
19
  Requires-Dist: ansible-runner (>=2.3.2,<3.0.0)
20
20
  Requires-Dist: beautifulsoup4 (>=4.12.2,<5.0.0)
21
21
  Requires-Dist: cachetools (>=5.3.2,<6.0.0)
@@ -367,16 +367,16 @@ bbot -t evilcorp.com evilcorp.org 1.2.3.0/24 -p subdomain-enum
367
367
 
368
368
  Targets can be any of the following:
369
369
 
370
- - `DNS_NAME` (`evilcorp.com`)
371
- - `IP_ADDRESS` (`1.2.3.4`)
372
- - `IP_RANGE` (`1.2.3.0/24`)
373
- - `OPEN_TCP_PORT` (`192.168.0.1:80`)
374
- - `URL` (`https://www.evilcorp.com`)
375
- - `EMAIL_ADDRESS` (`bob@evilcorp.com`)
376
- - `ORG_STUB` (`ORG:evilcorp`)
377
- - `USER_STUB` (`USER:bobsmith`)
378
- - `FILESYSTEM` (`FILESYSTEM:/tmp/asdf`)
379
- - `MOBILE_APP` (`MOBILE_APP:https://play.google.com/store/apps/details?id=com.evilcorp.app`)
370
+ - DNS Name (`evilcorp.com`)
371
+ - IP Address (`1.2.3.4`)
372
+ - IP Range (`1.2.3.0/24`)
373
+ - Open TCP Port (`192.168.0.1:80`)
374
+ - URL (`https://www.evilcorp.com`)
375
+ - Email Address (`bob@evilcorp.com`)
376
+ - Organization (`ORG:evilcorp`)
377
+ - Username (`USER:bobsmith`)
378
+ - Filesystem (`FILESYSTEM:/tmp/asdf`)
379
+ - Mobile App (`MOBILE_APP:https://play.google.com/store/apps/details?id=com.evilcorp.app`)
380
380
 
381
381
  For more information, see [Targets](https://www.blacklanternsecurity.com/bbot/Stable/scanning/#targets-t). To learn how BBOT handles scope, see [Scope](https://www.blacklanternsecurity.com/bbot/Stable/scanning/#scope).
382
382
 
@@ -1,5 +1,5 @@
1
- bbot/__init__.py,sha256=ieE73Fq94Re3L1L6yRrfMcyZnoY5aJWs2V9feNleIYw,130
2
- bbot/cli.py,sha256=hrzJX07sK3psSQWa461BXFuOxgCA94iztsw8syLdpNw,10830
1
+ bbot/__init__.py,sha256=Aru214KorNuqpOkhOzn5hOGImv7I_W2SWOlM2XfGPU8,130
2
+ bbot/cli.py,sha256=H7L3yIoYuSpkrf1K1qqiBMQBTyt8UI9FfConpjqr7KI,11029
3
3
  bbot/core/__init__.py,sha256=l255GJE_DvUnWvrRb0J5lG-iMztJ8zVvoweDOfegGtI,46
4
4
  bbot/core/config/__init__.py,sha256=zYNw2Me6tsEr8hOOkLb4BQ97GB7Kis2k--G81S8vofU,342
5
5
  bbot/core/config/files.py,sha256=zANvrTRLJQIOWSNkxd9MpWmf9cQFr0gRZLUxeIbTwQc,1412
@@ -16,7 +16,7 @@ bbot/core/helpers/bloom.py,sha256=gk02rO6x3F5MICa7ZUDsinRudwoGAifsbiyiMCwd0Gs,27
16
16
  bbot/core/helpers/cache.py,sha256=1aMr3HVD45cDtHEG5xlznDUCywRgO9oRFidscrs_5sA,1537
17
17
  bbot/core/helpers/command.py,sha256=UBJa2RInEJtGjZ5e24PUQxPu1aTCIFkcCrrB0ERLdGI,12810
18
18
  bbot/core/helpers/depsinstaller/__init__.py,sha256=2mx1nYylSyvwl0GCM9YDHqrFEt2_5dSWAjP1RmhmbQg,37
19
- bbot/core/helpers/depsinstaller/installer.py,sha256=lDglXOo72zFKa-xdWaWxBgdOepDg1BTjaEs1u2ESrdY,18914
19
+ bbot/core/helpers/depsinstaller/installer.py,sha256=0sEut_B1rJKEnlTJvtk6nsWv1_1hJsbDRsVzylidmYc,19774
20
20
  bbot/core/helpers/depsinstaller/sudo_askpass.py,sha256=yGa2OQv30RO75QkMuG1iruKqb7amQxRVRRcHmvIeGhk,1276
21
21
  bbot/core/helpers/diff.py,sha256=7pDibPTSsF_1_PoFypa8WvxbFDGeB_SGNzSyOEa1QQw,10791
22
22
  bbot/core/helpers/dns/__init__.py,sha256=2JK8P0BUfPlh4CTuuOWQCOacwL7NEtGFYPJsxbA0Zwo,27
@@ -30,16 +30,16 @@ bbot/core/helpers/helper.py,sha256=eD9yJUhrFUmmoXm4pyi31dulJ5W2eyS-YLGXmx7AyDQ,8
30
30
  bbot/core/helpers/interactsh.py,sha256=VBYYH6-rWBofRsgemndK6iZNmyifOps8vgQOw2mac4k,12624
31
31
  bbot/core/helpers/libmagic.py,sha256=QMHyxjgDLb2jyjBvK1MQ-xt6WkGXhKcHu9ZP1li-sik,3460
32
32
  bbot/core/helpers/misc.py,sha256=r-FUL5zdZagmLjNd_F577IE1CrT22f5qPb69RQcEHD0,87452
33
- bbot/core/helpers/names_generator.py,sha256=x6nZfEPKMwv3qR_RI4U6TBNbo6PgCF4fqbldtwilvpw,10334
33
+ bbot/core/helpers/names_generator.py,sha256=rJE6G-Brrgm1uFJUiCw2hseJVDGe4WfRZyCMeAcQ0lM,10314
34
34
  bbot/core/helpers/ntlm.py,sha256=P2Xj4-GPos2iAzw4dfk0FJp6oGyycGhu2x6sLDVjYjs,2573
35
35
  bbot/core/helpers/process.py,sha256=00uRpLMFi3Pt3uT8qXwAIhsXdoa7h-ifoXh0sGYgwqs,1702
36
36
  bbot/core/helpers/ratelimiter.py,sha256=fQp5mKfqfCkDkZzgntDu4NWlRsWSMCto0V8vaV8-34k,2115
37
- bbot/core/helpers/regex.py,sha256=yK8F6b2lOthvyNfZ62pqKXiF_LLFjblzH7HSo6hsuOE,4168
37
+ bbot/core/helpers/regex.py,sha256=YCyvK78piK8p4YMTPH9hD1mILkZtPzLC0lNRf0vsj9g,4371
38
38
  bbot/core/helpers/regexes.py,sha256=whzgjomHsXVvKtvXLS037EMPxT9RSOxdWukpUHY8Pfc,5818
39
39
  bbot/core/helpers/url.py,sha256=1NDrvirODzzD6Mcssu-4WDNerMeMdekHCFzhRCS0m3g,5947
40
40
  bbot/core/helpers/validators.py,sha256=RBRCWpU-tKvcThx-KnEePpWTjsIxfQ_CrPEUBmiqPF0,9695
41
41
  bbot/core/helpers/web/__init__.py,sha256=pIEkL3DhjaGTSmZ7D3yKKYwWpntoLRILekV2wWsbsws,27
42
- bbot/core/helpers/web/client.py,sha256=UTjNnsAz-bPO6GEc1lEm_ZhatwaVOIGG7nRIn7KdZAQ,3562
42
+ bbot/core/helpers/web/client.py,sha256=12lKbyWJQpVKBnKGCuMNNUn47ifs1fsB02nebceX75Y,3591
43
43
  bbot/core/helpers/web/engine.py,sha256=mzXpYmlB1pvNSXs8FuliGMv7myUwAcQWTtnMHqblMHA,8875
44
44
  bbot/core/helpers/web/ssl_context.py,sha256=aWVgl-d0HoE8B4EBKNxaa5UAzQmx79DjDByfBw9tezo,356
45
45
  bbot/core/helpers/web/web.py,sha256=sesBGwqXRmePwQIScfg8PbrlCPMArQVj55E1aJsWctI,23685
@@ -103,8 +103,9 @@ bbot/modules/filedownload.py,sha256=TOxftfxguaRSEKI8oG79XVRQqUGg1_IhYDYl_Jw9eYc,
103
103
  bbot/modules/fingerprintx.py,sha256=rdlR9d64AntAhbS_eJzh8bZCeLPTJPSKdkdKdhH_qAo,3269
104
104
  bbot/modules/fullhunt.py,sha256=zeehQb9akBSbHW9dF4icH8Vfd8LqoTrpIvnQEEMWes8,1311
105
105
  bbot/modules/generic_ssrf.py,sha256=KFdcHpUV9-Z7oN7emzbirimsNc2xZ_1IFqnsfIkEbcM,9196
106
- bbot/modules/git.py,sha256=CMDarsmBemZEzZSeQTzB70XD8IRdwdG39zXpwDdgZbw,1383
106
+ bbot/modules/git.py,sha256=zmHeI0bn181T1P8C55HSebkdVGLTpzGxPc-LRqiHrbc,1723
107
107
  bbot/modules/git_clone.py,sha256=XFZXx0k97EMY3E5PZzdNvqQzZddOfRMaVp5ol2gk11s,2468
108
+ bbot/modules/gitdumper.py,sha256=XBYt6oSXm09FJVdH37zrn9T1Nhqc0zK4KLugMevedOw,11531
108
109
  bbot/modules/github_codesearch.py,sha256=a-r2vE9N9WyBpFUiKCsg0TK4Qn7DaEGyVRTUKzkDLWA,3641
109
110
  bbot/modules/github_org.py,sha256=WM18vJCHuOHJJ5rPzQzQ3Pmp7XPPuaMeVgNfW-FlO0k,8938
110
111
  bbot/modules/github_workflows.py,sha256=RDtzR0DC2sqiWzMtiqlrCSwtZHWL2MoIJBKd6LVTAdI,9720
@@ -164,7 +165,7 @@ bbot/modules/paramminer_getparams.py,sha256=_j6rgaqV5wGJoa8p5-KKbe2YsVGUtmWIanCV
164
165
  bbot/modules/paramminer_headers.py,sha256=CuiqT3nY3eIrZhT4CAEkRDfCbCYci8CmnXsippf3Qb4,10450
165
166
  bbot/modules/passivetotal.py,sha256=uGT6c_CUxBNInmClsTg8afIYA2ZykKYYCgjkyzujfHg,1653
166
167
  bbot/modules/pgp.py,sha256=Xu2M9WEIlwTm5-Lv29g7BblI05tD9Dl0XsYSeY6UURs,2065
167
- bbot/modules/portfilter.py,sha256=QMyO2Zu4hLqViMk92xK8z_wiRfrjoQ5O-mU1zESVx1s,1698
168
+ bbot/modules/portfilter.py,sha256=FB1plaBTZxiJnLJ8RiyPyc2Hrh7N7_DRSiyfeQEAfms,1723
168
169
  bbot/modules/portscan.py,sha256=dM2p3tBGQKSdeZRMlCpOwqRpz0XJfIMwY2n3Ajaig_M,13441
169
170
  bbot/modules/postman.py,sha256=vo761Nzu3kPBzfCY3KJcvsGEsjImaa7iA2z-LyASBDc,4589
170
171
  bbot/modules/postman_download.py,sha256=LUB9cP-otkB1HaNACGS5YPwsxnwp1uSo28SpGvmQ60A,3467
@@ -333,6 +334,7 @@ bbot/test/test_step_2/module_tests/test_module_fullhunt.py,sha256=NblfNHQrE82j-c
333
334
  bbot/test/test_step_2/module_tests/test_module_generic_ssrf.py,sha256=ZhfZpH0QTl6_YftGoZzZk6_2x0ZDnWjZ7vNZMTibBHw,3228
334
335
  bbot/test/test_step_2/module_tests/test_module_git.py,sha256=gyBS3vZUWAyatGlcY26mGOYeqXSqJA5pbhJWgTmLqNo,1656
335
336
  bbot/test/test_step_2/module_tests/test_module_git_clone.py,sha256=Mo0Q7bCXcrkGWJc3-u5y4sdfC13ei-qj79aKvEbnkk4,13198
337
+ bbot/test/test_step_2/module_tests/test_module_gitdumper.py,sha256=ya_eQUQk0344G7iqBYMls2z5H-bYM87rydbz-ACR2Ng,17461
336
338
  bbot/test/test_step_2/module_tests/test_module_github_codesearch.py,sha256=M50xBiGG2EuPGXDJU6uFsSUE-fhqZl3CzYtNdszW7LM,4735
337
339
  bbot/test/test_step_2/module_tests/test_module_github_org.py,sha256=5tKO6NH4TPBeIdeTf7Bz9PUZ1pcvKsjrG0nFhc3YgT0,25458
338
340
  bbot/test/test_step_2/module_tests/test_module_github_workflows.py,sha256=o_teEaskm3H22QEKod5KJayFvvcgOQoG4eItGWv8C8E,38006
@@ -423,8 +425,8 @@ bbot/wordlists/raft-small-extensions-lowercase_CLEANED.txt,sha256=ZSIVebs7ptMvHx
423
425
  bbot/wordlists/top_open_ports_nmap.txt,sha256=LmdFYkfapSxn1pVuQC2LkOIY2hMLgG-Xts7DVtYzweM,42727
424
426
  bbot/wordlists/valid_url_schemes.txt,sha256=0B_VAr9Dv7aYhwi6JSBDU-3M76vNtzN0qEC_RNLo7HE,3310
425
427
  bbot/wordlists/wordninja_dns.txt.gz,sha256=DYHvvfW0TvzrVwyprqODAk4tGOxv5ezNmCPSdPuDUnQ,570241
426
- bbot-2.3.2.5915rc0.dist-info/LICENSE,sha256=GzeCzK17hhQQDNow0_r0L8OfLpeTKQjFQwBQU7ZUymg,32473
427
- bbot-2.3.2.5915rc0.dist-info/METADATA,sha256=1C-ozr_Q04_hBUMFFgChTaoKR3mumIIDZcz5LeBJKqU,18224
428
- bbot-2.3.2.5915rc0.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
429
- bbot-2.3.2.5915rc0.dist-info/entry_points.txt,sha256=cWjvcU_lLrzzJgjcjF7yeGuRA_eDS8pQ-kmPUAyOBfo,38
430
- bbot-2.3.2.5915rc0.dist-info/RECORD,,
428
+ bbot-2.3.2.5938rc0.dist-info/LICENSE,sha256=GzeCzK17hhQQDNow0_r0L8OfLpeTKQjFQwBQU7ZUymg,32473
429
+ bbot-2.3.2.5938rc0.dist-info/METADATA,sha256=JYgdVRHBmrMfy17beoLLQuzDtJJWpv8kcw6U2BgEDys,18218
430
+ bbot-2.3.2.5938rc0.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
431
+ bbot-2.3.2.5938rc0.dist-info/entry_points.txt,sha256=cWjvcU_lLrzzJgjcjF7yeGuRA_eDS8pQ-kmPUAyOBfo,38
432
+ bbot-2.3.2.5938rc0.dist-info/RECORD,,