bbot 2.0.1.4720rc0__py3-none-any.whl → 2.3.0.5397rc0__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 (267) 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 +11 -9
  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 +18 -19
  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 +27 -12
  86. bbot/modules/internal/dnsresolve.py +22 -20
  87. bbot/modules/internal/excavate.py +85 -48
  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 +5 -8
  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 +11 -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 -0
  146. bbot/presets/spider.yml +4 -0
  147. bbot/presets/subdomain-enum.yml +7 -7
  148. bbot/scanner/manager.py +5 -16
  149. bbot/scanner/preset/args.py +44 -26
  150. bbot/scanner/preset/environ.py +7 -2
  151. bbot/scanner/preset/path.py +7 -4
  152. bbot/scanner/preset/preset.py +36 -23
  153. bbot/scanner/scanner.py +172 -62
  154. bbot/scanner/target.py +236 -434
  155. bbot/scripts/docs.py +1 -1
  156. bbot/test/bbot_fixtures.py +13 -3
  157. bbot/test/conftest.py +132 -100
  158. bbot/test/fastapi_test.py +17 -0
  159. bbot/test/owasp_mastg.apk +0 -0
  160. bbot/test/run_tests.sh +4 -4
  161. bbot/test/test.conf +2 -0
  162. bbot/test/test_step_1/test_bbot_fastapi.py +82 -0
  163. bbot/test/test_step_1/test_bloom_filter.py +2 -0
  164. bbot/test/test_step_1/test_cli.py +138 -64
  165. bbot/test/test_step_1/test_dns.py +62 -25
  166. bbot/test/test_step_1/test_engine.py +17 -17
  167. bbot/test/test_step_1/test_events.py +183 -28
  168. bbot/test/test_step_1/test_helpers.py +64 -28
  169. bbot/test/test_step_1/test_manager_deduplication.py +1 -1
  170. bbot/test/test_step_1/test_manager_scope_accuracy.py +333 -330
  171. bbot/test/test_step_1/test_modules_basic.py +68 -70
  172. bbot/test/test_step_1/test_presets.py +184 -96
  173. bbot/test/test_step_1/test_python_api.py +7 -2
  174. bbot/test/test_step_1/test_regexes.py +35 -5
  175. bbot/test/test_step_1/test_scan.py +39 -5
  176. bbot/test/test_step_1/test_scope.py +4 -3
  177. bbot/test/test_step_1/test_target.py +243 -145
  178. bbot/test/test_step_1/test_web.py +14 -8
  179. bbot/test/test_step_2/module_tests/base.py +15 -7
  180. bbot/test/test_step_2/module_tests/test_module_anubisdb.py +1 -1
  181. bbot/test/test_step_2/module_tests/test_module_apkpure.py +71 -0
  182. bbot/test/test_step_2/module_tests/test_module_asset_inventory.py +0 -1
  183. bbot/test/test_step_2/module_tests/test_module_azure_realm.py +1 -1
  184. bbot/test/test_step_2/module_tests/test_module_baddns.py +6 -6
  185. bbot/test/test_step_2/module_tests/test_module_baddns_direct.py +62 -0
  186. bbot/test/test_step_2/module_tests/test_module_bevigil.py +29 -2
  187. bbot/test/test_step_2/module_tests/test_module_binaryedge.py +4 -2
  188. bbot/test/test_step_2/module_tests/test_module_bucket_amazon.py +2 -2
  189. bbot/test/test_step_2/module_tests/test_module_bucket_azure.py +1 -1
  190. bbot/test/test_step_2/module_tests/test_module_bufferoverrun.py +35 -0
  191. bbot/test/test_step_2/module_tests/test_module_builtwith.py +2 -2
  192. bbot/test/test_step_2/module_tests/test_module_bypass403.py +1 -1
  193. bbot/test/test_step_2/module_tests/test_module_c99.py +126 -0
  194. bbot/test/test_step_2/module_tests/test_module_censys.py +4 -1
  195. bbot/test/test_step_2/module_tests/test_module_cloudcheck.py +4 -0
  196. bbot/test/test_step_2/module_tests/test_module_code_repository.py +11 -1
  197. bbot/test/test_step_2/module_tests/test_module_columbus.py +1 -1
  198. bbot/test/test_step_2/module_tests/test_module_credshed.py +3 -3
  199. bbot/test/test_step_2/module_tests/test_module_dastardly.py +2 -1
  200. bbot/test/test_step_2/module_tests/test_module_dehashed.py +2 -2
  201. bbot/test/test_step_2/module_tests/test_module_digitorus.py +1 -1
  202. bbot/test/test_step_2/module_tests/test_module_discord.py +1 -1
  203. bbot/test/test_step_2/module_tests/test_module_dnsbimi.py +103 -0
  204. bbot/test/test_step_2/module_tests/test_module_dnsbrute.py +9 -10
  205. bbot/test/test_step_2/module_tests/test_module_dnsbrute_mutations.py +1 -2
  206. bbot/test/test_step_2/module_tests/test_module_dnscommonsrv.py +1 -2
  207. bbot/test/test_step_2/module_tests/test_module_dnsdumpster.py +4 -4
  208. bbot/test/test_step_2/module_tests/test_module_dnstlsrpt.py +64 -0
  209. bbot/test/test_step_2/module_tests/test_module_dotnetnuke.py +0 -8
  210. bbot/test/test_step_2/module_tests/test_module_excavate.py +17 -37
  211. bbot/test/test_step_2/module_tests/test_module_extractous.py +54 -0
  212. bbot/test/test_step_2/module_tests/test_module_ffuf_shortnames.py +1 -1
  213. bbot/test/test_step_2/module_tests/test_module_filedownload.py +14 -14
  214. bbot/test/test_step_2/module_tests/test_module_git_clone.py +2 -2
  215. bbot/test/test_step_2/module_tests/test_module_github_org.py +19 -8
  216. bbot/test/test_step_2/module_tests/test_module_github_workflows.py +1 -1
  217. bbot/test/test_step_2/module_tests/test_module_gitlab.py +9 -4
  218. bbot/test/test_step_2/module_tests/test_module_google_playstore.py +83 -0
  219. bbot/test/test_step_2/module_tests/test_module_gowitness.py +4 -4
  220. bbot/test/test_step_2/module_tests/test_module_host_header.py +1 -1
  221. bbot/test/test_step_2/module_tests/test_module_http.py +4 -4
  222. bbot/test/test_step_2/module_tests/test_module_httpx.py +10 -8
  223. bbot/test/test_step_2/module_tests/test_module_hunterio.py +68 -4
  224. bbot/test/test_step_2/module_tests/test_module_jadx.py +55 -0
  225. bbot/test/test_step_2/module_tests/test_module_json.py +22 -9
  226. bbot/test/test_step_2/module_tests/test_module_leakix.py +7 -3
  227. bbot/test/test_step_2/module_tests/test_module_mysql.py +76 -0
  228. bbot/test/test_step_2/module_tests/test_module_myssl.py +1 -1
  229. bbot/test/test_step_2/module_tests/test_module_neo4j.py +1 -1
  230. bbot/test/test_step_2/module_tests/test_module_newsletters.py +6 -6
  231. bbot/test/test_step_2/module_tests/test_module_ntlm.py +7 -7
  232. bbot/test/test_step_2/module_tests/test_module_oauth.py +1 -1
  233. bbot/test/test_step_2/module_tests/test_module_otx.py +1 -1
  234. bbot/test/test_step_2/module_tests/test_module_paramminer_cookies.py +1 -2
  235. bbot/test/test_step_2/module_tests/test_module_paramminer_getparams.py +0 -6
  236. bbot/test/test_step_2/module_tests/test_module_paramminer_headers.py +2 -9
  237. bbot/test/test_step_2/module_tests/test_module_passivetotal.py +3 -1
  238. bbot/test/test_step_2/module_tests/test_module_portscan.py +9 -8
  239. bbot/test/test_step_2/module_tests/test_module_postgres.py +74 -0
  240. bbot/test/test_step_2/module_tests/test_module_postman.py +84 -253
  241. bbot/test/test_step_2/module_tests/test_module_postman_download.py +439 -0
  242. bbot/test/test_step_2/module_tests/test_module_rapiddns.py +93 -1
  243. bbot/test/test_step_2/module_tests/test_module_shodan_dns.py +20 -1
  244. bbot/test/test_step_2/module_tests/test_module_sitedossier.py +2 -2
  245. bbot/test/test_step_2/module_tests/test_module_smuggler.py +1 -1
  246. bbot/test/test_step_2/module_tests/test_module_social.py +11 -1
  247. bbot/test/test_step_2/module_tests/test_module_speculate.py +2 -6
  248. bbot/test/test_step_2/module_tests/test_module_splunk.py +4 -4
  249. bbot/test/test_step_2/module_tests/test_module_sqlite.py +18 -0
  250. bbot/test/test_step_2/module_tests/test_module_sslcert.py +1 -1
  251. bbot/test/test_step_2/module_tests/test_module_stdout.py +5 -3
  252. bbot/test/test_step_2/module_tests/test_module_subdomaincenter.py +1 -1
  253. bbot/test/test_step_2/module_tests/test_module_subdomainradar.py +208 -0
  254. bbot/test/test_step_2/module_tests/test_module_subdomains.py +1 -1
  255. bbot/test/test_step_2/module_tests/test_module_teams.py +8 -6
  256. bbot/test/test_step_2/module_tests/test_module_telerik.py +1 -1
  257. bbot/test/test_step_2/module_tests/test_module_trufflehog.py +317 -14
  258. bbot/test/test_step_2/module_tests/test_module_wayback.py +1 -1
  259. bbot/test/test_step_2/template_tests/test_template_subdomain_enum.py +2 -2
  260. {bbot-2.0.1.4720rc0.dist-info → bbot-2.3.0.5397rc0.dist-info}/METADATA +48 -18
  261. bbot-2.3.0.5397rc0.dist-info/RECORD +421 -0
  262. {bbot-2.0.1.4720rc0.dist-info → bbot-2.3.0.5397rc0.dist-info}/WHEEL +1 -1
  263. bbot/modules/unstructured.py +0 -163
  264. bbot/test/test_step_2/module_tests/test_module_unstructured.py +0 -102
  265. bbot-2.0.1.4720rc0.dist-info/RECORD +0 -387
  266. {bbot-2.0.1.4720rc0.dist-info → bbot-2.3.0.5397rc0.dist-info}/LICENSE +0 -0
  267. {bbot-2.0.1.4720rc0.dist-info → bbot-2.3.0.5397rc0.dist-info}/entry_points.txt +0 -0
