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,28 @@
1
+ from __future__ import annotations
2
+
3
+ from enum import Enum
4
+
5
+
6
+ class EntityKind(str, Enum):
7
+ EMAIL = "email"
8
+ USERNAME = "username"
9
+ PERSON = "person"
10
+ DOMAIN = "domain"
11
+ IP_ADDRESS = "ip"
12
+ ORGANIZATION = "organization"
13
+
14
+
15
+ class EvidenceKind(str, Enum):
16
+ NETWORK = "network"
17
+ WEB = "web"
18
+ FILE = "file"
19
+ MANUAL = "manual"
20
+
21
+
22
+ class ConfidenceBand(str, Enum):
23
+ HIGH = "high"
24
+ MEDIUM = "medium"
25
+ INDICATIVE = "indicative"
26
+
27
+
28
+ __all__ = ["EntityKind", "EvidenceKind", "ConfidenceBand"]
File without changes
@@ -0,0 +1,184 @@
1
+ """Hashing perceptual de avatares para matching."""
2
+ import hashlib
3
+ from dataclasses import dataclass
4
+ from io import BytesIO
5
+ from typing import Optional
6
+
7
+ import httpx
8
+ import structlog
9
+ from PIL import Image
10
+
11
+ logger = structlog.get_logger(__name__)
12
+
13
+
14
+ @dataclass
15
+ class AvatarHash:
16
+ """Hash perceptual de avatar."""
17
+ url: str
18
+ phash: str # Perceptual hash (64 bits hex)
19
+ ahash: str # Average hash (64 bits hex)
20
+ dhash: str # Difference hash (64 bits hex)
21
+ size: tuple # (width, height)
22
+ format: str # JPEG, PNG, etc.
23
+
24
+
25
+ class AvatarHasher:
26
+ """Cria hashes perceptuais de avatares para comparação."""
27
+
28
+ def __init__(self, timeout: float = 10.0):
29
+ self._timeout = timeout
30
+
31
+ async def hash_avatar(self, url: str) -> Optional[AvatarHash]:
32
+ """
33
+ Baixa e cria hashes perceptuais de um avatar.
34
+
35
+ Hashes perceptuais permitem:
36
+ - Encontrar avatares similares mesmo com pequenas modificações
37
+ - Detectar mesma pessoa usando avatares levemente diferentes
38
+ - Comparar avatares em diferentes resoluções
39
+ """
40
+ logger.info("avatar.hash.start", url=url)
41
+
42
+ try:
43
+ # Baixa imagem
44
+ async with httpx.AsyncClient(timeout=self._timeout) as client:
45
+ response = await client.get(url)
46
+ response.raise_for_status()
47
+
48
+ image_data = response.content
49
+
50
+ # Abre com PIL
51
+ image = Image.open(BytesIO(image_data))
52
+
53
+ # Redimensiona para processamento
54
+ image = image.convert("RGB")
55
+
56
+ # Calcula hashes
57
+ phash = self._perceptual_hash(image)
58
+ ahash = self._average_hash(image)
59
+ dhash = self._difference_hash(image)
60
+
61
+ logger.info("avatar.hash.complete", url=url, phash=phash[:16])
62
+
63
+ return AvatarHash(
64
+ url=url,
65
+ phash=phash,
66
+ ahash=ahash,
67
+ dhash=dhash,
68
+ size=image.size,
69
+ format=image.format or "Unknown",
70
+ )
71
+
72
+ except Exception as e:
73
+ logger.warning("avatar.hash.error", url=url, error=str(e))
74
+ return None
75
+
76
+ def _perceptual_hash(self, image: Image.Image, hash_size: int = 8) -> str:
77
+ """
78
+ Calcula pHash (perceptual hash).
79
+
80
+ Algoritmo:
81
+ 1. Redimensiona para hash_size x hash_size
82
+ 2. Converte para grayscale
83
+ 3. Calcula DCT (Discrete Cosine Transform)
84
+ 4. Extrai top-left 8x8 excluindo DC
85
+ 5. Compara com mediana
86
+ """
87
+ # Redimensiona
88
+ image = image.resize((hash_size * 4, hash_size * 4), Image.LANCZOS)
89
+ image = image.convert("L") # Grayscale
90
+
91
+ # Simplificação: usa average hash como aproximação de pHash
92
+ # Em produção, implementar DCT real ou usar biblioteca imagehash
93
+ image = image.resize((hash_size, hash_size), Image.LANCZOS)
94
+ pixels = list(image.getdata())
95
+
96
+ avg = sum(pixels) / len(pixels)
97
+
98
+ # Cria hash binário
99
+ bits = "".join("1" if pixel > avg else "0" for pixel in pixels)
100
+
101
+ # Converte para hex
102
+ hash_hex = hex(int(bits, 2))[2:].zfill(16)
103
+
104
+ return hash_hex
105
+
106
+ def _average_hash(self, image: Image.Image, hash_size: int = 8) -> str:
107
+ """
108
+ Calcula aHash (average hash).
109
+
110
+ Algoritmo:
111
+ 1. Redimensiona para hash_size x hash_size
112
+ 2. Converte para grayscale
113
+ 3. Calcula média dos pixels
114
+ 4. Cada pixel > média = 1, senão 0
115
+ """
116
+ image = image.resize((hash_size, hash_size), Image.LANCZOS)
117
+ image = image.convert("L")
118
+
119
+ pixels = list(image.getdata())
120
+ avg = sum(pixels) / len(pixels)
121
+
122
+ bits = "".join("1" if pixel > avg else "0" for pixel in pixels)
123
+ hash_hex = hex(int(bits, 2))[2:].zfill(16)
124
+
125
+ return hash_hex
126
+
127
+ def _difference_hash(self, image: Image.Image, hash_size: int = 8) -> str:
128
+ """
129
+ Calcula dHash (difference hash).
130
+
131
+ Algoritmo:
132
+ 1. Redimensiona para (hash_size+1) x hash_size
133
+ 2. Converte para grayscale
134
+ 3. Compara cada pixel com o próximo
135
+ 4. pixel[i] > pixel[i+1] = 1, senão 0
136
+ """
137
+ image = image.resize((hash_size + 1, hash_size), Image.LANCZOS)
138
+ image = image.convert("L")
139
+
140
+ pixels = list(image.getdata())
141
+
142
+ bits = ""
143
+ for row in range(hash_size):
144
+ for col in range(hash_size):
145
+ index = row * (hash_size + 1) + col
146
+ left = pixels[index]
147
+ right = pixels[index + 1]
148
+ bits += "1" if left > right else "0"
149
+
150
+ hash_hex = hex(int(bits, 2))[2:].zfill(16)
151
+
152
+ return hash_hex
153
+
154
+ def compare_hashes(self, hash1: str, hash2: str) -> int:
155
+ """
156
+ Compara dois hashes e retorna distância de Hamming.
157
+
158
+ Distância 0 = idênticos
159
+ Distância < 10 = muito similares
160
+ Distância < 20 = similares
161
+ Distância > 20 = diferentes
162
+ """
163
+ if len(hash1) != len(hash2):
164
+ return 64 # Máxima distância
165
+
166
+ # Converte para binário
167
+ bin1 = bin(int(hash1, 16))[2:].zfill(64)
168
+ bin2 = bin(int(hash2, 16))[2:].zfill(64)
169
+
170
+ # Calcula distância de Hamming
171
+ distance = sum(b1 != b2 for b1, b2 in zip(bin1, bin2))
172
+
173
+ return distance
174
+
175
+ def is_similar(self, hash1: str, hash2: str, threshold: int = 10) -> bool:
176
+ """Verifica se dois avatares são similares."""
177
+ distance = self.compare_hashes(hash1, hash2)
178
+ return distance <= threshold
179
+
180
+
181
+ __all__ = [
182
+ "AvatarHasher",
183
+ "AvatarHash",
184
+ ]
@@ -0,0 +1,322 @@
1
+ """Directory Fuzzer avançado para descoberta de diretórios e arquivos."""
2
+ import asyncio
3
+ from dataclasses import dataclass
4
+ from pathlib import Path
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 FuzzResult:
18
+ """Resultado de fuzzing."""
19
+ url: str
20
+ status_code: int
21
+ size: int
22
+ redirect_url: Optional[str] = None
23
+ server: Optional[str] = None
24
+ content_type: Optional[str] = None
25
+
26
+
27
+ class DirectoryFuzzer:
28
+ """
29
+ Directory/File fuzzer avançado.
30
+
31
+ Features:
32
+ - Wordlists (small, medium, large)
33
+ - Fuzzing de extensões
34
+ - Recursive fuzzing
35
+ - Status code filtering
36
+ - Rate limiting
37
+ - Stealth mode integration
38
+ - Smart filtering (tamanho, tipo)
39
+ """
40
+
41
+ # Wordlists embutidas
42
+ SMALL_WORDLIST = [
43
+ 'admin', 'administrator', 'login', 'wp-admin', 'dashboard', 'panel',
44
+ 'api', 'v1', 'v2', 'test', 'dev', 'staging', 'backup', 'old',
45
+ 'config', 'conf', 'settings', 'setup', 'install', 'debug',
46
+ 'logs', 'log', 'tmp', 'temp', 'cache', 'uploads', 'upload',
47
+ 'files', 'file', 'download', 'downloads', 'assets', 'static',
48
+ 'images', 'img', 'css', 'js', 'scripts', 'includes', 'inc',
49
+ 'vendor', 'node_modules', 'lib', 'libs', 'bin', 'src', 'source',
50
+ 'public', 'private', 'secure', 'backup', 'backups', 'db', 'database',
51
+ 'sql', 'data', 'users', 'user', 'accounts', 'account', 'profile',
52
+ 'profiles', 'settings', 'preferences', 'config', 'configuration',
53
+ 'admin', 'administrator', 'root', 'superuser', 'sudo', 'manager',
54
+ 'staff', 'employee', 'member', 'members', 'reports', 'report',
55
+ 'analytics', 'stats', 'statistics', 'monitor', 'monitoring',
56
+ 'metrics', 'health', 'status', 'info', 'information', 'about',
57
+ 'contact', 'support', 'help', 'docs', 'documentation', 'api-docs',
58
+ 'swagger', 'graphql', 'rest', 'soap', 'xml-rpc', 'json-rpc'
59
+ ]
60
+
61
+ COMMON_EXTENSIONS = [
62
+ '', '.html', '.php', '.asp', '.aspx', '.jsp', '.jspx',
63
+ '.txt', '.xml', '.json', '.yml', '.yaml', '.conf', '.config',
64
+ '.bak', '.backup', '.old', '.orig', '.tmp', '.temp', '.swp',
65
+ '.log', '.sql', '.db', '.sqlite', '.mdb',
66
+ '.zip', '.tar', '.gz', '.rar', '.7z',
67
+ '.env', '.git', '.svn', '.hg', '.DS_Store',
68
+ ]
69
+
70
+ INTERESTING_STATUS = [200, 201, 202, 204, 301, 302, 307, 308, 401, 403, 405, 500]
71
+
72
+ def __init__(
73
+ self,
74
+ base_url: str,
75
+ wordlist: Optional[List[str]] = None,
76
+ wordlist_file: Optional[str] = None,
77
+ extensions: Optional[List[str]] = None,
78
+ recursive: bool = False,
79
+ max_depth: int = 2,
80
+ threads: int = 50,
81
+ timeout: float = 5.0,
82
+ status_filter: Optional[List[int]] = None,
83
+ size_filter: Optional[int] = None,
84
+ stealth_level: int = 0,
85
+ ):
86
+ self.base_url = base_url.rstrip('/')
87
+ self.wordlist = wordlist or self._load_wordlist(wordlist_file)
88
+ self.extensions = extensions or self.COMMON_EXTENSIONS
89
+ self.recursive = recursive
90
+ self.max_depth = max_depth
91
+ self.threads = threads
92
+ self.timeout = timeout
93
+ self.status_filter = status_filter or self.INTERESTING_STATUS
94
+ self.size_filter = size_filter
95
+ self.stealth_level = stealth_level
96
+
97
+ self.results: List[FuzzResult] = []
98
+ self.found_dirs: Set[str] = set()
99
+ self.baseline_sizes: dict = {}
100
+
101
+ def _load_wordlist(self, wordlist_file: Optional[str]) -> List[str]:
102
+ """Carrega wordlist de arquivo ou usa embutida."""
103
+ if wordlist_file and Path(wordlist_file).exists():
104
+ with open(wordlist_file, 'r') as f:
105
+ return [line.strip() for line in f if line.strip()]
106
+
107
+ # Usa wordlist pequena embutida
108
+ return self.SMALL_WORDLIST
109
+
110
+ async def fuzz(self) -> List[FuzzResult]:
111
+ """Executa fuzzing."""
112
+ logger.info("fuzzer.start", url=self.base_url, words=len(self.wordlist))
113
+
114
+ # Calibração inicial (baseline)
115
+ await self._calibrate()
116
+
117
+ # Fuzz inicial
118
+ await self._fuzz_directory(self.base_url, depth=0)
119
+
120
+ logger.info("fuzzer.complete", results=len(self.results))
121
+ return self.results
122
+
123
+ async def _calibrate(self):
124
+ """Calibra fuzzer com requests de baseline."""
125
+ console.print("[dim]Calibrating fuzzer...[/dim]")
126
+
127
+ baseline_paths = [
128
+ f"/{self._generate_random_string(10)}",
129
+ f"/{self._generate_random_string(15)}.{self._generate_random_string(3)}",
130
+ ]
131
+
132
+ async with httpx.AsyncClient(timeout=self.timeout, follow_redirects=True) as client:
133
+ for path in baseline_paths:
134
+ try:
135
+ response = await client.get(f"{self.base_url}{path}")
136
+ self.baseline_sizes[response.status_code] = len(response.content)
137
+ except:
138
+ pass
139
+
140
+ logger.debug("fuzzer.calibrated", baseline_sizes=self.baseline_sizes)
141
+
142
+ async def _fuzz_directory(self, base_url: str, depth: int):
143
+ """Fuzz um diretório."""
144
+ if depth > self.max_depth:
145
+ return
146
+
147
+ # Cria lista de URLs para testar
148
+ urls_to_test = []
149
+ for word in self.wordlist:
150
+ for ext in self.extensions:
151
+ url = f"{base_url}/{word}{ext}"
152
+ urls_to_test.append(url)
153
+
154
+ # Semaphore para controlar concorrência
155
+ semaphore = asyncio.Semaphore(self.threads)
156
+
157
+ async with httpx.AsyncClient(
158
+ timeout=self.timeout,
159
+ follow_redirects=False,
160
+ verify=False
161
+ ) as client:
162
+
163
+ with Progress() as progress:
164
+ task_id = progress.add_task(
165
+ f"[cyan]Fuzzing {base_url.split('/')[-1] or 'root'}...",
166
+ total=len(urls_to_test)
167
+ )
168
+
169
+ tasks = [
170
+ self._test_url(client, semaphore, url, progress, task_id)
171
+ for url in urls_to_test
172
+ ]
173
+
174
+ await asyncio.gather(*tasks, return_exceptions=True)
175
+
176
+ # Recursive fuzzing em diretórios encontrados
177
+ if self.recursive and depth < self.max_depth:
178
+ for dir_url in list(self.found_dirs):
179
+ if dir_url.startswith(base_url):
180
+ await self._fuzz_directory(dir_url, depth + 1)
181
+
182
+ async def _test_url(
183
+ self,
184
+ client: httpx.AsyncClient,
185
+ semaphore: asyncio.Semaphore,
186
+ url: str,
187
+ progress: Progress,
188
+ task_id: int
189
+ ):
190
+ """Testa uma URL."""
191
+ async with semaphore:
192
+ try:
193
+ # Stealth delay
194
+ if self.stealth_level > 0:
195
+ await asyncio.sleep(self.stealth_level * 0.1)
196
+
197
+ headers = self._get_headers()
198
+ response = await client.get(url, headers=headers)
199
+
200
+ progress.update(task_id, advance=1)
201
+
202
+ # Filtra por status code
203
+ if response.status_code not in self.status_filter:
204
+ return
205
+
206
+ # Filtra por tamanho (baseline)
207
+ content_size = len(response.content)
208
+ if self._is_baseline_size(response.status_code, content_size):
209
+ return
210
+
211
+ # Filtra por tamanho customizado
212
+ if self.size_filter and content_size > self.size_filter:
213
+ return
214
+
215
+ # Cria resultado
216
+ result = FuzzResult(
217
+ url=url,
218
+ status_code=response.status_code,
219
+ size=content_size,
220
+ redirect_url=response.headers.get('location'),
221
+ server=response.headers.get('server'),
222
+ content_type=response.headers.get('content-type'),
223
+ )
224
+
225
+ self.results.append(result)
226
+
227
+ # Se é diretório, adiciona para recursive fuzzing
228
+ if response.status_code in [301, 302, 307, 308]:
229
+ if result.redirect_url and result.redirect_url.endswith('/'):
230
+ self.found_dirs.add(result.redirect_url.rstrip('/'))
231
+ elif url.endswith('/'):
232
+ self.found_dirs.add(url.rstrip('/'))
233
+
234
+ # Log descoberta
235
+ color = self._get_status_color(response.status_code)
236
+ console.print(
237
+ f" [{color}]{response.status_code}[/{color}] "
238
+ f"[cyan]{url.replace(self.base_url, '')}[/cyan] "
239
+ f"[dim]({content_size} bytes)[/dim]"
240
+ )
241
+
242
+ logger.info(
243
+ "fuzzer.found",
244
+ url=url,
245
+ status=response.status_code,
246
+ size=content_size
247
+ )
248
+
249
+ except httpx.TimeoutException:
250
+ pass
251
+ except Exception as e:
252
+ logger.debug("fuzzer.error", url=url, error=str(e))
253
+
254
+ def _is_baseline_size(self, status_code: int, size: int) -> bool:
255
+ """Verifica se tamanho é baseline (falso positivo)."""
256
+ baseline = self.baseline_sizes.get(status_code)
257
+ if baseline is None:
258
+ return False
259
+
260
+ # Permite variação de 5%
261
+ tolerance = baseline * 0.05
262
+ return abs(size - baseline) <= tolerance
263
+
264
+ def _get_headers(self) -> dict:
265
+ """Retorna headers com stealth."""
266
+ headers = {
267
+ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
268
+ 'Accept': '*/*',
269
+ }
270
+
271
+ if self.stealth_level > 1:
272
+ headers.update({
273
+ 'Accept-Language': 'en-US,en;q=0.9',
274
+ 'Accept-Encoding': 'gzip, deflate',
275
+ 'DNT': '1',
276
+ 'Connection': 'keep-alive',
277
+ })
278
+
279
+ return headers
280
+
281
+ def _get_status_color(self, status_code: int) -> str:
282
+ """Retorna cor baseada no status code."""
283
+ if status_code < 300:
284
+ return "green"
285
+ elif status_code < 400:
286
+ return "yellow"
287
+ elif status_code == 401 or status_code == 403:
288
+ return "red"
289
+ elif status_code < 500:
290
+ return "blue"
291
+ else:
292
+ return "magenta"
293
+
294
+ def _generate_random_string(self, length: int) -> str:
295
+ """Gera string aleatória."""
296
+ import random
297
+ import string
298
+ return ''.join(random.choices(string.ascii_lowercase + string.digits, k=length))
299
+
300
+ def export(self, output: str):
301
+ """Exporta resultados."""
302
+ import json
303
+
304
+ data = [
305
+ {
306
+ 'url': r.url,
307
+ 'status_code': r.status_code,
308
+ 'size': r.size,
309
+ 'redirect_url': r.redirect_url,
310
+ 'server': r.server,
311
+ 'content_type': r.content_type,
312
+ }
313
+ for r in self.results
314
+ ]
315
+
316
+ with open(output, 'w') as f:
317
+ json.dump(data, f, indent=2)
318
+
319
+ logger.info("fuzzer.export", file=output, count=len(self.results))
320
+
321
+
322
+ __all__ = ["DirectoryFuzzer", "FuzzResult"]
@@ -0,0 +1,40 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass
4
+
5
+ import structlog
6
+
7
+ from .orchestrator import Orchestrator, TaskContext
8
+ from ..net.dns_client import DNSClient, DNSLookupResult
9
+
10
+ logger = structlog.get_logger(__name__)
11
+
12
+
13
+ @dataclass(slots=True)
14
+ class DNSScanResult:
15
+ domain: str
16
+ records: DNSLookupResult
17
+
18
+
19
+ class DNSScanService:
20
+ def __init__(
21
+ self,
22
+ domain: str,
23
+ orchestrator: Orchestrator[DNSLookupResult],
24
+ dns_client: DNSClient,
25
+ ) -> None:
26
+ self._domain = domain
27
+ self._orchestrator = orchestrator
28
+ self._dns_client = dns_client
29
+
30
+ async def run(self) -> DNSScanResult:
31
+ logger.info("dns.scan.start", domain=self._domain)
32
+ records = await self._orchestrator.run(
33
+ TaskContext(name="dns_lookup", metadata={"domain": self._domain}),
34
+ lambda: self._dns_client.lookup_domain(self._domain),
35
+ )
36
+ logger.info("dns.scan.success", domain=self._domain)
37
+ return DNSScanResult(domain=self._domain, records=records)
38
+
39
+
40
+ __all__ = ["DNSScanResult", "DNSScanService"]