Enumerate IAM Privileges dinamically

This is a cool way to automate the process of enumerating the Credentials in AWS that I came up for Nebula.

When it comes to enumerating API Privileges on AWS, you need to Enumerate both Read and Write Privs. Write Privs are a bit tricky, since they change stuff on infrastructure (though I'm working on a module to make a Dry-Run Test on Write Privs), but Read ones are not that hard to test. Just find a set of credentials and try new API. If you get AccessDenied, you are not allowed to test, else, you get the info.

Read Privs are split into Get and List Privs, while there are commands/functions that have Describe. Describe are a combination of List+Get of a few APIs.

List and Describe do not need parameters to be called, so just creating a client and calling them will do. The trick is that there are over 250 Services with tens of functions, which needs to be listed, gathered, checked and called. To not do that, I came up with an idea to use the metadata from an object and list the functions. Then, just get the List and Describe functions and use them.

dir() on an object

The dir() method tries to return a list of valid attributes of the object. The syntax is **dir(object)**

As you can see, we have the TestClass, with 2 variables, one int and one string and 2 functions, one with no arguments (asside from self) and the other with one.

When we create an object and use dir(testobj), we get the attributes of that object, including the functions and the variables.

**Be aware**

Functions do not have parenthesis "()" after them, so you don't always know if something is a function or a variable. Ofc, that is not a problem on boto3, since what you'll call are functions, but you get the idea.

Let's now test it using a client. We'll create the client from a saved session on ~/.aws, but you can also include the credentials on the client using boto3.client()

As seen, we created the client for IAM and used dir() to get all the functions. Now we have every callable attribute from out client object. The only thing that is left is to get all the list, get and describe methods.

IAM has no Describe Methods, but has List methods. Now, we just need to call them. To call a function/method dynamically, use getattr() function (Don't forget the () at the end) and provide the object and the function name.

For example, calling STS:GetCallerIdentity from getattr() looks like this:

Now, just loop the methods on the desctibe and list lists and you get the privs. To not get the exceptions, use a try/catch and you are set. The final script is:

Running the script, you'll get:

Now, just get the list of services, put them on an list, on a loop create the client from session or by providing the credentials and use the above script to get them.

Pro Tip

To generate a list of allowed services, call a nonexistent service and you will get an error telling the list of all services.

enum_user_privs

This method is added to Nebula (https://github.com/gl4ssesbo1/Nebula):

use credentials <credname>
use workspace <workspace name>
enum_user_privs

Conclusions

In the end, this was not a big discovery when it comes to Python, but was a really cool way to automate all the process. Will come in a while with a new module on Write Privs.

Last updated