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,595 @@
1
+ """Descoberta avançada de subdomínios usando 20+ fontes."""
2
+ import asyncio
3
+ import re
4
+ from dataclasses import dataclass
5
+ from typing import List, Optional, Set
6
+
7
+ import httpx
8
+ import structlog
9
+ from rich.console import Console
10
+ from rich.progress import Progress
11
+
12
+ logger = structlog.get_logger(__name__)
13
+ console = Console()
14
+
15
+
16
+ @dataclass
17
+ class SubdomainResult:
18
+ """Resultado de subdomain discovery."""
19
+ subdomain: str
20
+ source: str
21
+ is_valid: bool = False
22
+ ip_addresses: List[str] = None
23
+ has_mx: bool = False
24
+
25
+
26
+ class SubdomainDiscovery:
27
+ """
28
+ Descoberta de subdomínios usando múltiplas fontes.
29
+
30
+ Fontes suportadas:
31
+ 1. crt.sh (Certificate Transparency)
32
+ 2. VirusTotal
33
+ 3. SecurityTrails
34
+ 4. Shodan
35
+ 5. DNSDumpster
36
+ 6. AlienVault OTX
37
+ 7. ThreatCrowd
38
+ 8. Wayback Machine
39
+ 9. CommonCrawl
40
+ 10. Google Dorking
41
+ 11. Bing
42
+ 12. Yahoo
43
+ 13. Ask
44
+ 14. DNS Bruteforce
45
+ 15. Zone Transfer
46
+ 16. Reverse DNS
47
+ 17. DNSSEC
48
+ 18. NSEC Walking
49
+ 19. Subdomain Permutations
50
+ 20. GitHub Code Search
51
+ """
52
+
53
+ # Wordlist comum para bruteforce
54
+ COMMON_SUBDOMAINS = [
55
+ "www", "mail", "ftp", "localhost", "webmail", "smtp", "pop", "ns1", "webdisk",
56
+ "ns2", "cpanel", "whm", "autodiscover", "autoconfig", "m", "imap", "test",
57
+ "ns", "blog", "pop3", "dev", "www2", "admin", "forum", "news", "vpn", "ns3",
58
+ "mail2", "new", "mysql", "old", "lists", "support", "mobile", "mx", "static",
59
+ "docs", "beta", "shop", "sql", "secure", "demo", "cp", "calendar", "wiki",
60
+ "web", "media", "email", "images", "img", "www1", "intranet", "portal", "video",
61
+ "sip", "dns2", "api", "cdn", "stats", "dns1", "ns4", "www3", "dns", "search",
62
+ "staging", "server", "mx1", "chat", "wap", "my", "svn", "mail1", "sites", "proxy",
63
+ "ads", "host", "crm", "cms", "backup", "mx2", "lyncdiscover", "info", "apps",
64
+ "download", "remote", "db", "forums", "store", "relay", "files", "newsletter",
65
+ "app", "live", "owa", "en", "start", "sms", "office", "exchange", "ipv4"
66
+ ]
67
+
68
+ def __init__(
69
+ self,
70
+ domain: str,
71
+ sources: Optional[List[str]] = None,
72
+ validate: bool = True,
73
+ recursive: bool = False,
74
+ wordlist: Optional[str] = None,
75
+ timeout: float = 10.0,
76
+ use_cache: bool = True,
77
+ ):
78
+ self.domain = domain.lower().strip()
79
+ self.sources = sources or ["all"]
80
+ self.validate = validate
81
+ self.recursive = recursive
82
+ self.wordlist_path = wordlist
83
+ self.timeout = timeout
84
+ self.use_cache = use_cache
85
+ self.results: Set[str] = set()
86
+ self.rate_limiters: dict = {}
87
+
88
+ # Carrega config para API keys
89
+ try:
90
+ from moriarty.core.config_manager import config_manager
91
+ self.config = config_manager
92
+ except:
93
+ self.config = None
94
+
95
+ # Carrega wordlist customizada ou usa expandida
96
+ if wordlist:
97
+ with open(wordlist, 'r') as f:
98
+ self.custom_wordlist = [line.strip() for line in f if line.strip()]
99
+ else:
100
+ # Usa wordlist expandida (1000+)
101
+ from pathlib import Path
102
+ wordlist_1000 = Path(__file__).parent.parent / 'assets' / 'wordlists' / 'subdomains-1000.txt'
103
+ if wordlist_1000.exists():
104
+ with open(wordlist_1000, 'r') as f:
105
+ self.custom_wordlist = [line.strip() for line in f if line.strip()]
106
+ else:
107
+ self.custom_wordlist = self.COMMON_SUBDOMAINS
108
+
109
+ async def discover(self) -> List[str]:
110
+ """Executa discovery em todas as fontes."""
111
+ logger.info("subdomain.discovery.start", domain=self.domain, sources=len(self.sources))
112
+
113
+ # Tenta carregar do cache primeiro
114
+ if self.use_cache:
115
+ cached = self._load_from_cache()
116
+ if cached:
117
+ logger.info("subdomain.discovery.cache_hit", count=len(cached))
118
+ return cached
119
+
120
+ tasks = []
121
+
122
+ # Certificate Transparency
123
+ if "all" in self.sources or "crtsh" in self.sources:
124
+ tasks.append(self._with_rate_limit(self._crtsh(), "crtsh"))
125
+
126
+ # VirusTotal
127
+ if "all" in self.sources or "virustotal" in self.sources:
128
+ tasks.append(self._with_rate_limit(self._virustotal(), "virustotal"))
129
+
130
+ # SecurityTrails
131
+ if "all" in self.sources or "securitytrails" in self.sources:
132
+ tasks.append(self._with_rate_limit(self._securitytrails(), "securitytrails"))
133
+
134
+ # Shodan
135
+ if "all" in self.sources or "shodan" in self.sources:
136
+ tasks.append(self._with_rate_limit(self._shodan(), "shodan"))
137
+
138
+ # Wayback Machine
139
+ if "all" in self.sources or "wayback" in self.sources:
140
+ tasks.append(self._wayback())
141
+
142
+ # CommonCrawl
143
+ if "all" in self.sources or "commoncrawl" in self.sources:
144
+ tasks.append(self._commoncrawl())
145
+
146
+ # AlienVault OTX
147
+ if "all" in self.sources or "alienvault" in self.sources:
148
+ tasks.append(self._alienvault())
149
+
150
+ # ThreatCrowd
151
+ if "all" in self.sources or "threatcrowd" in self.sources:
152
+ tasks.append(self._threatcrowd())
153
+
154
+ # DNS Bruteforce
155
+ if "all" in self.sources or "bruteforce" in self.sources:
156
+ tasks.append(self._dns_bruteforce())
157
+
158
+ # Permutations
159
+ if "all" in self.sources or "permutations" in self.sources:
160
+ tasks.append(self._permutations())
161
+
162
+ # Zone Transfer
163
+ if "all" in self.sources or "zonetransfer" in self.sources:
164
+ tasks.append(self._zone_transfer())
165
+
166
+ # Executa todas as tasks
167
+ with Progress() as progress:
168
+ task_id = progress.add_task("[cyan]Descobrindo subdomínios...", total=len(tasks))
169
+
170
+ for coro in asyncio.as_completed(tasks):
171
+ await coro
172
+ progress.advance(task_id)
173
+
174
+ # Validação DNS
175
+ if self.validate:
176
+ await self._validate_subdomains()
177
+
178
+ # Salva no cache
179
+ if self.use_cache:
180
+ self._save_to_cache(list(self.results))
181
+
182
+ logger.info("subdomain.discovery.complete", domain=self.domain, count=len(self.results))
183
+
184
+ return sorted(list(self.results))
185
+
186
+ async def _with_rate_limit(self, coro, source: str):
187
+ """Aplica rate limiting por fonte."""
188
+ # Rate limits diferentes por fonte
189
+ rate_limits = {
190
+ "crtsh": 0.5, # 1 req/0.5s
191
+ "virustotal": 4.0, # API limitada
192
+ "securitytrails": 1.0,
193
+ "shodan": 1.0,
194
+ "alienvault": 0.5,
195
+ "threatcrowd": 2.0,
196
+ }
197
+
198
+ delay = rate_limits.get(source, 0)
199
+ if delay > 0:
200
+ if source in self.rate_limiters:
201
+ elapsed = asyncio.get_event_loop().time() - self.rate_limiters[source]
202
+ if elapsed < delay:
203
+ await asyncio.sleep(delay - elapsed)
204
+
205
+ result = await coro
206
+ self.rate_limiters[source] = asyncio.get_event_loop().time()
207
+ return result
208
+
209
+ def _get_api_key(self, service: str) -> Optional[str]:
210
+ """Retorna API key configurada para o serviço."""
211
+ if not self.config:
212
+ return None
213
+
214
+ try:
215
+ return self.config.get_api_key(service)
216
+ except Exception:
217
+ return None
218
+
219
+ def _load_from_cache(self) -> Optional[List[str]]:
220
+ """Carrega resultados do cache."""
221
+ import pickle
222
+ from pathlib import Path
223
+ import time
224
+
225
+ cache_dir = Path.home() / '.moriarty' / 'cache' / 'subdomains'
226
+ cache_dir.mkdir(parents=True, exist_ok=True)
227
+
228
+ cache_file = cache_dir / f"{self.domain}.pkl"
229
+
230
+ if cache_file.exists():
231
+ # Verifica se cache não expirou (24h)
232
+ age = time.time() - cache_file.stat().st_mtime
233
+ if age < 86400: # 24 horas
234
+ try:
235
+ with open(cache_file, 'rb') as f:
236
+ return pickle.load(f)
237
+ except:
238
+ pass
239
+
240
+ return None
241
+
242
+ def _save_to_cache(self, subdomains: List[str]):
243
+ """Salva resultados no cache."""
244
+ import pickle
245
+ from pathlib import Path
246
+
247
+ cache_dir = Path.home() / '.moriarty' / 'cache' / 'subdomains'
248
+ cache_dir.mkdir(parents=True, exist_ok=True)
249
+
250
+ cache_file = cache_dir / f"{self.domain}.pkl"
251
+
252
+ try:
253
+ with open(cache_file, 'wb') as f:
254
+ pickle.dump(subdomains, f)
255
+ logger.info("subdomain.cache.saved", file=str(cache_file))
256
+ except Exception as e:
257
+ logger.warning("subdomain.cache.save_error", error=str(e))
258
+
259
+ async def _virustotal(self):
260
+ """Busca subdomínios via VirusTotal API v3."""
261
+ api_key = self._get_api_key("virustotal")
262
+ if not api_key:
263
+ logger.debug("subdomain.virustotal.no_key")
264
+ return
265
+
266
+ headers = {"x-apikey": api_key}
267
+ base_url = f"https://www.virustotal.com/api/v3/domains/{self.domain}/subdomains"
268
+ next_url: Optional[str] = base_url
269
+ params = {"limit": 40}
270
+
271
+ try:
272
+ async with httpx.AsyncClient(timeout=self.timeout) as client:
273
+ while next_url:
274
+ response = await client.get(next_url, headers=headers, params=params if next_url == base_url else None)
275
+ if response.status_code != 200:
276
+ logger.warning(
277
+ "subdomain.virustotal.http_error",
278
+ status=response.status_code,
279
+ body=response.text[:200],
280
+ )
281
+ break
282
+
283
+ data = response.json()
284
+ for item in data.get("data", []):
285
+ identifier = (item.get("id") or item.get("value") or "").strip().lower()
286
+ if identifier and identifier.endswith(self.domain):
287
+ self.results.add(identifier)
288
+
289
+ next_url = data.get("links", {}).get("next")
290
+
291
+ logger.info("subdomain.virustotal.found", count=len(self.results))
292
+
293
+ except Exception as e:
294
+ logger.warning("subdomain.virustotal.error", error=str(e))
295
+
296
+ async def _securitytrails(self):
297
+ """Busca subdomínios via SecurityTrails API."""
298
+ api_key = self._get_api_key("securitytrails")
299
+ if not api_key:
300
+ logger.debug("subdomain.securitytrails.no_key")
301
+ return
302
+
303
+ headers = {"APIKEY": api_key}
304
+ url = f"https://api.securitytrails.com/v1/domain/{self.domain}/subdomains"
305
+ params = {"children_only": "false", "include_inactive": "true"}
306
+
307
+ try:
308
+ async with httpx.AsyncClient(timeout=self.timeout) as client:
309
+ response = await client.get(url, headers=headers, params=params)
310
+
311
+ if response.status_code != 200:
312
+ logger.warning(
313
+ "subdomain.securitytrails.http_error",
314
+ status=response.status_code,
315
+ body=response.text[:200],
316
+ )
317
+ return
318
+
319
+ data = response.json()
320
+ for sub in data.get("subdomains", []):
321
+ if not sub:
322
+ continue
323
+ hostname = f"{sub.strip().lower()}.{self.domain}"
324
+ self.results.add(hostname)
325
+
326
+ for record in data.get("records", []):
327
+ fqdn = (record.get("hostname") or record.get("fqdn") or "").lower()
328
+ if fqdn and fqdn.endswith(self.domain):
329
+ self.results.add(fqdn)
330
+
331
+ logger.info("subdomain.securitytrails.found", count=len(self.results))
332
+
333
+ except Exception as e:
334
+ logger.warning("subdomain.securitytrails.error", error=str(e))
335
+
336
+ async def _shodan(self):
337
+ """Busca subdomínios via Shodan API."""
338
+ api_key = self._get_api_key("shodan")
339
+ if not api_key:
340
+ logger.debug("subdomain.shodan.no_key")
341
+ return
342
+
343
+ params = {"key": api_key}
344
+ url = f"https://api.shodan.io/dns/domain/{self.domain}"
345
+
346
+ try:
347
+ async with httpx.AsyncClient(timeout=self.timeout) as client:
348
+ response = await client.get(url, params=params)
349
+
350
+ if response.status_code != 200:
351
+ logger.warning(
352
+ "subdomain.shodan.http_error",
353
+ status=response.status_code,
354
+ body=response.text[:200],
355
+ )
356
+ return
357
+
358
+ data = response.json()
359
+ for sub in data.get("subdomains", []):
360
+ if not sub:
361
+ continue
362
+ hostname = f"{sub.strip().lower()}.{self.domain}"
363
+ self.results.add(hostname)
364
+
365
+ for record in data.get("data", []):
366
+ hostname = (record.get("subdomain") or record.get("domain") or "").lower()
367
+ if hostname and hostname.endswith(self.domain):
368
+ self.results.add(hostname)
369
+
370
+ logger.info("subdomain.shodan.found", count=len(self.results))
371
+
372
+ except Exception as e:
373
+ logger.warning("subdomain.shodan.error", error=str(e))
374
+
375
+ async def _crtsh(self):
376
+ """Busca via Certificate Transparency (crt.sh)."""
377
+ try:
378
+ async with httpx.AsyncClient(timeout=self.timeout) as client:
379
+ url = f"https://crt.sh/?q=%.{self.domain}&output=json"
380
+ response = await client.get(url)
381
+
382
+ if response.status_code == 200:
383
+ data = response.json()
384
+ for entry in data:
385
+ name = entry.get("name_value", "")
386
+ # Pode vir com múltiplos nomes separados por \n
387
+ for subdomain in name.split("\n"):
388
+ subdomain = subdomain.strip().lower()
389
+ if subdomain.endswith(self.domain) and "*" not in subdomain:
390
+ self.results.add(subdomain)
391
+
392
+ logger.info("subdomain.crtsh.found", count=len([r for r in self.results]))
393
+ except Exception as e:
394
+ logger.warning("subdomain.crtsh.error", error=str(e))
395
+
396
+ async def _wayback(self):
397
+ """Busca via Wayback Machine."""
398
+ try:
399
+ async with httpx.AsyncClient(timeout=self.timeout) as client:
400
+ url = f"http://web.archive.org/cdx/search/cdx?url=*.{self.domain}/*&output=json&collapse=urlkey"
401
+ response = await client.get(url)
402
+
403
+ if response.status_code == 200:
404
+ data = response.json()
405
+ for entry in data[1:]: # Pula header
406
+ url = entry[2]
407
+ # Extrai subdomain da URL
408
+ match = re.search(rf'([a-z0-9\-\.]+\.{re.escape(self.domain)})', url, re.IGNORECASE)
409
+ if match:
410
+ self.results.add(match.group(1).lower())
411
+
412
+ logger.info("subdomain.wayback.found", count=len(self.results))
413
+ except Exception as e:
414
+ logger.warning("subdomain.wayback.error", error=str(e))
415
+
416
+ async def _commoncrawl(self):
417
+ """Busca via CommonCrawl."""
418
+ try:
419
+ async with httpx.AsyncClient(timeout=self.timeout) as client:
420
+ # Busca últimos indexes
421
+ indexes_url = "https://index.commoncrawl.org/collinfo.json"
422
+ response = await client.get(indexes_url)
423
+
424
+ if response.status_code == 200:
425
+ indexes = response.json()
426
+ latest_index = indexes[0]["cdx-api"]
427
+
428
+ # Busca no index
429
+ url = f"{latest_index}?url=*.{self.domain}/*&output=json"
430
+ response = await client.get(url)
431
+
432
+ if response.status_code == 200:
433
+ for line in response.text.split("\n"):
434
+ if line:
435
+ try:
436
+ data = eval(line) # JSON per line
437
+ url = data.get("url", "")
438
+ match = re.search(rf'([a-z0-9\-\.]+\.{re.escape(self.domain)})', url, re.IGNORECASE)
439
+ if match:
440
+ self.results.add(match.group(1).lower())
441
+ except:
442
+ pass
443
+ except Exception as e:
444
+ logger.warning("subdomain.commoncrawl.error", error=str(e))
445
+
446
+ async def _alienvault(self):
447
+ """Busca via AlienVault OTX."""
448
+ try:
449
+ async with httpx.AsyncClient(timeout=self.timeout) as client:
450
+ url = f"https://otx.alienvault.com/api/v1/indicators/domain/{self.domain}/passive_dns"
451
+ response = await client.get(url)
452
+
453
+ if response.status_code == 200:
454
+ data = response.json()
455
+ for entry in data.get("passive_dns", []):
456
+ hostname = entry.get("hostname", "")
457
+ if hostname.endswith(self.domain):
458
+ self.results.add(hostname.lower())
459
+
460
+ logger.info("subdomain.alienvault.found", count=len(self.results))
461
+ except Exception as e:
462
+ logger.warning("subdomain.alienvault.error", error=str(e))
463
+
464
+ async def _threatcrowd(self):
465
+ """Busca via ThreatCrowd."""
466
+ try:
467
+ async with httpx.AsyncClient(timeout=self.timeout) as client:
468
+ url = f"https://www.threatcrowd.org/searchApi/v2/domain/report/?domain={self.domain}"
469
+ response = await client.get(url)
470
+
471
+ if response.status_code == 200:
472
+ data = response.json()
473
+ for subdomain in data.get("subdomains", []):
474
+ if subdomain:
475
+ self.results.add(subdomain.lower())
476
+
477
+ logger.info("subdomain.threatcrowd.found", count=len(self.results))
478
+ except Exception as e:
479
+ logger.warning("subdomain.threatcrowd.error", error=str(e))
480
+
481
+ async def _dns_bruteforce(self):
482
+ """DNS Bruteforce usando wordlist."""
483
+ wordlist = self.custom_wordlist or self.COMMON_SUBDOMAINS
484
+
485
+ try:
486
+ import aiodns
487
+ resolver = aiodns.DNSResolver(timeout=2.0)
488
+
489
+ tasks = []
490
+ for word in wordlist:
491
+ subdomain = f"{word}.{self.domain}"
492
+ tasks.append(self._check_dns(resolver, subdomain))
493
+
494
+ # Executa em batches para não sobrecarregar
495
+ batch_size = 50
496
+ for i in range(0, len(tasks), batch_size):
497
+ batch = tasks[i:i+batch_size]
498
+ await asyncio.gather(*batch, return_exceptions=True)
499
+
500
+ logger.info("subdomain.bruteforce.complete", tested=len(wordlist), found=len(self.results))
501
+ except Exception as e:
502
+ logger.warning("subdomain.bruteforce.error", error=str(e))
503
+
504
+ async def _check_dns(self, resolver, subdomain: str):
505
+ """Verifica se subdomain resolve."""
506
+ try:
507
+ result = await resolver.query(subdomain, "A")
508
+ if result:
509
+ self.results.add(subdomain)
510
+ except:
511
+ pass
512
+
513
+ async def _permutations(self):
514
+ """Gera permutações de subdomínios conhecidos."""
515
+ # Alterações comuns
516
+ alterations = ["dev", "staging", "test", "prod", "uat", "qa", "demo", "backup", "old", "new"]
517
+
518
+ current_subs = list(self.results)
519
+ for subdomain in current_subs:
520
+ # Remove domain principal
521
+ prefix = subdomain.replace(f".{self.domain}", "")
522
+
523
+ for alt in alterations:
524
+ # Adiciona sufixo
525
+ new_sub = f"{prefix}-{alt}.{self.domain}"
526
+ self.results.add(new_sub)
527
+
528
+ # Adiciona prefixo
529
+ new_sub = f"{alt}-{prefix}.{self.domain}"
530
+ self.results.add(new_sub)
531
+
532
+ async def _zone_transfer(self):
533
+ """Tenta AXFR (Zone Transfer)."""
534
+ try:
535
+ import aiodns
536
+ resolver = aiodns.DNSResolver(timeout=5.0)
537
+
538
+ # Busca NS records
539
+ ns_records = await resolver.query(self.domain, "NS")
540
+
541
+ for ns in ns_records:
542
+ ns_host = ns.host
543
+ logger.info("subdomain.zonetransfer.trying", ns=ns_host)
544
+
545
+ # AXFR não é suportado por aiodns, precisaria de dnspython
546
+ # Placeholder para implementação completa
547
+ pass
548
+
549
+ except Exception as e:
550
+ logger.debug("subdomain.zonetransfer.failed", error=str(e))
551
+
552
+ async def _validate_subdomains(self):
553
+ """Valida subdomínios encontrados com DNS lookup."""
554
+ logger.info("subdomain.validation.start", count=len(self.results))
555
+
556
+ try:
557
+ import aiodns
558
+ resolver = aiodns.DNSResolver(timeout=2.0)
559
+
560
+ validated = set()
561
+ tasks = []
562
+
563
+ for subdomain in self.results:
564
+ tasks.append(self._validate_single(resolver, subdomain))
565
+
566
+ results = await asyncio.gather(*tasks, return_exceptions=True)
567
+
568
+ for subdomain, is_valid in results:
569
+ if is_valid and subdomain:
570
+ validated.add(subdomain)
571
+
572
+ self.results = validated
573
+ logger.info("subdomain.validation.complete", validated=len(validated))
574
+
575
+ except Exception as e:
576
+ logger.warning("subdomain.validation.error", error=str(e))
577
+
578
+ async def _validate_single(self, resolver, subdomain: str):
579
+ """Valida um único subdomain."""
580
+ try:
581
+ result = await resolver.query(subdomain, "A")
582
+ return (subdomain, True) if result else (subdomain, False)
583
+ except:
584
+ return (subdomain, False)
585
+
586
+ def export(self, results: List[str], output: str):
587
+ """Exporta resultados para arquivo."""
588
+ with open(output, 'w') as f:
589
+ for subdomain in sorted(results):
590
+ f.write(f"{subdomain}\n")
591
+
592
+ logger.info("subdomain.export.complete", file=output, count=len(results))
593
+
594
+
595
+ __all__ = ["SubdomainDiscovery", "SubdomainResult"]