bbot 2.3.0.5376rc0__py3-none-any.whl → 2.3.0.5384rc0__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 +1 -1
- bbot/cli.py +2 -2
- bbot/core/config/logger.py +1 -1
- bbot/core/core.py +1 -1
- bbot/core/event/base.py +13 -13
- bbot/core/helpers/command.py +4 -4
- bbot/core/helpers/depsinstaller/installer.py +5 -5
- bbot/core/helpers/diff.py +7 -7
- bbot/core/helpers/dns/brute.py +1 -1
- bbot/core/helpers/dns/dns.py +1 -1
- bbot/core/helpers/dns/engine.py +4 -4
- bbot/core/helpers/files.py +1 -1
- bbot/core/helpers/helper.py +3 -1
- bbot/core/helpers/interactsh.py +3 -3
- bbot/core/helpers/misc.py +11 -11
- bbot/core/helpers/regex.py +1 -1
- bbot/core/helpers/regexes.py +3 -3
- bbot/core/helpers/validators.py +1 -1
- bbot/core/helpers/web/client.py +1 -1
- bbot/core/helpers/web/engine.py +1 -1
- bbot/core/helpers/web/web.py +2 -2
- bbot/core/helpers/wordcloud.py +5 -5
- bbot/core/modules.py +21 -21
- bbot/modules/azure_tenant.py +2 -2
- bbot/modules/base.py +16 -16
- bbot/modules/bypass403.py +5 -5
- bbot/modules/c99.py +1 -1
- bbot/modules/columbus.py +1 -1
- bbot/modules/deadly/ffuf.py +8 -8
- bbot/modules/deadly/nuclei.py +1 -1
- bbot/modules/deadly/vhost.py +3 -3
- bbot/modules/dnsbimi.py +1 -1
- bbot/modules/dnsdumpster.py +2 -2
- bbot/modules/dockerhub.py +1 -1
- bbot/modules/extractous.py +1 -1
- bbot/modules/filedownload.py +1 -1
- bbot/modules/generic_ssrf.py +3 -3
- bbot/modules/github_workflows.py +1 -1
- bbot/modules/gowitness.py +7 -7
- bbot/modules/host_header.py +5 -5
- bbot/modules/httpx.py +1 -1
- bbot/modules/iis_shortnames.py +6 -6
- bbot/modules/internal/cloudcheck.py +5 -5
- bbot/modules/internal/dnsresolve.py +7 -7
- bbot/modules/internal/excavate.py +5 -5
- bbot/modules/internal/speculate.py +4 -4
- bbot/modules/ipneighbor.py +1 -1
- bbot/modules/jadx.py +1 -1
- bbot/modules/newsletters.py +2 -2
- bbot/modules/output/asset_inventory.py +6 -6
- bbot/modules/output/base.py +1 -1
- bbot/modules/output/csv.py +1 -1
- bbot/modules/output/stdout.py +2 -2
- bbot/modules/paramminer_headers.py +3 -3
- bbot/modules/portscan.py +3 -3
- bbot/modules/report/asn.py +11 -11
- bbot/modules/robots.py +3 -3
- bbot/modules/securitytxt.py +1 -1
- bbot/modules/sitedossier.py +1 -1
- bbot/modules/social.py +1 -1
- bbot/modules/subdomainradar.py +1 -1
- bbot/modules/telerik.py +7 -7
- bbot/modules/templates/bucket.py +1 -1
- bbot/modules/templates/github.py +1 -1
- bbot/modules/templates/shodan.py +1 -1
- bbot/modules/templates/subdomain_enum.py +1 -1
- bbot/modules/templates/webhook.py +1 -1
- bbot/modules/trufflehog.py +1 -1
- bbot/modules/url_manipulation.py +3 -3
- bbot/modules/urlscan.py +1 -1
- bbot/modules/viewdns.py +1 -1
- bbot/modules/wafw00f.py +1 -1
- bbot/scanner/preset/args.py +10 -10
- bbot/scanner/preset/preset.py +9 -9
- bbot/scanner/scanner.py +17 -17
- bbot/scanner/target.py +1 -1
- bbot/scripts/docs.py +1 -1
- bbot/test/bbot_fixtures.py +1 -1
- bbot/test/conftest.py +1 -1
- bbot/test/run_tests.sh +4 -4
- bbot/test/test_step_1/test_bbot_fastapi.py +2 -2
- bbot/test/test_step_1/test_cli.py +56 -56
- bbot/test/test_step_1/test_dns.py +15 -15
- bbot/test/test_step_1/test_engine.py +17 -17
- bbot/test/test_step_1/test_events.py +22 -22
- bbot/test/test_step_1/test_helpers.py +26 -26
- bbot/test/test_step_1/test_manager_scope_accuracy.py +306 -306
- bbot/test/test_step_1/test_modules_basic.py +52 -53
- bbot/test/test_step_1/test_presets.py +81 -81
- bbot/test/test_step_1/test_regexes.py +5 -5
- bbot/test/test_step_1/test_scan.py +4 -4
- bbot/test/test_step_1/test_target.py +25 -25
- bbot/test/test_step_1/test_web.py +5 -5
- bbot/test/test_step_2/module_tests/base.py +6 -6
- bbot/test/test_step_2/module_tests/test_module_anubisdb.py +1 -1
- bbot/test/test_step_2/module_tests/test_module_azure_realm.py +1 -1
- bbot/test/test_step_2/module_tests/test_module_baddns.py +6 -6
- bbot/test/test_step_2/module_tests/test_module_baddns_direct.py +2 -4
- bbot/test/test_step_2/module_tests/test_module_bevigil.py +4 -4
- bbot/test/test_step_2/module_tests/test_module_binaryedge.py +2 -2
- bbot/test/test_step_2/module_tests/test_module_bucket_amazon.py +2 -2
- bbot/test/test_step_2/module_tests/test_module_bucket_azure.py +1 -1
- bbot/test/test_step_2/module_tests/test_module_builtwith.py +2 -2
- bbot/test/test_step_2/module_tests/test_module_c99.py +9 -9
- bbot/test/test_step_2/module_tests/test_module_columbus.py +1 -1
- bbot/test/test_step_2/module_tests/test_module_credshed.py +2 -2
- bbot/test/test_step_2/module_tests/test_module_dehashed.py +1 -1
- bbot/test/test_step_2/module_tests/test_module_digitorus.py +1 -1
- bbot/test/test_step_2/module_tests/test_module_dnsbrute.py +8 -8
- bbot/test/test_step_2/module_tests/test_module_dnsdumpster.py +2 -2
- bbot/test/test_step_2/module_tests/test_module_excavate.py +10 -10
- bbot/test/test_step_2/module_tests/test_module_extractous.py +9 -9
- bbot/test/test_step_2/module_tests/test_module_filedownload.py +14 -14
- bbot/test/test_step_2/module_tests/test_module_git_clone.py +2 -2
- bbot/test/test_step_2/module_tests/test_module_gowitness.py +4 -4
- bbot/test/test_step_2/module_tests/test_module_host_header.py +1 -1
- bbot/test/test_step_2/module_tests/test_module_http.py +4 -4
- bbot/test/test_step_2/module_tests/test_module_httpx.py +7 -7
- bbot/test/test_step_2/module_tests/test_module_leakix.py +2 -2
- bbot/test/test_step_2/module_tests/test_module_myssl.py +1 -1
- bbot/test/test_step_2/module_tests/test_module_neo4j.py +1 -1
- bbot/test/test_step_2/module_tests/test_module_newsletters.py +6 -6
- bbot/test/test_step_2/module_tests/test_module_ntlm.py +7 -7
- bbot/test/test_step_2/module_tests/test_module_oauth.py +1 -1
- bbot/test/test_step_2/module_tests/test_module_otx.py +1 -1
- bbot/test/test_step_2/module_tests/test_module_paramminer_cookies.py +1 -1
- bbot/test/test_step_2/module_tests/test_module_paramminer_headers.py +2 -2
- bbot/test/test_step_2/module_tests/test_module_portscan.py +3 -3
- bbot/test/test_step_2/module_tests/test_module_postgres.py +1 -1
- bbot/test/test_step_2/module_tests/test_module_rapiddns.py +9 -9
- bbot/test/test_step_2/module_tests/test_module_sitedossier.py +2 -2
- bbot/test/test_step_2/module_tests/test_module_smuggler.py +1 -1
- bbot/test/test_step_2/module_tests/test_module_speculate.py +2 -6
- bbot/test/test_step_2/module_tests/test_module_splunk.py +4 -4
- bbot/test/test_step_2/module_tests/test_module_subdomaincenter.py +1 -1
- bbot/test/test_step_2/module_tests/test_module_subdomains.py +1 -1
- bbot/test/test_step_2/module_tests/test_module_trufflehog.py +2 -2
- bbot/test/test_step_2/module_tests/test_module_wayback.py +1 -1
- {bbot-2.3.0.5376rc0.dist-info → bbot-2.3.0.5384rc0.dist-info}/METADATA +2 -2
- {bbot-2.3.0.5376rc0.dist-info → bbot-2.3.0.5384rc0.dist-info}/RECORD +143 -143
- {bbot-2.3.0.5376rc0.dist-info → bbot-2.3.0.5384rc0.dist-info}/LICENSE +0 -0
- {bbot-2.3.0.5376rc0.dist-info → bbot-2.3.0.5384rc0.dist-info}/WHEEL +0 -0
- {bbot-2.3.0.5376rc0.dist-info → bbot-2.3.0.5384rc0.dist-info}/entry_points.txt +0 -0
|
@@ -106,24 +106,24 @@ async def test_target(bbot_scanner):
|
|
|
106
106
|
assert scan1.target.whitelist.get("publicapis.org") is None
|
|
107
107
|
|
|
108
108
|
target = RadixTarget("evilcorp.com")
|
|
109
|
-
assert
|
|
109
|
+
assert "com" not in target
|
|
110
110
|
assert "evilcorp.com" in target
|
|
111
111
|
assert "www.evilcorp.com" in target
|
|
112
112
|
strict_target = RadixTarget("evilcorp.com", strict_dns_scope=True)
|
|
113
|
-
assert
|
|
113
|
+
assert "com" not in strict_target
|
|
114
114
|
assert "evilcorp.com" in strict_target
|
|
115
|
-
assert
|
|
115
|
+
assert "www.evilcorp.com" not in strict_target
|
|
116
116
|
|
|
117
117
|
target = RadixTarget()
|
|
118
118
|
target.add("evilcorp.com")
|
|
119
|
-
assert
|
|
119
|
+
assert "com" not in target
|
|
120
120
|
assert "evilcorp.com" in target
|
|
121
121
|
assert "www.evilcorp.com" in target
|
|
122
122
|
strict_target = RadixTarget(strict_dns_scope=True)
|
|
123
123
|
strict_target.add("evilcorp.com")
|
|
124
|
-
assert
|
|
124
|
+
assert "com" not in strict_target
|
|
125
125
|
assert "evilcorp.com" in strict_target
|
|
126
|
-
assert
|
|
126
|
+
assert "www.evilcorp.com" not in strict_target
|
|
127
127
|
|
|
128
128
|
# test target hashing
|
|
129
129
|
|
|
@@ -164,8 +164,8 @@ async def test_target(bbot_scanner):
|
|
|
164
164
|
bbottarget = BBOTTarget("http://1.2.3.4:8443", "bob@evilcorp.com")
|
|
165
165
|
assert bbottarget.seeds.hosts == {ip_network("1.2.3.4"), "evilcorp.com"}
|
|
166
166
|
assert bbottarget.whitelist.hosts == {ip_network("1.2.3.4"), "evilcorp.com"}
|
|
167
|
-
assert
|
|
168
|
-
assert
|
|
167
|
+
assert {e.data for e in bbottarget.seeds.events} == {"http://1.2.3.4:8443/", "bob@evilcorp.com"}
|
|
168
|
+
assert {e.data for e in bbottarget.whitelist.events} == {"1.2.3.4", "evilcorp.com"}
|
|
169
169
|
|
|
170
170
|
bbottarget1 = BBOTTarget("evilcorp.com", "evilcorp.net", whitelist=["1.2.3.4/24"], blacklist=["1.2.3.4"])
|
|
171
171
|
bbottarget2 = BBOTTarget("evilcorp.com", "evilcorp.net", whitelist=["1.2.3.0/24"], blacklist=["1.2.3.4"])
|
|
@@ -228,22 +228,22 @@ async def test_target(bbot_scanner):
|
|
|
228
228
|
with pytest.raises(TypeError):
|
|
229
229
|
assert list(bbottarget) == ["http://evilcorp.com:8080"]
|
|
230
230
|
assert list(bbottarget.seeds) == ["http://evilcorp.com:8080"]
|
|
231
|
-
assert
|
|
232
|
-
assert
|
|
231
|
+
assert {e.data for e in bbottarget.whitelist} == {"evilcorp.net:443", "http://evilcorp.net:8080/"}
|
|
232
|
+
assert {e.data for e in bbottarget.blacklist} == {"http://evilcorp.org:8080/", "evilcorp.org:443"}
|
|
233
233
|
|
|
234
234
|
# test org stub as target
|
|
235
235
|
for org_target in ("ORG:evilcorp", "ORG_STUB:evilcorp"):
|
|
236
236
|
scan = bbot_scanner(org_target)
|
|
237
237
|
events = [e async for e in scan.async_start()]
|
|
238
238
|
assert len(events) == 3
|
|
239
|
-
assert
|
|
239
|
+
assert {e.type for e in events} == {"SCAN", "ORG_STUB"}
|
|
240
240
|
|
|
241
241
|
# test username as target
|
|
242
242
|
for user_target in ("USER:vancerefrigeration", "USERNAME:vancerefrigeration"):
|
|
243
243
|
scan = bbot_scanner(user_target)
|
|
244
244
|
events = [e async for e in scan.async_start()]
|
|
245
245
|
assert len(events) == 3
|
|
246
|
-
assert
|
|
246
|
+
assert {e.type for e in events} == {"SCAN", "USERNAME"}
|
|
247
247
|
|
|
248
248
|
# verify hash values
|
|
249
249
|
bbottarget = BBOTTarget(
|
|
@@ -253,17 +253,17 @@ async def test_target(bbot_scanner):
|
|
|
253
253
|
whitelist=["evilcorp.com", "bob@www.evilcorp.com", "evilcorp.net"],
|
|
254
254
|
blacklist=["1.2.3.4", "4.3.2.1/24", "http://1.2.3.4", "bob@asdf.evilcorp.net"],
|
|
255
255
|
)
|
|
256
|
-
assert
|
|
256
|
+
assert {e.data for e in bbottarget.seeds.events} == {
|
|
257
257
|
"1.2.3.0/24",
|
|
258
258
|
"http://www.evilcorp.net/",
|
|
259
259
|
"bob@fdsa.evilcorp.net",
|
|
260
260
|
}
|
|
261
|
-
assert
|
|
261
|
+
assert {e.data for e in bbottarget.whitelist.events} == {
|
|
262
262
|
"evilcorp.com",
|
|
263
263
|
"evilcorp.net",
|
|
264
264
|
"bob@www.evilcorp.com",
|
|
265
265
|
}
|
|
266
|
-
assert
|
|
266
|
+
assert {e.data for e in bbottarget.blacklist.events} == {
|
|
267
267
|
"1.2.3.4",
|
|
268
268
|
"4.3.2.0/24",
|
|
269
269
|
"http://1.2.3.4/",
|
|
@@ -293,7 +293,7 @@ async def test_target(bbot_scanner):
|
|
|
293
293
|
assert target_dict["seeds"] == ["1.2.3.0/24", "bob@fdsa.evilcorp.net", "http://www.evilcorp.net/"]
|
|
294
294
|
assert target_dict["whitelist"] == ["bob@www.evilcorp.com", "evilcorp.com", "evilcorp.net"]
|
|
295
295
|
assert target_dict["blacklist"] == ["1.2.3.4", "4.3.2.0/24", "bob@asdf.evilcorp.net", "http://1.2.3.4/"]
|
|
296
|
-
assert target_dict["strict_scope"]
|
|
296
|
+
assert target_dict["strict_scope"] is False
|
|
297
297
|
assert target_dict["hash"] == "b36955a8238a71842fc5f23b11110c26ea07d451"
|
|
298
298
|
assert target_dict["seed_hash"] == "560af51d1f3d69bc5c156fc270b28497fe52dec1"
|
|
299
299
|
assert target_dict["whitelist_hash"] == "8ed0a7368e6d34630e1cfd419d2a73767debc4c4"
|
|
@@ -321,8 +321,8 @@ async def test_target(bbot_scanner):
|
|
|
321
321
|
assert set(target.hosts) == {"evilcorp.co.uk", "www.evilcorp.co.uk"}
|
|
322
322
|
assert "evilcorp.co.uk" in target
|
|
323
323
|
assert "www.evilcorp.co.uk" in target
|
|
324
|
-
assert
|
|
325
|
-
assert
|
|
324
|
+
assert "api.evilcorp.co.uk" not in target
|
|
325
|
+
assert "api.www.evilcorp.co.uk" not in target
|
|
326
326
|
|
|
327
327
|
# test 'single' boolean argument
|
|
328
328
|
target = ScanSeeds("http://evilcorp.com", "evilcorp.com:443")
|
|
@@ -332,7 +332,7 @@ async def test_target(bbot_scanner):
|
|
|
332
332
|
assert event.host == "evilcorp.com"
|
|
333
333
|
events = target.get("www.evilcorp.com", single=False)
|
|
334
334
|
assert len(events) == 2
|
|
335
|
-
assert
|
|
335
|
+
assert {e.data for e in events} == {"http://evilcorp.com/", "evilcorp.com:443"}
|
|
336
336
|
|
|
337
337
|
|
|
338
338
|
@pytest.mark.asyncio
|
|
@@ -361,13 +361,13 @@ async def test_blacklist_regex(bbot_scanner, bbot_httpserver):
|
|
|
361
361
|
blacklist.get("www.evil.com", raise_error=True)
|
|
362
362
|
assert "test.com" in blacklist
|
|
363
363
|
assert "http://evilcorp.com/test.aspx" in blacklist
|
|
364
|
-
assert
|
|
364
|
+
assert "http://tes.com" not in blacklist
|
|
365
365
|
|
|
366
366
|
blacklist = ScanBlacklist("evilcorp.com", r"RE:[0-9]{6}\.aspx$")
|
|
367
367
|
assert "http://evilcorp.com" in blacklist
|
|
368
|
-
assert
|
|
369
|
-
assert
|
|
370
|
-
assert
|
|
368
|
+
assert "http://test.com/123456" not in blacklist
|
|
369
|
+
assert "http://test.com/12345.aspx?a=asdf" not in blacklist
|
|
370
|
+
assert "http://test.com/asdf/123456.aspx/asdf" not in blacklist
|
|
371
371
|
assert "http://test.com/asdf/123456.aspx?a=asdf" in blacklist
|
|
372
372
|
assert "http://test.com/asdf/123456.aspx" in blacklist
|
|
373
373
|
|
|
@@ -382,7 +382,7 @@ async def test_blacklist_regex(bbot_scanner, bbot_httpserver):
|
|
|
382
382
|
|
|
383
383
|
# make sure URL is detected normally
|
|
384
384
|
scan = bbot_scanner("http://127.0.0.1:8888/", presets=["spider"], config={"excavate": True}, debug=True)
|
|
385
|
-
assert
|
|
385
|
+
assert {r.pattern for r in scan.target.blacklist.blacklist_regexes} == {r"/.*(sign|log)[_-]?out"}
|
|
386
386
|
events = [e async for e in scan.async_start()]
|
|
387
387
|
urls = [e.data for e in events if e.type == "URL"]
|
|
388
388
|
assert len(urls) == 2
|
|
@@ -397,7 +397,7 @@ async def test_blacklist_regex(bbot_scanner, bbot_httpserver):
|
|
|
397
397
|
debug=True,
|
|
398
398
|
)
|
|
399
399
|
assert scan.target.blacklist.blacklist_regexes
|
|
400
|
-
assert
|
|
400
|
+
assert {r.pattern for r in scan.target.blacklist.blacklist_regexes} == {
|
|
401
401
|
r"evil[0-9]{3}",
|
|
402
402
|
r"/.*(sign|log)[_-]?out",
|
|
403
403
|
}
|
|
@@ -29,7 +29,7 @@ async def test_web_engine(bbot_scanner, bbot_httpserver, httpx_mock):
|
|
|
29
29
|
urls = [f"{base_url}{i}" for i in range(num_urls)]
|
|
30
30
|
responses = [r async for r in scan.helpers.request_batch(urls)]
|
|
31
31
|
assert len(responses) == 100
|
|
32
|
-
assert all(
|
|
32
|
+
assert all(r[1].status_code == 200 and r[1].text.startswith(f"{r[0]}: ") for r in responses)
|
|
33
33
|
|
|
34
34
|
# request_batch w/ cancellation
|
|
35
35
|
agen = scan.helpers.request_batch(urls)
|
|
@@ -211,14 +211,14 @@ async def test_web_helpers(bbot_scanner, bbot_httpserver, httpx_mock):
|
|
|
211
211
|
url = bbot_httpserver.url_for(path)
|
|
212
212
|
bbot_httpserver.expect_request(uri=path).respond_with_data(download_content, status=200)
|
|
213
213
|
webpage = await scan1.helpers.request(url)
|
|
214
|
-
assert webpage,
|
|
214
|
+
assert webpage, "Webpage is False"
|
|
215
215
|
soup = scan1.helpers.beautifulsoup(webpage, "html.parser")
|
|
216
|
-
assert soup,
|
|
216
|
+
assert soup, "Soup is False"
|
|
217
217
|
# pretty_print = soup.prettify()
|
|
218
218
|
# assert pretty_print, f"PrettyPrint is False"
|
|
219
219
|
# scan1.helpers.log.info(f"{pretty_print}")
|
|
220
220
|
html_text = soup.find(text="Example Domain")
|
|
221
|
-
assert html_text,
|
|
221
|
+
assert html_text, "Find HTML Text is False"
|
|
222
222
|
|
|
223
223
|
# 404
|
|
224
224
|
path = "/test_http_helpers_download_404"
|
|
@@ -389,7 +389,7 @@ async def test_web_http_compare(httpx_mock, bbot_scanner):
|
|
|
389
389
|
await compare_helper.compare("http://www.example.com", check_reflection=True)
|
|
390
390
|
compare_helper.compare_body({"asdf": "fdsa"}, {"fdsa": "asdf"})
|
|
391
391
|
for mode in ("getparam", "header", "cookie"):
|
|
392
|
-
assert await compare_helper.canary_check("http://www.example.com", mode=mode)
|
|
392
|
+
assert await compare_helper.canary_check("http://www.example.com", mode=mode) is True
|
|
393
393
|
|
|
394
394
|
await scan._cleanup()
|
|
395
395
|
|
|
@@ -99,15 +99,15 @@ class ModuleTestBase:
|
|
|
99
99
|
module_test = self.ModuleTest(
|
|
100
100
|
self, httpx_mock, bbot_httpserver, bbot_httpserver_ssl, monkeypatch, request, caplog, capsys
|
|
101
101
|
)
|
|
102
|
-
self.log.debug(
|
|
102
|
+
self.log.debug("Mocking DNS")
|
|
103
103
|
await module_test.mock_dns({"blacklanternsecurity.com": {"A": ["127.0.0.88"]}})
|
|
104
|
-
self.log.debug(
|
|
104
|
+
self.log.debug("Executing setup_before_prep()")
|
|
105
105
|
await self.setup_before_prep(module_test)
|
|
106
|
-
self.log.debug(
|
|
106
|
+
self.log.debug("Executing scan._prep()")
|
|
107
107
|
await module_test.scan._prep()
|
|
108
|
-
self.log.debug(
|
|
108
|
+
self.log.debug("Executing setup_after_prep()")
|
|
109
109
|
await self.setup_after_prep(module_test)
|
|
110
|
-
self.log.debug(
|
|
110
|
+
self.log.debug("Starting scan")
|
|
111
111
|
module_test.events = [e async for e in module_test.scan.async_start()]
|
|
112
112
|
self.log.debug(f"Finished {module_test.name} module test")
|
|
113
113
|
yield module_test
|
|
@@ -123,7 +123,7 @@ class ModuleTestBase:
|
|
|
123
123
|
if len(tasks):
|
|
124
124
|
module_test.log.info(f"Unfinished tasks detected: {tasks}")
|
|
125
125
|
else:
|
|
126
|
-
module_test.log.info(
|
|
126
|
+
module_test.log.info("No unfinished tasks detected")
|
|
127
127
|
|
|
128
128
|
def check(self, module_test, events):
|
|
129
129
|
assert False, f"Must override {self.name}.check()"
|
|
@@ -5,7 +5,7 @@ class TestAnubisdb(ModuleTestBase):
|
|
|
5
5
|
async def setup_after_prep(self, module_test):
|
|
6
6
|
module_test.module.abort_if = lambda e: False
|
|
7
7
|
module_test.httpx_mock.add_response(
|
|
8
|
-
url=
|
|
8
|
+
url="https://jldc.me/anubis/subdomains/blacklanternsecurity.com",
|
|
9
9
|
json=["asdf.blacklanternsecurity.com", "zzzz.blacklanternsecurity.com"],
|
|
10
10
|
)
|
|
11
11
|
|
|
@@ -22,7 +22,7 @@ class TestAzure_Realm(ModuleTestBase):
|
|
|
22
22
|
async def setup_after_prep(self, module_test):
|
|
23
23
|
await module_test.mock_dns({"evilcorp.com": {"A": ["127.0.0.5"]}})
|
|
24
24
|
module_test.httpx_mock.add_response(
|
|
25
|
-
url=
|
|
25
|
+
url="https://login.microsoftonline.com/getuserrealm.srf?login=test@evilcorp.com",
|
|
26
26
|
json=self.response_json,
|
|
27
27
|
)
|
|
28
28
|
|
|
@@ -31,9 +31,9 @@ class TestBaddns_cname_nxdomain(BaseTestBaddns):
|
|
|
31
31
|
module_test.monkeypatch.setattr(WhoisManager, "dispatchWHOIS", self.dispatchWHOIS)
|
|
32
32
|
|
|
33
33
|
def check(self, module_test, events):
|
|
34
|
-
assert any(
|
|
35
|
-
assert any(
|
|
36
|
-
assert any(
|
|
34
|
+
assert any(e.data == "baddns.azurewebsites.net" for e in events), "CNAME detection failed"
|
|
35
|
+
assert any(e.type == "VULNERABILITY" for e in events), "Failed to emit VULNERABILITY"
|
|
36
|
+
assert any("baddns-cname" in e.tags for e in events), "Failed to add baddns tag"
|
|
37
37
|
|
|
38
38
|
|
|
39
39
|
class TestBaddns_cname_signature(BaseTestBaddns):
|
|
@@ -60,8 +60,8 @@ class TestBaddns_cname_signature(BaseTestBaddns):
|
|
|
60
60
|
module_test.monkeypatch.setattr(WhoisManager, "dispatchWHOIS", self.dispatchWHOIS)
|
|
61
61
|
|
|
62
62
|
def check(self, module_test, events):
|
|
63
|
-
assert any(
|
|
63
|
+
assert any(e for e in events)
|
|
64
64
|
assert any(
|
|
65
|
-
|
|
65
|
+
e.type == "VULNERABILITY" and "bigcartel.com" in e.data["description"] for e in events
|
|
66
66
|
), "Failed to emit VULNERABILITY"
|
|
67
|
-
assert any(
|
|
67
|
+
assert any("baddns-cname" in e.tags for e in events), "Failed to add baddns tag"
|
|
@@ -54,11 +54,9 @@ class TestBaddns_direct_cloudflare(BaseTestBaddns):
|
|
|
54
54
|
|
|
55
55
|
def check(self, module_test, events):
|
|
56
56
|
assert any(
|
|
57
|
-
|
|
58
|
-
e.type == "FINDING"
|
|
57
|
+
e.type == "FINDING"
|
|
59
58
|
and "Possible [AWS Bucket Takeover Detection] via direct BadDNS analysis. Indicator: [[Words: The specified bucket does not exist | Condition: and | Part: body] Matchers-Condition: and] Trigger: [self] baddns Module: [CNAME]"
|
|
60
59
|
in e.data["description"]
|
|
61
60
|
for e in events
|
|
62
|
-
]
|
|
63
61
|
), "Failed to emit FINDING"
|
|
64
|
-
assert any(
|
|
62
|
+
assert any("baddns-cname" in e.tags for e in events), "Failed to add baddns tag"
|
|
@@ -9,7 +9,7 @@ class TestBeVigil(ModuleTestBase):
|
|
|
9
9
|
|
|
10
10
|
async def setup_after_prep(self, module_test):
|
|
11
11
|
module_test.httpx_mock.add_response(
|
|
12
|
-
url=
|
|
12
|
+
url="https://osint.bevigil.com/api/blacklanternsecurity.com/subdomains/",
|
|
13
13
|
match_headers={"X-Access-Token": "asdf"},
|
|
14
14
|
json={
|
|
15
15
|
"domain": "blacklanternsecurity.com",
|
|
@@ -19,7 +19,7 @@ class TestBeVigil(ModuleTestBase):
|
|
|
19
19
|
},
|
|
20
20
|
)
|
|
21
21
|
module_test.httpx_mock.add_response(
|
|
22
|
-
url=
|
|
22
|
+
url="https://osint.bevigil.com/api/blacklanternsecurity.com/urls/",
|
|
23
23
|
json={"domain": "blacklanternsecurity.com", "urls": ["https://asdf.blacklanternsecurity.com"]},
|
|
24
24
|
)
|
|
25
25
|
|
|
@@ -35,7 +35,7 @@ class TestBeVigilMultiKey(TestBeVigil):
|
|
|
35
35
|
|
|
36
36
|
async def setup_after_prep(self, module_test):
|
|
37
37
|
module_test.httpx_mock.add_response(
|
|
38
|
-
url=
|
|
38
|
+
url="https://osint.bevigil.com/api/blacklanternsecurity.com/subdomains/",
|
|
39
39
|
match_headers={"X-Access-Token": "fdsa"},
|
|
40
40
|
json={
|
|
41
41
|
"domain": "blacklanternsecurity.com",
|
|
@@ -46,6 +46,6 @@ class TestBeVigilMultiKey(TestBeVigil):
|
|
|
46
46
|
)
|
|
47
47
|
module_test.httpx_mock.add_response(
|
|
48
48
|
match_headers={"X-Access-Token": "asdf"},
|
|
49
|
-
url=
|
|
49
|
+
url="https://osint.bevigil.com/api/blacklanternsecurity.com/urls/",
|
|
50
50
|
json={"domain": "blacklanternsecurity.com", "urls": ["https://asdf.blacklanternsecurity.com"]},
|
|
51
51
|
)
|
|
@@ -6,7 +6,7 @@ class TestBinaryEdge(ModuleTestBase):
|
|
|
6
6
|
|
|
7
7
|
async def setup_before_prep(self, module_test):
|
|
8
8
|
module_test.httpx_mock.add_response(
|
|
9
|
-
url=
|
|
9
|
+
url="https://api.binaryedge.io/v2/query/domains/subdomain/blacklanternsecurity.com",
|
|
10
10
|
match_headers={"X-Key": "asdf"},
|
|
11
11
|
json={
|
|
12
12
|
"query": "blacklanternsecurity.com",
|
|
@@ -19,7 +19,7 @@ class TestBinaryEdge(ModuleTestBase):
|
|
|
19
19
|
},
|
|
20
20
|
)
|
|
21
21
|
module_test.httpx_mock.add_response(
|
|
22
|
-
url=
|
|
22
|
+
url="https://api.binaryedge.io/v2/user/subscription",
|
|
23
23
|
match_headers={"X-Key": "asdf"},
|
|
24
24
|
json={
|
|
25
25
|
"subscription": {"name": "Free"},
|
|
@@ -82,8 +82,8 @@ class Bucket_Amazon_Base(ModuleTestBase):
|
|
|
82
82
|
if e.type == "FINDING" and str(e.module) == self.module_name:
|
|
83
83
|
url = e.data.get("url", "")
|
|
84
84
|
assert self.random_bucket_2 in url
|
|
85
|
-
assert
|
|
86
|
-
assert
|
|
85
|
+
assert self.random_bucket_1 not in url
|
|
86
|
+
assert self.random_bucket_3 not in url
|
|
87
87
|
# make sure bucket mutations were found
|
|
88
88
|
assert any(
|
|
89
89
|
e.type == "STORAGE_BUCKET"
|
|
@@ -21,7 +21,7 @@ class TestBucket_Azure_NoDup(ModuleTestBase):
|
|
|
21
21
|
|
|
22
22
|
async def setup_before_prep(self, module_test):
|
|
23
23
|
module_test.httpx_mock.add_response(
|
|
24
|
-
url=
|
|
24
|
+
url="https://tesla.blob.core.windows.net/tesla?restype=container",
|
|
25
25
|
text="",
|
|
26
26
|
)
|
|
27
27
|
await module_test.mock_dns(
|
|
@@ -6,7 +6,7 @@ class TestBuiltWith(ModuleTestBase):
|
|
|
6
6
|
|
|
7
7
|
async def setup_after_prep(self, module_test):
|
|
8
8
|
module_test.httpx_mock.add_response(
|
|
9
|
-
url=
|
|
9
|
+
url="https://api.builtwith.com/v20/api.json?KEY=asdf&LOOKUP=blacklanternsecurity.com&NOMETA=yes&NOATTR=yes&HIDETEXT=yes&HIDEDL=yes",
|
|
10
10
|
json={
|
|
11
11
|
"Results": [
|
|
12
12
|
{
|
|
@@ -91,7 +91,7 @@ class TestBuiltWith(ModuleTestBase):
|
|
|
91
91
|
},
|
|
92
92
|
)
|
|
93
93
|
module_test.httpx_mock.add_response(
|
|
94
|
-
url=
|
|
94
|
+
url="https://api.builtwith.com/redirect1/api.json?KEY=asdf&LOOKUP=blacklanternsecurity.com",
|
|
95
95
|
json={
|
|
96
96
|
"Lookup": "blacklanternsecurity.com",
|
|
97
97
|
"Inbound": [
|
|
@@ -51,10 +51,10 @@ class TestC99AbortThreshold1(TestC99):
|
|
|
51
51
|
|
|
52
52
|
def check(self, module_test, events):
|
|
53
53
|
assert module_test.module.api_failure_abort_threshold == 13
|
|
54
|
-
assert module_test.module.errored
|
|
54
|
+
assert module_test.module.errored is False
|
|
55
55
|
# assert module_test.module._api_request_failures == 4
|
|
56
56
|
assert module_test.module.api_retries == 4
|
|
57
|
-
assert
|
|
57
|
+
assert {e.data for e in events if e.type == "DNS_NAME"} == {"blacklanternsecurity.com"}
|
|
58
58
|
assert self.url_count == {
|
|
59
59
|
"https://api.c99.nl/randomnumber?key=6789&between=1,100&json": 1,
|
|
60
60
|
"https://api.c99.nl/randomnumber?key=4321&between=1,100&json": 1,
|
|
@@ -82,10 +82,10 @@ class TestC99AbortThreshold2(TestC99AbortThreshold1):
|
|
|
82
82
|
|
|
83
83
|
def check(self, module_test, events):
|
|
84
84
|
assert module_test.module.api_failure_abort_threshold == 13
|
|
85
|
-
assert module_test.module.errored
|
|
85
|
+
assert module_test.module.errored is False
|
|
86
86
|
assert module_test.module._api_request_failures == 8
|
|
87
87
|
assert module_test.module.api_retries == 4
|
|
88
|
-
assert
|
|
88
|
+
assert {e.data for e in events if e.type == "DNS_NAME"} == {"blacklanternsecurity.com", "evilcorp.com"}
|
|
89
89
|
assert self.url_count == {
|
|
90
90
|
"https://api.c99.nl/randomnumber?key=6789&between=1,100&json": 1,
|
|
91
91
|
"https://api.c99.nl/randomnumber?key=4321&between=1,100&json": 1,
|
|
@@ -106,10 +106,10 @@ class TestC99AbortThreshold3(TestC99AbortThreshold2):
|
|
|
106
106
|
|
|
107
107
|
def check(self, module_test, events):
|
|
108
108
|
assert module_test.module.api_failure_abort_threshold == 13
|
|
109
|
-
assert module_test.module.errored
|
|
109
|
+
assert module_test.module.errored is False
|
|
110
110
|
assert module_test.module._api_request_failures == 12
|
|
111
111
|
assert module_test.module.api_retries == 4
|
|
112
|
-
assert
|
|
112
|
+
assert {e.data for e in events if e.type == "DNS_NAME"} == {
|
|
113
113
|
"blacklanternsecurity.com",
|
|
114
114
|
"evilcorp.com",
|
|
115
115
|
"evilcorp.net",
|
|
@@ -138,14 +138,14 @@ class TestC99AbortThreshold4(TestC99AbortThreshold3):
|
|
|
138
138
|
|
|
139
139
|
def check(self, module_test, events):
|
|
140
140
|
assert module_test.module.api_failure_abort_threshold == 13
|
|
141
|
-
assert module_test.module.errored
|
|
141
|
+
assert module_test.module.errored is True
|
|
142
142
|
assert module_test.module._api_request_failures == 13
|
|
143
143
|
assert module_test.module.api_retries == 4
|
|
144
|
-
assert
|
|
144
|
+
assert {e.data for e in events if e.type == "DNS_NAME"} == {
|
|
145
145
|
"blacklanternsecurity.com",
|
|
146
146
|
"evilcorp.com",
|
|
147
147
|
"evilcorp.net",
|
|
148
148
|
"evilcorp.co.uk",
|
|
149
149
|
}
|
|
150
150
|
assert len(self.url_count) == 16
|
|
151
|
-
assert all(
|
|
151
|
+
assert all(v == 1 for v in self.url_count.values())
|
|
@@ -4,7 +4,7 @@ from .base import ModuleTestBase
|
|
|
4
4
|
class TestColumbus(ModuleTestBase):
|
|
5
5
|
async def setup_after_prep(self, module_test):
|
|
6
6
|
module_test.httpx_mock.add_response(
|
|
7
|
-
url=
|
|
7
|
+
url="https://columbus.elmasy.com/api/lookup/blacklanternsecurity.com?days=365",
|
|
8
8
|
json=["asdf", "zzzz"],
|
|
9
9
|
)
|
|
10
10
|
|
|
@@ -58,12 +58,12 @@ class TestCredshed(ModuleTestBase):
|
|
|
58
58
|
|
|
59
59
|
async def setup_before_prep(self, module_test):
|
|
60
60
|
module_test.httpx_mock.add_response(
|
|
61
|
-
url=
|
|
61
|
+
url="https://credshed.com/api/auth",
|
|
62
62
|
json=credshed_auth_response,
|
|
63
63
|
method="POST",
|
|
64
64
|
)
|
|
65
65
|
module_test.httpx_mock.add_response(
|
|
66
|
-
url=
|
|
66
|
+
url="https://credshed.com/api/search",
|
|
67
67
|
json=credshed_response,
|
|
68
68
|
method="POST",
|
|
69
69
|
)
|
|
@@ -45,7 +45,7 @@ class TestDehashed(ModuleTestBase):
|
|
|
45
45
|
|
|
46
46
|
async def setup_before_prep(self, module_test):
|
|
47
47
|
module_test.httpx_mock.add_response(
|
|
48
|
-
url=
|
|
48
|
+
url="https://api.dehashed.com/search?query=domain:blacklanternsecurity.com&size=10000&page=1",
|
|
49
49
|
json=dehashed_domain_response,
|
|
50
50
|
)
|
|
51
51
|
await module_test.mock_dns(
|
|
@@ -11,7 +11,7 @@ class TestDigitorus(ModuleTestBase):
|
|
|
11
11
|
|
|
12
12
|
async def setup_after_prep(self, module_test):
|
|
13
13
|
module_test.httpx_mock.add_response(
|
|
14
|
-
url=
|
|
14
|
+
url="https://certificatedetails.com/blacklanternsecurity.com",
|
|
15
15
|
text=self.web_response,
|
|
16
16
|
)
|
|
17
17
|
|
|
@@ -56,39 +56,39 @@ class TestDnsbrute(ModuleTestBase):
|
|
|
56
56
|
event = module_test.scan.make_event("blacklanternsecurity.com", "DNS_NAME", parent=module_test.scan.root_event)
|
|
57
57
|
event.scope_distance = 0
|
|
58
58
|
result, reason = await module_test.module.filter_event(event)
|
|
59
|
-
assert result
|
|
59
|
+
assert result is True
|
|
60
60
|
event = module_test.scan.make_event(
|
|
61
61
|
"www.blacklanternsecurity.com", "DNS_NAME", parent=module_test.scan.root_event
|
|
62
62
|
)
|
|
63
63
|
event.scope_distance = 0
|
|
64
64
|
result, reason = await module_test.module.filter_event(event)
|
|
65
|
-
assert result
|
|
65
|
+
assert result is True
|
|
66
66
|
event = module_test.scan.make_event(
|
|
67
67
|
"test.www.blacklanternsecurity.com", "DNS_NAME", parent=module_test.scan.root_event
|
|
68
68
|
)
|
|
69
69
|
event.scope_distance = 0
|
|
70
70
|
result, reason = await module_test.module.filter_event(event)
|
|
71
|
-
assert result
|
|
71
|
+
assert result is True
|
|
72
72
|
event = module_test.scan.make_event(
|
|
73
73
|
"asdf.test.www.blacklanternsecurity.com", "DNS_NAME", parent=module_test.scan.root_event
|
|
74
74
|
)
|
|
75
75
|
event.scope_distance = 0
|
|
76
76
|
result, reason = await module_test.module.filter_event(event)
|
|
77
|
-
assert result
|
|
77
|
+
assert result is True
|
|
78
78
|
event = module_test.scan.make_event(
|
|
79
79
|
"wat.asdf.test.www.blacklanternsecurity.com", "DNS_NAME", parent=module_test.scan.root_event
|
|
80
80
|
)
|
|
81
81
|
event.scope_distance = 0
|
|
82
82
|
result, reason = await module_test.module.filter_event(event)
|
|
83
|
-
assert result
|
|
84
|
-
assert reason ==
|
|
83
|
+
assert result is False
|
|
84
|
+
assert reason == "subdomain depth of *.asdf.test.www.blacklanternsecurity.com (4) > max_depth (3)"
|
|
85
85
|
event = module_test.scan.make_event(
|
|
86
86
|
"hmmm.ptr1234.blacklanternsecurity.com", "DNS_NAME", parent=module_test.scan.root_event
|
|
87
87
|
)
|
|
88
88
|
event.scope_distance = 0
|
|
89
89
|
result, reason = await module_test.module.filter_event(event)
|
|
90
|
-
assert result
|
|
91
|
-
assert reason ==
|
|
90
|
+
assert result is False
|
|
91
|
+
assert reason == '"ptr1234.blacklanternsecurity.com" looks like an autogenerated PTR'
|
|
92
92
|
|
|
93
93
|
def check(self, module_test, events):
|
|
94
94
|
assert len(events) == 4
|