bbot 2.0.1.4720rc0__py3-none-any.whl → 2.3.0.5401rc0__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.

Files changed (278) hide show
  1. bbot/__init__.py +1 -1
  2. bbot/cli.py +3 -7
  3. bbot/core/config/files.py +0 -1
  4. bbot/core/config/logger.py +34 -4
  5. bbot/core/core.py +21 -4
  6. bbot/core/engine.py +9 -8
  7. bbot/core/event/base.py +131 -52
  8. bbot/core/helpers/bloom.py +10 -3
  9. bbot/core/helpers/command.py +8 -7
  10. bbot/core/helpers/depsinstaller/installer.py +31 -13
  11. bbot/core/helpers/diff.py +10 -10
  12. bbot/core/helpers/dns/brute.py +7 -4
  13. bbot/core/helpers/dns/dns.py +1 -2
  14. bbot/core/helpers/dns/engine.py +4 -6
  15. bbot/core/helpers/dns/helpers.py +2 -2
  16. bbot/core/helpers/dns/mock.py +0 -1
  17. bbot/core/helpers/files.py +1 -1
  18. bbot/core/helpers/helper.py +7 -4
  19. bbot/core/helpers/interactsh.py +3 -3
  20. bbot/core/helpers/libmagic.py +65 -0
  21. bbot/core/helpers/misc.py +65 -22
  22. bbot/core/helpers/names_generator.py +17 -3
  23. bbot/core/helpers/process.py +0 -20
  24. bbot/core/helpers/regex.py +1 -1
  25. bbot/core/helpers/regexes.py +12 -6
  26. bbot/core/helpers/validators.py +1 -2
  27. bbot/core/helpers/web/client.py +1 -1
  28. bbot/core/helpers/web/engine.py +1 -2
  29. bbot/core/helpers/web/web.py +4 -114
  30. bbot/core/helpers/wordcloud.py +5 -5
  31. bbot/core/modules.py +36 -27
  32. bbot/core/multiprocess.py +58 -0
  33. bbot/core/shared_deps.py +46 -3
  34. bbot/db/sql/models.py +147 -0
  35. bbot/defaults.yml +12 -10
  36. bbot/modules/anubisdb.py +2 -2
  37. bbot/modules/apkpure.py +63 -0
  38. bbot/modules/azure_tenant.py +2 -2
  39. bbot/modules/baddns.py +35 -19
  40. bbot/modules/baddns_direct.py +92 -0
  41. bbot/modules/baddns_zone.py +3 -8
  42. bbot/modules/badsecrets.py +4 -3
  43. bbot/modules/base.py +195 -51
  44. bbot/modules/bevigil.py +7 -7
  45. bbot/modules/binaryedge.py +7 -4
  46. bbot/modules/bufferoverrun.py +47 -0
  47. bbot/modules/builtwith.py +6 -10
  48. bbot/modules/bypass403.py +5 -5
  49. bbot/modules/c99.py +10 -7
  50. bbot/modules/censys.py +9 -13
  51. bbot/modules/certspotter.py +5 -3
  52. bbot/modules/chaos.py +9 -7
  53. bbot/modules/code_repository.py +1 -0
  54. bbot/modules/columbus.py +3 -3
  55. bbot/modules/crt.py +5 -3
  56. bbot/modules/deadly/dastardly.py +1 -1
  57. bbot/modules/deadly/ffuf.py +9 -9
  58. bbot/modules/deadly/nuclei.py +3 -3
  59. bbot/modules/deadly/vhost.py +4 -3
  60. bbot/modules/dehashed.py +1 -1
  61. bbot/modules/digitorus.py +1 -1
  62. bbot/modules/dnsbimi.py +145 -0
  63. bbot/modules/dnscaa.py +3 -3
  64. bbot/modules/dnsdumpster.py +4 -4
  65. bbot/modules/dnstlsrpt.py +144 -0
  66. bbot/modules/docker_pull.py +7 -5
  67. bbot/modules/dockerhub.py +2 -2
  68. bbot/modules/dotnetnuke.py +20 -21
  69. bbot/modules/emailformat.py +1 -1
  70. bbot/modules/extractous.py +122 -0
  71. bbot/modules/filedownload.py +9 -7
  72. bbot/modules/fullhunt.py +7 -4
  73. bbot/modules/generic_ssrf.py +5 -5
  74. bbot/modules/github_codesearch.py +3 -2
  75. bbot/modules/github_org.py +4 -4
  76. bbot/modules/github_workflows.py +4 -4
  77. bbot/modules/gitlab.py +2 -5
  78. bbot/modules/google_playstore.py +93 -0
  79. bbot/modules/gowitness.py +48 -50
  80. bbot/modules/hackertarget.py +5 -3
  81. bbot/modules/host_header.py +5 -5
  82. bbot/modules/httpx.py +1 -4
  83. bbot/modules/hunterio.py +3 -9
  84. bbot/modules/iis_shortnames.py +19 -30
  85. bbot/modules/internal/cloudcheck.py +29 -12
  86. bbot/modules/internal/dnsresolve.py +22 -22
  87. bbot/modules/internal/excavate.py +97 -59
  88. bbot/modules/internal/speculate.py +41 -32
  89. bbot/modules/internetdb.py +4 -2
  90. bbot/modules/ip2location.py +3 -5
  91. bbot/modules/ipneighbor.py +1 -1
  92. bbot/modules/ipstack.py +3 -8
  93. bbot/modules/jadx.py +87 -0
  94. bbot/modules/leakix.py +11 -10
  95. bbot/modules/myssl.py +2 -2
  96. bbot/modules/newsletters.py +2 -2
  97. bbot/modules/otx.py +5 -3
  98. bbot/modules/output/asset_inventory.py +7 -7
  99. bbot/modules/output/base.py +1 -1
  100. bbot/modules/output/csv.py +1 -1
  101. bbot/modules/output/http.py +20 -14
  102. bbot/modules/output/mysql.py +51 -0
  103. bbot/modules/output/neo4j.py +7 -2
  104. bbot/modules/output/postgres.py +49 -0
  105. bbot/modules/output/slack.py +0 -1
  106. bbot/modules/output/sqlite.py +29 -0
  107. bbot/modules/output/stdout.py +2 -2
  108. bbot/modules/output/teams.py +107 -6
  109. bbot/modules/paramminer_headers.py +8 -11
  110. bbot/modules/passivetotal.py +13 -13
  111. bbot/modules/portscan.py +32 -6
  112. bbot/modules/postman.py +50 -126
  113. bbot/modules/postman_download.py +220 -0
  114. bbot/modules/rapiddns.py +3 -8
  115. bbot/modules/report/asn.py +18 -11
  116. bbot/modules/robots.py +3 -3
  117. bbot/modules/securitytrails.py +7 -10
  118. bbot/modules/securitytxt.py +1 -1
  119. bbot/modules/shodan_dns.py +7 -9
  120. bbot/modules/sitedossier.py +1 -1
  121. bbot/modules/skymem.py +2 -2
  122. bbot/modules/social.py +2 -1
  123. bbot/modules/subdomaincenter.py +1 -1
  124. bbot/modules/subdomainradar.py +160 -0
  125. bbot/modules/telerik.py +8 -8
  126. bbot/modules/templates/bucket.py +1 -1
  127. bbot/modules/templates/github.py +22 -14
  128. bbot/modules/templates/postman.py +21 -0
  129. bbot/modules/templates/shodan.py +14 -13
  130. bbot/modules/templates/sql.py +95 -0
  131. bbot/modules/templates/subdomain_enum.py +51 -16
  132. bbot/modules/templates/webhook.py +2 -4
  133. bbot/modules/trickest.py +8 -37
  134. bbot/modules/trufflehog.py +10 -12
  135. bbot/modules/url_manipulation.py +3 -3
  136. bbot/modules/urlscan.py +1 -1
  137. bbot/modules/viewdns.py +1 -1
  138. bbot/modules/virustotal.py +8 -30
  139. bbot/modules/wafw00f.py +1 -1
  140. bbot/modules/wayback.py +1 -1
  141. bbot/modules/wpscan.py +17 -11
  142. bbot/modules/zoomeye.py +11 -6
  143. bbot/presets/baddns-thorough.yml +12 -0
  144. bbot/presets/fast.yml +16 -0
  145. bbot/presets/kitchen-sink.yml +1 -2
  146. bbot/presets/spider.yml +4 -0
  147. bbot/presets/subdomain-enum.yml +7 -7
  148. bbot/presets/web/dotnet-audit.yml +0 -1
  149. bbot/scanner/manager.py +5 -16
  150. bbot/scanner/preset/args.py +46 -26
  151. bbot/scanner/preset/environ.py +7 -2
  152. bbot/scanner/preset/path.py +7 -4
  153. bbot/scanner/preset/preset.py +36 -23
  154. bbot/scanner/scanner.py +172 -62
  155. bbot/scanner/target.py +236 -434
  156. bbot/scripts/docs.py +1 -1
  157. bbot/test/bbot_fixtures.py +13 -3
  158. bbot/test/conftest.py +132 -100
  159. bbot/test/fastapi_test.py +17 -0
  160. bbot/test/owasp_mastg.apk +0 -0
  161. bbot/test/run_tests.sh +4 -4
  162. bbot/test/test.conf +2 -0
  163. bbot/test/test_step_1/test__module__tests.py +0 -1
  164. bbot/test/test_step_1/test_bbot_fastapi.py +79 -0
  165. bbot/test/test_step_1/test_bloom_filter.py +2 -1
  166. bbot/test/test_step_1/test_cli.py +138 -64
  167. bbot/test/test_step_1/test_dns.py +61 -27
  168. bbot/test/test_step_1/test_engine.py +17 -19
  169. bbot/test/test_step_1/test_events.py +183 -30
  170. bbot/test/test_step_1/test_helpers.py +64 -29
  171. bbot/test/test_step_1/test_manager_deduplication.py +1 -1
  172. bbot/test/test_step_1/test_manager_scope_accuracy.py +333 -330
  173. bbot/test/test_step_1/test_modules_basic.py +68 -70
  174. bbot/test/test_step_1/test_presets.py +183 -100
  175. bbot/test/test_step_1/test_python_api.py +7 -2
  176. bbot/test/test_step_1/test_regexes.py +35 -5
  177. bbot/test/test_step_1/test_scan.py +39 -5
  178. bbot/test/test_step_1/test_scope.py +4 -3
  179. bbot/test/test_step_1/test_target.py +242 -145
  180. bbot/test/test_step_1/test_web.py +14 -10
  181. bbot/test/test_step_2/module_tests/base.py +15 -7
  182. bbot/test/test_step_2/module_tests/test_module_anubisdb.py +1 -1
  183. bbot/test/test_step_2/module_tests/test_module_apkpure.py +71 -0
  184. bbot/test/test_step_2/module_tests/test_module_asset_inventory.py +0 -1
  185. bbot/test/test_step_2/module_tests/test_module_azure_realm.py +1 -1
  186. bbot/test/test_step_2/module_tests/test_module_baddns.py +6 -6
  187. bbot/test/test_step_2/module_tests/test_module_baddns_direct.py +62 -0
  188. bbot/test/test_step_2/module_tests/test_module_bevigil.py +29 -2
  189. bbot/test/test_step_2/module_tests/test_module_binaryedge.py +4 -2
  190. bbot/test/test_step_2/module_tests/test_module_bucket_amazon.py +2 -2
  191. bbot/test/test_step_2/module_tests/test_module_bucket_azure.py +1 -1
  192. bbot/test/test_step_2/module_tests/test_module_bufferoverrun.py +35 -0
  193. bbot/test/test_step_2/module_tests/test_module_builtwith.py +2 -2
  194. bbot/test/test_step_2/module_tests/test_module_bypass403.py +1 -1
  195. bbot/test/test_step_2/module_tests/test_module_c99.py +126 -0
  196. bbot/test/test_step_2/module_tests/test_module_censys.py +4 -1
  197. bbot/test/test_step_2/module_tests/test_module_cloudcheck.py +4 -0
  198. bbot/test/test_step_2/module_tests/test_module_code_repository.py +11 -1
  199. bbot/test/test_step_2/module_tests/test_module_columbus.py +1 -1
  200. bbot/test/test_step_2/module_tests/test_module_credshed.py +3 -3
  201. bbot/test/test_step_2/module_tests/test_module_dastardly.py +2 -1
  202. bbot/test/test_step_2/module_tests/test_module_dehashed.py +2 -2
  203. bbot/test/test_step_2/module_tests/test_module_digitorus.py +1 -1
  204. bbot/test/test_step_2/module_tests/test_module_discord.py +1 -1
  205. bbot/test/test_step_2/module_tests/test_module_dnsbimi.py +103 -0
  206. bbot/test/test_step_2/module_tests/test_module_dnsbrute.py +9 -10
  207. bbot/test/test_step_2/module_tests/test_module_dnsbrute_mutations.py +1 -2
  208. bbot/test/test_step_2/module_tests/test_module_dnscommonsrv.py +1 -2
  209. bbot/test/test_step_2/module_tests/test_module_dnsdumpster.py +4 -4
  210. bbot/test/test_step_2/module_tests/test_module_dnstlsrpt.py +64 -0
  211. bbot/test/test_step_2/module_tests/test_module_dotnetnuke.py +0 -8
  212. bbot/test/test_step_2/module_tests/test_module_excavate.py +28 -48
  213. bbot/test/test_step_2/module_tests/test_module_extractous.py +54 -0
  214. bbot/test/test_step_2/module_tests/test_module_ffuf_shortnames.py +1 -1
  215. bbot/test/test_step_2/module_tests/test_module_filedownload.py +14 -14
  216. bbot/test/test_step_2/module_tests/test_module_git_clone.py +2 -2
  217. bbot/test/test_step_2/module_tests/test_module_github_org.py +19 -8
  218. bbot/test/test_step_2/module_tests/test_module_github_workflows.py +1 -1
  219. bbot/test/test_step_2/module_tests/test_module_gitlab.py +9 -4
  220. bbot/test/test_step_2/module_tests/test_module_google_playstore.py +83 -0
  221. bbot/test/test_step_2/module_tests/test_module_gowitness.py +4 -6
  222. bbot/test/test_step_2/module_tests/test_module_host_header.py +1 -1
  223. bbot/test/test_step_2/module_tests/test_module_http.py +4 -4
  224. bbot/test/test_step_2/module_tests/test_module_httpx.py +10 -8
  225. bbot/test/test_step_2/module_tests/test_module_hunterio.py +68 -4
  226. bbot/test/test_step_2/module_tests/test_module_jadx.py +55 -0
  227. bbot/test/test_step_2/module_tests/test_module_json.py +22 -9
  228. bbot/test/test_step_2/module_tests/test_module_leakix.py +7 -3
  229. bbot/test/test_step_2/module_tests/test_module_mysql.py +76 -0
  230. bbot/test/test_step_2/module_tests/test_module_myssl.py +1 -1
  231. bbot/test/test_step_2/module_tests/test_module_neo4j.py +1 -1
  232. bbot/test/test_step_2/module_tests/test_module_newsletters.py +16 -16
  233. bbot/test/test_step_2/module_tests/test_module_ntlm.py +8 -7
  234. bbot/test/test_step_2/module_tests/test_module_oauth.py +1 -1
  235. bbot/test/test_step_2/module_tests/test_module_otx.py +1 -1
  236. bbot/test/test_step_2/module_tests/test_module_paramminer_cookies.py +1 -2
  237. bbot/test/test_step_2/module_tests/test_module_paramminer_getparams.py +0 -6
  238. bbot/test/test_step_2/module_tests/test_module_paramminer_headers.py +2 -9
  239. bbot/test/test_step_2/module_tests/test_module_passivetotal.py +3 -1
  240. bbot/test/test_step_2/module_tests/test_module_pgp.py +2 -2
  241. bbot/test/test_step_2/module_tests/test_module_portscan.py +9 -8
  242. bbot/test/test_step_2/module_tests/test_module_postgres.py +74 -0
  243. bbot/test/test_step_2/module_tests/test_module_postman.py +84 -253
  244. bbot/test/test_step_2/module_tests/test_module_postman_download.py +439 -0
  245. bbot/test/test_step_2/module_tests/test_module_rapiddns.py +93 -1
  246. bbot/test/test_step_2/module_tests/test_module_shodan_dns.py +20 -1
  247. bbot/test/test_step_2/module_tests/test_module_sitedossier.py +2 -2
  248. bbot/test/test_step_2/module_tests/test_module_smuggler.py +14 -14
  249. bbot/test/test_step_2/module_tests/test_module_social.py +11 -1
  250. bbot/test/test_step_2/module_tests/test_module_speculate.py +4 -8
  251. bbot/test/test_step_2/module_tests/test_module_splunk.py +4 -4
  252. bbot/test/test_step_2/module_tests/test_module_sqlite.py +18 -0
  253. bbot/test/test_step_2/module_tests/test_module_sslcert.py +1 -1
  254. bbot/test/test_step_2/module_tests/test_module_stdout.py +5 -3
  255. bbot/test/test_step_2/module_tests/test_module_subdomaincenter.py +1 -1
  256. bbot/test/test_step_2/module_tests/test_module_subdomainradar.py +208 -0
  257. bbot/test/test_step_2/module_tests/test_module_subdomains.py +1 -1
  258. bbot/test/test_step_2/module_tests/test_module_teams.py +8 -6
  259. bbot/test/test_step_2/module_tests/test_module_telerik.py +1 -1
  260. bbot/test/test_step_2/module_tests/test_module_trufflehog.py +317 -14
  261. bbot/test/test_step_2/module_tests/test_module_viewdns.py +1 -1
  262. bbot/test/test_step_2/module_tests/test_module_wayback.py +1 -1
  263. bbot/test/test_step_2/template_tests/test_template_subdomain_enum.py +2 -2
  264. bbot/wordlists/devops_mutations.txt +1 -1
  265. bbot/wordlists/ffuf_shortname_candidates.txt +1 -1
  266. bbot/wordlists/nameservers.txt +1 -1
  267. bbot/wordlists/paramminer_headers.txt +1 -1
  268. bbot/wordlists/paramminer_parameters.txt +1 -1
  269. bbot/wordlists/raft-small-extensions-lowercase_CLEANED.txt +1 -1
  270. bbot/wordlists/valid_url_schemes.txt +1 -1
  271. {bbot-2.0.1.4720rc0.dist-info → bbot-2.3.0.5401rc0.dist-info}/METADATA +48 -18
  272. bbot-2.3.0.5401rc0.dist-info/RECORD +421 -0
  273. {bbot-2.0.1.4720rc0.dist-info → bbot-2.3.0.5401rc0.dist-info}/WHEEL +1 -1
  274. bbot/modules/unstructured.py +0 -163
  275. bbot/test/test_step_2/module_tests/test_module_unstructured.py +0 -102
  276. bbot-2.0.1.4720rc0.dist-info/RECORD +0 -387
  277. {bbot-2.0.1.4720rc0.dist-info → bbot-2.3.0.5401rc0.dist-info}/LICENSE +0 -0
  278. {bbot-2.0.1.4720rc0.dist-info → bbot-2.3.0.5401rc0.dist-info}/entry_points.txt +0 -0
