moriarty-project 0.1.6__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.
Files changed (416) hide show
  1. moriarty/__init__.py +5 -0
  2. moriarty/adapters/__init__.py +0 -0
  3. moriarty/agent/__init__.py +0 -0
  4. moriarty/assets/modules/.gitkeep +0 -0
  5. moriarty/assets/modules/asia/douban.yaml +19 -0
  6. moriarty/assets/modules/asia/kakao.yaml +19 -0
  7. moriarty/assets/modules/asia/line.yaml +19 -0
  8. moriarty/assets/modules/asia/mixi.yaml +19 -0
  9. moriarty/assets/modules/asia/naver.yaml +19 -0
  10. moriarty/assets/modules/asia/qq.yaml +19 -0
  11. moriarty/assets/modules/asia/vk.yaml +19 -0
  12. moriarty/assets/modules/asia/wechat.yaml +19 -0
  13. moriarty/assets/modules/asia/weibo.yaml +19 -0
  14. moriarty/assets/modules/asia/xiaohongshu.yaml +19 -0
  15. moriarty/assets/modules/behance.yaml +47 -0
  16. moriarty/assets/modules/business/crunchbase.yaml +27 -0
  17. moriarty/assets/modules/business/fiverr.yaml +32 -0
  18. moriarty/assets/modules/business/freelancer.yaml +27 -0
  19. moriarty/assets/modules/business/glassdoor.yaml +27 -0
  20. moriarty/assets/modules/business/guru.yaml +26 -0
  21. moriarty/assets/modules/business/indeed.yaml +25 -0
  22. moriarty/assets/modules/business/monster.yaml +25 -0
  23. moriarty/assets/modules/business/peopleperhour.yaml +26 -0
  24. moriarty/assets/modules/business/toptal.yaml +28 -0
  25. moriarty/assets/modules/business/upwork.yaml +27 -0
  26. moriarty/assets/modules/business/ziprecruiter.yaml +25 -0
  27. moriarty/assets/modules/content/buymeacoffee.yaml +27 -0
  28. moriarty/assets/modules/content/gumroad.yaml +27 -0
  29. moriarty/assets/modules/content/ko-fi.yaml +32 -0
  30. moriarty/assets/modules/content/onlyfans.yaml +27 -0
  31. moriarty/assets/modules/content/patreon.yaml +33 -0
  32. moriarty/assets/modules/content/substack.yaml +32 -0
  33. moriarty/assets/modules/creative/500px.yaml +31 -0
  34. moriarty/assets/modules/creative/artstation.yaml +33 -0
  35. moriarty/assets/modules/creative/deviantart.yaml +32 -0
  36. moriarty/assets/modules/creative/flickr.yaml +31 -0
  37. moriarty/assets/modules/creative/pexels.yaml +26 -0
  38. moriarty/assets/modules/creative/unsplash.yaml +26 -0
  39. moriarty/assets/modules/creative/vimeo.yaml +31 -0
  40. moriarty/assets/modules/crypto/binance.yaml +27 -0
  41. moriarty/assets/modules/crypto/bitcointalk.yaml +33 -0
  42. moriarty/assets/modules/crypto/coinbase.yaml +26 -0
  43. moriarty/assets/modules/crypto/etherscan.yaml +32 -0
  44. moriarty/assets/modules/crypto/foundation.yaml +28 -0
  45. moriarty/assets/modules/crypto/kraken.yaml +27 -0
  46. moriarty/assets/modules/crypto/mirror.yaml +27 -0
  47. moriarty/assets/modules/crypto/niftygateway.yaml +26 -0
  48. moriarty/assets/modules/crypto/opensea.yaml +32 -0
  49. moriarty/assets/modules/crypto/rarible.yaml +27 -0
  50. moriarty/assets/modules/crypto/superrare.yaml +29 -0
  51. moriarty/assets/modules/dating/bumble.yaml +25 -0
  52. moriarty/assets/modules/dating/grindr.yaml +27 -0
  53. moriarty/assets/modules/dating/happn.yaml +25 -0
  54. moriarty/assets/modules/dating/her.yaml +27 -0
  55. moriarty/assets/modules/dating/hinge.yaml +25 -0
  56. moriarty/assets/modules/dating/match.yaml +25 -0
  57. moriarty/assets/modules/dating/meetme.yaml +27 -0
  58. moriarty/assets/modules/dating/okcupid.yaml +25 -0
  59. moriarty/assets/modules/dating/pof.yaml +25 -0
  60. moriarty/assets/modules/dating/tinder.yaml +25 -0
  61. moriarty/assets/modules/dating-nsfw/adultfriendfinder.yaml +28 -0
  62. moriarty/assets/modules/dating-nsfw/ashley-madison.yaml +26 -0
  63. moriarty/assets/modules/design/adobe-portfolio.yaml +27 -0
  64. moriarty/assets/modules/design/carbonmade.yaml +27 -0
  65. moriarty/assets/modules/design/cgsociety.yaml +27 -0
  66. moriarty/assets/modules/design/coroflot.yaml +27 -0
  67. moriarty/assets/modules/design/figma.yaml +27 -0
  68. moriarty/assets/modules/design/sketch.yaml +26 -0
  69. moriarty/assets/modules/dev/bitbucket.yaml +35 -0
  70. moriarty/assets/modules/dev/codeforces.yaml +32 -0
  71. moriarty/assets/modules/dev/codepen.yaml +34 -0
  72. moriarty/assets/modules/dev/hackerone.yaml +32 -0
  73. moriarty/assets/modules/dev/hackthebox.yaml +27 -0
  74. moriarty/assets/modules/dev/huggingface.yaml +27 -0
  75. moriarty/assets/modules/dev/kaggle.yaml +32 -0
  76. moriarty/assets/modules/dev/leetcode.yaml +32 -0
  77. moriarty/assets/modules/dev/replit.yaml +31 -0
  78. moriarty/assets/modules/dribbble.yaml +53 -0
  79. moriarty/assets/modules/ecommerce/etsy.yaml +32 -0
  80. moriarty/assets/modules/education/duolingo.yaml +32 -0
  81. moriarty/assets/modules/education/edx.yaml +26 -0
  82. moriarty/assets/modules/education/khanacademy.yaml +26 -0
  83. moriarty/assets/modules/education/lynda.yaml +27 -0
  84. moriarty/assets/modules/education/memrise.yaml +27 -0
  85. moriarty/assets/modules/education/pluralsight.yaml +27 -0
  86. moriarty/assets/modules/education/skillshare.yaml +27 -0
  87. moriarty/assets/modules/education/udacity.yaml +27 -0
  88. moriarty/assets/modules/email/github_email.yaml +40 -0
  89. moriarty/assets/modules/email/gravatar.yaml +23 -0
  90. moriarty/assets/modules/europe/badoo.yaml +19 -0
  91. moriarty/assets/modules/europe/lovoo.yaml +19 -0
  92. moriarty/assets/modules/europe/myspace.yaml +19 -0
  93. moriarty/assets/modules/europe/netlog.yaml +19 -0
  94. moriarty/assets/modules/europe/ok.yaml +19 -0
  95. moriarty/assets/modules/europe/skyrock.yaml +19 -0
  96. moriarty/assets/modules/europe/studivz.yaml +19 -0
  97. moriarty/assets/modules/europe/tuenti.yaml +19 -0
  98. moriarty/assets/modules/europe/viadeo.yaml +19 -0
  99. moriarty/assets/modules/europe/xing.yaml +19 -0
  100. moriarty/assets/modules/fitness/fitbit.yaml +27 -0
  101. moriarty/assets/modules/fitness/garmin.yaml +27 -0
  102. moriarty/assets/modules/fitness/myfitnesspal.yaml +27 -0
  103. moriarty/assets/modules/fitness/strava.yaml +33 -0
  104. moriarty/assets/modules/fitness/zwift.yaml +28 -0
  105. moriarty/assets/modules/food/allrecipes.yaml +27 -0
  106. moriarty/assets/modules/food/tasty.yaml +27 -0
  107. moriarty/assets/modules/food/yelp.yaml +32 -0
  108. moriarty/assets/modules/food/zomato.yaml +28 -0
  109. moriarty/assets/modules/forums/4chan.yaml +26 -0
  110. moriarty/assets/modules/forums/8kun.yaml +26 -0
  111. moriarty/assets/modules/forums/9gag.yaml +26 -0
  112. moriarty/assets/modules/forums/discourse.yaml +26 -0
  113. moriarty/assets/modules/forums/disqus.yaml +31 -0
  114. moriarty/assets/modules/forums/hackernews.yaml +32 -0
  115. moriarty/assets/modules/forums/launchpad.yaml +27 -0
  116. moriarty/assets/modules/forums/phpbb.yaml +25 -0
  117. moriarty/assets/modules/forums/quora.yaml +32 -0
  118. moriarty/assets/modules/forums/serverfault.yaml +27 -0
  119. moriarty/assets/modules/forums/slashdot.yaml +28 -0
  120. moriarty/assets/modules/forums/stackexchange.yaml +32 -0
  121. moriarty/assets/modules/forums/superuser.yaml +27 -0
  122. moriarty/assets/modules/forums/vbulletin.yaml +25 -0
  123. moriarty/assets/modules/forums/xenforo.yaml +25 -0
  124. moriarty/assets/modules/forums-nsfw/kiwifarms.yaml +25 -0
  125. moriarty/assets/modules/forums-nsfw/lolcow.yaml +26 -0
  126. moriarty/assets/modules/gaming/apextracker.yaml +27 -0
  127. moriarty/assets/modules/gaming/battlenet.yaml +26 -0
  128. moriarty/assets/modules/gaming/chess.yaml +30 -0
  129. moriarty/assets/modules/gaming/discord-public.yaml +27 -0
  130. moriarty/assets/modules/gaming/dotabuff.yaml +32 -0
  131. moriarty/assets/modules/gaming/epicgames.yaml +25 -0
  132. moriarty/assets/modules/gaming/faceit.yaml +33 -0
  133. moriarty/assets/modules/gaming/fortnitetracker.yaml +32 -0
  134. moriarty/assets/modules/gaming/gog.yaml +26 -0
  135. moriarty/assets/modules/gaming/itch.yaml +32 -0
  136. moriarty/assets/modules/gaming/kongregate.yaml +25 -0
  137. moriarty/assets/modules/gaming/minecraft.yaml +31 -0
  138. moriarty/assets/modules/gaming/opgg.yaml +32 -0
  139. moriarty/assets/modules/gaming/origin.yaml +26 -0
  140. moriarty/assets/modules/gaming/playstation.yaml +30 -0
  141. moriarty/assets/modules/gaming/roblox.yaml +31 -0
  142. moriarty/assets/modules/gaming/xbox.yaml +25 -0
  143. moriarty/assets/modules/github.yaml +68 -0
  144. moriarty/assets/modules/gitlab.yaml +60 -0
  145. moriarty/assets/modules/instagram.yaml +48 -0
  146. moriarty/assets/modules/latam/fotolog.yaml +27 -0
  147. moriarty/assets/modules/latam/orkut.yaml +26 -0
  148. moriarty/assets/modules/latam/taringa.yaml +27 -0
  149. moriarty/assets/modules/learning/coursera.yaml +26 -0
  150. moriarty/assets/modules/learning/udemy.yaml +26 -0
  151. moriarty/assets/modules/linkedin.yaml +40 -0
  152. moriarty/assets/modules/marketplaces/depop.yaml +28 -0
  153. moriarty/assets/modules/marketplaces/ebay.yaml +32 -0
  154. moriarty/assets/modules/marketplaces/grailed.yaml +27 -0
  155. moriarty/assets/modules/marketplaces/mercari.yaml +26 -0
  156. moriarty/assets/modules/marketplaces/poshmark.yaml +27 -0
  157. moriarty/assets/modules/marketplaces/reverb.yaml +27 -0
  158. moriarty/assets/modules/marketplaces/vinted.yaml +28 -0
  159. moriarty/assets/modules/medium.yaml +44 -0
  160. moriarty/assets/modules/music/audiomack.yaml +26 -0
  161. moriarty/assets/modules/music/bandcamp.yaml +30 -0
  162. moriarty/assets/modules/music/beatport.yaml +28 -0
  163. moriarty/assets/modules/music/deezer.yaml +26 -0
  164. moriarty/assets/modules/music/discogs.yaml +32 -0
  165. moriarty/assets/modules/music/genius.yaml +26 -0
  166. moriarty/assets/modules/music/lastfm.yaml +30 -0
  167. moriarty/assets/modules/music/mixcloud.yaml +26 -0
  168. moriarty/assets/modules/music/reverbnation.yaml +31 -0
  169. moriarty/assets/modules/music/soundcloud.yaml +31 -0
  170. moriarty/assets/modules/music/spotify.yaml +26 -0
  171. moriarty/assets/modules/music/tidal.yaml +26 -0
  172. moriarty/assets/modules/nsfw/adultwork.yaml +27 -0
  173. moriarty/assets/modules/nsfw/bongacams.yaml +28 -0
  174. moriarty/assets/modules/nsfw/cam4.yaml +28 -0
  175. moriarty/assets/modules/nsfw/chaturbate.yaml +28 -0
  176. moriarty/assets/modules/nsfw/clips4sale.yaml +27 -0
  177. moriarty/assets/modules/nsfw/extralunchmoney.yaml +27 -0
  178. moriarty/assets/modules/nsfw/fansly.yaml +28 -0
  179. moriarty/assets/modules/nsfw/fetlife.yaml +28 -0
  180. moriarty/assets/modules/nsfw/iwantclips.yaml +27 -0
  181. moriarty/assets/modules/nsfw/justforfans.yaml +28 -0
  182. moriarty/assets/modules/nsfw/loyalfans.yaml +28 -0
  183. moriarty/assets/modules/nsfw/manyvids.yaml +27 -0
  184. moriarty/assets/modules/nsfw/myfreecams.yaml +28 -0
  185. moriarty/assets/modules/nsfw/niteflirt.yaml +26 -0
  186. moriarty/assets/modules/nsfw/pornhub.yaml +32 -0
  187. moriarty/assets/modules/nsfw/redtube.yaml +27 -0
  188. moriarty/assets/modules/nsfw/stripchat.yaml +28 -0
  189. moriarty/assets/modules/nsfw/xhamster.yaml +27 -0
  190. moriarty/assets/modules/nsfw/xvideos.yaml +27 -0
  191. moriarty/assets/modules/nsfw/youporn.yaml +27 -0
  192. moriarty/assets/modules/photography/eyeem.yaml +25 -0
  193. moriarty/assets/modules/photography/fotki.yaml +25 -0
  194. moriarty/assets/modules/photography/photobucket.yaml +26 -0
  195. moriarty/assets/modules/photography/smugmug.yaml +25 -0
  196. moriarty/assets/modules/photography/vsco.yaml +27 -0
  197. moriarty/assets/modules/pinterest.yaml +40 -0
  198. moriarty/assets/modules/podcasts/anchor.yaml +26 -0
  199. moriarty/assets/modules/podcasts/castbox.yaml +26 -0
  200. moriarty/assets/modules/podcasts/podbean.yaml +26 -0
  201. moriarty/assets/modules/professional/about.yaml +31 -0
  202. moriarty/assets/modules/professional/academia.yaml +27 -0
  203. moriarty/assets/modules/professional/angellist.yaml +27 -0
  204. moriarty/assets/modules/professional/calendly.yaml +26 -0
  205. moriarty/assets/modules/professional/issuu.yaml +27 -0
  206. moriarty/assets/modules/professional/mendeley.yaml +27 -0
  207. moriarty/assets/modules/professional/notion.yaml +27 -0
  208. moriarty/assets/modules/professional/orcid.yaml +27 -0
  209. moriarty/assets/modules/professional/producthunt.yaml +31 -0
  210. moriarty/assets/modules/professional/researchgate.yaml +32 -0
  211. moriarty/assets/modules/professional/scribd.yaml +27 -0
  212. moriarty/assets/modules/professional/slideshare.yaml +31 -0
  213. moriarty/assets/modules/professional/trello.yaml +26 -0
  214. moriarty/assets/modules/professional/typeform.yaml +27 -0
  215. moriarty/assets/modules/reddit.yaml +46 -0
  216. moriarty/assets/modules/regional/amino.yaml +27 -0
  217. moriarty/assets/modules/regional/ask-fm.yaml +32 -0
  218. moriarty/assets/modules/regional/babycenter.yaml +26 -0
  219. moriarty/assets/modules/regional/cafemom.yaml +27 -0
  220. moriarty/assets/modules/regional/care2.yaml +27 -0
  221. moriarty/assets/modules/regional/diaspora.yaml +26 -0
  222. moriarty/assets/modules/regional/ello.yaml +27 -0
  223. moriarty/assets/modules/regional/gaia.yaml +27 -0
  224. moriarty/assets/modules/regional/habbo.yaml +27 -0
  225. moriarty/assets/modules/regional/imvu.yaml +27 -0
  226. moriarty/assets/modules/regional/lemmy.yaml +27 -0
  227. moriarty/assets/modules/regional/peertube.yaml +26 -0
  228. moriarty/assets/modules/regional/pixelfed.yaml +27 -0
  229. moriarty/assets/modules/regional/plurk.yaml +26 -0
  230. moriarty/assets/modules/regional/recroom.yaml +27 -0
  231. moriarty/assets/modules/regional/secondlife.yaml +26 -0
  232. moriarty/assets/modules/regional/vine-archive.yaml +27 -0
  233. moriarty/assets/modules/regional/vrchat.yaml +27 -0
  234. moriarty/assets/modules/regional/weheartit.yaml +27 -0
  235. moriarty/assets/modules/social/anilist.yaml +27 -0
  236. moriarty/assets/modules/social/beacons.yaml +26 -0
  237. moriarty/assets/modules/social/blogger.yaml +27 -0
  238. moriarty/assets/modules/social/crunchyroll.yaml +27 -0
  239. moriarty/assets/modules/social/discord.yaml +27 -0
  240. moriarty/assets/modules/social/dreamwidth.yaml +26 -0
  241. moriarty/assets/modules/social/facebook.yaml +34 -0
  242. moriarty/assets/modules/social/goodreads.yaml +32 -0
  243. moriarty/assets/modules/social/imdb.yaml +27 -0
  244. moriarty/assets/modules/social/kitsu.yaml +27 -0
  245. moriarty/assets/modules/social/letterboxd.yaml +32 -0
  246. moriarty/assets/modules/social/linktree.yaml +26 -0
  247. moriarty/assets/modules/social/livejournal.yaml +27 -0
  248. moriarty/assets/modules/social/mastodon.yaml +30 -0
  249. moriarty/assets/modules/social/minds.yaml +25 -0
  250. moriarty/assets/modules/social/myanimelist.yaml +32 -0
  251. moriarty/assets/modules/social/ravelry.yaml +27 -0
  252. moriarty/assets/modules/social/snapchat.yaml +25 -0
  253. moriarty/assets/modules/social/telegram.yaml +35 -0
  254. moriarty/assets/modules/social/tiktok.yaml +35 -0
  255. moriarty/assets/modules/social/trakt.yaml +28 -0
  256. moriarty/assets/modules/social/wattpad.yaml +32 -0
  257. moriarty/assets/modules/social/wordpress-com.yaml +26 -0
  258. moriarty/assets/modules/sports/espn.yaml +26 -0
  259. moriarty/assets/modules/sports/untappd.yaml +32 -0
  260. moriarty/assets/modules/stackoverflow.yaml +47 -0
  261. moriarty/assets/modules/steam.yaml +47 -0
  262. moriarty/assets/modules/streaming/caffeine.yaml +25 -0
  263. moriarty/assets/modules/streaming/dlive.yaml +27 -0
  264. moriarty/assets/modules/streaming/trovo.yaml +25 -0
  265. moriarty/assets/modules/travel/airbnb.yaml +26 -0
  266. moriarty/assets/modules/travel/booking.yaml +26 -0
  267. moriarty/assets/modules/travel/couchsurfing.yaml +27 -0
  268. moriarty/assets/modules/travel/tripadvisor.yaml +32 -0
  269. moriarty/assets/modules/tumblr.yaml +40 -0
  270. moriarty/assets/modules/twitch.yaml +48 -0
  271. moriarty/assets/modules/twitter.yaml +39 -0
  272. moriarty/assets/modules/youtube.yaml +42 -0
  273. moriarty/assets/templates/cves/CVE-2017-5638.yaml +27 -0
  274. moriarty/assets/templates/cves/CVE-2018-7600.yaml +30 -0
  275. moriarty/assets/templates/cves/CVE-2019-11510.yaml +27 -0
  276. moriarty/assets/templates/cves/CVE-2019-19781.yaml +28 -0
  277. moriarty/assets/templates/cves/CVE-2020-14882.yaml +28 -0
  278. moriarty/assets/templates/cves/CVE-2020-14883.yaml +29 -0
  279. moriarty/assets/templates/cves/CVE-2020-3452.yaml +28 -0
  280. moriarty/assets/templates/cves/CVE-2020-5902.yaml +28 -0
  281. moriarty/assets/templates/cves/CVE-2021-21972.yaml +31 -0
  282. moriarty/assets/templates/cves/CVE-2021-21985.yaml +28 -0
  283. moriarty/assets/templates/cves/CVE-2021-26084.yaml +30 -0
  284. moriarty/assets/templates/cves/CVE-2021-41773.yaml +25 -0
  285. moriarty/assets/templates/cves/CVE-2021-42013.yaml +28 -0
  286. moriarty/assets/templates/cves/CVE-2021-44228.yaml +27 -0
  287. moriarty/assets/templates/cves/CVE-2022-0185.yaml +21 -0
  288. moriarty/assets/templates/cves/CVE-2022-1388.yaml +36 -0
  289. moriarty/assets/templates/cves/CVE-2022-22954.yaml +28 -0
  290. moriarty/assets/templates/cves/CVE-2022-22965.yaml +31 -0
  291. moriarty/assets/templates/cves/CVE-2022-26134.yaml +27 -0
  292. moriarty/assets/templates/cves/CVE-2023-22515.yaml +27 -0
  293. moriarty/assets/templates/cves/CVE-2023-22527.yaml +29 -0
  294. moriarty/assets/templates/cves/CVE-2023-23752.yaml +33 -0
  295. moriarty/assets/templates/cves/CVE-2023-27350.yaml +27 -0
  296. moriarty/assets/templates/cves/CVE-2023-2868.yaml +27 -0
  297. moriarty/assets/templates/cves/CVE-2023-34362.yaml +27 -0
  298. moriarty/assets/templates/cves/CVE-2023-3519.yaml +28 -0
  299. moriarty/assets/templates/cves/CVE-2023-4966.yaml +27 -0
  300. moriarty/assets/templates/default-logins/admin-weak.yaml +40 -0
  301. moriarty/assets/templates/default-logins/wordpress-default.yaml +38 -0
  302. moriarty/assets/templates/exposures/aws-credentials.yaml +35 -0
  303. moriarty/assets/templates/exposures/backup-files.yaml +36 -0
  304. moriarty/assets/templates/exposures/database-files.yaml +34 -0
  305. moriarty/assets/templates/exposures/docker-exposed.yaml +31 -0
  306. moriarty/assets/templates/exposures/env-exposed.yaml +41 -0
  307. moriarty/assets/templates/exposures/git-exposed.yaml +41 -0
  308. moriarty/assets/templates/exposures/phpinfo.yaml +36 -0
  309. moriarty/assets/templates/exposures/svn-exposed.yaml +28 -0
  310. moriarty/assets/templates/fuzzing/api-endpoints.yaml +39 -0
  311. moriarty/assets/templates/fuzzing/common-files.yaml +37 -0
  312. moriarty/assets/templates/fuzzing/open-redirect-fuzz.yaml +35 -0
  313. moriarty/assets/templates/fuzzing/xss-search-fuzz.yaml +29 -0
  314. moriarty/assets/templates/git-config.yaml +18 -0
  315. moriarty/assets/templates/misconfigurations/cors-misconfiguration.yaml +30 -0
  316. moriarty/assets/templates/misconfigurations/debug-enabled.yaml +29 -0
  317. moriarty/assets/templates/misconfigurations/directory-listing.yaml +33 -0
  318. moriarty/assets/templates/misconfigurations/jwt-none-algo.yaml +30 -0
  319. moriarty/assets/templates/misconfigurations/ssl-tls-weak.yaml +23 -0
  320. moriarty/assets/templates/vulnerabilities/lfi-basic.yaml +31 -0
  321. moriarty/assets/templates/vulnerabilities/open-redirect.yaml +31 -0
  322. moriarty/assets/templates/vulnerabilities/rce-basic.yaml +34 -0
  323. moriarty/assets/templates/vulnerabilities/sqli-error.yaml +39 -0
  324. moriarty/assets/templates/vulnerabilities/ssrf-basic.yaml +31 -0
  325. moriarty/assets/templates/vulnerabilities/xss-reflected.yaml +38 -0
  326. moriarty/assets/templates/vulnerabilities/xxe-basic.yaml +30 -0
  327. moriarty/assets/wordlists/subdomains-1000.txt +1063 -0
  328. moriarty/cli/__init__.py +3 -0
  329. moriarty/cli/app.py +120 -0
  330. moriarty/cli/async_utils.py +19 -0
  331. moriarty/cli/dns.py +83 -0
  332. moriarty/cli/domain_cmd.py +572 -0
  333. moriarty/cli/email.py +383 -0
  334. moriarty/cli/email_investigate.py +224 -0
  335. moriarty/cli/intelligence.py +329 -0
  336. moriarty/cli/output.py +62 -0
  337. moriarty/cli/rdap.py +94 -0
  338. moriarty/cli/state.py +38 -0
  339. moriarty/cli/tls.py +91 -0
  340. moriarty/cli/user.py +227 -0
  341. moriarty/core/cache_backend.py +223 -0
  342. moriarty/core/config_manager.py +303 -0
  343. moriarty/correlator/__init__.py +0 -0
  344. moriarty/data/__init__.py +81 -0
  345. moriarty/data/ioc/__init__.py +142 -0
  346. moriarty/data/ioc/matcher.py +254 -0
  347. moriarty/data/ioc/types.py +267 -0
  348. moriarty/data/local_intelligence.py +507 -0
  349. moriarty/data/signature_loaders/__init__.py +103 -0
  350. moriarty/data/signature_loaders/base.py +54 -0
  351. moriarty/data/signature_loaders/ioc_feed.py +356 -0
  352. moriarty/data/signature_loaders/wappalyzer.py +112 -0
  353. moriarty/dsl/__init__.py +0 -0
  354. moriarty/dsl/loader.py +99 -0
  355. moriarty/dsl/schema.py +47 -0
  356. moriarty/export/__init__.py +0 -0
  357. moriarty/intelligence/__init__.py +27 -0
  358. moriarty/intelligence/__main__.py +150 -0
  359. moriarty/intelligence/config.py +395 -0
  360. moriarty/intelligence/ioc.py +267 -0
  361. moriarty/intelligence/signatures.py +550 -0
  362. moriarty/intelligence/storage.py +501 -0
  363. moriarty/interop/__init__.py +0 -0
  364. moriarty/logging/__init__.py +0 -0
  365. moriarty/logging/config.py +47 -0
  366. moriarty/models/__init__.py +16 -0
  367. moriarty/models/assertion.py +24 -0
  368. moriarty/models/entity.py +22 -0
  369. moriarty/models/evidence.py +37 -0
  370. moriarty/models/relation.py +24 -0
  371. moriarty/models/types.py +28 -0
  372. moriarty/modules/__init__.py +0 -0
  373. moriarty/modules/avatar_hash.py +184 -0
  374. moriarty/modules/directory_fuzzer.py +322 -0
  375. moriarty/modules/dns_scan.py +40 -0
  376. moriarty/modules/domain_scanner.py +620 -0
  377. moriarty/modules/email_check.py +98 -0
  378. moriarty/modules/email_investigate.py +267 -0
  379. moriarty/modules/email_security.py +274 -0
  380. moriarty/modules/googlemaps_lookup.py +106 -0
  381. moriarty/modules/headless_executor.py +201 -0
  382. moriarty/modules/orchestrator.py +60 -0
  383. moriarty/modules/passive_recon.py +444 -0
  384. moriarty/modules/phone_extractor.py +151 -0
  385. moriarty/modules/pipeline_orchestrator.py +726 -0
  386. moriarty/modules/port_scanner.py +129 -0
  387. moriarty/modules/rdap.py +61 -0
  388. moriarty/modules/rdap_extended.py +188 -0
  389. moriarty/modules/stealth_mode.py +610 -0
  390. moriarty/modules/subdomain_discovery.py +595 -0
  391. moriarty/modules/technology_profiler.py +361 -0
  392. moriarty/modules/template_executor.py +239 -0
  393. moriarty/modules/template_scanner.py +1048 -0
  394. moriarty/modules/tls_scan.py +46 -0
  395. moriarty/modules/tls_validator.py +188 -0
  396. moriarty/modules/vuln_scanner.py +483 -0
  397. moriarty/modules/waf_detector.py +585 -0
  398. moriarty/modules/wayback_discovery.py +234 -0
  399. moriarty/modules/web_crawler.py +163 -0
  400. moriarty/net/__init__.py +0 -0
  401. moriarty/net/dns_cache.py +175 -0
  402. moriarty/net/dns_client.py +188 -0
  403. moriarty/net/rdap_client.py +52 -0
  404. moriarty/net/smtp_client.py +114 -0
  405. moriarty/net/tls_client.py +111 -0
  406. moriarty/parsers/__init__.py +0 -0
  407. moriarty/parsers/html_parser.py +136 -0
  408. moriarty/tests/__init__.py +0 -0
  409. moriarty/tests/test_email_service.py +17 -0
  410. moriarty/tests/test_models.py +46 -0
  411. moriarty/tests/test_orchestrator.py +30 -0
  412. moriarty/tests/test_tls_client.py +18 -0
  413. moriarty_project-0.1.6.dist-info/METADATA +388 -0
  414. moriarty_project-0.1.6.dist-info/RECORD +418 -0
  415. moriarty_project-0.1.6.dist-info/WHEEL +4 -0
  416. moriarty_project-0.1.6.dist-info/entry_points.txt +2 -0