@@ -13,13 +13,12 @@ class TestExcavate(ModuleTestBase):
13
13
  config_overrides = {"web": {"spider_distance": 1, "spider_depth": 1}}
14
14
 
15
15
  async def setup_before_prep(self, module_test):
16
-
17
16
  response_data = """
18
17
  ftp://ftp.test.notreal
19
18
  \\nhttps://www1.test.notreal
20
19
  \\x3dhttps://www2.test.notreal
21
20
  %0ahttps://www3.test.notreal
22
- \\u000ahttps://www4.test.notreal
21
+ \\u000ahttps://www4.test.notreal:
23
22
  \nwww5.test.notreal
24
23
  \\x3dwww6.test.notreal
25
24
  %0awww7.test.notreal
@@ -61,8 +60,8 @@ class TestExcavate(ModuleTestBase):
61
60
  assert "www6.test.notreal" in event_data
62
61
  assert "www7.test.notreal" in event_data
63
62
  assert "www8.test.notreal" in event_data
64
- assert not "http://127.0.0.1:8888/a_relative.js" in event_data
65
- assert not "http://127.0.0.1:8888/link_relative.js" in event_data
63
+ assert "http://127.0.0.1:8888/a_relative.js" not in event_data
64
+ assert "http://127.0.0.1:8888/link_relative.js" not in event_data
66
65
  assert "http://127.0.0.1:8888/a_relative.txt" in event_data
67
66
  assert "http://127.0.0.1:8888/link_relative.txt" in event_data
68
67
 
@@ -181,7 +180,6 @@ class TestExcavateRedirect(TestExcavate):
181
180
  module_test.httpserver.no_handler_status_code = 404
182
181
 
183
182
  def check(self, module_test, events):
184
-
185
183
  assert 1 == len(
186
184
  [
187
185
  e
@@ -222,7 +220,7 @@ class TestExcavateRedirect(TestExcavate):
222
220
  [e for e in events if e.type == "FINDING" and e.data["description"] == "Non-HTTP URI: smb://127.0.0.1"]
223
221
  )
224
222
  assert 1 == len(
225
- [e for e in events if e.type == "PROTOCOL" and e.data["protocol"] == "SMB" and not "port" in e.data]
223
+ [e for e in events if e.type == "PROTOCOL" and e.data["protocol"] == "SMB" and "port" not in e.data]
226
224
  )
227
225
  assert 0 == len([e for e in events if e.type == "FINDING" and "ssh://127.0.0.1" in e.data["description"]])
228
226
  assert 0 == len([e for e in events if e.type == "PROTOCOL" and e.data["protocol"] == "SSH"])
@@ -332,7 +330,6 @@ class TestExcavateMaxLinksPerPage(TestExcavate):
332
330
 
333
331
 
334
332
  class TestExcavateCSP(TestExcavate):
335
-
336
333
  csp_test_header = "default-src 'self'; script-src asdf.test.notreal; object-src 'none';"
337
334
 
338
335
  async def setup_before_prep(self, module_test):
@@ -356,7 +353,6 @@ class TestExcavateURL(TestExcavate):
356
353
 
357
354
 
358
355
  class TestExcavateURL_IP(TestExcavate):
359
-
360
356
  targets = ["http://127.0.0.1:8888/", "127.0.0.2"]
361
357
 
362
358
  async def setup_before_prep(self, module_test):
@@ -405,7 +401,6 @@ class TestExcavateSerializationPositive(TestExcavate):
405
401
 
406
402
 
407
403
  class TestExcavateNonHttpScheme(TestExcavate):
408
-
409
404
  targets = ["http://127.0.0.1:8888/", "test.notreal"]
410
405
 
411
406
  non_http_scheme_html = """