@@ -2,11 +2,12 @@ from .base import ModuleTestBase
2
2
 
3
3
 
4
4
  class TestCensys(ModuleTestBase):
5
- config_overrides = {"modules": {"censys": {"api_id": "api_id", "api_secret": "api_secret"}}}
5
+ config_overrides = {"modules": {"censys": {"api_key": "api_id:api_secret"}}}
6
6
 
7
7
  async def setup_before_prep(self, module_test):
8
8
  module_test.httpx_mock.add_response(
9
9
  url="https://search.censys.io/api/v1/account",
10
+ match_headers={"Authorization": "Basic YXBpX2lkOmFwaV9zZWNyZXQ="},
10
11
  json={
11
12
  "email": "info@blacklanternsecurity.com",
12
13
  "login": "nope",
@@ -17,6 +18,7 @@ class TestCensys(ModuleTestBase):
17
18
  )
18
19
  module_test.httpx_mock.add_response(
19
20
  url="https://search.censys.io/api/v2/certificates/search",
21
+ match_headers={"Authorization": "Basic YXBpX2lkOmFwaV9zZWNyZXQ="},
20
22
  match_content=b'{"q": "names: blacklanternsecurity.com", "per_page": 100}',
21
23
  json={
22
24
  "code": 200,
@@ -45,6 +47,7 @@ class TestCensys(ModuleTestBase):
45
47
  )
46
48
  module_test.httpx_mock.add_response(
47
49
  url="https://search.censys.io/api/v2/certificates/search",
50
+ match_headers={"Authorization": "Basic YXBpX2lkOmFwaV9zZWNyZXQ="},
48
51
  match_content=b'{"q": "names: blacklanternsecurity.com", "per_page": 100, "cursor": "NextToken"}',
49
52
  json={
50
53
  "code": 200,
@@ -51,6 +51,10 @@ class TestCloudCheck(ModuleTestBase):
51
51
  await module.handle_event(event)
52
52
  assert "cloud-amazon" in event.tags, f"{event} was not properly cloud-tagged"
53
53
 
54
+ assert "cloud-domain" in aws_event1.tags
55
+ assert "cloud-ip" in other_event2.tags
56
+ assert "cloud-cname" in other_event3.tags
57
+
54
58
  for event in (aws_event3, other_event1):
55
59
  await module.handle_event(event)
56
60
  assert "cloud-amazon" not in event.tags, f"{event} was improperly cloud-tagged"
@@ -14,13 +14,14 @@ class TestCodeRepository(ModuleTestBase):
14
14
  <a href="https://gitlab.com/blacklanternsecurity/bbot"/>
15
15
  <a href="https://gitlab.org/blacklanternsecurity/bbot"/>
16
16
  <a href="https://hub.docker.com/r/blacklanternsecurity/bbot"/>
17
+ <a href="https://www.postman.com/blacklanternsecurity/bbot"/>
17
18
  </html>
18
19
  """
19
20
  }
20
21
  module_test.set_expect_requests(expect_args=expect_args, respond_args=respond_args)
21
22
 
22
23
  def check(self, module_test, events):
23
- assert 4 == len([e for e in events if e.type == "CODE_REPOSITORY"])
24
+ assert 5 == len([e for e in events if e.type == "CODE_REPOSITORY"])
24
25
  assert 1 == len(
25
26
  [
26
27
  e
@@ -57,3 +58,12 @@ class TestCodeRepository(ModuleTestBase):
57
58
  and e.data["url"] == "https://hub.docker.com/r/blacklanternsecurity/bbot"
58
59
  ]
59
60
  )
61
+ assert 1 == len(
62
+ [
63
+ e
64
+ for e in events
65
+ if e.type == "CODE_REPOSITORY"
66
+ and "postman" in e.tags
67
+ and e.data["url"] == "https://www.postman.com/blacklanternsecurity/bbot"
68
+ ]
69
+ )
@@ -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=f"https://columbus.elmasy.com/api/lookup/blacklanternsecurity.com?days=365",
7
+ url="https://columbus.elmasy.com/api/lookup/blacklanternsecurity.com?days=365",
8
8
  json=["asdf", "zzzz"],
9
9
  )
10
10
 
@@ -58,18 +58,18 @@ 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=f"https://credshed.com/api/auth",
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=f"https://credshed.com/api/search",
66
+ url="https://credshed.com/api/search",
67
67
  json=credshed_response,
68
68
  method="POST",
69
69
  )
70
70
 
71
71
  def check(self, module_test, events):
72
- assert len(events) == 10
72
+ assert len(events) == 11
73
73
  assert 1 == len([e for e in events if e.type == "EMAIL_ADDRESS" and e.data == "bob@blacklanternsecurity.com"])
74
74
  assert 1 == len([e for e in events if e.type == "EMAIL_ADDRESS" and e.data == "judy@blacklanternsecurity.com"])
75
75
  assert 1 == len([e for e in events if e.type == "EMAIL_ADDRESS" and e.data == "tim@blacklanternsecurity.com"])
@@ -7,6 +7,7 @@ from .base import ModuleTestBase
7
7
  class TestDastardly(ModuleTestBase):
8
8
  targets = ["http://127.0.0.1:5556/"]
9
9
  modules_overrides = ["httpx", "dastardly"]
10
+ skip_distro_tests = True
10
11
 
11
12
  web_response = """<!DOCTYPE html>
12
13
  <html>
@@ -44,7 +45,7 @@ class TestDastardly(ModuleTestBase):
44
45
 
45
46
  # get docker IP
46
47
  docker_ip = await self.get_docker_ip(module_test)
47
- module_test.scan.target.add(docker_ip)
48
+ module_test.scan.target.seeds.add(docker_ip)
48
49
 
49
50
  # replace 127.0.0.1 with docker host IP to allow dastardly access to local http server
50
51
  old_filter_event = module_test.module.filter_event
@@ -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=f"https://api.dehashed.com/search?query=domain:blacklanternsecurity.com&size=10000&page=1",
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(
@@ -56,7 +56,7 @@ class TestDehashed(ModuleTestBase):
56
56
  )
57
57
 
58
58
  def check(self, module_test, events):
59
- assert len(events) == 11
59
+ assert len(events) == 12
60
60
  assert 1 == len([e for e in events if e.type == "DNS_NAME" and e.data == "blacklanternsecurity.com"])
61
61
  assert 1 == len([e for e in events if e.type == "ORG_STUB" and e.data == "blacklanternsecurity"])
62
62
  assert 1 == len(
@@ -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=f"https://certificatedetails.com/blacklanternsecurity.com",
14
+ url="https://certificatedetails.com/blacklanternsecurity.com",
15
15
  text=self.web_response,
16
16
  )
17
17
 
@@ -29,7 +29,7 @@ class TestDiscord(ModuleTestBase):
29
29
  if module_test.request_count == 2:
30
30
  return httpx.Response(status_code=429, json={"retry_after": 0.01})
31
31
  else:
32
- return httpx.Response(status_code=module_test.module.good_status_code)
32
+ return httpx.Response(status_code=200)
33
33
 
34
34
  module_test.httpx_mock.add_callback(custom_response, url=self.webhook_url)
35
35
 
@@ -0,0 +1,103 @@
1
+ from .base import ModuleTestBase
2
+
3
+ raw_bimi_txt_default = (
4
+ '"v=BIMI1;l=https://bimi.test.localdomain/logo.svg; a=https://bimi.test.localdomain/certificate.pem"'
5
+ )
6
+ raw_bimi_txt_nondefault = '"v=BIMI1; l=https://nondefault.thirdparty.tld/brand/logo.svg;a=https://nondefault.thirdparty.tld/brand/certificate.pem;"'
7
+
8
+
9
+ class TestBIMI(ModuleTestBase):
10
+ targets = ["test.localdomain"]
11
+ modules_overrides = ["dnsbimi", "speculate"]
12
+ config_overrides = {
13
+ "modules": {"dnsbimi": {"emit_raw_dns_records": True, "selectors": "default,nondefault"}},
14
+ }
15
+
16
+ async def setup_after_prep(self, module_test):
17
+ await module_test.mock_dns(
18
+ {
19
+ "test.localdomain": {
20
+ "A": ["127.0.0.11"],
21
+ },
22
+ "bimi.test.localdomain": {
23
+ "A": ["127.0.0.22"],
24
+ },
25
+ "_bimi.test.localdomain": {
26
+ "A": ["127.0.0.33"],
27
+ },
28
+ "default._bimi.test.localdomain": {
29
+ "A": ["127.0.0.44"],
30
+ "TXT": [raw_bimi_txt_default],
31
+ },
32
+ "nondefault._bimi.test.localdomain": {
33
+ "A": ["127.0.0.44"],
34
+ "TXT": [raw_bimi_txt_nondefault],
35
+ },
36
+ "_bimi.default._bimi.test.localdomain": {
37
+ "A": ["127.0.0.44"],
38
+ "TXT": [raw_bimi_txt_default],
39
+ },
40
+ "_bimi.nondefault._bimi.test.localdomain": {
41
+ "A": ["127.0.0.44"],
42
+ "TXT": [raw_bimi_txt_default],
43
+ },
44
+ "default._bimi.default._bimi.test.localdomain": {
45
+ "A": ["127.0.0.44"],
46
+ "TXT": [raw_bimi_txt_default],
47
+ },
48
+ "nondefault._bimi.nondefault._bimi.test.localdomain": {
49
+ "A": ["127.0.0.44"],
50
+ "TXT": [raw_bimi_txt_nondefault],
51
+ },
52
+ }
53
+ )
54
+
55
+ def check(self, module_test, events):
56
+ assert any(
57
+ e.type == "RAW_DNS_RECORD"
58
+ and e.data["host"] == "default._bimi.test.localdomain"
59
+ and e.data["type"] == "TXT"
60
+ and e.data["answer"] == raw_bimi_txt_default
61
+ for e in events
62
+ ), "Failed to emit RAW_DNS_RECORD"
63
+ assert any(
64
+ e.type == "RAW_DNS_RECORD"
65
+ and e.data["host"] == "nondefault._bimi.test.localdomain"
66
+ and e.data["type"] == "TXT"
67
+ and e.data["answer"] == raw_bimi_txt_nondefault
68
+ for e in events
69
+ ), "Failed to emit RAW_DNS_RECORD"
70
+
71
+ assert any(
72
+ e.type == "DNS_NAME" and e.data == "bimi.test.localdomain" for e in events
73
+ ), "Failed to emit DNS_NAME"
74
+
75
+ # This should be filtered by a default BBOT configuration
76
+ assert not any(str(e.data) == "https://nondefault.thirdparty.tld/brand/logo.svg" for e in events)
77
+
78
+ # This should not be filtered by a default BBOT configuration
79
+ assert any(
80
+ e.type == "URL_UNVERIFIED" and e.data == "https://bimi.test.localdomain/certificate.pem" for e in events
81
+ ), "Failed to emit URL_UNVERIFIED"
82
+
83
+ # These should be filtered simply due to distance
84
+ assert not any(str(e.data) == "https://nondefault.thirdparty.tld/brand/logo.svg" for e in events)
85
+ assert not any(str(e.data) == "https://nondefault.thirdparty.tld/certificate.pem" for e in events)
86
+
87
+ # These should have been filtered via filter_event()
88
+ assert not any(
89
+ e.type == "RAW_DNS_RECORD" and e.data["host"] == "default._bimi.default._bimi.test.localdomain"
90
+ for e in events
91
+ ), "Unwanted recursion occurring"
92
+ assert not any(
93
+ e.type == "RAW_DNS_RECORD" and e.data["host"] == "nondefault._bimi.nondefault._bimi.test.localdomain"
94
+ for e in events
95
+ ), "Unwanted recursion occurring"
96
+ assert not any(
97
+ e.type == "RAW_DNS_RECORD" and e.data["host"] == "nondefault._bimi.default._bimi.test.localdomain"
98
+ for e in events
99
+ ), "Unwanted recursion occurring"
100
+ assert not any(
101
+ e.type == "RAW_DNS_RECORD" and e.data["host"] == "default._bimi.nondefault._bimi.test.localdomain"
102
+ for e in events
103
+ ), "Unwanted recursion occurring"
@@ -7,7 +7,6 @@ class TestDnsbrute(ModuleTestBase):
7
7
  config_overrides = {"modules": {"dnsbrute": {"wordlist": str(subdomain_wordlist), "max_depth": 3}}}
8
8
 
9
9
  async def setup_after_prep(self, module_test):
10
-
11
10
  old_run_live = module_test.scan.helpers.run_live
12
11
 
13
12
  async def new_run_live(*command, check=False, text=True, **kwargs):
@@ -57,42 +56,42 @@ class TestDnsbrute(ModuleTestBase):
57
56
  event = module_test.scan.make_event("blacklanternsecurity.com", "DNS_NAME", parent=module_test.scan.root_event)
58
57
  event.scope_distance = 0
59
58
  result, reason = await module_test.module.filter_event(event)
60
- assert result == True
59
+ assert result is True
61
60
  event = module_test.scan.make_event(
62
61
  "www.blacklanternsecurity.com", "DNS_NAME", parent=module_test.scan.root_event
63
62
  )
64
63
  event.scope_distance = 0
65
64
  result, reason = await module_test.module.filter_event(event)
66
- assert result == True
65
+ assert result is True
67
66
  event = module_test.scan.make_event(
68
67
  "test.www.blacklanternsecurity.com", "DNS_NAME", parent=module_test.scan.root_event
69
68
  )
70
69
  event.scope_distance = 0
71
70
  result, reason = await module_test.module.filter_event(event)
72
- assert result == True
71
+ assert result is True
73
72
  event = module_test.scan.make_event(
74
73
  "asdf.test.www.blacklanternsecurity.com", "DNS_NAME", parent=module_test.scan.root_event
75
74
  )
76
75
  event.scope_distance = 0
77
76
  result, reason = await module_test.module.filter_event(event)
78
- assert result == True
77
+ assert result is True
79
78
  event = module_test.scan.make_event(
80
79
  "wat.asdf.test.www.blacklanternsecurity.com", "DNS_NAME", parent=module_test.scan.root_event
81
80
  )
82
81
  event.scope_distance = 0
83
82
  result, reason = await module_test.module.filter_event(event)
84
- assert result == False
85
- assert reason == f"subdomain depth of *.asdf.test.www.blacklanternsecurity.com (4) > max_depth (3)"
83
+ assert result is False
84
+ assert reason == "subdomain depth of *.asdf.test.www.blacklanternsecurity.com (4) > max_depth (3)"
86
85
  event = module_test.scan.make_event(
87
86
  "hmmm.ptr1234.blacklanternsecurity.com", "DNS_NAME", parent=module_test.scan.root_event
88
87
  )
89
88
  event.scope_distance = 0
90
89
  result, reason = await module_test.module.filter_event(event)
91
- assert result == False
92
- assert reason == f'"ptr1234.blacklanternsecurity.com" looks like an autogenerated PTR'
90
+ assert result is False
91
+ assert reason == '"ptr1234.blacklanternsecurity.com" looks like an autogenerated PTR'
93
92
 
94
93
  def check(self, module_test, events):
95
- assert len(events) == 3
94
+ assert len(events) == 4
96
95
  assert 1 == len(
97
96
  [e for e in events if e.data == "asdf.blacklanternsecurity.com" and str(e.module) == "dnsbrute"]
98
97
  )
@@ -11,7 +11,6 @@ class TestDnsbrute_mutations(ModuleTestBase):
11
11
  ]
12
12
 
13
13
  async def setup_after_prep(self, module_test):
14
-
15
14
  old_run_live = module_test.scan.helpers.run_live
16
15
 
17
16
  async def new_run_live(*command, check=False, text=True, **kwargs):
@@ -47,7 +46,7 @@ class TestDnsbrute_mutations(ModuleTestBase):
47
46
  )
48
47
 
49
48
  def check(self, module_test, events):
50
- assert len(events) == 9
49
+ assert len(events) == 10
51
50
  assert 1 == len(
52
51
  [
53
52
  e
@@ -8,7 +8,6 @@ class TestDNSCommonSRV(ModuleTestBase):
8
8
  config_overrides = {"dns": {"minimal": False}}
9
9
 
10
10
  async def setup_after_prep(self, module_test):
11
-
12
11
  old_run_live = module_test.scan.helpers.run_live
13
12
 
14
13
  async def new_run_live(*command, check=False, text=True, **kwargs):
@@ -56,7 +55,7 @@ class TestDNSCommonSRV(ModuleTestBase):
56
55
  )
57
56
 
58
57
  def check(self, module_test, events):
59
- assert len(events) == 19
58
+ assert len(events) == 20
60
59
  assert 1 == len([e for e in events if e.type == "DNS_NAME" and e.data == "blacklanternsecurity.com"])
61
60
  assert 1 == len(
62
61
  [