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.
- moriarty/__init__.py +5 -0
- moriarty/adapters/__init__.py +0 -0
- moriarty/agent/__init__.py +0 -0
- moriarty/assets/modules/.gitkeep +0 -0
- moriarty/assets/modules/asia/douban.yaml +19 -0
- moriarty/assets/modules/asia/kakao.yaml +19 -0
- moriarty/assets/modules/asia/line.yaml +19 -0
- moriarty/assets/modules/asia/mixi.yaml +19 -0
- moriarty/assets/modules/asia/naver.yaml +19 -0
- moriarty/assets/modules/asia/qq.yaml +19 -0
- moriarty/assets/modules/asia/vk.yaml +19 -0
- moriarty/assets/modules/asia/wechat.yaml +19 -0
- moriarty/assets/modules/asia/weibo.yaml +19 -0
- moriarty/assets/modules/asia/xiaohongshu.yaml +19 -0
- moriarty/assets/modules/behance.yaml +47 -0
- moriarty/assets/modules/business/crunchbase.yaml +27 -0
- moriarty/assets/modules/business/fiverr.yaml +32 -0
- moriarty/assets/modules/business/freelancer.yaml +27 -0
- moriarty/assets/modules/business/glassdoor.yaml +27 -0
- moriarty/assets/modules/business/guru.yaml +26 -0
- moriarty/assets/modules/business/indeed.yaml +25 -0
- moriarty/assets/modules/business/monster.yaml +25 -0
- moriarty/assets/modules/business/peopleperhour.yaml +26 -0
- moriarty/assets/modules/business/toptal.yaml +28 -0
- moriarty/assets/modules/business/upwork.yaml +27 -0
- moriarty/assets/modules/business/ziprecruiter.yaml +25 -0
- moriarty/assets/modules/content/buymeacoffee.yaml +27 -0
- moriarty/assets/modules/content/gumroad.yaml +27 -0
- moriarty/assets/modules/content/ko-fi.yaml +32 -0
- moriarty/assets/modules/content/onlyfans.yaml +27 -0
- moriarty/assets/modules/content/patreon.yaml +33 -0
- moriarty/assets/modules/content/substack.yaml +32 -0
- moriarty/assets/modules/creative/500px.yaml +31 -0
- moriarty/assets/modules/creative/artstation.yaml +33 -0
- moriarty/assets/modules/creative/deviantart.yaml +32 -0
- moriarty/assets/modules/creative/flickr.yaml +31 -0
- moriarty/assets/modules/creative/pexels.yaml +26 -0
- moriarty/assets/modules/creative/unsplash.yaml +26 -0
- moriarty/assets/modules/creative/vimeo.yaml +31 -0
- moriarty/assets/modules/crypto/binance.yaml +27 -0
- moriarty/assets/modules/crypto/bitcointalk.yaml +33 -0
- moriarty/assets/modules/crypto/coinbase.yaml +26 -0
- moriarty/assets/modules/crypto/etherscan.yaml +32 -0
- moriarty/assets/modules/crypto/foundation.yaml +28 -0
- moriarty/assets/modules/crypto/kraken.yaml +27 -0
- moriarty/assets/modules/crypto/mirror.yaml +27 -0
- moriarty/assets/modules/crypto/niftygateway.yaml +26 -0
- moriarty/assets/modules/crypto/opensea.yaml +32 -0
- moriarty/assets/modules/crypto/rarible.yaml +27 -0
- moriarty/assets/modules/crypto/superrare.yaml +29 -0
- moriarty/assets/modules/dating/bumble.yaml +25 -0
- moriarty/assets/modules/dating/grindr.yaml +27 -0
- moriarty/assets/modules/dating/happn.yaml +25 -0
- moriarty/assets/modules/dating/her.yaml +27 -0
- moriarty/assets/modules/dating/hinge.yaml +25 -0
- moriarty/assets/modules/dating/match.yaml +25 -0
- moriarty/assets/modules/dating/meetme.yaml +27 -0
- moriarty/assets/modules/dating/okcupid.yaml +25 -0
- moriarty/assets/modules/dating/pof.yaml +25 -0
- moriarty/assets/modules/dating/tinder.yaml +25 -0
- moriarty/assets/modules/dating-nsfw/adultfriendfinder.yaml +28 -0
- moriarty/assets/modules/dating-nsfw/ashley-madison.yaml +26 -0
- moriarty/assets/modules/design/adobe-portfolio.yaml +27 -0
- moriarty/assets/modules/design/carbonmade.yaml +27 -0
- moriarty/assets/modules/design/cgsociety.yaml +27 -0
- moriarty/assets/modules/design/coroflot.yaml +27 -0
- moriarty/assets/modules/design/figma.yaml +27 -0
- moriarty/assets/modules/design/sketch.yaml +26 -0
- moriarty/assets/modules/dev/bitbucket.yaml +35 -0
- moriarty/assets/modules/dev/codeforces.yaml +32 -0
- moriarty/assets/modules/dev/codepen.yaml +34 -0
- moriarty/assets/modules/dev/hackerone.yaml +32 -0
- moriarty/assets/modules/dev/hackthebox.yaml +27 -0
- moriarty/assets/modules/dev/huggingface.yaml +27 -0
- moriarty/assets/modules/dev/kaggle.yaml +32 -0
- moriarty/assets/modules/dev/leetcode.yaml +32 -0
- moriarty/assets/modules/dev/replit.yaml +31 -0
- moriarty/assets/modules/dribbble.yaml +53 -0
- moriarty/assets/modules/ecommerce/etsy.yaml +32 -0
- moriarty/assets/modules/education/duolingo.yaml +32 -0
- moriarty/assets/modules/education/edx.yaml +26 -0
- moriarty/assets/modules/education/khanacademy.yaml +26 -0
- moriarty/assets/modules/education/lynda.yaml +27 -0
- moriarty/assets/modules/education/memrise.yaml +27 -0
- moriarty/assets/modules/education/pluralsight.yaml +27 -0
- moriarty/assets/modules/education/skillshare.yaml +27 -0
- moriarty/assets/modules/education/udacity.yaml +27 -0
- moriarty/assets/modules/email/github_email.yaml +40 -0
- moriarty/assets/modules/email/gravatar.yaml +23 -0
- moriarty/assets/modules/europe/badoo.yaml +19 -0
- moriarty/assets/modules/europe/lovoo.yaml +19 -0
- moriarty/assets/modules/europe/myspace.yaml +19 -0
- moriarty/assets/modules/europe/netlog.yaml +19 -0
- moriarty/assets/modules/europe/ok.yaml +19 -0
- moriarty/assets/modules/europe/skyrock.yaml +19 -0
- moriarty/assets/modules/europe/studivz.yaml +19 -0
- moriarty/assets/modules/europe/tuenti.yaml +19 -0
- moriarty/assets/modules/europe/viadeo.yaml +19 -0
- moriarty/assets/modules/europe/xing.yaml +19 -0
- moriarty/assets/modules/fitness/fitbit.yaml +27 -0
- moriarty/assets/modules/fitness/garmin.yaml +27 -0
- moriarty/assets/modules/fitness/myfitnesspal.yaml +27 -0
- moriarty/assets/modules/fitness/strava.yaml +33 -0
- moriarty/assets/modules/fitness/zwift.yaml +28 -0
- moriarty/assets/modules/food/allrecipes.yaml +27 -0
- moriarty/assets/modules/food/tasty.yaml +27 -0
- moriarty/assets/modules/food/yelp.yaml +32 -0
- moriarty/assets/modules/food/zomato.yaml +28 -0
- moriarty/assets/modules/forums/4chan.yaml +26 -0
- moriarty/assets/modules/forums/8kun.yaml +26 -0
- moriarty/assets/modules/forums/9gag.yaml +26 -0
- moriarty/assets/modules/forums/discourse.yaml +26 -0
- moriarty/assets/modules/forums/disqus.yaml +31 -0
- moriarty/assets/modules/forums/hackernews.yaml +32 -0
- moriarty/assets/modules/forums/launchpad.yaml +27 -0
- moriarty/assets/modules/forums/phpbb.yaml +25 -0
- moriarty/assets/modules/forums/quora.yaml +32 -0
- moriarty/assets/modules/forums/serverfault.yaml +27 -0
- moriarty/assets/modules/forums/slashdot.yaml +28 -0
- moriarty/assets/modules/forums/stackexchange.yaml +32 -0
- moriarty/assets/modules/forums/superuser.yaml +27 -0
- moriarty/assets/modules/forums/vbulletin.yaml +25 -0
- moriarty/assets/modules/forums/xenforo.yaml +25 -0
- moriarty/assets/modules/forums-nsfw/kiwifarms.yaml +25 -0
- moriarty/assets/modules/forums-nsfw/lolcow.yaml +26 -0
- moriarty/assets/modules/gaming/apextracker.yaml +27 -0
- moriarty/assets/modules/gaming/battlenet.yaml +26 -0
- moriarty/assets/modules/gaming/chess.yaml +30 -0
- moriarty/assets/modules/gaming/discord-public.yaml +27 -0
- moriarty/assets/modules/gaming/dotabuff.yaml +32 -0
- moriarty/assets/modules/gaming/epicgames.yaml +25 -0
- moriarty/assets/modules/gaming/faceit.yaml +33 -0
- moriarty/assets/modules/gaming/fortnitetracker.yaml +32 -0
- moriarty/assets/modules/gaming/gog.yaml +26 -0
- moriarty/assets/modules/gaming/itch.yaml +32 -0
- moriarty/assets/modules/gaming/kongregate.yaml +25 -0
- moriarty/assets/modules/gaming/minecraft.yaml +31 -0
- moriarty/assets/modules/gaming/opgg.yaml +32 -0
- moriarty/assets/modules/gaming/origin.yaml +26 -0
- moriarty/assets/modules/gaming/playstation.yaml +30 -0
- moriarty/assets/modules/gaming/roblox.yaml +31 -0
- moriarty/assets/modules/gaming/xbox.yaml +25 -0
- moriarty/assets/modules/github.yaml +68 -0
- moriarty/assets/modules/gitlab.yaml +60 -0
- moriarty/assets/modules/instagram.yaml +48 -0
- moriarty/assets/modules/latam/fotolog.yaml +27 -0
- moriarty/assets/modules/latam/orkut.yaml +26 -0
- moriarty/assets/modules/latam/taringa.yaml +27 -0
- moriarty/assets/modules/learning/coursera.yaml +26 -0
- moriarty/assets/modules/learning/udemy.yaml +26 -0
- moriarty/assets/modules/linkedin.yaml +40 -0
- moriarty/assets/modules/marketplaces/depop.yaml +28 -0
- moriarty/assets/modules/marketplaces/ebay.yaml +32 -0
- moriarty/assets/modules/marketplaces/grailed.yaml +27 -0
- moriarty/assets/modules/marketplaces/mercari.yaml +26 -0
- moriarty/assets/modules/marketplaces/poshmark.yaml +27 -0
- moriarty/assets/modules/marketplaces/reverb.yaml +27 -0
- moriarty/assets/modules/marketplaces/vinted.yaml +28 -0
- moriarty/assets/modules/medium.yaml +44 -0
- moriarty/assets/modules/music/audiomack.yaml +26 -0
- moriarty/assets/modules/music/bandcamp.yaml +30 -0
- moriarty/assets/modules/music/beatport.yaml +28 -0
- moriarty/assets/modules/music/deezer.yaml +26 -0
- moriarty/assets/modules/music/discogs.yaml +32 -0
- moriarty/assets/modules/music/genius.yaml +26 -0
- moriarty/assets/modules/music/lastfm.yaml +30 -0
- moriarty/assets/modules/music/mixcloud.yaml +26 -0
- moriarty/assets/modules/music/reverbnation.yaml +31 -0
- moriarty/assets/modules/music/soundcloud.yaml +31 -0
- moriarty/assets/modules/music/spotify.yaml +26 -0
- moriarty/assets/modules/music/tidal.yaml +26 -0
- moriarty/assets/modules/nsfw/adultwork.yaml +27 -0
- moriarty/assets/modules/nsfw/bongacams.yaml +28 -0
- moriarty/assets/modules/nsfw/cam4.yaml +28 -0
- moriarty/assets/modules/nsfw/chaturbate.yaml +28 -0
- moriarty/assets/modules/nsfw/clips4sale.yaml +27 -0
- moriarty/assets/modules/nsfw/extralunchmoney.yaml +27 -0
- moriarty/assets/modules/nsfw/fansly.yaml +28 -0
- moriarty/assets/modules/nsfw/fetlife.yaml +28 -0
- moriarty/assets/modules/nsfw/iwantclips.yaml +27 -0
- moriarty/assets/modules/nsfw/justforfans.yaml +28 -0
- moriarty/assets/modules/nsfw/loyalfans.yaml +28 -0
- moriarty/assets/modules/nsfw/manyvids.yaml +27 -0
- moriarty/assets/modules/nsfw/myfreecams.yaml +28 -0
- moriarty/assets/modules/nsfw/niteflirt.yaml +26 -0
- moriarty/assets/modules/nsfw/pornhub.yaml +32 -0
- moriarty/assets/modules/nsfw/redtube.yaml +27 -0
- moriarty/assets/modules/nsfw/stripchat.yaml +28 -0
- moriarty/assets/modules/nsfw/xhamster.yaml +27 -0
- moriarty/assets/modules/nsfw/xvideos.yaml +27 -0
- moriarty/assets/modules/nsfw/youporn.yaml +27 -0
- moriarty/assets/modules/photography/eyeem.yaml +25 -0
- moriarty/assets/modules/photography/fotki.yaml +25 -0
- moriarty/assets/modules/photography/photobucket.yaml +26 -0
- moriarty/assets/modules/photography/smugmug.yaml +25 -0
- moriarty/assets/modules/photography/vsco.yaml +27 -0
- moriarty/assets/modules/pinterest.yaml +40 -0
- moriarty/assets/modules/podcasts/anchor.yaml +26 -0
- moriarty/assets/modules/podcasts/castbox.yaml +26 -0
- moriarty/assets/modules/podcasts/podbean.yaml +26 -0
- moriarty/assets/modules/professional/about.yaml +31 -0
- moriarty/assets/modules/professional/academia.yaml +27 -0
- moriarty/assets/modules/professional/angellist.yaml +27 -0
- moriarty/assets/modules/professional/calendly.yaml +26 -0
- moriarty/assets/modules/professional/issuu.yaml +27 -0
- moriarty/assets/modules/professional/mendeley.yaml +27 -0
- moriarty/assets/modules/professional/notion.yaml +27 -0
- moriarty/assets/modules/professional/orcid.yaml +27 -0
- moriarty/assets/modules/professional/producthunt.yaml +31 -0
- moriarty/assets/modules/professional/researchgate.yaml +32 -0
- moriarty/assets/modules/professional/scribd.yaml +27 -0
- moriarty/assets/modules/professional/slideshare.yaml +31 -0
- moriarty/assets/modules/professional/trello.yaml +26 -0
- moriarty/assets/modules/professional/typeform.yaml +27 -0
- moriarty/assets/modules/reddit.yaml +46 -0
- moriarty/assets/modules/regional/amino.yaml +27 -0
- moriarty/assets/modules/regional/ask-fm.yaml +32 -0
- moriarty/assets/modules/regional/babycenter.yaml +26 -0
- moriarty/assets/modules/regional/cafemom.yaml +27 -0
- moriarty/assets/modules/regional/care2.yaml +27 -0
- moriarty/assets/modules/regional/diaspora.yaml +26 -0
- moriarty/assets/modules/regional/ello.yaml +27 -0
- moriarty/assets/modules/regional/gaia.yaml +27 -0
- moriarty/assets/modules/regional/habbo.yaml +27 -0
- moriarty/assets/modules/regional/imvu.yaml +27 -0
- moriarty/assets/modules/regional/lemmy.yaml +27 -0
- moriarty/assets/modules/regional/peertube.yaml +26 -0
- moriarty/assets/modules/regional/pixelfed.yaml +27 -0
- moriarty/assets/modules/regional/plurk.yaml +26 -0
- moriarty/assets/modules/regional/recroom.yaml +27 -0
- moriarty/assets/modules/regional/secondlife.yaml +26 -0
- moriarty/assets/modules/regional/vine-archive.yaml +27 -0
- moriarty/assets/modules/regional/vrchat.yaml +27 -0
- moriarty/assets/modules/regional/weheartit.yaml +27 -0
- moriarty/assets/modules/social/anilist.yaml +27 -0
- moriarty/assets/modules/social/beacons.yaml +26 -0
- moriarty/assets/modules/social/blogger.yaml +27 -0
- moriarty/assets/modules/social/crunchyroll.yaml +27 -0
- moriarty/assets/modules/social/discord.yaml +27 -0
- moriarty/assets/modules/social/dreamwidth.yaml +26 -0
- moriarty/assets/modules/social/facebook.yaml +34 -0
- moriarty/assets/modules/social/goodreads.yaml +32 -0
- moriarty/assets/modules/social/imdb.yaml +27 -0
- moriarty/assets/modules/social/kitsu.yaml +27 -0
- moriarty/assets/modules/social/letterboxd.yaml +32 -0
- moriarty/assets/modules/social/linktree.yaml +26 -0
- moriarty/assets/modules/social/livejournal.yaml +27 -0
- moriarty/assets/modules/social/mastodon.yaml +30 -0
- moriarty/assets/modules/social/minds.yaml +25 -0
- moriarty/assets/modules/social/myanimelist.yaml +32 -0
- moriarty/assets/modules/social/ravelry.yaml +27 -0
- moriarty/assets/modules/social/snapchat.yaml +25 -0
- moriarty/assets/modules/social/telegram.yaml +35 -0
- moriarty/assets/modules/social/tiktok.yaml +35 -0
- moriarty/assets/modules/social/trakt.yaml +28 -0
- moriarty/assets/modules/social/wattpad.yaml +32 -0
- moriarty/assets/modules/social/wordpress-com.yaml +26 -0
- moriarty/assets/modules/sports/espn.yaml +26 -0
- moriarty/assets/modules/sports/untappd.yaml +32 -0
- moriarty/assets/modules/stackoverflow.yaml +47 -0
- moriarty/assets/modules/steam.yaml +47 -0
- moriarty/assets/modules/streaming/caffeine.yaml +25 -0
- moriarty/assets/modules/streaming/dlive.yaml +27 -0
- moriarty/assets/modules/streaming/trovo.yaml +25 -0
- moriarty/assets/modules/travel/airbnb.yaml +26 -0
- moriarty/assets/modules/travel/booking.yaml +26 -0
- moriarty/assets/modules/travel/couchsurfing.yaml +27 -0
- moriarty/assets/modules/travel/tripadvisor.yaml +32 -0
- moriarty/assets/modules/tumblr.yaml +40 -0
- moriarty/assets/modules/twitch.yaml +48 -0
- moriarty/assets/modules/twitter.yaml +39 -0
- moriarty/assets/modules/youtube.yaml +42 -0
- moriarty/assets/templates/cves/CVE-2017-5638.yaml +27 -0
- moriarty/assets/templates/cves/CVE-2018-7600.yaml +30 -0
- moriarty/assets/templates/cves/CVE-2019-11510.yaml +27 -0
- moriarty/assets/templates/cves/CVE-2019-19781.yaml +28 -0
- moriarty/assets/templates/cves/CVE-2020-14882.yaml +28 -0
- moriarty/assets/templates/cves/CVE-2020-14883.yaml +29 -0
- moriarty/assets/templates/cves/CVE-2020-3452.yaml +28 -0
- moriarty/assets/templates/cves/CVE-2020-5902.yaml +28 -0
- moriarty/assets/templates/cves/CVE-2021-21972.yaml +31 -0
- moriarty/assets/templates/cves/CVE-2021-21985.yaml +28 -0
- moriarty/assets/templates/cves/CVE-2021-26084.yaml +30 -0
- moriarty/assets/templates/cves/CVE-2021-41773.yaml +25 -0
- moriarty/assets/templates/cves/CVE-2021-42013.yaml +28 -0
- moriarty/assets/templates/cves/CVE-2021-44228.yaml +27 -0
- moriarty/assets/templates/cves/CVE-2022-0185.yaml +21 -0
- moriarty/assets/templates/cves/CVE-2022-1388.yaml +36 -0
- moriarty/assets/templates/cves/CVE-2022-22954.yaml +28 -0
- moriarty/assets/templates/cves/CVE-2022-22965.yaml +31 -0
- moriarty/assets/templates/cves/CVE-2022-26134.yaml +27 -0
- moriarty/assets/templates/cves/CVE-2023-22515.yaml +27 -0
- moriarty/assets/templates/cves/CVE-2023-22527.yaml +29 -0
- moriarty/assets/templates/cves/CVE-2023-23752.yaml +33 -0
- moriarty/assets/templates/cves/CVE-2023-27350.yaml +27 -0
- moriarty/assets/templates/cves/CVE-2023-2868.yaml +27 -0
- moriarty/assets/templates/cves/CVE-2023-34362.yaml +27 -0
- moriarty/assets/templates/cves/CVE-2023-3519.yaml +28 -0
- moriarty/assets/templates/cves/CVE-2023-4966.yaml +27 -0
- moriarty/assets/templates/default-logins/admin-weak.yaml +40 -0
- moriarty/assets/templates/default-logins/wordpress-default.yaml +38 -0
- moriarty/assets/templates/exposures/aws-credentials.yaml +35 -0
- moriarty/assets/templates/exposures/backup-files.yaml +36 -0
- moriarty/assets/templates/exposures/database-files.yaml +34 -0
- moriarty/assets/templates/exposures/docker-exposed.yaml +31 -0
- moriarty/assets/templates/exposures/env-exposed.yaml +41 -0
- moriarty/assets/templates/exposures/git-exposed.yaml +41 -0
- moriarty/assets/templates/exposures/phpinfo.yaml +36 -0
- moriarty/assets/templates/exposures/svn-exposed.yaml +28 -0
- moriarty/assets/templates/fuzzing/api-endpoints.yaml +39 -0
- moriarty/assets/templates/fuzzing/common-files.yaml +37 -0
- moriarty/assets/templates/fuzzing/open-redirect-fuzz.yaml +35 -0
- moriarty/assets/templates/fuzzing/xss-search-fuzz.yaml +29 -0
- moriarty/assets/templates/git-config.yaml +18 -0
- moriarty/assets/templates/misconfigurations/cors-misconfiguration.yaml +30 -0
- moriarty/assets/templates/misconfigurations/debug-enabled.yaml +29 -0
- moriarty/assets/templates/misconfigurations/directory-listing.yaml +33 -0
- moriarty/assets/templates/misconfigurations/jwt-none-algo.yaml +30 -0
- moriarty/assets/templates/misconfigurations/ssl-tls-weak.yaml +23 -0
- moriarty/assets/templates/vulnerabilities/lfi-basic.yaml +31 -0
- moriarty/assets/templates/vulnerabilities/open-redirect.yaml +31 -0
- moriarty/assets/templates/vulnerabilities/rce-basic.yaml +34 -0
- moriarty/assets/templates/vulnerabilities/sqli-error.yaml +39 -0
- moriarty/assets/templates/vulnerabilities/ssrf-basic.yaml +31 -0
- moriarty/assets/templates/vulnerabilities/xss-reflected.yaml +38 -0
- moriarty/assets/templates/vulnerabilities/xxe-basic.yaml +30 -0
- moriarty/assets/wordlists/subdomains-1000.txt +1063 -0
- moriarty/cli/__init__.py +3 -0
- moriarty/cli/app.py +120 -0
- moriarty/cli/async_utils.py +19 -0
- moriarty/cli/dns.py +83 -0
- moriarty/cli/domain_cmd.py +572 -0
- moriarty/cli/email.py +383 -0
- moriarty/cli/email_investigate.py +224 -0
- moriarty/cli/intelligence.py +329 -0
- moriarty/cli/output.py +62 -0
- moriarty/cli/rdap.py +94 -0
- moriarty/cli/state.py +38 -0
- moriarty/cli/tls.py +91 -0
- moriarty/cli/user.py +227 -0
- moriarty/core/cache_backend.py +223 -0
- moriarty/core/config_manager.py +303 -0
- moriarty/correlator/__init__.py +0 -0
- moriarty/data/__init__.py +81 -0
- moriarty/data/ioc/__init__.py +142 -0
- moriarty/data/ioc/matcher.py +254 -0
- moriarty/data/ioc/types.py +267 -0
- moriarty/data/local_intelligence.py +507 -0
- moriarty/data/signature_loaders/__init__.py +103 -0
- moriarty/data/signature_loaders/base.py +54 -0
- moriarty/data/signature_loaders/ioc_feed.py +356 -0
- moriarty/data/signature_loaders/wappalyzer.py +112 -0
- moriarty/dsl/__init__.py +0 -0
- moriarty/dsl/loader.py +99 -0
- moriarty/dsl/schema.py +47 -0
- moriarty/export/__init__.py +0 -0
- moriarty/intelligence/__init__.py +27 -0
- moriarty/intelligence/__main__.py +150 -0
- moriarty/intelligence/config.py +395 -0
- moriarty/intelligence/ioc.py +267 -0
- moriarty/intelligence/signatures.py +550 -0
- moriarty/intelligence/storage.py +501 -0
- moriarty/interop/__init__.py +0 -0
- moriarty/logging/__init__.py +0 -0
- moriarty/logging/config.py +47 -0
- moriarty/models/__init__.py +16 -0
- moriarty/models/assertion.py +24 -0
- moriarty/models/entity.py +22 -0
- moriarty/models/evidence.py +37 -0
- moriarty/models/relation.py +24 -0
- moriarty/models/types.py +28 -0
- moriarty/modules/__init__.py +0 -0
- moriarty/modules/avatar_hash.py +184 -0
- moriarty/modules/directory_fuzzer.py +322 -0
- moriarty/modules/dns_scan.py +40 -0
- moriarty/modules/domain_scanner.py +620 -0
- moriarty/modules/email_check.py +98 -0
- moriarty/modules/email_investigate.py +267 -0
- moriarty/modules/email_security.py +274 -0
- moriarty/modules/googlemaps_lookup.py +106 -0
- moriarty/modules/headless_executor.py +201 -0
- moriarty/modules/orchestrator.py +60 -0
- moriarty/modules/passive_recon.py +444 -0
- moriarty/modules/phone_extractor.py +151 -0
- moriarty/modules/pipeline_orchestrator.py +726 -0
- moriarty/modules/port_scanner.py +129 -0
- moriarty/modules/rdap.py +61 -0
- moriarty/modules/rdap_extended.py +188 -0
- moriarty/modules/stealth_mode.py +610 -0
- moriarty/modules/subdomain_discovery.py +595 -0
- moriarty/modules/technology_profiler.py +361 -0
- moriarty/modules/template_executor.py +239 -0
- moriarty/modules/template_scanner.py +1048 -0
- moriarty/modules/tls_scan.py +46 -0
- moriarty/modules/tls_validator.py +188 -0
- moriarty/modules/vuln_scanner.py +483 -0
- moriarty/modules/waf_detector.py +585 -0
- moriarty/modules/wayback_discovery.py +234 -0
- moriarty/modules/web_crawler.py +163 -0
- moriarty/net/__init__.py +0 -0
- moriarty/net/dns_cache.py +175 -0
- moriarty/net/dns_client.py +188 -0
- moriarty/net/rdap_client.py +52 -0
- moriarty/net/smtp_client.py +114 -0
- moriarty/net/tls_client.py +111 -0
- moriarty/parsers/__init__.py +0 -0
- moriarty/parsers/html_parser.py +136 -0
- moriarty/tests/__init__.py +0 -0
- moriarty/tests/test_email_service.py +17 -0
- moriarty/tests/test_models.py +46 -0
- moriarty/tests/test_orchestrator.py +30 -0
- moriarty/tests/test_tls_client.py +18 -0
- moriarty_project-0.1.6.dist-info/METADATA +388 -0
- moriarty_project-0.1.6.dist-info/RECORD +418 -0
- moriarty_project-0.1.6.dist-info/WHEEL +4 -0
- moriarty_project-0.1.6.dist-info/entry_points.txt +2 -0
@@ -0,0 +1,254 @@
|
|
1
|
+
"""Módulo para correspondência avançada de IOCs."""
|
2
|
+
from __future__ import annotations
|
3
|
+
|
4
|
+
import re
|
5
|
+
import ipaddress
|
6
|
+
from typing import Dict, List, Optional, Set, Union, Any, Pattern, Tuple
|
7
|
+
from datetime import datetime, timedelta
|
8
|
+
from collections import defaultdict
|
9
|
+
|
10
|
+
from .types import IOC, IOCType, ThreatType
|
11
|
+
|
12
|
+
class IOCMatcher:
|
13
|
+
"""Classe para realizar correspondência avançada de IOCs."""
|
14
|
+
|
15
|
+
def __init__(self):
|
16
|
+
self.iocs: Dict[IOCType, Dict[str, List[IOC]]] = defaultdict(dict)
|
17
|
+
self.compiled_patterns: Dict[IOCType, Dict[str, Pattern]] = defaultdict(dict)
|
18
|
+
self.tags_index: Dict[str, Set[IOC]] = defaultdict(set)
|
19
|
+
self.threat_type_index: Dict[ThreatType, Set[IOC]] = defaultdict(set)
|
20
|
+
self.source_index: Dict[str, Set[IOC]] = defaultdict(set)
|
21
|
+
|
22
|
+
def add_ioc(self, ioc: IOC) -> None:
|
23
|
+
"""Adiciona um IOC ao matcher."""
|
24
|
+
# Adiciona ao índice principal
|
25
|
+
if ioc.value not in self.iocs[ioc.ioc_type]:
|
26
|
+
self.iocs[ioc.ioc_type][ioc.value] = []
|
27
|
+
|
28
|
+
self.iocs[ioc.ioc_type][ioc.value].append(ioc)
|
29
|
+
|
30
|
+
# Adiciona aos índices secundários
|
31
|
+
for tag in ioc.tags:
|
32
|
+
self.tags_index[tag.lower()].add(ioc)
|
33
|
+
|
34
|
+
self.threat_type_index[ioc.threat_type].add(ioc)
|
35
|
+
self.source_index[ioc.source.lower()].add(ioc)
|
36
|
+
|
37
|
+
# Compila padrões regex se necessário
|
38
|
+
if ioc.ioc_type in {IOCType.URL, IOCType.EMAIL, IOCType.DOMAIN}:
|
39
|
+
self._compile_pattern(ioc)
|
40
|
+
|
41
|
+
def _compile_pattern(self, ioc: IOC) -> None:
|
42
|
+
"""Compila padrões regex para IOCs que suportam correspondência de padrão."""
|
43
|
+
if ioc.ioc_type == IOCType.URL:
|
44
|
+
# Converte wildcards para regex
|
45
|
+
pattern = re.escape(ioc.value)
|
46
|
+
pattern = pattern.replace('\\*', '.*')
|
47
|
+
self.compiled_patterns[ioc.ioc_type][ioc.value] = re.compile(f'^{pattern}$', re.IGNORECASE)
|
48
|
+
|
49
|
+
elif ioc.ioc_type == IOCType.EMAIL:
|
50
|
+
# Suporta wildcards no domínio (ex: user@*.example.com)
|
51
|
+
user, domain = ioc.value.split('@', 1)
|
52
|
+
pattern = f"^{re.escape(user)}@{re.escape(domain).replace('\\*', '.*')}$"
|
53
|
+
self.compiled_patterns[ioc.ioc_type][ioc.value] = re.compile(pattern, re.IGNORECASE)
|
54
|
+
|
55
|
+
elif ioc.ioc_type == IOCType.DOMAIN:
|
56
|
+
# Suporta wildcards (ex: *.example.com)
|
57
|
+
pattern = f"^{re.escape(ioc.value).replace('\\*', '.*')}$"
|
58
|
+
self.compiled_patterns[ioc.ioc_type][ioc.value] = re.compile(pattern, re.IGNORECASE)
|
59
|
+
|
60
|
+
def match(self, value: str, ioc_type: Optional[IOCType] = None) -> List[IOC]:
|
61
|
+
"""
|
62
|
+
Encontra todos os IOCs que correspondem ao valor fornecido.
|
63
|
+
|
64
|
+
Args:
|
65
|
+
value: O valor a ser verificado
|
66
|
+
ioc_type: Tipo de IOC para restringir a busca (opcional)
|
67
|
+
|
68
|
+
Returns:
|
69
|
+
Lista de IOCs correspondentes
|
70
|
+
"""
|
71
|
+
if not value:
|
72
|
+
return []
|
73
|
+
|
74
|
+
# Se o tipo for especificado, pesquisa apenas nesse tipo
|
75
|
+
if ioc_type is not None:
|
76
|
+
return self._match_single_type(value, ioc_type)
|
77
|
+
|
78
|
+
# Caso contrário, pesquisa em todos os tipos
|
79
|
+
results = []
|
80
|
+
for it in IOCType:
|
81
|
+
results.extend(self._match_single_type(value, it))
|
82
|
+
|
83
|
+
return results
|
84
|
+
|
85
|
+
def _match_single_type(self, value: str, ioc_type: IOCType) -> List[IOC]:
|
86
|
+
"""Verifica correspondência para um único tipo de IOC."""
|
87
|
+
if ioc_type not in self.iocs:
|
88
|
+
return []
|
89
|
+
|
90
|
+
# Para URLs, e-mails e domínios, usa correspondência de padrão
|
91
|
+
if ioc_type in {IOCType.URL, IOCType.EMAIL, IOCType.DOMAIN}:
|
92
|
+
return self._match_pattern(value, ioc_type)
|
93
|
+
|
94
|
+
# Para hashes, normaliza para minúsculas
|
95
|
+
if ioc_type in {IOCType.MD5, IOCType.SHA1, IOCType.SHA256, IOCType.SSDEEP}:
|
96
|
+
value = value.lower()
|
97
|
+
|
98
|
+
# Para IPs, normaliza o formato
|
99
|
+
if ioc_type == IOCType.IP:
|
100
|
+
try:
|
101
|
+
value = str(ipaddress.ip_address(value))
|
102
|
+
except ValueError:
|
103
|
+
return []
|
104
|
+
|
105
|
+
# Correspondência exata para outros tipos
|
106
|
+
return self.iocs[ioc_type].get(value, [])
|
107
|
+
|
108
|
+
def _match_pattern(self, value: str, ioc_type: IOCType) -> List[IOC]:
|
109
|
+
"""Verifica correspondência de padrão para URLs, e-mails e domínios."""
|
110
|
+
results = []
|
111
|
+
|
112
|
+
for ioc_value, ioc_list in self.iocs[ioc_type].items():
|
113
|
+
# Tenta correspondência exata primeiro
|
114
|
+
if ioc_value.lower() == value.lower():
|
115
|
+
results.extend(ioc_list)
|
116
|
+
continue
|
117
|
+
|
118
|
+
# Tenta correspondência de padrão se houver um padrão compilado
|
119
|
+
pattern = self.compiled_patterns[ioc_type].get(ioc_value)
|
120
|
+
if pattern and pattern.match(value):
|
121
|
+
results.extend(ioc_list)
|
122
|
+
|
123
|
+
return results
|
124
|
+
|
125
|
+
def search(self, query: str, limit: int = 100) -> List[IOC]:
|
126
|
+
"""
|
127
|
+
Realiza uma busca textual nos IOCs.
|
128
|
+
|
129
|
+
Args:
|
130
|
+
query: Termo de busca
|
131
|
+
limit: Número máximo de resultados a retornar
|
132
|
+
|
133
|
+
Returns:
|
134
|
+
Lista de IOCs correspondentes à consulta
|
135
|
+
"""
|
136
|
+
query = query.lower()
|
137
|
+
results = set()
|
138
|
+
|
139
|
+
# Busca em valores de IOC
|
140
|
+
for ioc_type, values in self.iocs.items():
|
141
|
+
for value, ioc_list in values.items():
|
142
|
+
if query in value.lower():
|
143
|
+
results.update(ioc_list)
|
144
|
+
if len(results) >= limit:
|
145
|
+
return list(results)[:limit]
|
146
|
+
|
147
|
+
# Busca em metadados
|
148
|
+
for ioc_list in self.iocs.values():
|
149
|
+
for ioc in ioc_list:
|
150
|
+
# Verifica tags
|
151
|
+
if any(query in tag.lower() for tag in ioc.tags):
|
152
|
+
results.add(ioc)
|
153
|
+
if len(results) >= limit:
|
154
|
+
return list(results)[:limit]
|
155
|
+
|
156
|
+
# Verifica metadados
|
157
|
+
if any(query in str(v).lower()
|
158
|
+
for v in ioc.metadata.values()
|
159
|
+
if v and isinstance(v, str)):
|
160
|
+
results.add(ioc)
|
161
|
+
if len(results) >= limit:
|
162
|
+
return list(results)[:limit]
|
163
|
+
|
164
|
+
return list(results)[:limit]
|
165
|
+
|
166
|
+
def get_by_tag(self, tag: str) -> List[IOC]:
|
167
|
+
"""Retorna todos os IOCs com a tag especificada."""
|
168
|
+
return list(self.tags_index.get(tag.lower(), set()))
|
169
|
+
|
170
|
+
def get_by_threat_type(self, threat_type: Union[str, ThreatType]) -> List[IOC]:
|
171
|
+
"""Retorna todos os IOCs do tipo de ameaça especificado."""
|
172
|
+
if isinstance(threat_type, str):
|
173
|
+
threat_type = ThreatType(threat_type.lower())
|
174
|
+
return list(self.threat_type_index.get(threat_type, set()))
|
175
|
+
|
176
|
+
def get_by_source(self, source: str) -> List[IOC]:
|
177
|
+
"""Retorna todos os IOCs da fonte especificada."""
|
178
|
+
return list(self.source_index.get(source.lower(), set()))
|
179
|
+
|
180
|
+
def get_recent(self, days: int = 7) -> List[IOC]:
|
181
|
+
"""Retorna IOCs adicionados nos últimos N dias."""
|
182
|
+
cutoff = datetime.utcnow() - timedelta(days=days)
|
183
|
+
results = []
|
184
|
+
|
185
|
+
for ioc_list in self.iocs.values():
|
186
|
+
for ioc in ioc_list:
|
187
|
+
if ioc.first_seen >= cutoff:
|
188
|
+
results.append(ioc)
|
189
|
+
|
190
|
+
return sorted(results, key=lambda x: x.first_seen, reverse=True)
|
191
|
+
|
192
|
+
def get_related(self, ioc: IOC, max_relations: int = 10) -> Dict[str, List[IOC]]:
|
193
|
+
"""
|
194
|
+
Encontra IOCs relacionados ao IOC fornecido.
|
195
|
+
|
196
|
+
Args:
|
197
|
+
ioc: O IOC de referência
|
198
|
+
max_relations: Número máximo de IOCs relacionados a retornar por tipo
|
199
|
+
|
200
|
+
Returns:
|
201
|
+
Dicionário mapeando tipos de relacionamento para listas de IOCs relacionados
|
202
|
+
"""
|
203
|
+
related = defaultdict(list)
|
204
|
+
|
205
|
+
# IOCs com as mesmas tags
|
206
|
+
for tag in ioc.tags:
|
207
|
+
for related_ioc in self.get_by_tag(tag):
|
208
|
+
if related_ioc != ioc and related_ioc not in related['tags']:
|
209
|
+
related['tags'].append(related_ioc)
|
210
|
+
|
211
|
+
# IOCs do mesmo tipo de ameaça
|
212
|
+
for threat_ioc in self.get_by_threat_type(ioc.threat_type):
|
213
|
+
if threat_ioc != ioc and threat_ioc not in related['threat_type']:
|
214
|
+
related['threat_type'].append(threat_ioc)
|
215
|
+
|
216
|
+
# IOCs da mesma fonte
|
217
|
+
for source_ioc in self.get_by_source(ioc.source):
|
218
|
+
if source_ioc != ioc and source_ioc not in related['source']:
|
219
|
+
related['source'].append(source_ioc)
|
220
|
+
|
221
|
+
# Limita o número de resultados por tipo
|
222
|
+
for key in related:
|
223
|
+
related[key] = related[key][:max_relations]
|
224
|
+
|
225
|
+
return dict(related)
|
226
|
+
|
227
|
+
def to_dict(self) -> Dict[str, Any]:
|
228
|
+
"""Converte o matcher para um dicionário."""
|
229
|
+
return {
|
230
|
+
'iocs': {
|
231
|
+
ioc_type.value: {
|
232
|
+
value: [ioc.to_dict() for ioc in ioc_list]
|
233
|
+
for value, ioc_list in values.items()
|
234
|
+
}
|
235
|
+
for ioc_type, values in self.iocs.items()
|
236
|
+
}
|
237
|
+
}
|
238
|
+
|
239
|
+
@classmethod
|
240
|
+
def from_dict(cls, data: Dict[str, Any]) -> 'IOCMatcher':
|
241
|
+
"""Cria um IOCMatcher a partir de um dicionário."""
|
242
|
+
matcher = cls()
|
243
|
+
|
244
|
+
for ioc_type_str, values in data.get('iocs', {}).items():
|
245
|
+
try:
|
246
|
+
ioc_type = IOCType(ioc_type_str)
|
247
|
+
for value, ioc_dicts in values.items():
|
248
|
+
for ioc_dict in ioc_dicts:
|
249
|
+
ioc = IOC.from_dict(ioc_dict)
|
250
|
+
matcher.add_ioc(ioc)
|
251
|
+
except (KeyError, ValueError) as e:
|
252
|
+
print(f"Erro ao carregar IOCs do tipo {ioc_type_str}: {e}")
|
253
|
+
|
254
|
+
return matcher
|
@@ -0,0 +1,267 @@
|
|
1
|
+
"""Tipos de IOCs (Indicadores de Comprometimento) suportados."""
|
2
|
+
from dataclasses import dataclass, field
|
3
|
+
from datetime import datetime
|
4
|
+
from enum import Enum, auto
|
5
|
+
from typing import Dict, List, Optional, Any, Union, Pattern
|
6
|
+
import re
|
7
|
+
import ipaddress
|
8
|
+
from urllib.parse import urlparse
|
9
|
+
|
10
|
+
class IOCType(Enum):
|
11
|
+
"""Tipos de IOCs suportados."""
|
12
|
+
IP = "ip"
|
13
|
+
DOMAIN = "domain"
|
14
|
+
URL = "url"
|
15
|
+
HASH = "hash"
|
16
|
+
EMAIL = "email"
|
17
|
+
CVE = "cve"
|
18
|
+
BTC = "btc"
|
19
|
+
MD5 = "md5"
|
20
|
+
SHA1 = "sha1"
|
21
|
+
SHA256 = "sha256"
|
22
|
+
SSDEEP = "ssdeep"
|
23
|
+
YARA = "yara"
|
24
|
+
SNORT = "snort"
|
25
|
+
SURICATA = "suricata"
|
26
|
+
CUSTOM = "custom"
|
27
|
+
|
28
|
+
class ThreatType(Enum):
|
29
|
+
"""Tipos de ameaças."""
|
30
|
+
MALWARE = "malware"
|
31
|
+
PHISHING = "phishing"
|
32
|
+
EXPLOIT = "exploit"
|
33
|
+
C2 = "c2"
|
34
|
+
BOTNET = "botnet"
|
35
|
+
SCANNING = "scanning"
|
36
|
+
SPAM = "spam"
|
37
|
+
PHISHING_KIT = "phishing_kit"
|
38
|
+
MALICIOUS_DOC = "malicious_document"
|
39
|
+
EXPLOIT_KIT = "exploit_kit"
|
40
|
+
BRUTE_FORCE = "brute_force"
|
41
|
+
DATA_LEAK = "data_leak"
|
42
|
+
CREDENTIAL_STUFFING = "credential_stuffing"
|
43
|
+
DARKNET = "darknet"
|
44
|
+
TOR = "tor"
|
45
|
+
VPN = "vpn"
|
46
|
+
PROXY = "proxy"
|
47
|
+
ABUSE = "abuse"
|
48
|
+
SCAM = "scam"
|
49
|
+
FRAUD = "fraud"
|
50
|
+
CRYPTOJACKING = "cryptojacking"
|
51
|
+
RANSOMWARE = "ransomware"
|
52
|
+
TROJAN = "trojan"
|
53
|
+
SPYWARE = "spyware"
|
54
|
+
ADWARE = "adware"
|
55
|
+
ROOTKIT = "rootkit"
|
56
|
+
BACKDOOR = "backdoor"
|
57
|
+
WORM = "worm"
|
58
|
+
VIRUS = "virus"
|
59
|
+
UNKNOWN = "unknown"
|
60
|
+
|
61
|
+
@dataclass
|
62
|
+
class IOC:
|
63
|
+
"""Classe base para Indicadores de Comprometimento (IOCs)."""
|
64
|
+
value: str
|
65
|
+
ioc_type: IOCType
|
66
|
+
threat_type: ThreatType = ThreatType.UNKNOWN
|
67
|
+
source: str = "unknown"
|
68
|
+
first_seen: datetime = field(default_factory=datetime.utcnow)
|
69
|
+
last_seen: datetime = field(default_factory=datetime.utcnow)
|
70
|
+
confidence: int = 50 # 0-100
|
71
|
+
tags: List[str] = field(default_factory=list)
|
72
|
+
metadata: Dict[str, Any] = field(default_factory=dict)
|
73
|
+
|
74
|
+
def __post_init__(self):
|
75
|
+
# Garante que o tipo seja uma instância de IOCType
|
76
|
+
if isinstance(self.ioc_type, str):
|
77
|
+
self.ioc_type = IOCType(self.ioc_type.lower())
|
78
|
+
if isinstance(self.threat_type, str):
|
79
|
+
self.threat_type = ThreatType(self.threat_type.lower())
|
80
|
+
|
81
|
+
# Valida o valor com base no tipo
|
82
|
+
self._validate()
|
83
|
+
|
84
|
+
def _validate(self):
|
85
|
+
"""Valida o valor com base no tipo de IOC."""
|
86
|
+
if not self.value:
|
87
|
+
raise ValueError("O valor do IOC não pode estar vazio")
|
88
|
+
|
89
|
+
validators = {
|
90
|
+
IOCType.IP: self._validate_ip,
|
91
|
+
IOCType.DOMAIN: self._validate_domain,
|
92
|
+
IOCType.URL: self._validate_url,
|
93
|
+
IOCType.HASH: self._validate_hash,
|
94
|
+
IOCType.EMAIL: self._validate_email,
|
95
|
+
IOCType.CVE: self._validate_cve,
|
96
|
+
IOCType.BTC: self._validate_btc,
|
97
|
+
IOCType.MD5: self._validate_md5,
|
98
|
+
IOCType.SHA1: self._validate_sha1,
|
99
|
+
IOCType.SHA256: self._validate_sha256,
|
100
|
+
IOCType.SSDEEP: self._validate_ssdeep,
|
101
|
+
IOCType.YARA: self._validate_yara,
|
102
|
+
IOCType.SNORT: self._validate_snort,
|
103
|
+
IOCType.SURICATA: self._validate_suricata,
|
104
|
+
}
|
105
|
+
|
106
|
+
validator = validators.get(self.ioc_type)
|
107
|
+
if validator and not validator():
|
108
|
+
raise ValueError(f"Valor inválido para IOC do tipo {self.ioc_type.value}: {self.value}")
|
109
|
+
|
110
|
+
# Métodos de validação
|
111
|
+
|
112
|
+
def _validate_ip(self) -> bool:
|
113
|
+
"""Valida um endereço IP."""
|
114
|
+
try:
|
115
|
+
ipaddress.ip_address(self.value)
|
116
|
+
return True
|
117
|
+
except ValueError:
|
118
|
+
return False
|
119
|
+
|
120
|
+
def _validate_domain(self) -> bool:
|
121
|
+
"""Valida um domínio."""
|
122
|
+
if not self.value or len(self.value) > 253:
|
123
|
+
return False
|
124
|
+
|
125
|
+
# Verifica se é um domínio válido
|
126
|
+
domain_regex = r'^([a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}$'
|
127
|
+
return bool(re.match(domain_regex, self.value))
|
128
|
+
|
129
|
+
def _validate_url(self) -> bool:
|
130
|
+
"""Valida uma URL."""
|
131
|
+
try:
|
132
|
+
result = urlparse(self.value)
|
133
|
+
return all([result.scheme in ('http', 'https', 'ftp', 'ftps'),
|
134
|
+
result.netloc])
|
135
|
+
except:
|
136
|
+
return False
|
137
|
+
|
138
|
+
def _validate_hash(self) -> bool:
|
139
|
+
"""Valida um hash genérico."""
|
140
|
+
# Aceita MD5, SHA-1, SHA-256, etc.
|
141
|
+
hash_regex = r'^[a-fA-F0-9]{32,128}$'
|
142
|
+
return bool(re.match(hash_regex, self.value))
|
143
|
+
|
144
|
+
def _validate_email(self) -> bool:
|
145
|
+
"""Valida um endereço de e-mail."""
|
146
|
+
email_regex = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
|
147
|
+
return bool(re.match(email_regex, self.value))
|
148
|
+
|
149
|
+
def _validate_cve(self) -> bool:
|
150
|
+
"""Valida um CVE (Common Vulnerabilities and Exposures)."""
|
151
|
+
cve_regex = r'^CVE-\d{4}-\d{4,}$'
|
152
|
+
return bool(re.match(cve_regex, self.value, re.IGNORECASE))
|
153
|
+
|
154
|
+
def _validate_btc(self) -> bool:
|
155
|
+
"""Valida um endereço Bitcoin."""
|
156
|
+
btc_regex = r'^[13][a-km-zA-HJ-NP-Z1-9]{25,34}$|^bc1[ac-hj-np-zAC-HJ-NP-Z02-9]{11,71}$'
|
157
|
+
return bool(re.match(btc_regex, self.value))
|
158
|
+
|
159
|
+
def _validate_md5(self) -> bool:
|
160
|
+
"""Valida um hash MD5."""
|
161
|
+
return bool(re.match(r'^[a-fA-F0-9]{32}$', self.value))
|
162
|
+
|
163
|
+
def _validate_sha1(self) -> bool:
|
164
|
+
"""Valida um hash SHA-1."""
|
165
|
+
return bool(re.match(r'^[a-fA-F0-9]{40}$', self.value))
|
166
|
+
|
167
|
+
def _validate_sha256(self) -> bool:
|
168
|
+
"""Valida um hash SHA-256."""
|
169
|
+
return bool(re.match(r'^[a-fA-F0-9]{64}$', self.value))
|
170
|
+
|
171
|
+
def _validate_ssdeep(self) -> bool:
|
172
|
+
"""Valida um hash ssdeep."""
|
173
|
+
return ':' in self.value and all(part for part in self.value.split(':'))
|
174
|
+
|
175
|
+
def _validate_yara(self) -> bool:
|
176
|
+
"""Valida uma regra YARA."""
|
177
|
+
return 'rule ' in self.value and '{' in self.value and '}' in self.value
|
178
|
+
|
179
|
+
def _validate_snort(self) -> bool:
|
180
|
+
"""Valida uma regra Snort."""
|
181
|
+
return self.value.strip().startswith('alert ') and ('->' in self.value or '<>' in self.value)
|
182
|
+
|
183
|
+
def _validate_suricata(self) -> bool:
|
184
|
+
"""Valida uma regra Suricata."""
|
185
|
+
return self.value.strip().startswith(('alert ', 'drop ', 'reject ')) and ';' in self.value
|
186
|
+
|
187
|
+
def to_dict(self) -> Dict[str, Any]:
|
188
|
+
"""Converte o IOC para um dicionário."""
|
189
|
+
return {
|
190
|
+
'value': self.value,
|
191
|
+
'type': self.ioc_type.value,
|
192
|
+
'threat_type': self.threat_type.value,
|
193
|
+
'source': self.source,
|
194
|
+
'first_seen': self.first_seen.isoformat(),
|
195
|
+
'last_seen': self.last_seen.isoformat(),
|
196
|
+
'confidence': self.confidence,
|
197
|
+
'tags': self.tags,
|
198
|
+
'metadata': self.metadata
|
199
|
+
}
|
200
|
+
|
201
|
+
@classmethod
|
202
|
+
def from_dict(cls, data: Dict[str, Any]) -> 'IOC':
|
203
|
+
"""Cria um IOC a partir de um dicionário."""
|
204
|
+
return cls(
|
205
|
+
value=data['value'],
|
206
|
+
ioc_type=data['type'],
|
207
|
+
threat_type=data.get('threat_type', 'unknown'),
|
208
|
+
source=data.get('source', 'unknown'),
|
209
|
+
first_seen=datetime.fromisoformat(data.get('first_seen', datetime.utcnow().isoformat())),
|
210
|
+
last_seen=datetime.fromisoformat(data.get('last_seen', datetime.utcnow().isoformat())),
|
211
|
+
confidence=data.get('confidence', 50),
|
212
|
+
tags=data.get('tags', []),
|
213
|
+
metadata=data.get('metadata', {})
|
214
|
+
)
|
215
|
+
|
216
|
+
# Classes específicas para cada tipo de IOC
|
217
|
+
|
218
|
+
@dataclass
|
219
|
+
class IPAddress(IOC):
|
220
|
+
"""Representa um endereço IP como IOC."""
|
221
|
+
def __post_init__(self):
|
222
|
+
self.ioc_type = IOCType.IP
|
223
|
+
super().__post_init__()
|
224
|
+
|
225
|
+
@property
|
226
|
+
def is_private(self) -> bool:
|
227
|
+
"""Verifica se o IP é privado."""
|
228
|
+
return ipaddress.ip_address(self.value).is_private
|
229
|
+
|
230
|
+
@property
|
231
|
+
def is_global(self) -> bool:
|
232
|
+
"""Verifica se o IP é global (público)."""
|
233
|
+
return ipaddress.ip_address(self.value).is_global
|
234
|
+
|
235
|
+
@dataclass
|
236
|
+
class Domain(IOC):
|
237
|
+
"""Representa um domínio como IOC."""
|
238
|
+
def __post_init__(self):
|
239
|
+
self.ioc_type = IOCType.DOMAIN
|
240
|
+
super().__post_init__()
|
241
|
+
|
242
|
+
@property
|
243
|
+
def tld(self) -> str:
|
244
|
+
"""Retorna o TLD (Top-Level Domain) do domínio."""
|
245
|
+
return self.value.split('.')[-1] if '.' in self.value else ''
|
246
|
+
|
247
|
+
@property
|
248
|
+
def sld(self) -> str:
|
249
|
+
"""Retorna o SLD (Second-Level Domain) do domínio."""
|
250
|
+
parts = self.value.split('.')
|
251
|
+
return parts[-2] if len(parts) > 1 else ''
|
252
|
+
|
253
|
+
# Adicione mais classes específicas conforme necessário
|
254
|
+
|
255
|
+
def create_ioc(value: str, ioc_type: Union[str, IOCType], **kwargs) -> IOC:
|
256
|
+
"""Cria um IOC do tipo especificado."""
|
257
|
+
if isinstance(ioc_type, str):
|
258
|
+
ioc_type = IOCType(ioc_type.lower())
|
259
|
+
|
260
|
+
ioc_classes = {
|
261
|
+
IOCType.IP: IPAddress,
|
262
|
+
IOCType.DOMAIN: Domain,
|
263
|
+
# Adicione mais mapeamentos conforme necessário
|
264
|
+
}
|
265
|
+
|
266
|
+
ioc_class = ioc_classes.get(ioc_type, IOC)
|
267
|
+
return ioc_class(value=value, ioc_type=ioc_type, **kwargs)
|