@@ -425,7 +420,6 @@ class TestExcavateNonHttpScheme(TestExcavate):
425
420
  module_test.httpserver.expect_request("/").respond_with_data(self.non_http_scheme_html)
426
421
 
427
422
  def check(self, module_test, events):
428
-
429
423
  found_hxxp_url = False
430
424
  found_ftp_url = False
431
425
  found_nonsense_url = False
@@ -540,7 +534,6 @@ class TestExcavateParameterExtraction(TestExcavate):
540
534
 
541
535
 
542
536
  class TestExcavateParameterExtraction_getparam(ModuleTestBase):
543
-
544
537
  targets = ["http://127.0.0.1:8888/"]
545
538
 
546
539
  # hunt is added as parameter extraction is only activated by one or more modules that consume WEB_PARAMETER
@@ -554,11 +547,9 @@ class TestExcavateParameterExtraction_getparam(ModuleTestBase):
554
547
  module_test.set_expect_requests(respond_args=respond_args)
555
548
 
556
549
  def check(self, module_test, events):
557
-
558
550
  excavate_getparam_extraction = False
559
551
  for e in events:
560
552
  if e.type == "WEB_PARAMETER":
561
-
562
553
  if "HTTP Extracted Parameter [hack] (HTML Tags Submodule)" in e.data["description"]:
563
554
  excavate_getparam_extraction = True
564
555
  assert excavate_getparam_extraction, "Excavate failed to extract web parameter"
@@ -626,7 +617,6 @@ class excavateTestRule(ExcavateRule):
626
617
 
627
618
 
628
619
  class TestExcavateYara(TestExcavate):
629
-
630
620
  targets = ["http://127.0.0.1:8888/"]
631
621
  yara_test_html = """
632
622
  <html>
@@ -641,12 +631,10 @@ class TestExcavateYara(TestExcavate):
641
631
  """
642
632
 
643
633
  async def setup_before_prep(self, module_test):
644
-
645
634
  self.modules_overrides = ["excavate", "httpx"]
646
635
  module_test.httpserver.expect_request("/").respond_with_data(self.yara_test_html)
647
636
 
648
637
  async def setup_after_prep(self, module_test):
649
-
650
638
  excavate_module = module_test.scan.modules["excavate"]
651
639
  excavateruleinstance = excavateTestRule(excavate_module)
