{ "info": { "author": "Erik Steringer", "author_email": "erik.steringer@nccgroup.com", "bugtrack_url": null, "classifiers": [ "Environment :: Console", "Intended Audience :: Developers", "Intended Audience :: Information Technology", "Intended Audience :: System Administrators", "License :: OSI Approved :: GNU Affero General Public License v3", "Natural Language :: English", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Topic :: Security" ], "description": "# Principal Mapper\n\nPrincipal Mapper (PMapper) is a script and library for identifying risks in the configuration of AWS Identity and \nAccess Management (IAM) in an AWS account.\n\nPMapper allows users to identify which IAM users and roles have access to certain actions and resources in an AWS \naccount. This is important for ensuring that sensitive resources, such as S3 objects with PII, are isolated. \n\nPMapper creates a graph of an AWS account's IAM users and roles (principals). This graph, composed of nodes and edges, \nrepresents the different ways that one principal could access another. When running a query to determine if a \nprincipal has access to a certain action/resource, it also checks if the user or role could access other users or roles \nthat have access to that action/resource. This catches scenarios such as when a user doesn't have direct access to an \nS3 object, but could launch an EC2 instance that has access to the S3 object.\n\n# Installation\n\n## Requirements\n\nPrincipal Mapper is built using the `botocore` library and Python 3.5+. Python 2 is not supported. Principal Mapper \nalso requires `pydot` (available on `pip`), and `graphviz` (available on Windows, macOS, and Linux from \nhttps://graphviz.org/ ).\n\n## Installation from Pip\n\n~~~bash\npip install principalmapper\n~~~\n\n## Installation From Source Code\n\nClone the repository:\n\n~~~bash\ngit clone git@github.com:nccgroup/PMapper.git\n~~~\n\nThen install with Pip:\n\n~~~bash\ncd PMapper\npip install .\n~~~\n\n# Usage\n\n## Graphing\n\nTo start, create a graph for an AWS account:\n\n~~~bash\npmapper graph --create\n~~~\n\nThis stores information locally on disk about all the IAM users, roles, groups, and policies in the account. Accounts \nthat are already graphed can be found using:\n\n~~~bash\npmapper graph --list\n~~~\n\nThe account IDs that are printed can be used in other `pmapper` subcommands via the `--account` parameter.\n\n## Querying\n\nAfter creating a graph, write queries to learn more about which users and roles can access certain actions or resources.\n\n~~~bash\npmapper argquery --action s3:GetObject --resource arn:aws:s3:::bucket/path/to/object \n~~~\n\n`argquery` takes the elements to check for (principal, action, resource, conditions) as arguments of the `pmapper` \ncommand. When `--principal` is not specified, it runs the query for all IAM users and roles in the account. When \n`--resource` is not specified, it defaults to the wildcard (`*`).\n\n`query` parses a more human-readable input string into a query and returns the results.\n\n~~~bash\npmapper query \"who can do s3:GetObject with arn:aws:s3:::bucket/path/to/object\"\n~~~\n\nThere are two special queries, presets, available:\n\n* `privesc`: Identify privilege escalation risks.\n* `connected`: Identify which principals can access other principals.\n\nThese presets are accessible from `query` and `argquery`. See the following examples:\n\n~~~bash\n# Determine if PowerUser can escalate privileges\npmapper query \"preset privesc user/PowerUser\"\npmapper argquery --principal user/PowerUser --preset privesc\n\n# Find all principals that can escalate privileges\npmapper query \"preset privesc *\"\npmapper argquery --principal '*' --preset privesc\n\n# Find all principals that PowerUser can access\npmapper query \"preset connected user/PowerUser *\"\npmapper argquery --principal user/PowerUser --resource '*' --preset connected\n\n# Find all principals that can access PowerUser\npmapper query \"preset connected * user/PowerUser\"\npmapper argquery --principal '*' --resource user/PowerUser --preset connected\n~~~\n\n## REPL\n\nThe Read-Evaluate-Print-Loop (REPL) is a program for running several queries at once. The REPL has four commands:\n\n* `query`: Executes human-readable queries.\n* `argquery`: Executes queries with a set of parameters.\n* `help`: Prints out information on how to use the REPL.\n* `exit`: Exits the REPL (Ctrl+C should also work).\n\nWhen the REPL is launched, it loads the data for a single graph and executes all queries against that graph. You can \nlaunch the repl like so:\n\n~~~bash\npmapper repl\n~~~\n\nInteracting with the REPL is very similar to running multiple queries from the command-line:\n\n~~~\nrepl> query \"who can do s3:GetObject with *\"\n...\nrepl> argquery --principal \"*\" --preset privesc\n~~~\n\n## Visualization\n\nPMapper includes a visualization feature, which draws a specified graph. This graph highlights principals with \nadministrative privileges in blue, and principals that can escalate privileges in red. It supports SVG, PNG, and DOT \nfile outputs. It uses `graphviz` in order to create the image. It can be used like so:\n\n~~~bash\npmapper visualize --filetype png\n~~~\n\n![](example-viz.png)\n\n## Analysis\n\nPMapper provides analysis to identify risks with the configuration in an account. It provides details on the risk, what \nimpact it could have on the account, which principals are affected, and a recommendation on how to mitigate the risk. \nThe outputs from `analysis` can be in text or JSON format, and can be created with the following command:\n\n~~~bash\npmapper analysis --output-type text\n~~~\n\n# Credentials and Global Parameters\n\nPMapper grabs credentials in the following order:\n\n1. The `--profile` argument, when specified, is checked first. If specified, PMapper grabs credentials from botocore \nfor that profile name.\n2. PMapper uses the `get_session()` function from `botocore.session`, which should grab credentials from the \nenvironment variables/metadata service/default profile.\n\nFor querying, REPL, visualization, and analysis, you can specify the `--account` argument with the 12-digit ID of the \naccount to examine. This cannot be specified along with `--profile`. It directs PMapper to use that account \nfor the command, rather that deriving the account from credentials.\n\n# Library Use\n\nPrincipal Mapper includes a library that can be used instead of the command-line interface. All functions and methods \nhave type-hints and a small amount of documentation for reference. See [example_script.py](example_script.py) for \nan example.\n\nFuture major-version revisions (e.g. 1.X.X -> 2.0.0) of Principal Mapper may alter/remove functions/classes/methods. \nMinor-version revisions (e.g. 1.1.X -> 1.2.0) will not remove existing functions/classes/methods but may add new ones \nor alter their behaviors.\n\n**Exception:** All instances of the `debug` parameter in all of the functions in this library, which is used by the \n`dprint` function, will eventually be removed as the logging bits are improved. Just keep the `debug` parameter out \nof your production code. `dprint` is gonna be replaced too.\n\n## Packages of Interest\n\n### Common\n\n* `principalmapper.common`\n * Classes `Graph`, `Node`, `Edge`, `Group`, and `Policy`. These can be imported \n straight through `principalmapper.common` with a single statement:\n \n ~~~python\n from principalmapper.common import Graph, Node, Edge\n ~~~\n\n### Graphing\n\n* `principalmapper.graphing.graph_actions`\n * function `get_existing_graph`: grabs a Graph object from disk, based on current botocore session or account ID, \n from a standard location on-disk.\n * function `get_graph_from_disk`: grabs a Graph object from disk, user-specified directory.\n* `principalmapper.graphing.gathering` \n * function `create_graph`: generates Graph objects using a botocore Session object.\n* `principalmapper.graphing.edge_identification` \n * variable `checker_map`: a dictionary, the keys of which are services that this version of Principal Mapper can get \n edge data from. This should always be updated with all services that are supported, and `checker_map.keys()` can \n always be passed to `create_graph` without error.\n\n### Querying\n\n* `principalmapper.querying.query_interface`\n * function `search_authorization_for`: performs an expansive search to determine if a principal can make a given \n AWS API call, or if the principal can access another that does have permission. Returns `QueryResult` objects \n (defined in `principalmapper.querying.query_result`) with information on if the principal is authorized, or if \n it has to chain through other principals with authorization.\n * function `local_check_authorization`: determines if a principal can make a given AWS API call, but **DOES NOT** \n perform the expansive search of `search_authorization_for`.\n * function `local_check_authorization_handling_mfa`: determines if a principal can make a given AWS API call, \n **DOES NOT** perform the expansive search of `search_authorization_for`, but **DOES** manipulate condition keys \n to test if the AWS API call can be made with or without MFA. Note that you can achieve the same effect by calling \n `local_check_authorization` and setting the multi-factor auth conditions.\n\n### Visualizing\n\n* `principalmapper.visualizing.graph_writer`:\n * function `handle_request`: creates an image file (PNG/SVG) or graph file (DOT)\n \n### Analysis\n\n* `principalmapper.analysis.find_risks`:\n * function `gen_findings_and_print`: dumps findings in markdown(text)/JSON format to stdout. Wraps around \n `gen_report`, which can be used instead for custom formatting by pulling `Report` and `Finding` objects.\n* `principalmapper.analysis.report`: \n * class `Report`: a simple object containing metadata about generated findings (account ID, date, version of \n PMapper).\n* `principalmapper.analysis.finding`:\n * class `Finding`: a simple object containing data about a risk to the AWS account. \n \n### Utils\n\n* `principalmapper.util.arns`:\n * functions prefixed with `get_`: extract a specific chunk of an ARN, like the account ID or region.\n* `principalmapper.util.botocore_tools`:\n * function `get_session`: get a botocore Session object based on optional profile parameter.\n* `principalmapper.util.storage`:\n * function `get_storage_root`: returns a path on disk that Principal Mapper will use for storing Graph data by \n default. Output depends on OS.\n\n# License\n\n Copyright (c) NCC Group and Erik Steringer 2019. This file is part of Principal Mapper.\n\n Principal Mapper is free software: you can redistribute it and/or modify\n it under the terms of the GNU Affero General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n Principal Mapper is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Affero General Public License for more details.\n\n You should have received a copy of the GNU Affero General Public License\n along with Principal Mapper. If not, see .", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/nccgroup/PMapper", "keywords": "AWS,IAM,Security,PMapper,principalmapper,Principal Mapper,NCC Group", "license": "AGPLv3", "maintainer": "", "maintainer_email": "", "name": "principalmapper", "package_url": "https://pypi.org/project/principalmapper/", "platform": "", "project_url": "https://pypi.org/project/principalmapper/", "project_urls": { "Homepage": "https://github.com/nccgroup/PMapper" }, "release_url": "https://pypi.org/project/principalmapper/1.0.1/", "requires_dist": null, "requires_python": ">=3.5, <4", "summary": "A Python script and library for analyzing an AWS account's use of IAM.", "version": "1.0.1" }, "last_serial": 5914964, "releases": { "1.0.0": [ { "comment_text": "", "digests": { "md5": "14ad90e48c56cdac1a5fe989c45b1e6f", "sha256": "48b40052d6e30a3e3086804a4858d59c4aa45d16fbe07eb702432a68f89503ea" }, "downloads": -1, "filename": "principalmapper-1.0.0.tar.gz", "has_sig": false, "md5_digest": "14ad90e48c56cdac1a5fe989c45b1e6f", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.5, <4", "size": 370059, "upload_time": "2019-09-18T03:14:45", "url": "https://files.pythonhosted.org/packages/64/cf/6509d5b01d44672662359b6c73abbefcc275812c5c63e3931711e31f2e33/principalmapper-1.0.0.tar.gz" } ], "1.0.1": [ { "comment_text": "", "digests": { "md5": "c72fdd59a60dad008fa81c4b69978426", "sha256": "20178f17a1937ab9b73b2dc247314f46c11f562369097af3a9455117e778b6f8" }, "downloads": -1, "filename": "principalmapper-1.0.1.tar.gz", "has_sig": false, "md5_digest": "c72fdd59a60dad008fa81c4b69978426", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.5, <4", "size": 370321, "upload_time": "2019-10-01T21:19:38", "url": "https://files.pythonhosted.org/packages/c3/f8/59030be97f8cc7c866e00ae4d4b06fd790e1707551e280ca5a111c5901bb/principalmapper-1.0.1.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "c72fdd59a60dad008fa81c4b69978426", "sha256": "20178f17a1937ab9b73b2dc247314f46c11f562369097af3a9455117e778b6f8" }, "downloads": -1, "filename": "principalmapper-1.0.1.tar.gz", "has_sig": false, "md5_digest": "c72fdd59a60dad008fa81c4b69978426", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.5, <4", "size": 370321, "upload_time": "2019-10-01T21:19:38", "url": "https://files.pythonhosted.org/packages/c3/f8/59030be97f8cc7c866e00ae4d4b06fd790e1707551e280ca5a111c5901bb/principalmapper-1.0.1.tar.gz" } ] }