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
moriarty/cli/email.py ADDED
@@ -0,0 +1,383 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Any, Dict, Optional
4
+
5
+ import typer
6
+ from rich import box
7
+ from rich.panel import Panel
8
+ from rich.table import Table
9
+
10
+ from .async_utils import run_async
11
+ from .output import console, emit_json, emit_yaml, ensure_state
12
+ from .state import GlobalOptions
13
+ from ..modules.email_check import EmailCheckOptions, EmailCheckResult, EmailCheckService
14
+ from ..modules.email_investigate import EmailInvestigator, EmailInvestigationResult
15
+
16
+ app = typer.Typer(add_completion=False, help="Email reconnaissance primitives.")
17
+
18
+
19
+ @app.command("check")
20
+ def check( # noqa: PLR0913 - CLI interface requires multiple parameters
21
+ ctx: typer.Context,
22
+ email: str = typer.Option(..., "--email", "-e", help="Target email address."),
23
+ dns: bool = typer.Option(True, "--dns/--no-dns", help="Run DNS lookups (MX/SPF/DMARC)."),
24
+ smtp: bool = typer.Option(False, "--smtp/--no-smtp", help="Attempt SMTP RCPT TO verification."),
25
+ from_address: str = typer.Option("postmaster@localhost", "--from", help="Envelope MAIL FROM address."),
26
+ retries: int = typer.Option(1, min=0, help="SMTP retry attempts after the first try."),
27
+ wait: float = typer.Option(1.0, min=0.0, help="Seconds to wait between SMTP retries."),
28
+ json_output: Optional[str] = typer.Option(None, "--json", help="Write JSON output to path or '-' for stdout."),
29
+ ) -> None:
30
+ """Validate an email address using DNS and SMTP heuristics."""
31
+ state = ensure_state(ctx)
32
+
33
+ options = EmailCheckOptions(
34
+ check_dns=dns,
35
+ check_smtp=smtp,
36
+ from_address=from_address,
37
+ retries=retries,
38
+ wait=wait,
39
+ )
40
+
41
+ service = EmailCheckService(email=email, options=options, timeout=state.options.timeout)
42
+
43
+ try:
44
+ result = run_async(service.run())
45
+ except ValueError as exc:
46
+ raise typer.BadParameter(str(exc)) from exc
47
+
48
+ if state.options.professional_mode:
49
+ _render_professional_banner(state.options)
50
+
51
+ output_format = ("json" if json_output else state.options.format).lower()
52
+
53
+ if output_format == "json":
54
+ payload = _result_to_dict(result)
55
+ emit_json(payload, json_output, state.options.output)
56
+ elif output_format == "yaml":
57
+ payload = _result_to_dict(result)
58
+ emit_yaml(payload, json_output, state.options.output)
59
+ else:
60
+ _render_table(result, state.options)
61
+
62
+ for warning in result.warnings:
63
+ console.print(f"[warning]⚠️ {warning}")
64
+
65
+
66
+ def _render_professional_banner(options: GlobalOptions) -> None:
67
+ notice = (
68
+ "⚠️ Professional Mode\n"
69
+ "Consent required. Ensure investigative actions comply with policy."
70
+ )
71
+ console.print(
72
+ Panel(
73
+ notice,
74
+ title="MORIARTY",
75
+ border_style="yellow",
76
+ )
77
+ )
78
+
79
+
80
+ def _render_table(result: EmailCheckResult, options: GlobalOptions) -> None:
81
+ table = Table(title=f"Email Check · {result.normalized_email}", box=box.SIMPLE_HEAVY)
82
+ table.add_column("Attribute", style="cyan", no_wrap=True)
83
+ table.add_column("Value", style="white")
84
+
85
+ table.add_row("Input", result.input_email)
86
+ table.add_row("Normalized", result.normalized_email)
87
+ table.add_row("Local Part", result.local_part)
88
+ table.add_row("Domain", result.domain)
89
+
90
+ if result.dns:
91
+ mx_summary = ", ".join(f"{mx.exchange} (prio {mx.priority})" for mx in result.dns.mx) or "—"
92
+ spf_summary = "; ".join(result.dns.spf) or "—"
93
+ dmarc_summary = "; ".join(result.dns.dmarc) or "—"
94
+ table.add_row("A", ", ".join(result.dns.a) or "—")
95
+ table.add_row("AAAA", ", ".join(result.dns.aaaa) or "—")
96
+ table.add_row("MX", mx_summary)
97
+ table.add_row("SPF", spf_summary)
98
+ table.add_row("DMARC", dmarc_summary)
99
+
100
+ if result.smtp:
101
+ status = "deliverable" if result.smtp.deliverable else "undeliverable"
102
+ attempt_lines = []
103
+ for attempt in result.smtp.attempts:
104
+ if attempt.result_code is not None:
105
+ message = attempt.result_message or ""
106
+ attempt_lines.append(f"{attempt.host}: {attempt.result_code} {message}".strip())
107
+ elif attempt.error:
108
+ attempt_lines.append(f"{attempt.host}: error {attempt.error}")
109
+ table.add_row("SMTP", f"{status}\n" + "\n".join(attempt_lines) if attempt_lines else status)
110
+
111
+ console.print(table)
112
+
113
+
114
+ def _result_to_dict(result: EmailCheckResult) -> Dict[str, Any]:
115
+ return {
116
+ "input_email": result.input_email,
117
+ "normalized_email": result.normalized_email,
118
+ "local_part": result.local_part,
119
+ "domain": result.domain,
120
+ "dns": _dns_to_dict(result.dns) if result.dns else None,
121
+ "smtp": _smtp_to_dict(result.smtp) if result.smtp else None,
122
+ "warnings": result.warnings,
123
+ }
124
+
125
+
126
+ def _dns_to_dict(dns_result: Optional[Any]) -> Optional[Dict[str, Any]]:
127
+ if dns_result is None:
128
+ return None
129
+ return {
130
+ "a": dns_result.a,
131
+ "aaaa": dns_result.aaaa,
132
+ "mx": [
133
+ {
134
+ "priority": record.priority,
135
+ "exchange": record.exchange,
136
+ }
137
+ for record in dns_result.mx
138
+ ],
139
+ "spf": dns_result.spf,
140
+ "dmarc": dns_result.dmarc,
141
+ "txt": [record.text for record in dns_result.txt],
142
+ }
143
+
144
+
145
+ def _smtp_to_dict(smtp_result: Optional[Any]) -> Optional[Dict[str, Any]]:
146
+ if smtp_result is None:
147
+ return None
148
+ return {
149
+ "deliverable": smtp_result.deliverable,
150
+ "attempts": [
151
+ {
152
+ "host": attempt.host,
153
+ "port": attempt.port,
154
+ "code": attempt.result_code,
155
+ "message": attempt.result_message,
156
+ "success": attempt.success,
157
+ "error": attempt.error,
158
+ }
159
+ for attempt in smtp_result.attempts
160
+ ],
161
+ }
162
+
163
+
164
+ @app.command("investigate")
165
+ def investigate(
166
+ ctx: typer.Context,
167
+ email: str = typer.Option(..., "--email", "-e", help="Email a investigar."),
168
+ json_output: Optional[str] = typer.Option(None, "--json", help="Escreve saída JSON no caminho ou '-'"),
169
+ include_breaches: bool = typer.Option(True, "--breaches/--no-breaches", help="Verificar data breaches."),
170
+ ) -> None:
171
+ """Investiga email em múltiplas fontes (Gravatar, social, breaches)."""
172
+ import logging
173
+ from rich.tree import Tree
174
+
175
+ state = ensure_state(ctx)
176
+
177
+ # Suprime logs INFO/WARNING de bibliotecas externas - apenas durante investigate
178
+ if not state.options.verbose:
179
+ logging.getLogger("httpx").setLevel(logging.ERROR)
180
+ logging.getLogger("httpcore").setLevel(logging.ERROR)
181
+ logging.getLogger("moriarty.modules.email_investigate").setLevel(logging.ERROR)
182
+ logging.getLogger("moriarty.modules.template_executor").setLevel(logging.ERROR)
183
+
184
+ if state.options.professional_mode:
185
+ notice = (
186
+ "⚠️ Investigação Profunda\n\n"
187
+ "Esta ferramenta consulta fontes públicas. Respeite a privacidade e "
188
+ "use apenas para fins legítimos de segurança e investigação autorizada."
189
+ )
190
+ console.print(
191
+ Panel(
192
+ notice,
193
+ title="MORIARTY · Professional Mode",
194
+ border_style="yellow",
195
+ padding=(1, 2),
196
+ )
197
+ )
198
+ console.print()
199
+
200
+ console.print(f"[info]🔎 Investigando: {email}")
201
+ console.print()
202
+
203
+ with console.status("[cyan]Buscando em múltiplas fontes...", spinner="dots"):
204
+ investigator = EmailInvestigator(timeout=state.options.timeout)
205
+ result = run_async(investigator.investigate(email))
206
+
207
+ # Saída
208
+ output_format = ("json" if json_output else state.options.format).lower()
209
+
210
+ if output_format == "json":
211
+ payload = _investigation_to_dict(result)
212
+ emit_json(payload, json_output, state.options.output)
213
+ elif output_format == "yaml":
214
+ payload = _investigation_to_dict(result)
215
+ emit_yaml(payload, json_output, state.options.output)
216
+ else:
217
+ _render_investigation(result, state.options.redact)
218
+
219
+ if not include_breaches:
220
+ console.print("\n[dim]Verificação de breaches desabilitada (use --breaches para habilitar)")
221
+
222
+
223
+ def _render_investigation(result: EmailInvestigationResult, redact: bool) -> None:
224
+ """Renderiza resultado da investigação."""
225
+ from rich.tree import Tree
226
+
227
+ # Painel principal
228
+ email_display = _redact_email(result.email) if redact else result.email
229
+
230
+ tree = Tree(f"[bold cyan]📧 {email_display}[/bold cyan]")
231
+
232
+ # Informações básicas
233
+ basic_node = tree.add("[bold]Informações Básicas[/bold]")
234
+ basic_node.add(f"Local Part: {result.local_part}")
235
+ basic_node.add(f"Domínio: {result.domain}")
236
+ basic_node.add(f"Normalizado: {result.normalized_email}")
237
+
238
+ # Gravatar
239
+ gravatar_node = tree.add("[bold]Gravatar[/bold]")
240
+ if result.gravatar_profile:
241
+ gravatar_node.add("✓ Perfil encontrado")
242
+ gravatar_node.add(f"Hash: {result.gravatar_hash[:16]}...")
243
+ if result.gravatar_avatar:
244
+ gravatar_node.add(f"Avatar: {result.gravatar_avatar}")
245
+
246
+ # Dados do perfil
247
+ profile = result.gravatar_profile
248
+ if profile.get("displayName"):
249
+ gravatar_node.add(f"Nome: {profile['displayName']}")
250
+ if profile.get("profileUrl"):
251
+ gravatar_node.add(f"URL: {profile['profileUrl']}")
252
+ else:
253
+ gravatar_node.add("[dim]✗ Nenhum perfil Gravatar encontrado[/dim]")
254
+
255
+ # Perfis sociais
256
+ social_node = tree.add(f"[bold]Perfis Sociais ({len(result.social_profiles)})[/bold]")
257
+ if result.social_profiles:
258
+ for profile in result.social_profiles:
259
+ platform_node = social_node.add(f"[green]✓[/green] [cyan]{profile.platform.title()}[/cyan]")
260
+ platform_node.add(f"🔗 {profile.url}")
261
+ if profile.display_name:
262
+ platform_node.add(f"👤 {profile.display_name}")
263
+ if profile.bio:
264
+ bio_preview = profile.bio[:80] + "..." if len(profile.bio) > 80 else profile.bio
265
+ platform_node.add(f"📝 {bio_preview}")
266
+ if profile.metadata.get("location"):
267
+ platform_node.add(f"📍 {profile.metadata['location']}")
268
+ if profile.metadata.get("website"):
269
+ platform_node.add(f"🌐 {profile.metadata['website']}")
270
+ platform_node.add(f"💯 Confidence: {profile.confidence:.0%}")
271
+ else:
272
+ social_node.add("[dim]✗ Nenhum perfil encontrado com o username '{local_part}'[/dim]".format(local_part=result.local_part))
273
+
274
+ # Usernames extraídos
275
+ if result.usernames:
276
+ usernames_node = tree.add(f"[bold]Usernames Encontrados ({len(result.usernames)})[/bold]")
277
+ for username in result.usernames:
278
+ usernames_node.add(f"• {username}")
279
+
280
+ # Websites
281
+ if result.websites:
282
+ websites_node = tree.add(f"[bold]Websites Vinculados ({len(result.websites)})[/bold]")
283
+ for website in result.websites:
284
+ websites_node.add(f"🔗 {website}")
285
+
286
+ # Data Breaches
287
+ breach_node = tree.add("[bold]Data Breaches[/bold]")
288
+ if result.breached:
289
+ breach_node.add(f"[red]⚠️ Email encontrado em {result.breach_count} breach(es)[/red]")
290
+ for breach in result.breaches:
291
+ breach_node.add(f"• {breach.get('source', 'Unknown')}: {breach.get('occurrences', 0)} ocorrências")
292
+ else:
293
+ breach_node.add("[green]✓ Nenhum breach conhecido[/green]")
294
+
295
+ console.print(tree)
296
+ console.print()
297
+
298
+ # Estatísticas
299
+ stats_table = Table(title="Resumo da Investigação", box=box.SIMPLE)
300
+ stats_table.add_column("Métrica", style="cyan")
301
+ stats_table.add_column("Valor", style="white")
302
+
303
+ stats_table.add_row("Email", email_display)
304
+ stats_table.add_row("Plataformas encontradas", str(result.total_platforms_found))
305
+ stats_table.add_row("Usernames únicos", str(len(result.usernames)))
306
+ stats_table.add_row("Websites vinculados", str(len(result.websites)))
307
+ stats_table.add_row("Gravatar", "✓ Sim" if result.gravatar_profile else "✗ Não")
308
+ stats_table.add_row("Breaches", f"{'✗ Sim (' + str(result.breach_count) + ')' if result.breached else '✓ Não'}")
309
+ stats_table.add_row("Timestamp", result.search_timestamp)
310
+
311
+ console.print(stats_table)
312
+
313
+ # Recomendações
314
+ if result.breached:
315
+ console.print()
316
+ console.print(
317
+ Panel(
318
+ "[red]⚠️ Este email foi encontrado em data breaches.\n"
319
+ "Recomendações:\n"
320
+ "• Alterar senhas imediatamente\n"
321
+ "• Habilitar autenticação de dois fatores\n"
322
+ "• Verificar atividades suspeitas nas contas[/red]",
323
+ title="Alerta de Segurança",
324
+ border_style="red",
325
+ )
326
+ )
327
+
328
+
329
+ def _redact_email(email: str) -> str:
330
+ """Redige email para exibição."""
331
+ local, domain = email.split("@", 1)
332
+ if len(local) <= 2:
333
+ redacted_local = local[0] + "*"
334
+ else:
335
+ redacted_local = local[0] + "*" * (len(local) - 2) + local[-1]
336
+ return f"{redacted_local}@{domain}"
337
+
338
+
339
+ def _investigation_to_dict(result: EmailInvestigationResult) -> Dict[str, Any]:
340
+ """Converte resultado para dict."""
341
+ return {
342
+ "email": result.email,
343
+ "normalized_email": result.normalized_email,
344
+ "domain": result.domain,
345
+ "local_part": result.local_part,
346
+ "gravatar": {
347
+ "hash": result.gravatar_hash,
348
+ "profile": result.gravatar_profile,
349
+ "avatar_url": result.gravatar_avatar,
350
+ },
351
+ "social_profiles": [
352
+ {
353
+ "platform": p.platform,
354
+ "url": p.url,
355
+ "username": p.username,
356
+ "user_id": p.user_id,
357
+ "display_name": p.display_name,
358
+ "avatar_url": p.avatar_url,
359
+ "bio": p.bio,
360
+ "verified": p.verified,
361
+ "confidence": p.confidence,
362
+ "metadata": p.metadata,
363
+ }
364
+ for p in result.social_profiles
365
+ ],
366
+ "breaches": {
367
+ "breached": result.breached,
368
+ "count": result.breach_count,
369
+ "details": result.breaches,
370
+ },
371
+ "extracted_data": {
372
+ "usernames": result.usernames,
373
+ "websites": result.websites,
374
+ "phone_numbers": result.phone_numbers,
375
+ },
376
+ "metadata": {
377
+ "total_platforms_found": result.total_platforms_found,
378
+ "search_timestamp": result.search_timestamp,
379
+ },
380
+ }
381
+
382
+
383
+ __all__ = ["app"]
@@ -0,0 +1,224 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Any, Dict, List, Optional
4
+
5
+ import typer
6
+ from rich import box
7
+ from rich.panel import Panel
8
+ from rich.table import Table
9
+ from rich.tree import Tree
10
+
11
+ from .async_utils import run_async
12
+ from .output import console, emit_json, emit_yaml, ensure_state
13
+ from ..modules.email_investigate import EmailInvestigator, SocialProfile
14
+
15
+ app = typer.Typer(add_completion=False, help="Investigação profunda de emails.")
16
+
17
+
18
+ @app.command("investigate")
19
+ def investigate(
20
+ ctx: typer.Context,
21
+ email: str = typer.Option(..., "--email", "-e", help="Email a investigar."),
22
+ json_output: Optional[str] = typer.Option(None, "--json", help="Escreve saída JSON no caminho ou '-'"),
23
+ include_breaches: bool = typer.Option(True, "--breaches/--no-breaches", help="Verificar data breaches."),
24
+ ) -> None:
25
+ """Investiga email em múltiplas fontes (Gravatar, social, breaches)."""
26
+ state = ensure_state(ctx)
27
+
28
+ if state.options.professional_mode:
29
+ _render_professional_banner()
30
+
31
+ console.print(f"[info]🔎 Investigando: {email}")
32
+ console.print()
33
+
34
+ investigator = EmailInvestigator(timeout=state.options.timeout)
35
+ result = run_async(investigator.investigate(email))
36
+
37
+ # Saída
38
+ output_format = ("json" if json_output else state.options.format).lower()
39
+
40
+ if output_format == "json":
41
+ payload = _result_to_dict(result)
42
+ emit_json(payload, json_output, state.options.output)
43
+ elif output_format == "yaml":
44
+ payload = _result_to_dict(result)
45
+ emit_yaml(payload, json_output, state.options.output)
46
+ else:
47
+ _render_investigation(result, state.options.redact)
48
+
49
+ if not include_breaches:
50
+ console.print("\n[dim]Verificação de breaches desabilitada (use --breaches para habilitar)")
51
+
52
+
53
+ def _render_professional_banner() -> None:
54
+ notice = (
55
+ "⚠️ Investigação Profunda\n\n"
56
+ "Esta ferramenta consulta fontes públicas. Respeite a privacidade e "
57
+ "use apenas para fins legítimos de segurança e investigação autorizada."
58
+ )
59
+ console.print(
60
+ Panel(
61
+ notice,
62
+ title="MORIARTY · Professional Mode",
63
+ border_style="yellow",
64
+ padding=(1, 2),
65
+ )
66
+ )
67
+ console.print()
68
+
69
+
70
+ def _render_investigation(result: Any, redact: bool) -> None:
71
+ """Renderiza resultado da investigação."""
72
+
73
+ # Painel principal
74
+ email_display = _redact_email(result.email) if redact else result.email
75
+
76
+ tree = Tree(f"[bold cyan]📧 {email_display}[/bold cyan]")
77
+
78
+ # Informações básicas
79
+ basic_node = tree.add("[bold]Informações Básicas[/bold]")
80
+ basic_node.add(f"Local Part: {result.local_part}")
81
+ basic_node.add(f"Domínio: {result.domain}")
82
+ basic_node.add(f"Normalizado: {result.normalized_email}")
83
+
84
+ # Gravatar
85
+ gravatar_node = tree.add("[bold]Gravatar[/bold]")
86
+ if result.gravatar_profile:
87
+ gravatar_node.add(f"✓ Perfil encontrado")
88
+ gravatar_node.add(f"Hash: {result.gravatar_hash[:16]}...")
89
+ if result.gravatar_avatar:
90
+ gravatar_node.add(f"Avatar: {result.gravatar_avatar}")
91
+
92
+ # Dados do perfil
93
+ profile = result.gravatar_profile
94
+ if profile.get("displayName"):
95
+ gravatar_node.add(f"Nome: {profile['displayName']}")
96
+ if profile.get("profileUrl"):
97
+ gravatar_node.add(f"URL: {profile['profileUrl']}")
98
+ else:
99
+ gravatar_node.add("[dim]✗ Nenhum perfil Gravatar encontrado[/dim]")
100
+
101
+ # Perfis sociais
102
+ social_node = tree.add(f"[bold]Perfis Sociais ({len(result.social_profiles)})[/bold]")
103
+ if result.social_profiles:
104
+ for profile in result.social_profiles:
105
+ platform_node = social_node.add(f"[cyan]{profile.platform}[/cyan]")
106
+ platform_node.add(f"URL: {profile.url}")
107
+ if profile.username:
108
+ platform_node.add(f"Username: {profile.username}")
109
+ if profile.display_name:
110
+ platform_node.add(f"Nome: {profile.display_name}")
111
+ platform_node.add(f"Confidence: {profile.confidence:.2f}")
112
+ else:
113
+ social_node.add("[dim]Nenhum perfil encontrado (use local_part como username)[/dim]")
114
+
115
+ # Usernames extraídos
116
+ if result.usernames:
117
+ usernames_node = tree.add(f"[bold]Usernames Encontrados ({len(result.usernames)})[/bold]")
118
+ for username in result.usernames:
119
+ usernames_node.add(f"• {username}")
120
+
121
+ # Websites
122
+ if result.websites:
123
+ websites_node = tree.add(f"[bold]Websites Vinculados ({len(result.websites)})[/bold]")
124
+ for website in result.websites:
125
+ websites_node.add(f"🔗 {website}")
126
+
127
+ # Data Breaches
128
+ breach_node = tree.add("[bold]Data Breaches[/bold]")
129
+ if result.breached:
130
+ breach_node.add(f"[red]⚠️ Email encontrado em {result.breach_count} breach(es)[/red]")
131
+ for breach in result.breaches:
132
+ breach_node.add(f"• {breach.get('source', 'Unknown')}: {breach.get('occurrences', 0)} ocorrências")
133
+ else:
134
+ breach_node.add("[green]✓ Nenhum breach conhecido[/green]")
135
+
136
+ console.print(tree)
137
+ console.print()
138
+
139
+ # Estatísticas
140
+ stats_table = Table(title="Resumo da Investigação", box=box.SIMPLE)
141
+ stats_table.add_column("Métrica", style="cyan")
142
+ stats_table.add_column("Valor", style="white")
143
+
144
+ stats_table.add_row("Email", email_display)
145
+ stats_table.add_row("Plataformas encontradas", str(result.total_platforms_found))
146
+ stats_table.add_row("Usernames únicos", str(len(result.usernames)))
147
+ stats_table.add_row("Websites vinculados", str(len(result.websites)))
148
+ stats_table.add_row("Gravatar", "✓ Sim" if result.gravatar_profile else "✗ Não")
149
+ stats_table.add_row("Breaches", f"{'✗ Sim (' + str(result.breach_count) + ')' if result.breached else '✓ Não'}")
150
+ stats_table.add_row("Timestamp", result.search_timestamp)
151
+
152
+ console.print(stats_table)
153
+
154
+ # Recomendações
155
+ if result.breached:
156
+ console.print()
157
+ console.print(
158
+ Panel(
159
+ "[red]⚠️ Este email foi encontrado em data breaches.\n"
160
+ "Recomendações:\n"
161
+ "• Alterar senhas imediatamente\n"
162
+ "• Habilitar autenticação de dois fatores\n"
163
+ "• Verificar atividades suspeitas nas contas[/red]",
164
+ title="Alerta de Segurança",
165
+ border_style="red",
166
+ )
167
+ )
168
+
169
+
170
+ def _redact_email(email: str) -> str:
171
+ """Redige email para exibição."""
172
+ local, domain = email.split("@", 1)
173
+ if len(local) <= 2:
174
+ redacted_local = local[0] + "*"
175
+ else:
176
+ redacted_local = local[0] + "*" * (len(local) - 2) + local[-1]
177
+ return f"{redacted_local}@{domain}"
178
+
179
+
180
+ def _result_to_dict(result: Any) -> Dict[str, Any]:
181
+ """Converte resultado para dict."""
182
+ return {
183
+ "email": result.email,
184
+ "normalized_email": result.normalized_email,
185
+ "domain": result.domain,
186
+ "local_part": result.local_part,
187
+ "gravatar": {
188
+ "hash": result.gravatar_hash,
189
+ "profile": result.gravatar_profile,
190
+ "avatar_url": result.gravatar_avatar,
191
+ },
192
+ "social_profiles": [
193
+ {
194
+ "platform": p.platform,
195
+ "url": p.url,
196
+ "username": p.username,
197
+ "user_id": p.user_id,
198
+ "display_name": p.display_name,
199
+ "avatar_url": p.avatar_url,
200
+ "bio": p.bio,
201
+ "verified": p.verified,
202
+ "confidence": p.confidence,
203
+ "metadata": p.metadata,
204
+ }
205
+ for p in result.social_profiles
206
+ ],
207
+ "breaches": {
208
+ "breached": result.breached,
209
+ "count": result.breach_count,
210
+ "details": result.breaches,
211
+ },
212
+ "extracted_data": {
213
+ "usernames": result.usernames,
214
+ "websites": result.websites,
215
+ "phone_numbers": result.phone_numbers,
216
+ },
217
+ "metadata": {
218
+ "total_platforms_found": result.total_platforms_found,
219
+ "search_timestamp": result.search_timestamp,
220
+ },
221
+ }
222
+
223
+
224
+ __all__ = ["app"]