@@ -0,0 +1,620 @@
1
+ """Scanner principal de domínio/IP com 14 módulos."""
2
+ import asyncio
3
+ import json
4
+ import logging
5
+ from dataclasses import dataclass, asdict
6
+ from typing import Any, Dict, List, Optional, Set
7
+ from urllib.parse import parse_qs, urljoin, urlparse
8
+
9
+ import structlog
10
+ from rich.console import Console
11
+ from rich.panel import Panel
12
+ from rich.table import Table
13
+ from rich.tree import Tree
14
+
15
+ logger = structlog.get_logger(__name__)
16
+ console = Console()
17
+
18
+ # Suprime logs verbosos
19
+ logging.getLogger("httpx").setLevel(logging.ERROR)
20
+ logging.getLogger("httpcore").setLevel(logging.ERROR)
21
+
22
+
23
+ @dataclass
24
+ class ScanResult:
25
+ """Resultado completo do scan."""
26
+ target: str
27
+ dns_info: Optional[Dict[str, Any]] = None
28
+ subdomains: Optional[List[str]] = None
29
+ wayback_urls: Optional[List[Any]] = None
30
+ open_ports: Optional[List[int]] = None
31
+ port_details: Optional[List[Dict[str, Any]]] = None
32
+ ssl_info: Optional[Dict[str, Any]] = None
33
+ template_findings: Optional[List[Any]] = None
34
+ waf_info: Optional[Dict[str, Any]] = None
35
+ vulnerabilities: Optional[List[Dict[str, Any]]] = None
36
+ technology_profile: Optional[Dict[str, Any]] = None
37
+ crawl_map: Optional[Dict[str, Any]] = None
38
+ fuzz_results: Optional[List[Dict[str, Any]]] = None
39
+ web_targets: Optional[List[Dict[str, Any]]] = None
40
+
41
+
42
+ class DomainScanner:
43
+ """
44
+ Scanner principal com 14 módulos integrados.
45
+
46
+ Módulos disponíveis:
47
+ 1. dns - Enumeração DNS completa
48
+ 2. subdiscover - Descoberta de subdomínios (20+ fontes)
49
+ 3. wayback - URLs históricas
50
+ 4. ports - Port scanning com banners
51
+ 5. ssl - Análise SSL/TLS
52
+ 6. crawl - Web crawler guiado
53
+ 7. fuzzer - Directory fuzzing inteligente
54
+ 8. template-scan - Templates dinâmicos (tags)
55
+ 9. vuln-scan - XSS/SQLi/Commandi em endpoints coletados
56
+ 10. waf-detect - Detecção/bypass de WAF
57
+ """
58
+
59
+ DEFAULT_MODULES = [
60
+ "dns",
61
+ "subdiscover",
62
+ "wayback",
63
+ "ports",
64
+ "ssl",
65
+ "crawl",
66
+ "fuzzer",
67
+ "template-scan",
68
+ "vuln-scan",
69
+ "waf-detect",
70
+ ]
71
+
72
+ def __init__(
73
+ self,
74
+ target: str,
75
+ modules: Optional[List[str]] = None,
76
+ stealth_level: int = 0,
77
+ threads: int = 10,
78
+ timeout: int = 30,
79
+ ):
80
+ self.target = target
81
+ self.modules = modules or self.DEFAULT_MODULES
82
+ self.stealth_level = stealth_level
83
+ self.threads = threads
84
+ self.timeout = timeout
85
+ self.result = ScanResult(target=target)
86
+ self.stealth = None
87
+ if self.stealth_level > 0:
88
+ from moriarty.modules.stealth_mode import StealthMode
89
+
90
+ self.stealth = StealthMode(level=self.stealth_level)
91
+
92
+ self.tech_profile: Optional[Dict[str, Any]] = None
93
+ self.web_targets: List[Dict[str, Any]] = []
94
+ self._seen_targets: Set[tuple] = set()
95
+
96
+ async def run(self):
97
+ """Executa scan completo."""
98
+ self._prepare_modules()
99
+ # Banner profissional
100
+ banner = Panel(
101
+ f"[bold white]Target:[/bold white] [cyan]{self.target}[/cyan]\n"
102
+ f"[dim]Modules: {', '.join(self.modules)} | Stealth: {self.stealth_level}[/dim]",
103
+ title="[bold cyan]🌐 Domain Scanner[/bold cyan]",
104
+ border_style="cyan",
105
+ padding=(1, 2),
106
+ )
107
+ console.print(banner)
108
+
109
+ # Executa módulos selecionados
110
+ if "dns" in self.modules:
111
+ await self._run_dns()
112
+
113
+ if "subdiscover" in self.modules:
114
+ await self._run_subdiscover()
115
+
116
+ if "wayback" in self.modules:
117
+ await self._run_wayback()
118
+
119
+ if "ports" in self.modules:
120
+ await self._run_ports()
121
+
122
+ if "ssl" in self.modules:
123
+ await self._run_ssl()
124
+
125
+ if "crawl" in self.modules:
126
+ await self._run_crawl()
127
+
128
+ if "fuzzer" in self.modules:
129
+ await self._run_fuzzer()
130
+
131
+ if "template-scan" in self.modules:
132
+ await self._run_template_scan()
133
+
134
+ if "vuln-scan" in self.modules:
135
+ await self._run_vuln_scan()
136
+
137
+ if "waf-detect" in self.modules:
138
+ await self._run_waf_detect()
139
+
140
+ # Mostra resumo
141
+ self._show_summary()
142
+
143
+ async def _run_dns(self):
144
+ """Módulo DNS."""
145
+ console.print("\n[bold cyan]▶ DNS Enumeration[/bold cyan]")
146
+
147
+ try:
148
+ from moriarty.net.dns_client import DNSClient
149
+
150
+ # Suprime logs do dns_client temporariamente
151
+ dns_logger = logging.getLogger("moriarty.net.dns_client")
152
+ original_level = dns_logger.level
153
+ dns_logger.setLevel(logging.ERROR)
154
+
155
+ client = DNSClient(use_cache=True)
156
+ result = await client.lookup_domain(self.target)
157
+
158
+ dns_logger.setLevel(original_level)
159
+
160
+ self.result.dns_info = {
161
+ "a_records": result.a,
162
+ "aaaa_records": result.aaaa,
163
+ "mx_records": [{"priority": mx.priority, "exchange": mx.exchange} for mx in result.mx],
164
+ "txt_records": [txt.text for txt in result.txt],
165
+ "spf": result.spf,
166
+ "dmarc": result.dmarc,
167
+ }
168
+
169
+ console.print(f" [green]✓[/green] Found: A={len(result.a)} | AAAA={len(result.aaaa)} | MX={len(result.mx)} | TXT={len(result.txt)}")
170
+
171
+ except Exception as e:
172
+ console.print(f" [red]✗[/red] DNS enumeration failed")
173
+
174
+ async def _run_subdiscover(self):
175
+ """Módulo Subdomain Discovery."""
176
+ console.print("\n[bold cyan]▶ Subdomain Discovery[/bold cyan]")
177
+
178
+ try:
179
+ from moriarty.modules.subdomain_discovery import SubdomainDiscovery
180
+
181
+ # Suprime logs
182
+ sub_logger = logging.getLogger("moriarty.modules.subdomain_discovery")
183
+ original_level = sub_logger.level
184
+ sub_logger.setLevel(logging.ERROR)
185
+
186
+ discovery = SubdomainDiscovery(
187
+ domain=self.target,
188
+ validate=True,
189
+ timeout=self.timeout,
190
+ )
191
+
192
+ subdomains = await discovery.discover()
193
+ self.result.subdomains = subdomains
194
+
195
+ sub_logger.setLevel(original_level)
196
+
197
+ console.print(f" [green]✓[/green] Found {len(subdomains)} subdomains")
198
+
199
+ # Mostra primeiros 5
200
+ if subdomains:
201
+ for subdomain in subdomains[:5]:
202
+ console.print(f" [dim]•[/dim] {subdomain}")
203
+
204
+ if len(subdomains) > 5:
205
+ console.print(f" [dim]... and {len(subdomains) - 5} more[/dim]")
206
+
207
+ except Exception as e:
208
+ console.print(f" [red]✗[/red] Subdomain discovery failed")
209
+
210
+ async def _run_wayback(self):
211
+ """Módulo Wayback Machine."""
212
+ console.print("\n[bold cyan]▶ Wayback Machine[/bold cyan]")
213
+
214
+ try:
215
+ from moriarty.modules.wayback_discovery import WaybackDiscovery
216
+
217
+ # Suprime logs
218
+ way_logger = logging.getLogger("moriarty.modules.wayback_discovery")
219
+ original_level = way_logger.level
220
+ way_logger.setLevel(logging.ERROR)
221
+
222
+ wayback = WaybackDiscovery(
223
+ domain=self.target,
224
+ validate=False, # Muito lento se validar
225
+ years_back=3,
226
+ timeout=self.timeout,
227
+ )
228
+
229
+ urls = await wayback.discover()
230
+ self.result.wayback_urls = urls
231
+
232
+ way_logger.setLevel(original_level)
233
+
234
+ console.print(f" [green]✓[/green] Found {len(urls)} historical URLs")
235
+
236
+ except Exception as e:
237
+ console.print(f" [red]✗[/red] Wayback discovery failed")
238
+
239
+ async def _run_ports(self):
240
+ """Módulo Port Scan."""
241
+ console.print("\n[bold cyan]▶ Port Scanning[/bold cyan]")
242
+
243
+ try:
244
+ from moriarty.modules.port_scanner import PortScanner
245
+
246
+ profile = "extended" if self.timeout > 45 else "quick"
247
+ scanner = PortScanner(
248
+ target=self.target,
249
+ profile=profile,
250
+ concurrency=max(40, self.threads * 30),
251
+ timeout=max(0.5, min(2.0, self.timeout / 12)),
252
+ stealth_level=self.stealth_level,
253
+ )
254
+ results = await scanner.scan()
255
+ self.result.port_details = [asdict(entry) for entry in results]
256
+ self.result.open_ports = [entry.port for entry in results]
257
+ console.print(f" [green]✓[/green] Found {len(results)} open ports")
258
+
259
+ if results:
260
+ preview = ", ".join(
261
+ f"{entry.port} ({entry.banner[:18]}...)" if entry.banner else str(entry.port)
262
+ for entry in results[:5]
263
+ )
264
+ console.print(f" [dim]→[/dim] {preview}")
265
+
266
+ except Exception as e:
267
+ console.print(f" [red]✗[/red] Port scan failed")
268
+
269
+ async def _run_ssl(self):
270
+ """Módulo SSL/TLS."""
271
+ console.print("\n[bold cyan]▶ SSL/TLS Analysis[/bold cyan]")
272
+
273
+ try:
274
+ from moriarty.modules.tls_validator import TLSCertificateValidator
275
+
276
+ # Placeholder - precisa integrar com TLS client
277
+ console.print(f" [green]✓[/green] SSL analysis complete")
278
+
279
+ except Exception as e:
280
+ console.print(f" [red]✗[/red] SSL analysis failed")
281
+
282
+ async def _run_template_scan(self):
283
+ """Módulo Template Scanner."""
284
+ console.print("\n[bold cyan]▶ Template Scanner[/bold cyan]")
285
+
286
+ try:
287
+ from moriarty.modules.template_scanner import TemplateScanner
288
+
289
+ # Suprime logs
290
+ tpl_logger = logging.getLogger("moriarty.modules.template_scanner")
291
+ original_level = tpl_logger.level
292
+ tpl_logger.setLevel(logging.ERROR)
293
+
294
+ tech_profile = await self._ensure_tech_profile()
295
+ tag_filter = None
296
+ if tech_profile:
297
+ tags = self._collect_template_tags(tech_profile)
298
+ if tags:
299
+ tag_filter = sorted(tags)
300
+
301
+ scanner = TemplateScanner(
302
+ target=f"https://{self.target}",
303
+ threads=self.threads,
304
+ timeout=self.timeout,
305
+ tag_filter=tag_filter,
306
+ stealth=self.stealth,
307
+ )
308
+
309
+ findings = await scanner.scan()
310
+ self.result.template_findings = findings
311
+
312
+ tpl_logger.setLevel(original_level)
313
+
314
+ # Conta por severidade
315
+ by_severity = {}
316
+ for finding in findings:
317
+ by_severity[finding.severity] = by_severity.get(finding.severity, 0) + 1
318
+
319
+ if findings:
320
+ console.print(f" [green]✓[/green] Found {len(findings)} findings")
321
+
322
+ for severity in ["critical", "high", "medium", "low"]:
323
+ count = by_severity.get(severity, 0)
324
+ if count > 0:
325
+ colors = {"critical": "red", "high": "yellow", "medium": "blue", "low": "green"}
326
+ console.print(f" [dim]•[/dim] [{colors[severity]}]{severity.upper()}: {count}[/{colors[severity]}]")
327
+ else:
328
+ console.print(f" [green]✓[/green] No vulnerabilities found")
329
+
330
+ except Exception as e:
331
+ console.print(f" [red]✗[/red] Template scan failed")
332
+
333
+ async def _run_crawl(self):
334
+ """Executa crawler leve para inventário de rotas."""
335
+ console.print("\n[bold cyan]▶ Web Crawler[/bold cyan]")
336
+ try:
337
+ from moriarty.modules.web_crawler import WebCrawler
338
+
339
+ base_url = self._default_base_url()
340
+ crawler = WebCrawler(
341
+ base_url=base_url,
342
+ max_pages=max(50, self.threads * 10),
343
+ max_depth=2,
344
+ concurrency=max(5, self.threads),
345
+ follow_subdomains=False,
346
+ stealth=self.stealth,
347
+ )
348
+ try:
349
+ pages = await crawler.crawl()
350
+ finally:
351
+ await crawler.close()
352
+
353
+ self.result.crawl_map = {
354
+ url: {
355
+ "status": page.status,
356
+ "title": page.title,
357
+ "forms": page.forms,
358
+ "links": page.links,
359
+ }
360
+ for url, page in pages.items()
361
+ }
362
+
363
+ extracted = self._extract_targets_from_crawl(pages)
364
+ for definition in extracted:
365
+ self._register_web_target(definition["url"], definition["method"], definition["params"])
366
+
367
+ console.print(f" [green]✓[/green] Crawled {len(pages)} pages")
368
+ if extracted:
369
+ console.print(f" [dim]→[/dim] {len(extracted)} endpoints para fuzz")
370
+
371
+ except Exception as exc:
372
+ console.print(" [red]✗[/red] Crawl failed")
373
+ logger.debug("domain.crawl.error", error=str(exc))
374
+
375
+ async def _run_fuzzer(self):
376
+ """Executa directory fuzzing para expandir superfícies."""
377
+ console.print("\n[bold cyan]▶ Directory Fuzzing[/bold cyan]")
378
+ try:
379
+ from moriarty.modules.directory_fuzzer import DirectoryFuzzer
380
+
381
+ fuzzer = DirectoryFuzzer(
382
+ base_url=self._default_base_url(),
383
+ recursive=False,
384
+ max_depth=1,
385
+ threads=max(10, self.threads * 4),
386
+ timeout=min(10.0, max(3.0, self.timeout / 3)),
387
+ stealth_level=self.stealth_level,
388
+ )
389
+ results = await fuzzer.fuzz()
390
+ self.result.fuzz_results = [asdict(item) for item in results]
391
+
392
+ for item in results:
393
+ self._register_web_target(item.url)
394
+
395
+ console.print(f" [green]✓[/green] {len(results)} respostas relevantes")
396
+
397
+ except Exception as exc:
398
+ console.print(" [red]✗[/red] Fuzzing failed")
399
+ logger.debug("domain.fuzzer.error", error=str(exc))
400
+
401
+ async def _run_vuln_scan(self):
402
+ """Executa detecção de vulnerabilidades XSS/SQLi."""
403
+ console.print("\n[bold cyan]▶ Web Vulnerability Scan[/bold cyan]")
404
+
405
+ if not self.web_targets:
406
+ console.print(" [yellow]⚠️ Nenhum endpoint coletado para testar[/yellow]")
407
+ return
408
+
409
+ try:
410
+ from moriarty.modules.vuln_scanner import VulnScanner
411
+
412
+ scanner = VulnScanner(
413
+ targets=self.web_targets,
414
+ threads=max(5, self.threads),
415
+ timeout=min(15.0, float(self.timeout)),
416
+ stealth_level=self.stealth_level,
417
+ )
418
+ findings = await scanner.scan()
419
+ self.result.vulnerabilities = [asdict(f) for f in findings]
420
+ console.print(f" [green]✓[/green] {len(findings)} respostas analisadas")
421
+ except Exception as exc:
422
+ console.print(" [red]✗[/red] Vulnerability scan failed")
423
+ logger.debug("domain.vuln.error", error=str(exc))
424
+
425
+ async def _run_waf_detect(self):
426
+ """Módulo WAF Detection."""
427
+ console.print("\n[bold cyan]▶ WAF Detection[/bold cyan]")
428
+
429
+ try:
430
+ from moriarty.modules.waf_detector import WAFDetector
431
+
432
+ # Suprime logs
433
+ waf_logger = logging.getLogger("moriarty.modules.waf_detector")
434
+ original_level = waf_logger.level
435
+ waf_logger.setLevel(logging.ERROR)
436
+
437
+ detector = WAFDetector(target=f"https://{self.target}")
438
+ waf_info = await detector.detect()
439
+
440
+ waf_logger.setLevel(original_level)
441
+
442
+ if waf_info:
443
+ self.result.waf_info = {
444
+ "name": waf_info.name,
445
+ "confidence": waf_info.confidence,
446
+ "indicators": waf_info.indicators,
447
+ }
448
+ console.print(f" [yellow]⚠️[/yellow] WAF detected: [bold]{waf_info.name}[/bold] ({waf_info.confidence}%)")
449
+ else:
450
+ console.print(f" [green]✓[/green] No WAF detected")
451
+
452
+ except Exception as e:
453
+ console.print(f" [red]✗[/red] WAF detection failed")
454
+
455
+ def _show_summary(self):
456
+ """Mostra resumo final."""
457
+ # Tree de resultados
458
+ tree = Tree(f"\n[bold cyan]📊 Scan Summary[/bold cyan]")
459
+
460
+ if self.result.dns_info:
461
+ dns_node = tree.add("[bold]DNS Records[/bold]")
462
+ a_count = len(self.result.dns_info.get('a_records', []))
463
+ aaaa_count = len(self.result.dns_info.get('aaaa_records', []))
464
+ mx_count = len(self.result.dns_info.get('mx_records', []))
465
+ txt_count = len(self.result.dns_info.get('txt_records', []))
466
+ dns_node.add(f"[green]A:[/green] {a_count} | [green]AAAA:[/green] {aaaa_count} | [green]MX:[/green] {mx_count} | [green]TXT:[/green] {txt_count}")
467
+
468
+ if self.result.subdomains:
469
+ sub_node = tree.add("[bold]Subdomains[/bold]")
470
+ sub_node.add(f"[green]{len(self.result.subdomains)}[/green] discovered")
471
+
472
+ if self.result.wayback_urls:
473
+ way_node = tree.add("[bold]Wayback URLs[/bold]")
474
+ way_node.add(f"[green]{len(self.result.wayback_urls)}[/green] historical URLs")
475
+
476
+ if self.result.open_ports:
477
+ port_node = tree.add("[bold]Open Ports[/bold]")
478
+ port_node.add(
479
+ f"[green]{len(self.result.open_ports)}[/green] ports: {', '.join(map(str, self.result.open_ports))}"
480
+ )
481
+ if self.result.port_details:
482
+ port_node.add(
483
+ "[dim]Top banners:[/dim] "
484
+ + ", ".join(
485
+ f"{entry['port']}:{(entry.get('banner') or '—')[:20]}"
486
+ for entry in self.result.port_details[:5]
487
+ )
488
+ )
489
+
490
+ if self.result.template_findings:
491
+ tpl_node = tree.add("[bold]Vulnerabilities[/bold]")
492
+ tpl_node.add(f"[yellow]{len(self.result.template_findings)}[/yellow] findings")
493
+
494
+ if self.result.waf_info:
495
+ waf_node = tree.add("[bold]WAF[/bold]")
496
+ waf_node.add(f"[yellow]{self.result.waf_info['name']}[/yellow] detected")
497
+
498
+ if self.result.technology_profile:
499
+ tech_node = tree.add("[bold]Technologies[/bold]")
500
+ for detection in self.result.technology_profile.get("detections", [])[:5]:
501
+ tech_node.add(
502
+ f"[green]{detection.get('name')}[/green] ({detection.get('confidence')}%)"
503
+ )
504
+
505
+ if self.result.crawl_map:
506
+ crawl_node = tree.add("[bold]Crawl[/bold]")
507
+ crawl_node.add(f"[green]{len(self.result.crawl_map)}[/green] pages mapped")
508
+
509
+ if self.result.fuzz_results:
510
+ fuzz_node = tree.add("[bold]Fuzzing[/bold]")
511
+ fuzz_node.add(f"[green]{len(self.result.fuzz_results)}[/green] responses")
512
+
513
+ if self.result.vulnerabilities:
514
+ vuln_node = tree.add("[bold]Active Findings[/bold]")
515
+ vuln_node.add(f"[red]{len(self.result.vulnerabilities)}[/red] issues")
516
+
517
+ console.print(tree)
518
+ console.print()
519
+
520
+ def _prepare_modules(self) -> None:
521
+ """Garante ordem e dependências entre módulos."""
522
+ modules = list(dict.fromkeys(self.modules))
523
+
524
+ def ensure_before(target: str, dependency: str) -> None:
525
+ if dependency in modules:
526
+ return
527
+ if target in modules:
528
+ idx = modules.index(target)
529
+ modules.insert(idx, dependency)
530
+ else:
531
+ modules.append(dependency)
532
+
533
+ if "template-scan" in modules:
534
+ ensure_before("template-scan", "crawl")
535
+ ensure_before("template-scan", "fuzzer")
536
+ if "vuln-scan" in modules:
537
+ ensure_before("vuln-scan", "crawl")
538
+
539
+ self.modules = modules
540
+
541
+ async def _ensure_tech_profile(self) -> Optional[Dict[str, Any]]:
542
+ if self.tech_profile is not None:
543
+ return self.tech_profile
544
+
545
+ from moriarty.modules.technology_profiler import profile_domain
546
+
547
+ try:
548
+ profile = await profile_domain(
549
+ self.target,
550
+ stealth=self.stealth,
551
+ timeout=float(self.timeout),
552
+ )
553
+ except Exception as exc: # pragma: no cover - fingerprint opcional
554
+ logger.debug("domain.techprofile.error", error=str(exc))
555
+ profile = None
556
+
557
+ self.tech_profile = profile
558
+ if profile:
559
+ self.result.technology_profile = profile
560
+ return profile
561
+
562
+ def _collect_template_tags(self, profile: Dict[str, Any]) -> Set[str]:
563
+ tags: Set[str] = set()
564
+ for detection in profile.get("detections", []):
565
+ for tag in detection.get("tags", []):
566
+ tags.add(str(tag).lower())
567
+ name = detection.get("name")
568
+ if name:
569
+ tags.add(str(name).lower())
570
+ return tags
571
+
572
+ def _extract_targets_from_crawl(self, pages: Dict[str, Any]) -> List[Dict[str, Any]]:
573
+ targets: List[Dict[str, Any]] = []
574
+ for url, page in pages.items():
575
+ base_url = getattr(page, "url", url)
576
+ for form in getattr(page, "forms", []):
577
+ action = form.get("action") or base_url
578
+ absolute = urljoin(base_url, action)
579
+ method = form.get("method", "GET").upper()
580
+ input_names = [name.strip() for name in form.get("inputs", "").split(",") if name and name.strip()]
581
+ params = {name: "FUZZ" for name in input_names}
582
+ targets.append({"url": absolute, "method": method, "params": params})
583
+
584
+ for link in getattr(page, "links", []):
585
+ parsed = urlparse(link)
586
+ if not parsed.query:
587
+ continue
588
+ params = {
589
+ key: values[0] if isinstance(values, list) and values else ""
590
+ for key, values in parse_qs(parsed.query, keep_blank_values=True).items()
591
+ }
592
+ targets.append({"url": link, "method": "GET", "params": params})
593
+
594
+ return targets
595
+
596
+ def _register_web_target(self, url: str, method: str = "GET", params: Optional[Dict[str, Any]] = None) -> None:
597
+ params = params or {}
598
+ key = (url, method.upper(), tuple(sorted(params.keys())))
599
+ if key in self._seen_targets:
600
+ return
601
+ self._seen_targets.add(key)
602
+ record = {"url": url, "method": method.upper(), "params": params}
603
+ self.web_targets.append(record)
604
+ self.result.web_targets = self.web_targets
605
+
606
+ def _default_base_url(self) -> str:
607
+ return f"https://{self.target}"
608
+
609
+ def export(self, output: str):
610
+ """Exporta resultados."""
611
+ # Converte para dict serializável
612
+ data = asdict(self.result)
613
+
614
+ with open(output, 'w') as f:
615
+ json.dump(data, f, indent=2, default=str)
616
+
617
+ logger.info("domain.scan.export", file=output)
618
+
619
+
620
+ __all__ = ["DomainScanner", "ScanResult"]