bbot 2.0.1.4654rc0__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 (270) 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 -6
  6. bbot/core/engine.py +9 -8
  7. bbot/core/event/base.py +162 -63
  8. bbot/core/helpers/bloom.py +10 -3
  9. bbot/core/helpers/command.py +9 -8
  10. bbot/core/helpers/depsinstaller/installer.py +89 -32
  11. bbot/core/helpers/depsinstaller/sudo_askpass.py +38 -2
  12. bbot/core/helpers/diff.py +10 -10
  13. bbot/core/helpers/dns/brute.py +18 -14
  14. bbot/core/helpers/dns/dns.py +16 -15
  15. bbot/core/helpers/dns/engine.py +159 -132
  16. bbot/core/helpers/dns/helpers.py +2 -2
  17. bbot/core/helpers/dns/mock.py +26 -8
  18. bbot/core/helpers/files.py +1 -1
  19. bbot/core/helpers/helper.py +7 -4
  20. bbot/core/helpers/interactsh.py +3 -3
  21. bbot/core/helpers/libmagic.py +65 -0
  22. bbot/core/helpers/misc.py +65 -22
  23. bbot/core/helpers/names_generator.py +17 -3
  24. bbot/core/helpers/process.py +0 -20
  25. bbot/core/helpers/regex.py +1 -1
  26. bbot/core/helpers/regexes.py +12 -6
  27. bbot/core/helpers/validators.py +1 -2
  28. bbot/core/helpers/web/client.py +1 -1
  29. bbot/core/helpers/web/engine.py +18 -13
  30. bbot/core/helpers/web/web.py +25 -116
  31. bbot/core/helpers/wordcloud.py +5 -5
  32. bbot/core/modules.py +36 -27
  33. bbot/core/multiprocess.py +58 -0
  34. bbot/core/shared_deps.py +46 -3
  35. bbot/db/sql/models.py +147 -0
  36. bbot/defaults.yml +15 -10
  37. bbot/errors.py +0 -8
  38. bbot/modules/anubisdb.py +2 -2
  39. bbot/modules/apkpure.py +63 -0
  40. bbot/modules/azure_tenant.py +2 -2
  41. bbot/modules/baddns.py +35 -19
  42. bbot/modules/baddns_direct.py +92 -0
  43. bbot/modules/baddns_zone.py +3 -8
  44. bbot/modules/badsecrets.py +4 -3
  45. bbot/modules/base.py +195 -51
  46. bbot/modules/bevigil.py +7 -7
  47. bbot/modules/binaryedge.py +7 -4
  48. bbot/modules/bufferoverrun.py +47 -0
  49. bbot/modules/builtwith.py +6 -10
  50. bbot/modules/bypass403.py +5 -5
  51. bbot/modules/c99.py +10 -7
  52. bbot/modules/censys.py +9 -13
  53. bbot/modules/certspotter.py +5 -3
  54. bbot/modules/chaos.py +9 -7
  55. bbot/modules/code_repository.py +1 -0
  56. bbot/modules/columbus.py +3 -3
  57. bbot/modules/crt.py +5 -3
  58. bbot/modules/deadly/dastardly.py +1 -1
  59. bbot/modules/deadly/ffuf.py +9 -9
  60. bbot/modules/deadly/nuclei.py +3 -3
  61. bbot/modules/deadly/vhost.py +4 -3
  62. bbot/modules/dehashed.py +1 -1
  63. bbot/modules/digitorus.py +1 -1
  64. bbot/modules/dnsbimi.py +145 -0
  65. bbot/modules/dnscaa.py +3 -3
  66. bbot/modules/dnsdumpster.py +4 -4
  67. bbot/modules/dnstlsrpt.py +144 -0
  68. bbot/modules/docker_pull.py +7 -5
  69. bbot/modules/dockerhub.py +2 -2
  70. bbot/modules/dotnetnuke.py +18 -19
  71. bbot/modules/emailformat.py +1 -1
  72. bbot/modules/extractous.py +122 -0
  73. bbot/modules/filedownload.py +9 -7
  74. bbot/modules/fullhunt.py +7 -4
  75. bbot/modules/generic_ssrf.py +5 -5
  76. bbot/modules/github_codesearch.py +3 -2
  77. bbot/modules/github_org.py +4 -4
  78. bbot/modules/github_workflows.py +4 -4
  79. bbot/modules/gitlab.py +2 -5
  80. bbot/modules/google_playstore.py +93 -0
  81. bbot/modules/gowitness.py +48 -50
  82. bbot/modules/hackertarget.py +5 -3
  83. bbot/modules/host_header.py +5 -5
  84. bbot/modules/httpx.py +1 -4
  85. bbot/modules/hunterio.py +3 -9
  86. bbot/modules/iis_shortnames.py +19 -30
  87. bbot/modules/internal/cloudcheck.py +27 -12
  88. bbot/modules/internal/dnsresolve.py +250 -276
  89. bbot/modules/internal/excavate.py +100 -64
  90. bbot/modules/internal/speculate.py +42 -33
  91. bbot/modules/internetdb.py +4 -2
  92. bbot/modules/ip2location.py +3 -5
  93. bbot/modules/ipneighbor.py +1 -1
  94. bbot/modules/ipstack.py +3 -8
  95. bbot/modules/jadx.py +87 -0
  96. bbot/modules/leakix.py +11 -10
  97. bbot/modules/myssl.py +2 -2
  98. bbot/modules/newsletters.py +2 -2
  99. bbot/modules/otx.py +5 -3
  100. bbot/modules/output/asset_inventory.py +7 -7
  101. bbot/modules/output/base.py +1 -1
  102. bbot/modules/output/csv.py +1 -2
  103. bbot/modules/output/http.py +20 -14
  104. bbot/modules/output/mysql.py +51 -0
  105. bbot/modules/output/neo4j.py +7 -2
  106. bbot/modules/output/postgres.py +49 -0
  107. bbot/modules/output/slack.py +0 -1
  108. bbot/modules/output/sqlite.py +29 -0
  109. bbot/modules/output/stdout.py +2 -2
  110. bbot/modules/output/teams.py +107 -6
  111. bbot/modules/paramminer_headers.py +5 -8
  112. bbot/modules/passivetotal.py +13 -13
  113. bbot/modules/portscan.py +32 -6
  114. bbot/modules/postman.py +50 -126
  115. bbot/modules/postman_download.py +220 -0
  116. bbot/modules/rapiddns.py +3 -8
  117. bbot/modules/report/asn.py +11 -11
  118. bbot/modules/robots.py +3 -3
  119. bbot/modules/securitytrails.py +7 -10
  120. bbot/modules/securitytxt.py +128 -0
  121. bbot/modules/shodan_dns.py +7 -9
  122. bbot/modules/sitedossier.py +1 -1
  123. bbot/modules/skymem.py +2 -2
  124. bbot/modules/social.py +2 -1
  125. bbot/modules/subdomaincenter.py +1 -1
  126. bbot/modules/subdomainradar.py +160 -0
  127. bbot/modules/telerik.py +8 -8
  128. bbot/modules/templates/bucket.py +1 -1
  129. bbot/modules/templates/github.py +22 -14
  130. bbot/modules/templates/postman.py +21 -0
  131. bbot/modules/templates/shodan.py +14 -13
  132. bbot/modules/templates/sql.py +95 -0
  133. bbot/modules/templates/subdomain_enum.py +53 -17
  134. bbot/modules/templates/webhook.py +2 -4
  135. bbot/modules/trickest.py +8 -37
  136. bbot/modules/trufflehog.py +18 -3
  137. bbot/modules/url_manipulation.py +3 -3
  138. bbot/modules/urlscan.py +1 -1
  139. bbot/modules/viewdns.py +1 -1
  140. bbot/modules/virustotal.py +8 -30
  141. bbot/modules/wafw00f.py +1 -1
  142. bbot/modules/wayback.py +1 -1
  143. bbot/modules/wpscan.py +17 -11
  144. bbot/modules/zoomeye.py +11 -6
  145. bbot/presets/baddns-thorough.yml +12 -0
  146. bbot/presets/fast.yml +16 -0
  147. bbot/presets/kitchen-sink.yml +1 -0
  148. bbot/presets/spider.yml +4 -0
  149. bbot/presets/subdomain-enum.yml +7 -7
  150. bbot/scanner/manager.py +5 -16
  151. bbot/scanner/preset/args.py +44 -26
  152. bbot/scanner/preset/environ.py +7 -2
  153. bbot/scanner/preset/path.py +7 -4
  154. bbot/scanner/preset/preset.py +36 -23
  155. bbot/scanner/scanner.py +176 -63
  156. bbot/scanner/target.py +236 -434
  157. bbot/scripts/docs.py +1 -1
  158. bbot/test/bbot_fixtures.py +22 -3
  159. bbot/test/conftest.py +132 -100
  160. bbot/test/fastapi_test.py +17 -0
  161. bbot/test/owasp_mastg.apk +0 -0
  162. bbot/test/run_tests.sh +4 -4
  163. bbot/test/test.conf +2 -0
  164. bbot/test/test_step_1/test_bbot_fastapi.py +82 -0
  165. bbot/test/test_step_1/test_bloom_filter.py +2 -0
  166. bbot/test/test_step_1/test_cli.py +138 -64
  167. bbot/test/test_step_1/test_dns.py +392 -70
  168. bbot/test/test_step_1/test_engine.py +17 -17
  169. bbot/test/test_step_1/test_events.py +203 -37
  170. bbot/test/test_step_1/test_helpers.py +64 -28
  171. bbot/test/test_step_1/test_manager_deduplication.py +1 -1
  172. bbot/test/test_step_1/test_manager_scope_accuracy.py +336 -338
  173. bbot/test/test_step_1/test_modules_basic.py +69 -71
  174. bbot/test/test_step_1/test_presets.py +184 -96
  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 +5 -4
  179. bbot/test/test_step_1/test_target.py +243 -145
  180. bbot/test/test_step_1/test_web.py +48 -10
  181. bbot/test/test_step_2/module_tests/base.py +17 -20
  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 +17 -37
  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 -4
  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 +24 -11
  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 +6 -6
  233. bbot/test/test_step_2/module_tests/test_module_ntlm.py +7 -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_portscan.py +9 -8
  241. bbot/test/test_step_2/module_tests/test_module_postgres.py +74 -0
  242. bbot/test/test_step_2/module_tests/test_module_postman.py +84 -253
  243. bbot/test/test_step_2/module_tests/test_module_postman_download.py +439 -0
  244. bbot/test/test_step_2/module_tests/test_module_rapiddns.py +93 -1
  245. bbot/test/test_step_2/module_tests/test_module_securitytxt.py +50 -0
  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 +1 -1
  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 +2 -6
  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 -11
  261. bbot/test/test_step_2/module_tests/test_module_wayback.py +1 -1
  262. bbot/test/test_step_2/template_tests/test_template_subdomain_enum.py +135 -0
  263. {bbot-2.0.1.4654rc0.dist-info → bbot-2.3.0.5397rc0.dist-info}/METADATA +48 -18
  264. bbot-2.3.0.5397rc0.dist-info/RECORD +421 -0
  265. {bbot-2.0.1.4654rc0.dist-info → bbot-2.3.0.5397rc0.dist-info}/WHEEL +1 -1
  266. bbot/modules/unstructured.py +0 -163
  267. bbot/test/test_step_2/module_tests/test_module_unstructured.py +0 -102
  268. bbot-2.0.1.4654rc0.dist-info/RECORD +0 -385
  269. {bbot-2.0.1.4654rc0.dist-info → bbot-2.3.0.5397rc0.dist-info}/LICENSE +0 -0
  270. {bbot-2.0.1.4654rc0.dist-info → bbot-2.3.0.5397rc0.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,439 @@
1
+ from .base import ModuleTestBase
2
+
3
+
4
+ class TestPostman_Download(ModuleTestBase):
5
+ config_overrides = {"modules": {"postman_download": {"api_key": "asdf"}}}
6
+ modules_overrides = ["postman", "postman_download", "speculate"]
7
+
8
+ async def setup_before_prep(self, module_test):
9
+ module_test.httpx_mock.add_response(
10
+ url="https://api.getpostman.com/me",
11
+ match_headers={"X-Api-Key": "asdf"},
12
+ json={
13
+ "user": {
14
+ "id": 000000,
15
+ "username": "test_key",
16
+ "email": "blacklanternsecurity@test.com",
17
+ "fullName": "Test Key",
18
+ "avatar": "",
19
+ "isPublic": True,
20
+ "teamId": 0,
21
+ "teamDomain": "",
22
+ "roles": ["user"],
23
+ },
24
+ "operations": [
25
+ {"name": "api_object_usage", "limit": 3, "usage": 0, "overage": 0},
26
+ {"name": "collection_run_limit", "limit": 25, "usage": 0, "overage": 0},
27
+ {"name": "file_storage_limit", "limit": 20, "usage": 0, "overage": 0},
28
+ {"name": "flow_count", "limit": 5, "usage": 0, "overage": 0},
29
+ {"name": "flow_requests", "limit": 5000, "usage": 0, "overage": 0},
30
+ {"name": "performance_test_limit", "limit": 25, "usage": 0, "overage": 0},
31
+ {"name": "postbot_calls", "limit": 50, "usage": 0, "overage": 0},
32
+ {"name": "reusable_packages", "limit": 3, "usage": 0, "overage": 0},
33
+ {"name": "test_data_retrieval", "limit": 1000, "usage": 0, "overage": 0},
34
+ {"name": "test_data_storage", "limit": 10, "usage": 0, "overage": 0},
35
+ {"name": "mock_usage", "limit": 1000, "usage": 0, "overage": 0},
36
+ {"name": "monitor_request_runs", "limit": 1000, "usage": 0, "overage": 0},
37
+ {"name": "api_usage", "limit": 1000, "usage": 0, "overage": 0},
38
+ ],
39
+ },
40
+ )
41
+
42
+ async def setup_after_prep(self, module_test):
43
+ await module_test.mock_dns(
44
+ {"blacklanternsecurity.com": {"A": ["127.0.0.99"]}, "github.com": {"A": ["127.0.0.99"]}}
45
+ )
46
+ module_test.httpx_mock.add_response(
47
+ url="https://www.postman.com/_api/ws/proxy",
48
+ match_content=b'{"service": "search", "method": "POST", "path": "/search-all", "body": {"queryIndices": ["collaboration.workspace"], "queryText": "blacklanternsecurity", "size": 100, "from": 0, "clientTraceId": "", "requestOrigin": "srp", "mergeEntities": "true", "nonNestedRequests": "true", "domain": "public"}}',
49
+ json={
50
+ "data": [
51
+ {
52
+ "score": 611.41156,
53
+ "normalizedScore": 23,
54
+ "document": {
55
+ "watcherCount": 6,
56
+ "apiCount": 0,
57
+ "forkCount": 0,
58
+ "isblacklisted": "false",
59
+ "createdAt": "2021-06-15T14:03:51",
60
+ "publishertype": "team",
61
+ "publisherHandle": "blacklanternsecurity",
62
+ "id": "11498add-357d-4bc5-a008-0a2d44fb8829",
63
+ "slug": "bbot-public",
64
+ "updatedAt": "2024-07-30T11:00:35",
65
+ "entityType": "workspace",
66
+ "visibilityStatus": "public",
67
+ "forkcount": "0",
68
+ "tags": [],
69
+ "createdat": "2021-06-15T14:03:51",
70
+ "forkLabel": "",
71
+ "publisherName": "blacklanternsecurity",
72
+ "name": "BlackLanternSecurity BBOT [Public]",
73
+ "dependencyCount": 7,
74
+ "collectionCount": 6,
75
+ "warehouse__updated_at": "2024-07-30 11:00:00",
76
+ "privateNetworkFolders": [],
77
+ "isPublisherVerified": False,
78
+ "publisherType": "team",
79
+ "curatedInList": [],
80
+ "creatorId": "6900157",
81
+ "description": "",
82
+ "forklabel": "",
83
+ "publisherId": "299401",
84
+ "publisherLogo": "",
85
+ "popularity": 5,
86
+ "isPublic": True,
87
+ "categories": [],
88
+ "universaltags": "",
89
+ "views": 5788,
90
+ "summary": "BLS public workspaces.",
91
+ "memberCount": 2,
92
+ "isBlacklisted": False,
93
+ "publisherid": "299401",
94
+ "isPrivateNetworkEntity": False,
95
+ "isDomainNonTrivial": True,
96
+ "privateNetworkMeta": "",
97
+ "updatedat": "2021-10-20T16:19:29",
98
+ "documentType": "workspace",
99
+ },
100
+ "highlight": {"summary": "<b>BLS</b> BBOT api test."},
101
+ },
102
+ {
103
+ "score": 611.41156,
104
+ "normalizedScore": 23,
105
+ "document": {
106
+ "watcherCount": 6,
107
+ "apiCount": 0,
108
+ "forkCount": 0,
109
+ "isblacklisted": "false",
110
+ "createdAt": "2021-06-15T14:03:51",
111
+ "publishertype": "team",
112
+ "publisherHandle": "testteam",
113
+ "id": "11498add-357d-4bc5-a008-0a2d44fb8829",
114
+ "slug": "testing-bbot-api",
115
+ "updatedAt": "2024-07-30T11:00:35",
116
+ "entityType": "workspace",
117
+ "visibilityStatus": "public",
118
+ "forkcount": "0",
119
+ "tags": [],
120
+ "createdat": "2021-06-15T14:03:51",
121
+ "forkLabel": "",
122
+ "publisherName": "testteam",
123
+ "name": "Test BlackLanternSecurity API Team Workspace",
124
+ "dependencyCount": 7,
125
+ "collectionCount": 6,
126
+ "warehouse__updated_at": "2024-07-30 11:00:00",
127
+ "privateNetworkFolders": [],
128
+ "isPublisherVerified": False,
129
+ "publisherType": "team",
130
+ "curatedInList": [],
131
+ "creatorId": "6900157",
132
+ "description": "",
133
+ "forklabel": "",
134
+ "publisherId": "299401",
135
+ "publisherLogo": "",
136
+ "popularity": 5,
137
+ "isPublic": True,
138
+ "categories": [],
139
+ "universaltags": "",
140
+ "views": 5788,
141
+ "summary": "Private test of BBOTs public API",
142
+ "memberCount": 2,
143
+ "isBlacklisted": False,
144
+ "publisherid": "299401",
145
+ "isPrivateNetworkEntity": False,
146
+ "isDomainNonTrivial": True,
147
+ "privateNetworkMeta": "",
148
+ "updatedat": "2021-10-20T16:19:29",
149
+ "documentType": "workspace",
150
+ },
151
+ "highlight": {"summary": "Private test of BBOTs Public API"},
152
+ },
153
+ ],
154
+ "meta": {
155
+ "queryText": "blacklanternsecurity",
156
+ "total": {
157
+ "collection": 0,
158
+ "request": 0,
159
+ "workspace": 2,
160
+ "api": 0,
161
+ "team": 0,
162
+ "user": 0,
163
+ "flow": 0,
164
+ "apiDefinition": 0,
165
+ "privateNetworkFolder": 0,
166
+ },
167
+ "state": "AQ4",
168
+ "spellCorrection": {"count": {"all": 2, "workspace": 2}, "correctedQueryText": None},
169
+ "featureFlags": {
170
+ "enabledPublicResultCuration": True,
171
+ "boostByPopularity": True,
172
+ "reRankPostNormalization": True,
173
+ "enableUrlBarHostNameSearch": True,
174
+ },
175
+ },
176
+ },
177
+ )
178
+ module_test.httpx_mock.add_response(
179
+ url="https://www.postman.com/_api/ws/proxy",
180
+ match_content=b'{"service": "workspaces", "method": "GET", "path": "/workspaces?handle=blacklanternsecurity&slug=bbot-public"}',
181
+ json={
182
+ "meta": {"model": "workspace", "action": "find", "nextCursor": ""},
183
+ "data": [
184
+ {
185
+ "id": "3a7e4bdc-7ff7-4dd4-8eaa-61ddce1c3d1b",
186
+ "name": "BlackLanternSecurity BBOT [Public]",
187
+ "description": None,
188
+ "summary": "BLS public workspaces.",
189
+ "createdBy": "299401",
190
+ "updatedBy": "299401",
191
+ "team": None,
192
+ "createdAt": "2021-10-20T16:19:29",
193
+ "updatedAt": "2021-10-20T16:19:29",
194
+ "visibilityStatus": "public",
195
+ "profileInfo": {
196
+ "slug": "bbot-public",
197
+ "profileType": "team",
198
+ "profileId": "000000",
199
+ "publicHandle": "https://www.postman.com/blacklanternsecurity",
200
+ "publicImageURL": "",
201
+ "publicName": "BlackLanternSecurity",
202
+ "isVerified": False,
203
+ },
204
+ }
205
+ ],
206
+ },
207
+ )
208
+ module_test.httpx_mock.add_response(
209
+ url="https://www.postman.com/_api/ws/proxy",
210
+ match_content=b'{"service": "workspaces", "method": "GET", "path": "/workspaces?handle=testteam&slug=testing-bbot-api"}',
211
+ json={
212
+ "meta": {"model": "workspace", "action": "find", "nextCursor": ""},
213
+ "data": [
214
+ {
215
+ "id": "a4dfe981-2593-4f0b-b4c3-5145e8640f7d",
216
+ "name": "Test BlackLanternSecurity API Team Workspace",
217
+ "description": None,
218
+ "summary": "Private test of BBOTs public API",
219
+ "createdBy": "299401",
220
+ "updatedBy": "299401",
221
+ "team": None,
222
+ "createdAt": "2021-10-20T16:19:29",
223
+ "updatedAt": "2021-10-20T16:19:29",
224
+ "visibilityStatus": "public",
225
+ "profileInfo": {
226
+ "slug": "bbot-public",
227
+ "profileType": "team",
228
+ "profileId": "000000",
229
+ "publicHandle": "https://www.postman.com/testteam",
230
+ "publicImageURL": "",
231
+ "publicName": "testteam",
232
+ "isVerified": False,
233
+ },
234
+ }
235
+ ],
236
+ },
237
+ )
238
+ module_test.httpx_mock.add_response(
239
+ url="https://api.getpostman.com/workspaces/3a7e4bdc-7ff7-4dd4-8eaa-61ddce1c3d1b",
240
+ match_headers={"X-Api-Key": "asdf"},
241
+ json={
242
+ "workspace": {
243
+ "id": "3a7e4bdc-7ff7-4dd4-8eaa-61ddce1c3d1b",
244
+ "name": "BlackLanternSecurity BBOT [Public]",
245
+ "type": "personal",
246
+ "description": None,
247
+ "visibility": "public",
248
+ "createdBy": "00000000",
249
+ "updatedBy": "00000000",
250
+ "createdAt": "2021-11-17T06:09:01.000Z",
251
+ "updatedAt": "2021-11-17T08:57:16.000Z",
252
+ "collections": [
253
+ {
254
+ "id": "2aab9fd0-3715-4abe-8bb0-8cb0264d023f",
255
+ "name": "BBOT Public",
256
+ "uid": "10197090-2aab9fd0-3715-4abe-8bb0-8cb0264d023f",
257
+ },
258
+ ],
259
+ "environments": [
260
+ {
261
+ "id": "f770f816-9c6a-40f7-bde3-c0855d2a1089",
262
+ "name": "BBOT Test",
263
+ "uid": "10197090-f770f816-9c6a-40f7-bde3-c0855d2a1089",
264
+ }
265
+ ],
266
+ "apis": [],
267
+ }
268
+ },
269
+ )
270
+ module_test.httpx_mock.add_response(
271
+ url="https://api.getpostman.com/workspaces/a4dfe981-2593-4f0b-b4c3-5145e8640f7d",
272
+ json={
273
+ "workspace": {
274
+ "id": "a4dfe981-2593-4f0b-b4c3-5145e8640f7d",
275
+ "name": "Test BlackLanternSecurity API Team Workspace",
276
+ "type": "personal",
277
+ "description": None,
278
+ "visibility": "public",
279
+ "createdBy": "00000000",
280
+ "updatedBy": "00000000",
281
+ "createdAt": "2021-11-17T06:09:01.000Z",
282
+ "updatedAt": "2021-11-17T08:57:16.000Z",
283
+ "collections": [
284
+ {
285
+ "id": "f46bebfd-420a-4adf-97d1-6fb5a02cf7fc",
286
+ "name": "BBOT Public",
287
+ "uid": "10197090-f46bebfd-420a-4adf-97d1-6fb5a02cf7fc",
288
+ },
289
+ ],
290
+ "environments": [],
291
+ "apis": [],
292
+ }
293
+ },
294
+ )
295
+ module_test.httpx_mock.add_response(
296
+ url="https://www.postman.com/_api/workspace/3a7e4bdc-7ff7-4dd4-8eaa-61ddce1c3d1b/globals",
297
+ json={
298
+ "model_id": "8be7574b-219f-49e0-8d25-da447a882e4e",
299
+ "meta": {"model": "globals", "action": "find"},
300
+ "data": {
301
+ "workspace": "3a7e4bdc-7ff7-4dd4-8eaa-61ddce1c3d1b",
302
+ "lastUpdatedBy": "00000000",
303
+ "lastRevision": 1637239113000,
304
+ "id": "8be7574b-219f-49e0-8d25-da447a882e4e",
305
+ "values": [
306
+ {
307
+ "key": "endpoint_url",
308
+ "value": "https://api.blacklanternsecurity.com/",
309
+ "enabled": True,
310
+ },
311
+ ],
312
+ "createdAt": "2021-11-17T06:09:01.000Z",
313
+ "updatedAt": "2021-11-18T12:38:33.000Z",
314
+ },
315
+ },
316
+ )
317
+ module_test.httpx_mock.add_response(
318
+ url="https://www.postman.com/_api/workspace/a4dfe981-2593-4f0b-b4c3-5145e8640f7d/globals",
319
+ json={
320
+ "model_id": "8be7574b-219f-49e0-8d25-da447a882e4e",
321
+ "meta": {"model": "globals", "action": "find"},
322
+ "data": {
323
+ "workspace": "a4dfe981-2593-4f0b-b4c3-5145e8640f7d",
324
+ "lastUpdatedBy": "00000000",
325
+ "lastRevision": 1637239113000,
326
+ "id": "8be7574b-219f-49e0-8d25-da447a882e4e",
327
+ "values": [],
328
+ "createdAt": "2021-11-17T06:09:01.000Z",
329
+ "updatedAt": "2021-11-18T12:38:33.000Z",
330
+ },
331
+ },
332
+ )
333
+ module_test.httpx_mock.add_response(
334
+ url="https://api.getpostman.com/environments/10197090-f770f816-9c6a-40f7-bde3-c0855d2a1089",
335
+ match_headers={"X-Api-Key": "asdf"},
336
+ json={
337
+ "environment": {
338
+ "id": "f770f816-9c6a-40f7-bde3-c0855d2a1089",
339
+ "name": "BBOT Test",
340
+ "owner": "00000000",
341
+ "createdAt": "2021-11-17T06:29:54.000Z",
342
+ "updatedAt": "2021-11-23T07:06:53.000Z",
343
+ "values": [
344
+ {
345
+ "key": "temp_session_endpoint",
346
+ "value": "https://api.blacklanternsecurity.com/",
347
+ "enabled": True,
348
+ },
349
+ ],
350
+ "isPublic": True,
351
+ }
352
+ },
353
+ )
354
+ module_test.httpx_mock.add_response(
355
+ url="https://api.getpostman.com/collections/10197090-2aab9fd0-3715-4abe-8bb0-8cb0264d023f",
356
+ match_headers={"X-Api-Key": "asdf"},
357
+ json={
358
+ "collection": {
359
+ "info": {
360
+ "_postman_id": "62b91565-d2e2-4bcd-8248-4dba2e3452f0",
361
+ "name": "BBOT Public",
362
+ "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json",
363
+ "updatedAt": "2021-11-17T07:13:16.000Z",
364
+ "createdAt": "2021-11-17T07:13:15.000Z",
365
+ "lastUpdatedBy": "00000000",
366
+ "uid": "00000000-62b91565-d2e2-4bcd-8248-4dba2e3452f0",
367
+ },
368
+ "item": [
369
+ {
370
+ "name": "Generate API Session",
371
+ "id": "c1bac38c-dfc9-4cc0-9c19-828cbc8543b1",
372
+ "protocolProfileBehavior": {"disableBodyPruning": True},
373
+ "request": {
374
+ "method": "POST",
375
+ "header": [{"key": "Content-Type", "value": "application/json"}],
376
+ "body": {
377
+ "mode": "raw",
378
+ "raw": '{"username": "test", "password": "Test"}',
379
+ },
380
+ "url": {"raw": "{{endpoint_url}}", "host": ["{{endpoint_url}}"]},
381
+ "description": "",
382
+ },
383
+ "response": [],
384
+ "uid": "10197090-c1bac38c-dfc9-4cc0-9c19-828cbc8543b1",
385
+ },
386
+ ],
387
+ }
388
+ },
389
+ )
390
+ module_test.httpx_mock.add_response(
391
+ url="https://api.getpostman.com/collections/10197090-f46bebfd-420a-4adf-97d1-6fb5a02cf7fc",
392
+ json={
393
+ "collection": {
394
+ "info": {
395
+ "_postman_id": "f46bebfd-420a-4adf-97d1-6fb5a02cf7fc",
396
+ "name": "BBOT Public",
397
+ "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json",
398
+ "updatedAt": "2021-11-17T07:13:16.000Z",
399
+ "createdAt": "2021-11-17T07:13:15.000Z",
400
+ "lastUpdatedBy": "00000000",
401
+ "uid": "00000000-f46bebfd-420a-4adf-97d1-6fb5a02cf7fc",
402
+ },
403
+ "item": [
404
+ {
405
+ "name": "Out of Scope API request",
406
+ "id": "c1bac38c-dfc9-4cc0-9c19-828cbc8543b1",
407
+ "protocolProfileBehavior": {"disableBodyPruning": True},
408
+ "request": {
409
+ "method": "POST",
410
+ "header": [{"key": "Content-Type", "value": "application/json"}],
411
+ "body": {
412
+ "mode": "raw",
413
+ "raw": '{"username": "test", "password": "Test"}',
414
+ },
415
+ "url": {"raw": "https://www.outofscope.com", "host": ["www.outofscope.com"]},
416
+ "description": "",
417
+ },
418
+ "response": [],
419
+ "uid": "10197090-c1bac38c-dfc9-4cc0-9c19-828cbc8543b1",
420
+ },
421
+ ],
422
+ }
423
+ },
424
+ )
425
+
426
+ def check(self, module_test, events):
427
+ assert 2 == len(
428
+ [e for e in events if e.type == "CODE_REPOSITORY" and "postman" in e.tags and e.scope_distance == 1]
429
+ ), "Failed to find blacklanternsecurity postman workspace"
430
+ assert 1 == len(
431
+ [
432
+ e
433
+ for e in events
434
+ if e.type == "FILESYSTEM"
435
+ and "postman_workspaces/BlackLanternSecurity BBOT [Public]" in e.data["path"]
436
+ and "postman" in e.tags
437
+ and e.scope_distance == 1
438
+ ]
439
+ ), "Failed to find blacklanternsecurity postman workspace"
@@ -1,3 +1,5 @@
1
+ import httpx
2
+
1
3
  from .base import ModuleTestBase
2
4
 
3
5
 
@@ -9,8 +11,98 @@ class TestRapidDNS(ModuleTestBase):
9
11
  async def setup_after_prep(self, module_test):
10
12
  module_test.module.abort_if = lambda e: False
11
13
  module_test.httpx_mock.add_response(
12
- url=f"https://rapiddns.io/subdomain/blacklanternsecurity.com?full=1#result", text=self.web_body
14
+ url="https://rapiddns.io/subdomain/blacklanternsecurity.com?full=1#result", text=self.web_body
13
15
  )
14
16
 
15
17
  def check(self, module_test, events):
16
18
  assert any(e.data == "asdf.blacklanternsecurity.com" for e in events), "Failed to detect subdomain"
19
+
20
+
21
+ class TestRapidDNSAbortThreshold1(TestRapidDNS):
22
+ module_name = "rapiddns"
23
+
24
+ async def setup_after_prep(self, module_test):
25
+ self.url_count = {}
26
+
27
+ async def custom_callback(request):
28
+ url = str(request.url)
29
+ try:
30
+ self.url_count[url] += 1
31
+ except KeyError:
32
+ self.url_count[url] = 1
33
+ raise httpx.TimeoutException("timeout")
34
+
35
+ module_test.httpx_mock.add_callback(custom_callback)
36
+
37
+ await module_test.mock_dns(
38
+ {
39
+ "blacklanternsecurity.com": {"A": ["127.0.0.88"]},
40
+ "evilcorp.com": {"A": ["127.0.0.11"]},
41
+ "evilcorp.net": {"A": ["127.0.0.22"]},
42
+ "evilcorp.co.uk": {"A": ["127.0.0.33"]},
43
+ }
44
+ )
45
+
46
+ def check(self, module_test, events):
47
+ assert module_test.module.api_failure_abort_threshold == 10
48
+ assert module_test.module.errored is False
49
+ assert module_test.module._api_request_failures == 3
50
+ assert module_test.module.api_retries == 3
51
+ assert {e.data for e in events if e.type == "DNS_NAME"} == {"blacklanternsecurity.com"}
52
+ assert self.url_count == {
53
+ "https://rapiddns.io/subdomain/blacklanternsecurity.com?full=1#result": 3,
54
+ }
55
+
56
+
57
+ class TestRapidDNSAbortThreshold2(TestRapidDNSAbortThreshold1):
58
+ targets = ["blacklanternsecurity.com", "evilcorp.com"]
59
+
60
+ def check(self, module_test, events):
61
+ assert module_test.module.api_failure_abort_threshold == 10
62
+ assert module_test.module.errored is False
63
+ assert module_test.module._api_request_failures == 6
64
+ assert module_test.module.api_retries == 3
65
+ assert {e.data for e in events if e.type == "DNS_NAME"} == {"blacklanternsecurity.com", "evilcorp.com"}
66
+ assert self.url_count == {
67
+ "https://rapiddns.io/subdomain/blacklanternsecurity.com?full=1#result": 3,
68
+ "https://rapiddns.io/subdomain/evilcorp.com?full=1#result": 3,
69
+ }
70
+
71
+
72
+ class TestRapidDNSAbortThreshold3(TestRapidDNSAbortThreshold1):
73
+ targets = ["blacklanternsecurity.com", "evilcorp.com", "evilcorp.net"]
74
+
75
+ def check(self, module_test, events):
76
+ assert module_test.module.api_failure_abort_threshold == 10
77
+ assert module_test.module.errored is False
78
+ assert module_test.module._api_request_failures == 9
79
+ assert module_test.module.api_retries == 3
80
+ assert {e.data for e in events if e.type == "DNS_NAME"} == {
81
+ "blacklanternsecurity.com",
82
+ "evilcorp.com",
83
+ "evilcorp.net",
84
+ }
85
+ assert self.url_count == {
86
+ "https://rapiddns.io/subdomain/blacklanternsecurity.com?full=1#result": 3,
87
+ "https://rapiddns.io/subdomain/evilcorp.com?full=1#result": 3,
88
+ "https://rapiddns.io/subdomain/evilcorp.net?full=1#result": 3,
89
+ }
90
+
91
+
92
+ class TestRapidDNSAbortThreshold4(TestRapidDNSAbortThreshold1):
93
+ targets = ["blacklanternsecurity.com", "evilcorp.com", "evilcorp.net", "evilcorp.co.uk"]
94
+
95
+ def check(self, module_test, events):
96
+ assert module_test.module.api_failure_abort_threshold == 10
97
+ assert module_test.module.errored is True
98
+ assert module_test.module._api_request_failures == 10
99
+ assert module_test.module.api_retries == 3
100
+ assert {e.data for e in events if e.type == "DNS_NAME"} == {
101
+ "blacklanternsecurity.com",
102
+ "evilcorp.com",
103
+ "evilcorp.net",
104
+ "evilcorp.co.uk",
105
+ }
106
+ assert len(self.url_count) == 4
107
+ assert list(self.url_count.values()).count(3) == 3
108
+ assert list(self.url_count.values()).count(1) == 1
@@ -0,0 +1,50 @@
1
+ from .base import ModuleTestBase
2
+
3
+
4
+ class TestSecurityTxt(ModuleTestBase):
5
+ targets = ["blacklanternsecurity.notreal"]
6
+ modules_overrides = ["securitytxt", "speculate"]
7
+
8
+ async def setup_before_prep(self, module_test):
9
+ module_test.httpx_mock.add_response(
10
+ url="https://blacklanternsecurity.notreal/.well-known/security.txt",
11
+ text="-----BEGIN PGP SIGNED MESSAGE-----\nHash: SHA512\n\nContact: mailto:joe.smith@blacklanternsecurity.notreal\nContact: mailto:vdp@example.com\nContact: https://vdp.example.com\nExpires: 2025-01-01T00:00:00.000Z\nPreferred-Languages: fr, en\nCanonical: https://blacklanternsecurity.notreal/.well-known/security.txt\nPolicy: https://example.com/cert\nHiring: https://www.careers.example.com\n-----BEGIN PGP SIGNATURE-----\n\nSIGNATURE\n\n-----END PGP SIGNATURE-----",
12
+ )
13
+
14
+ async def setup_after_prep(self, module_test):
15
+ await module_test.mock_dns(
16
+ {
17
+ "blacklanternsecurity.notreal": {
18
+ "A": ["127.0.0.11"],
19
+ },
20
+ }
21
+ )
22
+
23
+ def check(self, module_test, events):
24
+ assert any(
25
+ e.type == "EMAIL_ADDRESS" and e.data == "joe.smith@blacklanternsecurity.notreal" for e in events
26
+ ), "Failed to detect email address"
27
+ assert not any(
28
+ e.type == "URL_UNVERIFIED" and e.data == "https://blacklanternsecurity.notreal/.well-known/security.txt"
29
+ for e in events
30
+ ), "Failed to filter Canonical URL to self"
31
+ assert not any(str(e.data) == "vdp@example.com" for e in events)
32
+
33
+
34
+ class TestSecurityTxtEmailsFalse(TestSecurityTxt):
35
+ config_overrides = {
36
+ "scope": {"report_distance": 1},
37
+ "modules": {"securitytxt": {"emails": False}},
38
+ }
39
+
40
+ def check(self, module_test, events):
41
+ assert not any(e.type == "EMAIL_ADDRESS" for e in events), "Detected email address when emails=False"
42
+ assert any(
43
+ e.type == "URL_UNVERIFIED" and e.data == "https://vdp.example.com/" for e in events
44
+ ), "Failed to detect URL"
45
+ assert any(
46
+ e.type == "URL_UNVERIFIED" and e.data == "https://example.com/cert" for e in events
47
+ ), "Failed to detect URL"
48
+ assert any(
49
+ e.type == "URL_UNVERIFIED" and e.data == "https://www.careers.example.com/" for e in events
50
+ ), "Failed to detect URL"
@@ -9,13 +9,32 @@ class TestShodan_DNS(ModuleTestBase):
9
9
  url="https://api.shodan.io/api-info?key=asdf",
10
10
  )