652
640
  excavate_module.add_yara_rule(
@@ -665,7 +653,6 @@ class TestExcavateYara(TestExcavate):
665
653
  found_yara_string_1 = False
666
654
  found_yara_string_2 = False
667
655
  for e in events:
668
-
669
656
  if e.type == "FINDING":
670
657
  if e.data["description"] == "HTTP response (body) Contains the text AAAABBBBCCCC":
671
658
  found_yara_string_1 = True
@@ -677,7 +664,6 @@ class TestExcavateYara(TestExcavate):
677
664
 
678
665
 
679
666
  class TestExcavateYaraCustom(TestExcavateYara):
680
-
681
667
  rule_file = [
682
668
  'rule SearchForText { meta: description = "Contains the text AAAABBBBCCCC" strings: $text = "AAAABBBBCCCC" condition: $text }',
683
669
  'rule SearchForText2 { meta: description = "Contains the text DDDDEEEEFFFF" strings: $text2 = "DDDDEEEEFFFF" condition: $text2 }',
@@ -711,7 +697,6 @@ class TestExcavateSpiderDedupe(ModuleTestBase):
711
697
  module_test.httpserver.expect_request("/spider").respond_with_data("hi")
712
698
 
713
699
  def check(self, module_test, events):
714
-
715
700
  found_url_unverified_spider_max = False
716
701
  found_url_unverified_dummy = False
717
702
  found_url_event = False
@@ -726,7 +711,7 @@ class TestExcavateSpiderDedupe(ModuleTestBase):
726
711
  if (
727
712
  str(e.module) == "dummy_module"
728
713
  and "spider-danger" not in e.tags
729
- and not "spider-max" in e.tags
714
+ and "spider-max" not in e.tags
730
715
  ):
731
716
  found_url_unverified_dummy = True
732
717
  if e.type == "URL" and e.data == "http://127.0.0.1:8888/spider":
@@ -803,7 +788,6 @@ class TestExcavate_retain_querystring(ModuleTestBase):
803
788
 
804
789
 
805
790
  class TestExcavate_retain_querystring_not(TestExcavate_retain_querystring):
806
-
807
791
  config_overrides = {
808
792
  "url_querystring_remove": False,
809
793
  "url_querystring_collapse": False,
@@ -827,7 +811,6 @@ class TestExcavate_retain_querystring_not(TestExcavate_retain_querystring):
827
811
 
828
812
 
829
813
  class TestExcavate_webparameter_outofscope(ModuleTestBase):
830
-
831
814
  html_body = "<html><a class=button href='https://socialmediasite.com/send?text=foo'><a class=button href='https://outofscope.com/send?text=foo'></html>"
832
815
 
833
816
  targets = ["http://127.0.0.1:8888", "socialmediasite.com"]
@@ -858,13 +841,11 @@ class TestExcavate_webparameter_outofscope(ModuleTestBase):
858
841
 
859
842
 
860
843
  class TestExcavateHeaders(ModuleTestBase):
861
-
862
844
  targets = ["http://127.0.0.1:8888/"]
863
845
  modules_overrides = ["excavate", "httpx", "hunt"]
864
846
  config_overrides = {"web": {"spider_distance": 1, "spider_depth": 1}}
865
847
 
866
848
  async def setup_before_prep(self, module_test):
867
-
868
849
  module_test.httpserver.expect_request("/").respond_with_data(
869
850
  "<html><p>test</p></html>",
870
851
  status=200,
@@ -877,7 +858,6 @@ class TestExcavateHeaders(ModuleTestBase):
877
858
  )
878
859
 
879
860
  def check(self, module_test, events):
880
-
881
861
  found_first_cookie = False
882
862
  found_second_cookie = False
883
863
 
@@ -888,13 +868,13 @@ class TestExcavateHeaders(ModuleTestBase):
888
868
  if e.data["name"] == "COOKIE2":
889
869
  found_second_cookie = True
890
870
 
891
- assert found_first_cookie == True
892
- assert found_second_cookie == True
871
+ assert found_first_cookie is True
872
+ assert found_second_cookie is True
893
873
 
894
874
 
895
875
  class TestExcavateRAWTEXT(ModuleTestBase):
896
876
  targets = ["http://127.0.0.1:8888/", "test.notreal"]
897
- modules_overrides = ["excavate", "httpx", "filedownload", "unstructured"]
877
+ modules_overrides = ["excavate", "httpx", "filedownload", "extractous"]
898
878
  config_overrides = {"scope": {"report_distance": 1}, "web": {"spider_distance": 2, "spider_depth": 2}}
899
879
 
900
880
  pdf_data = r"""%PDF-1.3
@@ -965,7 +945,7 @@ trailer
965
945
  startxref
966
946
  1669
967
947
  %%EOF"""
968
- unstructured_response = """This is an email example@blacklanternsecurity.notreal
948
+ extractous_response = """This is an email example@blacklanternsecurity.notreal
969
949
 
970
950
  An example JWT eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
971
951
 
@@ -977,12 +957,12 @@ A href <a href='/donot_detect.js'>Click me</a>"""
977
957
 
978
958
  async def setup_after_prep(self, module_test):
979
959
  module_test.set_expect_requests(
980
- dict(uri="/"),
981
- dict(response_data='<a href="/Test_PDF"/>'),
960
+ {"uri": "/"},
961
+ {"response_data": '<a href="/Test_PDF"/>'},
982
962
  )
983
963
  module_test.set_expect_requests(
984
- dict(uri="/Test_PDF"),
985
- dict(response_data=self.pdf_data, headers={"Content-Type": "application/pdf"}),
964
+ {"uri": "/Test_PDF"},
965
+ {"response_data": self.pdf_data, "headers": {"Content-Type": "application/pdf"}},
986
966
  )
987
967
 
988
968
  def check(self, module_test, events):
@@ -995,13 +975,13 @@ A href <a href='/donot_detect.js'>Click me</a>"""
995
975
  raw_text_events = [e for e in events if e.type == "RAW_TEXT"]
996
976
  assert 1 == len(raw_text_events), "Failed to emit RAW_TEXT event"
997
977
  assert (
998
- raw_text_events[0].data == self.unstructured_response
978
+ raw_text_events[0].data == self.extractous_response
999
979
  ), f"Text extracted from PDF is incorrect, got {raw_text_events[0].data}"
1000
980
  email_events = [e for e in events if e.type == "EMAIL_ADDRESS"]
1001
981
  assert 1 == len(email_events), "Failed to emit EMAIL_ADDRESS event"
1002
982
  assert (
1003
983
  email_events[0].data == "example@blacklanternsecurity.notreal"
1004
- ), f"Email extracted from unstructured text is incorrect, got {email_events[0].data}"
984
+ ), f"Email extracted from extractous text is incorrect, got {email_events[0].data}"
1005
985
  finding_events = [e for e in events if e.type == "FINDING"]
1006
986
  assert 2 == len(finding_events), "Failed to emit FINDING events"
1007
987
  assert any(
@@ -1026,7 +1006,7 @@ A href <a href='/donot_detect.js'>Click me</a>"""
1026
1006
  url_events = [e.data for e in events if e.type == "URL_UNVERIFIED"]
1027
1007
  assert (
1028
1008
  "https://www.test.notreal/about" in url_events
1029
- ), f"URL extracted from unstructured text is incorrect, got {url_events}"
1009
+ ), f"URL extracted from extractous text is incorrect, got {url_events}"
1030
1010
  assert (
1031
1011
  "/donot_detect.js" not in url_events
1032
- ), f"URL extracted from unstructured text is incorrect, got {url_events}"
1012
+ ), f"URL extracted from extractous text is incorrect, got {url_events}"
@@ -0,0 +1,54 @@
1
+ import base64
2
+ from pathlib import Path
3
+ from .base import ModuleTestBase
4
+
5
+
6
+ class TestExtractous(ModuleTestBase):
7
+ targets = ["http://127.0.0.1:8888"]
8
+ modules_overrides = ["extractous", "filedownload", "httpx", "excavate", "speculate"]
9
+ config_overrides = {"web": {"spider_distance": 2, "spider_depth": 2}}
10
+
11
+ pdf_data = base64.b64decode(
12
+ "JVBERi0xLjMKJe+/ve+/ve+/ve+/vSBSZXBvcnRMYWIgR2VuZXJhdGVkIFBERiBkb2N1bWVudCBodHRwOi8vd3d3LnJlcG9ydGxhYi5jb20KMSAwIG9iago8PAovRjEgMiAwIFIKPj4KZW5kb2JqCjIgMCBvYmoKPDwKL0Jhc2VGb250IC9IZWx2ZXRpY2EgL0VuY29kaW5nIC9XaW5BbnNpRW5jb2RpbmcgL05hbWUgL0YxIC9TdWJ0eXBlIC9UeXBlMSAvVHlwZSAvRm9udAo+PgplbmRvYmoKMyAwIG9iago8PAovQ29udGVudHMgNyAwIFIgL01lZGlhQm94IFsgMCAwIDU5NS4yNzU2IDg0MS44ODk4IF0gL1BhcmVudCA2IDAgUiAvUmVzb3VyY2VzIDw8Ci9Gb250IDEgMCBSIC9Qcm9jU2V0IFsgL1BERiAvVGV4dCAvSW1hZ2VCIC9JbWFnZUMgL0ltYWdlSSBdCj4+IC9Sb3RhdGUgMCAvVHJhbnMgPDwKCj4+IAogIC9UeXBlIC9QYWdlCj4+CmVuZG9iago0IDAgb2JqCjw8Ci9QYWdlTW9kZSAvVXNlTm9uZSAvUGFnZXMgNiAwIFIgL1R5cGUgL0NhdGFsb2cKPj4KZW5kb2JqCjUgMCBvYmoKPDwKL0F1dGhvciAoYW5vbnltb3VzKSAvQ3JlYXRpb25EYXRlIChEOjIwMjQwNjAzMTg1ODE2KzAwJzAwJykgL0NyZWF0b3IgKFJlcG9ydExhYiBQREYgTGlicmFyeSAtIHd3dy5yZXBvcnRsYWIuY29tKSAvS2V5d29yZHMgKCkgL01vZERhdGUgKEQ6MjAyNDA2MDMxODU4MTYrMDAnMDAnKSAvUHJvZHVjZXIgKFJlcG9ydExhYiBQREYgTGlicmFyeSAtIHd3dy5yZXBvcnRsYWIuY29tKSAKICAvU3ViamVjdCAodW5zcGVjaWZpZWQpIC9UaXRsZSAodW50aXRsZWQpIC9UcmFwcGVkIC9GYWxzZQo+PgplbmRvYmoKNiAwIG9iago8PAovQ291bnQgMSAvS2lkcyBbIDMgMCBSIF0gL1R5cGUgL1BhZ2VzCj4+CmVuZG9iago3IDAgb2JqCjw8Ci9GaWx0ZXIgWyAvQVNDSUk4NURlY29kZSAvRmxhdGVEZWNvZGUgXSAvTGVuZ3RoIDEwNwo+PgpzdHJlYW0KR2FwUWgwRT1GLDBVXEgzVFxwTllUXlFLaz90Yz5JUCw7VyNVMV4yM2loUEVNXz9DVzRLSVNpOTBNakdeMixGUyM8UkM1K2MsbilaOyRiSyRiIjVJWzwhXlREI2dpXSY9NVgsWzVAWUBWfj5lbmRzdHJlYW0KZW5kb2JqCnhyZWYKMCA4CjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAwMDA3MyAwMDAwMCBuIAowMDAwMDAwMTA0IDAwMDAwIG4gCjAwMDAwMDAyMTEgMDAwMDAgbiAKMDAwMDAwMDQxNCAwMDAwMCBuIAowMDAwMDAwNDgyIDAwMDAwIG4gCjAwMDAwMDA3NzggMDAwMDAgbiAKMDAwMDAwMDgzNyAwMDAwMCBuIAp0cmFpbGVyCjw8Ci9JRCAKWzw4MGQ5ZjViOTY0ZmM5OTI4NDUwMWRlYjdhNmE2MzdmNz48ODBkOWY1Yjk2NGZjOTkyODQ1MDFkZWI3YTZhNjM3Zjc+XQolIFJlcG9ydExhYiBnZW5lcmF0ZWQgUERGIGRvY3VtZW50IC0tIGRpZ2VzdCAoaHR0cDovL3d3dy5yZXBvcnRsYWIuY29tKQoKL0luZm8gNSAwIFIKL1Jvb3QgNCAwIFIKL1NpemUgOAo+PgpzdGFydHhyZWYKMTAzNAolJUVPRg=="
13
+ )
14
+
15
+ docx_data = base64.b64decode(
16
+ "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"
17
+ )
18
+
19
+ expected_result_pdf = "Hello, World!"
20
+ expected_result_docx = "Hello, World!!"
21
+
22
+ async def setup_after_prep(self, module_test):
23
+ module_test.set_expect_requests(
24
+ {"uri": "/"},
25
+ {"response_data": '<a href="/Test_PDF"/><a href="/Test_DOCX"/>'},
26
+ )
27
+ module_test.set_expect_requests(
28
+ {"uri": "/Test_PDF"},
29
+ {"response_data": self.pdf_data, "headers": {"Content-Type": "application/pdf"}},
30
+ )
31
+ module_test.set_expect_requests(
32
+ {"uri": "/Test_DOCX"},
33
+ {
34
+ "response_data": self.docx_data,
35
+ "headers": {"Content-Type": "application/vnd.openxmlformats-officedocument.wordprocessingml.document"},
36
+ },
37
+ )
38
+
39
+ def check(self, module_test, events):
40
+ filesystem_events = [e for e in events if e.type == "FILESYSTEM"]
41
+ assert 2 == len(filesystem_events), filesystem_events
42
+ for filesystem_event in filesystem_events:
43
+ file = Path(filesystem_event.data["path"])
44
+ assert file.is_file(), "Destination file doesn't exist"
45
+ assert (
46
+ open(file, "rb").read() == self.pdf_data or open(file, "rb").read() == self.docx_data
47
+ ), f"File at {file} does not contain the correct content"
48
+ raw_text_events = [e for e in events if e.type == "RAW_TEXT"]
49
+ assert 2 == len(raw_text_events), "Failed to emit RAW_TEXT event"
50
+ for raw_text_event in raw_text_events:
51
+ assert raw_text_event.data in [
52
+ self.expected_result_pdf,
53
+ self.expected_result_docx,
54
+ ], f"Text extracted from {raw_text_event.data['path']} is incorrect, got {raw_text_event.data}"
@@ -142,7 +142,7 @@ class TestFFUFShortnames(ModuleTestBase):
142
142
  tags=["shortname-file"],
143
143
  )
144
144
  )
145
- module_test.scan.target.seeds._events = set(seed_events)
145
+ module_test.scan.target.seeds.events = set(seed_events)
146
146
 
147
147
  expect_args = {"method": "GET", "uri": "/administrator.aspx"}
148
148
  respond_args = {"response_data": "alive"}
@@ -15,28 +15,28 @@ trailer <</Root 1 0 R>>"""
15
15
 
16
16
  async def setup_after_prep(self, module_test):
17
17
  module_test.set_expect_requests(
18
- dict(uri="/"),
19
- dict(
20
- response_data='<a href="/Test_File.txt"/><a href="/Test_PDF"/><a href="/test.html"/><a href="/test2"/>'
21
- ),
18
+ {"uri": "/"},
19
+ {
20
+ "response_data": '<a href="/Test_File.txt"/><a href="/Test_PDF"/><a href="/test.html"/><a href="/test2"/>'
21
+ },
22
22
  )
23
23
  module_test.set_expect_requests(
24
- dict(uri="/Test_File.txt"),
25
- dict(
26
- response_data="juicy stuff",
27
- ),
24
+ {"uri": "/Test_File.txt"},
25
+ {
26
+ "response_data": "juicy stuff",
27
+ },
28
28
  )
29
29
  module_test.set_expect_requests(
30
- dict(uri="/Test_PDF"),
31
- dict(response_data=self.pdf_data, headers={"Content-Type": "application/pdf"}),
30
+ {"uri": "/Test_PDF"},
31
+ {"response_data": self.pdf_data, "headers": {"Content-Type": "application/pdf"}},
32
32
  )
33
33
  module_test.set_expect_requests(
34
- dict(uri="/test.html"),
35
- dict(response_data="<!DOCTYPE html>", headers={"Content-Type": "text/html"}),
34
+ {"uri": "/test.html"},
35
+ {"response_data": "<!DOCTYPE html>", "headers": {"Content-Type": "text/html"}},
36
36
  )
37
37
  module_test.set_expect_requests(
38
- dict(uri="/test2"),
39
- dict(response_data="<!DOCTYPE html>", headers={"Content-Type": "text/html"}),
38
+ {"uri": "/test2"},
39
+ {"response_data": "<!DOCTYPE html>", "headers": {"Content-Type": "text/html"}},
40
40
  )
41
41
 
42
42
  def check(self, module_test, events):
@@ -202,7 +202,7 @@ class TestGit_Clone(ModuleTestBase):
202
202
  ]
203
203
  assert 1 == len(filesystem_events), "Failed to git clone CODE_REPOSITORY"
204
204
  # make sure the binary blob isn't here
205
- assert not any(["blob" in e.data for e in [e for e in events if e.type == "FILESYSTEM"]])
205
+ assert not any("blob" in e.data for e in [e for e in events if e.type == "FILESYSTEM"])
206
206
  filesystem_event = filesystem_events[0]
207
207
  folder = Path(filesystem_event.data["path"])
208
208
  assert folder.is_dir(), "Destination folder doesn't exist"
@@ -217,7 +217,7 @@ class TestGit_CloneWithBlob(TestGit_Clone):
217
217
  def check(self, module_test, events):
218
218
  filesystem_events = [e for e in events if e.type == "FILESYSTEM"]
219
219
  assert len(filesystem_events) == 1
220
- assert all(["blob" in e.data for e in filesystem_events])
220
+ assert all("blob" in e.data for e in filesystem_events)
221
221
  filesystem_event = filesystem_events[0]
222
222
  blob = filesystem_event.data["blob"]
223
223
  tar_bytes = base64.b64decode(blob)
@@ -10,9 +10,12 @@ class TestGithub_Org(ModuleTestBase):
10
10
  {"blacklanternsecurity.com": {"A": ["127.0.0.99"]}, "github.com": {"A": ["127.0.0.99"]}}
11
11
  )
12
12
 
13
- module_test.httpx_mock.add_response(url="https://api.github.com/zen")
13
+ module_test.httpx_mock.add_response(
14
+ url="https://api.github.com/zen", match_headers={"Authorization": "token asdf"}
15
+ )
14
16
  module_test.httpx_mock.add_response(
15
17
  url="https://api.github.com/orgs/blacklanternsecurity",
18
+ match_headers={"Authorization": "token asdf"},
16
19
  json={
17
20
  "login": "blacklanternsecurity",
18
21
  "id": 25311592,
@@ -48,6 +51,7 @@ class TestGithub_Org(ModuleTestBase):
48
51
  )
49
52
  module_test.httpx_mock.add_response(
50
53
  url="https://api.github.com/orgs/blacklanternsecurity/repos?per_page=100&page=1",
54
+ match_headers={"Authorization": "token asdf"},
51
55
  json=[
52
56
  {
53
57
  "id": 459780477,
@@ -154,6 +158,7 @@ class TestGithub_Org(ModuleTestBase):
154
158
  )
155
159
  module_test.httpx_mock.add_response(
156
160
  url="https://api.github.com/orgs/blacklanternsecurity/members?per_page=100&page=1",
161
+ match_headers={"Authorization": "token asdf"},
157
162
  json=[
158
163
  {
159
164
  "login": "TheTechromancer",
@@ -179,6 +184,7 @@ class TestGithub_Org(ModuleTestBase):
179
184
  )
180
185
  module_test.httpx_mock.add_response(
181
186
  url="https://api.github.com/users/TheTechromancer/repos?per_page=100&page=1",
187
+ match_headers={"Authorization": "token asdf"},
182
188
  json=[
183
189
  {
184
190
  "id": 688270318,
@@ -284,7 +290,7 @@ class TestGithub_Org(ModuleTestBase):
284
290
  )
285
291
 
286
292
  def check(self, module_test, events):
287
- assert len(events) == 6
293
+ assert len(events) == 7
288
294
  assert 1 == len(
289
295
  [
290
296
  e
@@ -332,10 +338,10 @@ class TestGithub_Org(ModuleTestBase):
332
338
 
333
339
 
334
340
  class TestGithub_Org_No_Members(TestGithub_Org):
335
- config_overrides = {"modules": {"github_org": {"include_members": False}}}
341
+ config_overrides = {"modules": {"github_org": {"include_members": False}, "github": {"api_key": "asdf"}}}
336
342
 
337
343
  def check(self, module_test, events):
338
- assert len(events) == 5
344
+ assert len(events) == 6
339
345
  assert 1 == len(
340
346
  [
341
347
  e
@@ -360,10 +366,10 @@ class TestGithub_Org_No_Members(TestGithub_Org):
360
366
 
361
367
 
362
368
  class TestGithub_Org_MemberRepos(TestGithub_Org):
363
- config_overrides = {"modules": {"github_org": {"include_member_repos": True}}}
369
+ config_overrides = {"modules": {"github_org": {"include_member_repos": True}, "github": {"api_key": "asdf"}}}
364
370
 
365
371
  def check(self, module_test, events):
366
- assert len(events) == 7
372
+ assert len(events) == 8
367
373
  assert 1 == len(
368
374
  [
369
375
  e
@@ -378,10 +384,15 @@ class TestGithub_Org_MemberRepos(TestGithub_Org):
378
384
 
379
385
  class TestGithub_Org_Custom_Target(TestGithub_Org):
380
386
  targets = ["ORG:blacklanternsecurity"]
381
- config_overrides = {"scope": {"report_distance": 10}, "omit_event_types": [], "speculate": True}
387
+ config_overrides = {
388
+ "scope": {"report_distance": 10},
389
+ "omit_event_types": [],
390
+ "speculate": True,
391
+ "modules": {"github": {"api_key": "asdf"}},
392
+ }
382
393
 
383
394
  def check(self, module_test, events):
384
- assert len(events) == 7
395
+ assert len(events) == 8
385
396
  assert 1 == len(
386
397
  [e for e in events if e.type == "ORG_STUB" and e.data == "blacklanternsecurity" and e.scope_distance == 0]
387
398
  )
@@ -477,7 +477,7 @@ class TestGithub_Workflows(ModuleTestBase):
477
477
  )
478
478
 
479
479
  def check(self, module_test, events):
480
- assert len(events) == 8
480
+ assert len(events) == 9
481
481
  assert 1 == len(
482
482
  [
483
483
  e
@@ -4,10 +4,13 @@ from .base import ModuleTestBase
4
4
  class TestGitlab(ModuleTestBase):
5
5
  targets = ["http://127.0.0.1:8888"]
6
6
  modules_overrides = ["gitlab", "httpx"]
7
+ config_overrides = {"modules": {"gitlab": {"api_key": "asdf"}}}
7
8
 
8
9
  async def setup_before_prep(self, module_test):
9
10
  module_test.httpserver.expect_request("/").respond_with_data(headers={"X-Gitlab-Meta": "asdf"})
10
- module_test.httpserver.expect_request("/api/v4/projects", query_string="simple=true").respond_with_json(
11
+ module_test.httpserver.expect_request(
12
+ "/api/v4/projects", query_string="simple=true", headers={"Authorization": "Bearer asdf"}
13
+ ).respond_with_json(
11
14
  [
12
15
  {
13
16
  "id": 33,
@@ -41,7 +44,9 @@ class TestGitlab(ModuleTestBase):
41
44
  },
42
45
  ],
43
46
  )
44
- module_test.httpserver.expect_request("/api/v4/groups", query_string="simple=true").respond_with_json(
47
+ module_test.httpserver.expect_request(
48
+ "/api/v4/groups", query_string="simple=true", headers={"Authorization": "Bearer asdf"}
49
+ ).respond_with_json(
45
50
  [
46
51
  {
47
52
  "id": 9,
@@ -84,7 +89,7 @@ class TestGitlab(ModuleTestBase):
84
89
  ]
85
90
  )
86
91
  module_test.httpserver.expect_request(
87
- "/api/v4/groups/bbotgroup/projects", query_string="simple=true"
92
+ "/api/v4/groups/bbotgroup/projects", query_string="simple=true", headers={"Authorization": "Bearer asdf"}
88
93
  ).respond_with_json(
89
94
  [
90
95
  {
@@ -120,7 +125,7 @@ class TestGitlab(ModuleTestBase):
120
125
  ]
121
126
  )
122
127
  module_test.httpserver.expect_request(
123
- "/api/v4/users/bbotgroup/projects", query_string="simple=true"
128
+ "/api/v4/users/bbotgroup/projects", query_string="simple=true", headers={"Authorization": "Bearer asdf"}
124
129
  ).respond_with_json(
125
130
  [
126
131
  {
@@ -0,0 +1,83 @@
1
+ from .base import ModuleTestBase
2
+
3
+
4
+ class TestGoogle_Playstore(ModuleTestBase):
5
+ modules_overrides = ["google_playstore", "speculate"]
6
+
7
+ async def setup_after_prep(self, module_test):
8
+ await module_test.mock_dns({"blacklanternsecurity.com": {"A": ["127.0.0.99"]}})
9
+ module_test.httpx_mock.add_response(
10
+ url="https://play.google.com/store/search?q=blacklanternsecurity&c=apps",
11
+ text="""<!DOCTYPE html>
12
+ <html>
13
+ <head>
14
+ <title>"blacklanternsecurity" - Android Apps on Google Play</title>
15
+ </head>
16
+ <body>
17
+ <a href="/store/apps/details?id=com.bbot.test&pcampaignid=dontmatchme&pli=1"/>
18
+ <a href="/store/apps/details?id=com.bbot.other"/>
19
+ </body>
20
+ </html>""",
21
+ )
22
+ module_test.httpx_mock.add_response(
23
+ url="https://play.google.com/store/apps/details?id=com.bbot.test",
24
+ text="""<!DOCTYPE html>
25
+ <html>
26
+ <head>
27
+ <title>BBOT</title>
28
+ </head>
29
+ <body>
30
+ <meta name="appstore:developer_url" content="https://www.blacklanternsecurity.com">
31
+ </div>
32
+ </div>
33
+ </body>
34
+ </html>""",
35
+ )
36
+ module_test.httpx_mock.add_response(
37
+ url="https://play.google.com/store/apps/details?id=com.bbot.other",
38
+ text="""<!DOCTYPE html>
39
+ <html>
40
+ <head>
41
+ <title>BBOT</title>
42
+ </head>
43
+ <body>
44
+ <meta name="appstore:developer_url" content="">
45
+ <a href="mailto:support@blacklanternsecurity.com"></a>
46
+ </div>
47
+ </div>
48
+ </body>
49
+ </html>""",
50
+ )
51
+
52
+ def check(self, module_test, events):
53
+ assert len(events) == 6
54
+ assert 1 == len(
55
+ [
56
+ e
57
+ for e in events
58
+ if e.type == "DNS_NAME" and e.data == "blacklanternsecurity.com" and e.scope_distance == 0
59
+ ]
60
+ ), "Failed to emit target DNS_NAME"
61
+ assert 1 == len(
62
+ [e for e in events if e.type == "ORG_STUB" and e.data == "blacklanternsecurity" and e.scope_distance == 0]
63
+ ), "Failed to find ORG_STUB"
64
+ assert 1 == len(
65
+ [
66
+ e
67
+ for e in events
68
+ if e.type == "MOBILE_APP"
69
+ and "android" in e.tags
70
+ and e.data["id"] == "com.bbot.test"
71
+ and e.data["url"] == "https://play.google.com/store/apps/details?id=com.bbot.test"
72
+ ]
73
+ ), "Failed to find bbot android app"
74
+ assert 1 == len(
75
+ [
76
+ e
77
+ for e in events
78
+ if e.type == "MOBILE_APP"
79
+ and "android" in e.tags
80
+ and e.data["id"] == "com.bbot.other"
81
+ and e.data["url"] == "https://play.google.com/store/apps/details?id=com.bbot.other"
82
+ ]
83
+ ), "Failed to find other bbot android app"