Module 25: Attacking AWS Cloud Infrastructure

About the Public Cloud Labs

Progess is not saved. These labs are in OffSec's Ppublic Cloud Labs which are access directly through the internet.

Leaked Secrets to Poisoned Pipeline - Lab Design

Accessing the Labs

  • A DNS server's IP address

  • A Kali IP address

  • A Kali Password

  • An AWS account with no permissions (more on this later)

Each lab restart will require setting up the DNS server again.

Setting DNS server and verifying it:

kali@kali:~$ nmcli connection
NAME                UUID                                  TYPE      DEVICE 
Wired connection 1  67f8ac63-7383-4dfd-ae42-262991b260d7  ethernet  eth0   
lo                  1284e5c4-6819-4896-8ad4-edeae32c64ce  loopback  lo 

kali@kali:~$ sudo nmcli connection modify "Wired connection 1" ipv4.dns "203.0.113.84"

kali@kali:~$ sudo systemctl restart NetworkManager

kali@kali:~$ cat /etc/resolv.conf
# Generated by NetworkManager
search localdomain
nameserver 203.0.113.84
...

kali@kali:~$ nslookup git.offseclab.io
Server:         203.0.113.84
Address:        203.0.113.84#53

Non-authoritative answer:
Name:   git.offseclab.io
Address: 198.18.53.73

Enumeration

Enumerating Jenkins

Enumerating Jenkins with MSF:

Enumerating the Git Server

Running hydra on the user login:

Enumerating the Application

Reviewing the source code to find a S3 bucket:

Using curl to list the bucket:

Enumerating the bucket with just the first 50 lines of common.txt:

Using awscli to list contents of the bucket:

Discovering Secrets

Downloading the Bucket

Downloading a copy of the README.md:

Downloading the S3 bucket:

Reviewing contents of discovered scripts:

Searching for Secrets in Git

Installing gitleaks:

To run gitleaks, we must be in the root of the static_content folder:

Reviewing git log:

Reviewing the commit that noted "Fix issue":

Reviewing the basic authentication base64 string discovered:

Poisoning the Pipeline

Enumerating the Repositories

Reviewing the Jenkinsfile now that we are logged in as administrator and can browse the repo:

Nothing much here. Checking out the other repo's Jenkinsfile:

Reviewing Webhooks under Settings
Reviewing Webhook Triggers

Modifying the Pipeline

Modifying the Jenkinsfile for static_content to spawn a reverse shell:

Enumerating the Builder

OS and Kernel enumeration:

Listing working and home directory:

Checking for private keys, authorized keys, and the network configuration:

The results for network configuration information indicate likely being inside a container.

Checking mounts:

Output confirms we're inside a docker container.

Checking Capability for container:

Decoding the capabilities:

Discovering AWS keys:

Compromising the Environment via Backdoor Account

Discovering What We Have Access To

Configured a new profile with the information discovered:

Getting User Name:

Listing Policies and Group for User:

Getting the user policy discovered:

Creating a Backdoor Account

Creating our backdoor user:

Attaching the AdministratorAccess policy to our backdoor user:

Getting our user creds:

Configuring our new backdoor profile:

Dependency Chain Abuse

Accessing the Labs

  • A DNS server's IP address

  • A Kali IP address

  • A Kali password

Information Gathering

Enumerating the Services

Poke around the website. Check Network tab of the developer settings, look at the headers.

Conducting Open Source Intelligence

Search sites like Stack Overflow, Reddit, etc.

Dependency Chain Attack

Understanding the Attack

Flow of Downloading When Public Repo does not Contain Package
Flow of Downloading when Public Repo does Contain Package

Creating Our Malicious Package

Structure of a Python Package:

Instead of setup.py, we can also use pyproject.toml or setup.cfg.

Creating a basic Python Package:

Running the newly created Python Package:

Installing hackshort-util locally:

Importing and using hackshort_util package:

Uninstalling hackshort-util so we can reinstall with our updates:

Command Execution During Install

Adding custom code to run during install:

Removing the existing package then building the new package:

Installing the new package and checking if custom code executed:

Command Execution During Runtime

We know the developers we're targeting use the package by importing utils from hackshort_utils.

Creating utils.py file with Exception Hook function:

Uninstalling, rebuilding, and reinstalling hackshort-util package:

Testing our newly created package:

Adding a Payload

Generating a python meterpreter payload:

Modifying utils.py to add the generated payload:

Logging into the cloud Kali instance via SSH:

Initializing Metasploit's Database:

Starting Metasploit and configuring the handler:

Uninstalling, rebuilding, reinstalling, and importing the hackshort-util package:

Capturing the reverse shell:

Closing the Meterpreter Session:

Publishing Our Malicious Package

Configuring ~/.pypirc file to add server URL and login credentials:

Uploading our malicious package to offseclab repository:

If a bad package was uploaded and we need to remove it, we can run the following command: curl -u "student:password" --form ":action=remove_pkg" --form "name=hackshort-util" --form "version=1.1.4" http://pypi.offseclab.io/

Obtaining a reverse shell after publishing our malicious package to pypi.offseclab.io PyPI server:

Compromising the Environment

Enumerating the Production Container

Interacting with the new session:

Reviewing network interfaces:

Checking user and current directory:

Reviewing mounts:

Reviewing environment variables:

Closed and reopened meterpreter sessions:

Scanning the Network

Creating a python script for port scanning:

Transferring netscan.py to cloud kali instance:

Uploading netscan.py to the target:

Reminding ourselves o fthe network ranges we're targeting:

Port scanning 172.18.0.1/24 to shorten the scan time rather than /16:

When you run netscan.py, it might seem that the shell is frozen. This is normal while the script runs. Give it a few minutes, and it should become responsive and display the output of the scan.

Using curl to fingerprint services:

Port scanning on 172.30.0.1/24 for the same reason:

Discovered the Jenkins Service while running curl on specific endpoins:

Loading Jenkins

Tunneling Diagram

Exiting shell and sending session to background:

Using SOCKS proxy module and running it:

Creating a route:

Tunneling Diagram with no SSH tunnel

Creating local forward ssh tunnel:

Setup firefox proxy to SOCK5 to 127.0.0.1 on port 1080 or a FoxyProxy profile for SOCKS5 to 127.0.0.1 on port 1080.

Adding a SOCKS proxy to Firefox
Adding a SOCKS proxy to FoxyProxy
Jenkins on the internal network of our target via Firefox

Exploiting Jenkins

Self-registering a Jenkins account
Navigating to the Dashboard
Company Directory
Researching the S3 Explorer plugin
Navigating to S3 Explorer
View Source on S3 Explorer

Finding the AWS key in Source:

Enumerating with Discovered Credentials

Configuring a profile with our discovered AWS credentials:

Getting the Account ID and User Name:

Listing S3 bucket for Company Directory:

Listing all Buckets from stolen-s3 account:

The prefix "tf" in cloud environments often refers to Terraform, and a Terraform state often refers to the file that is used to store the current configuration, including potential secrets.

Discovering the State File and Escalating to Admin

Listing the Terraform State Bucket:

Copying Terraform State File to our local Kali machine:

Reviewing State File - Users:

Reviewing State File - Keys:

Configuring Goran.B Profile using AWS CLI:

Listing attached user policies with Goran.B profile:

Last updated