11
11
  module_test.httpx_mock.add_response(
12
- url="https://api.shodan.io/dns/domain/blacklanternsecurity.com?key=asdf",
12
+ url="https://api.shodan.io/dns/domain/blacklanternsecurity.com?key=asdf&page=1",
13
13
  json={
14
14
  "subdomains": [
15
15
  "asdf",
16
16
  ],
17
17
  },
18
18
  )
19
+ module_test.httpx_mock.add_response(
20
+ url="https://api.shodan.io/dns/domain/blacklanternsecurity.com?key=asdf&page=2",
21
+ json={
22
+ "subdomains": [
23
+ "www",
24
+ ],
25
+ },
26
+ )
27
+ await module_test.mock_dns(
28
+ {
29
+ "blacklanternsecurity.com": {
30
+ "A": ["127.0.0.11"],
31
+ },
32
+ "www.blacklanternsecurity.com": {"A": ["127.0.0.22"]},
33
+ "asdf.blacklanternsecurity.com": {"A": ["127.0.0.33"]},
34
+ }
35
+ )
19
36
 
20
37
  def check(self, module_test, events):
38
+ assert len([e for e in events if e.type == "DNS_NAME"]) == 3, "Failed to detect both subdomains"
21
39
  assert any(e.data == "asdf.blacklanternsecurity.com" for e in events), "Failed to detect subdomain"
40
+ assert any(e.data == "www.blacklanternsecurity.com" for e in events), "Failed to detect subdomain"
@@ -136,11 +136,11 @@ class TestSitedossier(ModuleTestBase):
136
136
  }
137
137
  )
138
138
  module_test.httpx_mock.add_response(
139
- url=f"http://www.sitedossier.com/parentdomain/evilcorp.com",
139
+ url="http://www.sitedossier.com/parentdomain/evilcorp.com",
140
140
  text=page1,
141
141
  )
142
142
  module_test.httpx_mock.add_response(
143
- url=f"http://www.sitedossier.com/parentdomain/evilcorp.com/101",
143
+ url="http://www.sitedossier.com/parentdomain/evilcorp.com/101",
144
144
  text=page2,
145
145
  )
146
146
 
@@ -39,7 +39,7 @@ class TestSmuggler(ModuleTestBase):
39
39
  old_run_live = module_test.scan.helpers.run_live
40
40
 
41
41
  async def smuggler_mock_run_live(*command, **kwargs):
42
- if not "smuggler" in command[0][1]:
42
+ if "smuggler" not in command[0][1]:
43
43
  async for l in old_run_live(*command, **kwargs):
44
44
  yield l
45
45
  else: