Since completing the SANS Institute Cloud Security and DevSecOps Automation (SEC540) Course last December, I have kept busy with some hands-on practice through the course CloudWars challenges. CloudWars challenges for courses in the SANS Cloud Security curriculum are intended to reinforce the concepts in the course materials through self-directed exploration of the tools and technologies. To say that I have learnt a ton would be quite the understatement. From a state of excited bewilderment during the week of the course last September, I worked through the labs multiple times, caused and debugged many an error and managed to crawl to the top of the leaderboard, earning myself a challenge coin along the way!

SEC540 CloudWars Challenges

The CloudWars Challenges for SEC540 covered exercises on various tools in the CI-CD toolchain, including Git and GitLab, Terraform, AWS Cloudformation, Jenkins, AWS CLI, Azure CLI, etc. The majority of the exercises are somewhat guided, with hints and snippets highlighting the “paved path” to solving challenge problems. However, there is a Leet skill section that is described on the course range as “Undocumented, off road, no hints challenges for advanced students to work on.” Some of the exercises in this section included developing a custom cfn_nag rule to detect an AWS Apigateway with data trace enabled (leads to excessive logging and potential leaking of sensitive information, hence only appropriate for development debugging but not production systems), developing a custom Semgrep rule to detect a vulnerability in a Java code using the Semgrep playground, implementing CIS Benchmark unit tests for AWS Infrastructure in the CI-CD Pipeline with Inspec (to help highlight potential misconfigurations in the cloud environment), and signing AWS Elastic Container Registry (ECR) container images with Cosign (to establish a chain of trust for images).

Arguably my favourite leet skill challenge, however, was one that required chaining together two web application vulnerabilities to exploit the Amazon ECS meta-data service running the web application and ultimately obtain the role credentials attached to the application. Before I tell you all about these vulnerabilities and how they were chained together, a little context about the DunderMifflin web application and infrastructure stack would be appropriate.

The DunderMifflin Paper Company’s Application Stack

SEC540 labs are built around the web application and APIs for the fictional DunderMifflin Paper company, together with the CI-CD infrastructure for deploying the application code to the cloud environment (AWS, in this case). DunderMifflin’s public-facing web application is a Java Spring Boot application running in a container service. The vulnerabilities we exploit are related to two features of the web application — a coupon service that allows a visitor to the website to get a discount coupon upon registration, and human resource service endpoints that allow logged in employees to view their profile information as well as allowing managers to view and manage profiles for employees that are their direct reports.

When a coupon can deliver more than just discounts?

Discount-related features for the DM-Web application are provided by a DiscountService and associated DiscountController in the Java code. One interesting endpoint in the discount service is the /api/discount/coupon . The code snippets for this endpoint and a related helper method are shown below:

The Vulnerable DiscountService /api/discount/coupon endpoint

The Vulnerable DiscountService /api/discount/coupon endpoint

Helper loadFileAsString method used by the vulnerable /api/discount/coupon endpoint

Helper loadFileAsString method used by the vulnerable /api/discount/coupon endpoint

This endpoint takes a file parameter in the incoming http request (lines 43 - 47) and returns the corresponding file in the web server file system as a string to the caller (lines 54 - 55). My guess is that this endpoint was intended to serve discount coupons files. There is however a security gap in the implementation; an absence of user input validation and sanitization — the file parameter from the request is passed directly to the loadFileAsString method without any pre-processing— leaving the endpoint vulnerable to path traversal and local file inclusion type exploits. We will delve into some detail about this vulnerability in a bit.