Last active
September 16, 2021 22:25
-
-
Save omarmciver/8752a6e6048a7445bfea1ddfdf85c4c2 to your computer and use it in GitHub Desktop.
Find Azure Linux Agent OMI Open Ports (CVE-2021-38647)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Omar McIver | |
# September 16th 2021 | |
# Subject: Open Management Infrastructure Remote Code Execution Vulnerability (CVE-2021-38647) | |
# Ref: https://msrc.microsoft.com/update-guide/en-US/vulnerability/CVE-2021-38647 | |
####################### | |
# This script will visit each of your Linux VMs and use a run-command to cat the omiserver.conf file and then grep for "port=" | |
# This will return you the httpport=XXX and httpsport=XXX settings. If these are non-Zero then you need to get your OMI agent patched to secure against the vulnerability. | |
####################### | |
# We will process the VMs in batches that run as Parrallel Powershell Jobs. | |
# Don't set this too high as the Ptyhon script behind the az cli can use a lot more memory than you think!! | |
$pageRequestSize = 10 | |
# If we want to skip an initial number of query results, set that here... (like if your network connection dies and you have to start again, you can resume). | |
$skipCount = 0 | |
# Define and execute the initial Resource Graph query to get non AKS Linux VMs | |
$query = "where (type == 'microsoft.compute/virtualmachines' and properties.storageProfile.osDisk.osType == 'Linux' and name !startswith 'aks-') | order by name asc" | |
$vms = az graph query --graph-query $query --first $pageRequestSize --skip $skipCount | ConvertFrom-Json | |
# Set some counters | |
$currentPageSize = $vms.count | |
$counter = $skipCount | |
$totalCount = $vms.total_records | |
# This is the script block that will be executed as a Job for each VM | |
# It is a run-command that cat's the omiserver.conf file and then greps for port=, which should get you httpport=XXX and httpsport=XXX | |
$scriptBlock = { | |
param($sub, $rg, $name) | |
az vm run-command invoke --subscription $sub -g $rg -n $name --command-id RunShellScript --scripts "sudo cat /etc/opt/omi/conf/omiserver.conf | grep port=" | |
} | |
# Do > While we have records to process.... | |
do { | |
# Define an array to store the Jobs in... | |
$jobs = @() | |
# Provide some user feedback on page progress... | |
Write-Output "Processing records $counter to $($counter+$currentPageSize) out of $totalCount..." | |
# For each VM on this result page, write out it's name, create a Job to execute the config file check, and add to the Jobs array. | |
foreach ($v in $vms.data) { | |
Write-Output $v.name | |
$jobs += Start-Job -ScriptBlock $scriptBlock -Name $v.name -ArgumentList $v.subscriptionId, $v.resourceGroup, $v.name | |
} | |
# Assuming we did create Jobs (should you add in some criteria to skip certain VMs above), let's wait until all those Jobs have completed. | |
if ($jobs.Length -gt 0) { | |
Wait-Job -Job $jobs #| Out-Null | |
} | |
# Revisit each VM on this results page and Recieve the Job result. | |
foreach ($v in $vms.data) { | |
# Parse the result message from the run-command. This will include the [stdout] and [stderr]. We only care about those lines we grepped. | |
# WARNING!: This script does not handle errors from the Job execution, so it is possible this result object processing could thrown an error. | |
# The lazy way to address this is to check the script after running for any errors | |
$result = ((Receive-Job -Name $v.name) | ConvertFrom-Json).value[0].message -split '\r?\n' | |
foreach ($line in $result) { | |
if ($line.Contains('port=')) { | |
$output = "$($v.name),$line" | |
Add-Content -Path .\omiportsfound.csv -Value $output -PassThru | |
} | |
} | |
} | |
# We're done with this page of results, so increment counters and enecute the next Resource Graph page query. | |
$counter += $currentPageSize | |
$vms = az graph query --graph-query $query --first $pageRequestSize --skip $counter | ConvertFrom-Json | |
$currentPageSize = $vms.count | |
# WARNING: There is a risk that while waiting for the Jobs to process, the Resource Graph query results may have changed, meaning you could miss some VMs. | |
# If this is an issue for you, re-write this script to first parse out all VM names, subscriptions and RGs - and process the run command AFTER getting a complete | |
# picture of the VM inventory. | |
} while ($currentPageSize -gt 0) | |
# Have fun! :) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment