A virtual machine has ever crashed, right? A great way to connect to your virtual machine directly and troubleshoot is with Azure Serial Console. Everyone has access to the free Azure Serial Console feature. Although this feature’s main goal is to help users debug their computer, there are a number of intriguing ways to abuse it and jeopardize private data. Let’s examine different ways to take advantage of different features and find out if there is exploitation activity going on.
Contents
- Azure Serial Console: What Is It?
- Why might an adversary make a good target out of Azure Serial Console?
- Logging for user operation tracking is enabled.
- various methods for utilizing Azure Serial Console features
- searching for shady activities
- best practices
- Conclusion
Azure Serial Console: What Is It?
Access is made independent of network or operating system state by Azure Serial Console, which connects to “ttyS0” or “COM1” serial ports of the Virtual Machine (VM ) or virtual machine scale set. In all Azure regions ( with the exception of Azure China Cloud ), it is a text-based console for virtual machines and VMSS that is currently available for public preview in Azure Government. to learn more
Accessing Azure Serial Console requires the following prerequisites:
- For the VM, boot diagnostics must be turned on ( this is possible while setting up a virtual machine )
- a persona that at the very least plays the” Virtual Machine Contributor role.”
- The website https ://portal .azure .com is accessible to Adversary.
- ( For a few attack scenarios, this is not necessary, but credentials to the VM/VMSS. )
Why might an adversary make a good target out of Azure Serial Console?
Because Azure Serial Console uses security features so heavily, it is a prime target for attackers.
- Consider a situation where access to your virtual machine has been restricted or disabled with RDP/SSH. This frequently occurs in production-grade setups where authentication is restricted to particular IPs or subnets. Azure Serial Console can help an attacker gain CLI access to the machine because it is not constrained by NSG restrictions.
- Just in time access ( JIT ) is a fantastic feature offered by Microsoft Defender for Cloud that enables administrators to only grant access when, where, and for the required amount of time. Azure Serial Console can still connect to VMs that have JIT enabled without needing to ask for access.
Logging for user operation tracking is enabled.
There are many ways to stream and analyze logs, but for the purposes of this blog, we’ll create a workspace for log analytics and add streamlogs to it. Without a logging solution, we could analyze the activity in this way. This would vary depending on your configuration, though. The schema and query language may differ if your setup uses an SIEM.
The development of a workspace for log analytics
Step 1: Select the appropriate subscription, resource group, and Name from the Azure Portal’s Log Analytics Workspace creation page. Please be aware that there are two SKUs for Azure Monitor. Please visit this page for more details on Azure Log Analytics ‘ pricing information.
Monitoring Azure ActivityLogs
First, go to Activity Log and select” Export Activity LOGs” from the menu.
Step 2: Select” Administrative” and” Security” Categories by clicking” Add diagnostic setting.” Select the created log analytics workspace by clicking” Send to Log Analytics Workspace.”
Monitoring Windows EventLogs
Please be aware that depending on your current setup, this might not be necessary. If Microsoft Sentinel or another security monitoring tool ( like SIEM) is already being used to monitor your cloud compute workloads, feel free to skip this step.
Install Sysmon by following the instructions in this step.
Download Azure Monitor and configure it in step two. Download Windows Agent 64- or 32-bit from Agents. Install the agent by following the on-screen instructions. Move on to the following step after the installation is finished.
Create a rule for collecting data in step three. Fill in the name, resource group, and location using the Creation Wizard. To finish the log configuration, refer to the video’s instructions. To backup” Sysmon” logs, use the following XPath.
<QueryId="0"Path="Microsoft-Windows-Sysmon/Operational"><SelectPath="Microsoft-Windows-Sysmon/Operational">*
Step 4: Run the following KQL queries to check that the Windows Event Logs and Azure Activity Logins are properly received. Check the Logs section in the navigation bar on the left side of the testing virtual machine you created.
- View the Activity Logs in Azure.
AzureActivity|summarizecount()byOperationNameValue|count
- View the event logs for Windows
Event|count
You have configured logging successfully if the output exceeds 0 in any way.
various methods for utilizing Azure Serial Console features
The following options are only available on Windows operating systems, so please take note of that.
Command is carried out:
Enabling command execution is the main feature of the Azure Serial console. An adversary can run commands on a VM with root/admin privileges as long as the attacker has access to the virtual machine. The CLI access can be used to run commands, maintain persistence, and move laterally across the network even though it does n’t offer a GUI access. The steps listed below can be used with an Azure serial console to run commands on a virtual machine.
-
Go to Serial Console option on the left navigation bar and once the prompt loads, enter
cmd
to create a command prompt channel. -
Enter
ch -sn Cmd0001
to switch to the channel’s context, press ENTER and then enter the credentials to login into the CLI of the VM.
The same can be done using Az CLI. The command az serial-console connect -n -g
can be used to connect using Az CLI. Know more
Using Azure Serial Console, track user activity:
Assuming that you have followed all the steps (Installing Sysmon, Configuring Windows Event logging), the following KQL query can be used to trace activities performed using Azure Serial Console. The logic that’s used for the query is gathering all the logon IDs from windows event ID: 4624
where the LogonProcess is sacsess.exe
and identifying processes whose SubjectLogonId belongs to the list of Logon IDs gathered in previous step.
letPIDs=Event|whereEventID==4624|extendLoginProcessName=replace_string(extract(@"Process Name:[t]+[w||:|.]+",0,RenderedDescription),"Process Name:","")|whereLoginProcessNamehas"sacsess.exe"|extendLogonID=replace_string(extract(@"TargetLogonId.>[w|d]+",0,EventData),'TargetLogonId">',"")| distinct LogonID;Event| where Source == "Microsoft-Windows-Sysmon" and EventID == 1| extend LogonID = replace_string(extract(@"LogonId.>[w|d]+",0,EventData),'LogonId">',"")|whereLogonIDin(PIDs)
We can track an adversary’s connection attempts using Azure Activity Logs:
AzureActivity|whereOperationNameValue=~"MICROSOFT.SERIALCONSOLE/SERIALPORTS/CONNECT/ACTION"|whereActivityStatusValue=~"Success"
dumping of a particular procedure
Dumping a process without any authentication is one of the most intriguing attack vectors supported by the Azure serial console. The steps that can be taken to accomplish the same are listed below.
- Use
t
command to list of all the processes. Once you identify the process and identify the PID of the process that you want to dump.
- Use the PID identified in the previous step and use the command
procdump
. In the following example, we are dumping LSASS.exe’s process memory.
Using Azure Serial Console, track the dumping activity:
The following query can be used for the process dumps produced by this process.
Event|whereEventID==11|whereRenderedDescriptionhas"lsass.dmp"
The query searches for the creation of the file lsass.dmp
in the event logs related to File creation (Event ID: 11 generated by Sysmon).
Further analysis indicated that the dump file is created by svchost.exe
[Command Line of the file creation process: C:Windowssystem32svchost.exe -k netsvcs -p
]whose parent process is services.exe
and grandparent process is wininit.exe
. This is interesting as there is no indication that this activity was performed using the serial console.
Microsoft Defender for Endpoint has currently identified this activity. Here is more information on how to spot and stop LSASS dumping.
Below is the process tree evidence as seen in Defender for Endpoint:
The Yara rule listed below can be used to identify the cause of the lsass dumping.
rulecreation_of_dmp{meta:author="Subhash P "filetype="DUMP File"date="1/1/2023"version="1.0"strings:$md={4d444d50}$a1="SeDebugPrivilege"fullwordwide$a2="pipelsass"fullwordwide$a3="lsasspirpc"fullwordwidecondition:($mdat0)andallof($a*)}
Other capabilities include enumeration
Few additional features are available in unauthenticated SAC console mode on Azure Serial Console. Please take note that the following is a comprehensive list of SAC commands ( aside from procdump ):
Command | Brief Description | Security Concern |
---|---|---|
ch |
commands for channel management | None |
cmd |
Make a channel for commands. | Execute VM commands |
d |
The current kernel log should be deleted. | assist a foe in conducting reconnaissance |
f |
tlist information that is detailed or condensed | assist a foe in conducting reconnaissance |
i |
Set IP information and list all IP network numbers along with their IP addresses. | assist a foe in conducting reconnaissance |
id |
Show the information for computer identification. | assist a foe in conducting reconnaissance |
k |
Execute the specified procedure. | aid an enemy in causing a denial of service |
l |
Reduce a process’s priority as much as you can. | assist a foe in lowering the standard of service performance |
lock |
Channels for Command Prompt should be locked. | aid an enemy in causing a denial of service |
m |
restrict a process’s memory usage to. | assist a foe in lowering the standard of service performance |
p |
The display is being paging in Toggle. | None |
r |
Increase a process’s priority by one | None |
s |
( Use of a 24-hour clock ) Show the time and date. | None |
s mm/dd/yyyy hh:mm |
Set the date and time ( the 24-hour clock is in use ). | aid an enemy in causing a denial of service |
t |
The task list is displayed. | assist a foe in conducting reconnaissance |
restart |
The system needs to be restarted right away. | aid an enemy in causing a denial of service |
shutdown |
Immediately turn off the system. | aid an enemy in causing a denial of service |
crashdump |
The system should crash. You need to be able to crash dump. | aid an enemy in causing a denial of service |
livedump [-u] [-h] |
A live kernel dump should be made. Userspace (u ) and hypervisor ( h ) memory in the dump are two possible arguments. | Secrets from the dump that are filthy |
tracking of an opponent’s actions:
The actions performed by an adversary using Azure Serial Console (inside the command line channel and otherwise) can be traced using Boot diagnostics logs. They can be viewed in the Help
section in the left navigation bar. They can’t be exported or streamed to an external location.
The log itself enables an attacker to mint credentials and other secrets present in command line parameters for commands such as net user /add
. As any command typed in, using Azure Serial Console is logged here, if an admin uses commands with secrets in command line, they can be extracted by an adversary. To identify if an adversary has visited Boot diagnostics, the following query can be used:
AzureActivity|whereOperationNameValue=="MICROSOFT.COMPUTE/VIRTUALMACHINES/RETRIEVEBOOTDIAGNOSTICSDATA/ACTION"|whereActivityStatusValue=="Success"
searching for shady activities
Azure Activity logs contain suspicious Azure Serial Console Interactions:
- Any Azure Serial console interaction carried out using an identity from an IP address that has n’t been used in 30 days is identified by the following query. Although this method of filtering is very primitive, Azure Sentinel offers cutting-edge methods like UEBA.
let30DaysData=AzureActivity|whereTimeGenerated>=ago(30d)|distinctCaller,CallerIpAddress;letCallers=30DaysData|distinctCaller;letIPs=30DaysData|distinctCallerIpAddress;AzureActivity|whereTimeGenerated>=ago(1d)|wherenot(Callerhas_any(Callers)andCallerIpAddresshas_any(IPs))
- Failed attempts to access Azure Serial Console are identified by the following query. This might be because a foe is conducting reconnaissance to see if they have console access.
AzureActivity|whereTimeGenerated>=ago(7d)|whereOperationNameValue=~"MICROSOFT.SERIALCONSOLE/SERIALPORTS/CONNECT/ACTION"|whereActivityStatusValue!="Success"
- Risky Signin and subsequent serial console actions are identified by the following query when accessing Azure Serial Console. Please be aware that following this guide requires logging to be enabled. Get a list of dangerous users and see if the same IP that triggered Microsoft Identity security algorithms has been used to access serial consoles using the following query.
letRiskyUsersData=AADUserRiskEvents|summarizebyUserPrincipalName,IpAddress;letRiskyCallers=RiskyUsersData|distinctUserPrincipalName;letRiskyIPs=RiskyUsersData|distinctIpAddress;AzureActivity|whereOperationNameValue=="MICROSOFT.SERIALCONSOLE/SERIALPORTS/CONNECT/ACTION"|whereCallerhas_any(RiskyCallers)andCallerIpAddresshas_any(RiskyIPs)
Windows Event logs contain suspicious operations:
- The following query, which extracts the list of LOLBINs from the lolbas API, identifies processes created using Azure Serial Console and verifies the presence of any binaries previously identified.
- Powershell execution through Azure Serial Console:The following query identifies processes that are created using Azure Serial console and have the keyword
powershell
in them.letPIDs=Event|whereEventID==4624|extendLoginProcessName=replace_string(extract(@"Process Name:[t]+[w||:|.]+",0,RenderedDescription),"Process Name:","")|whereLoginProcessNamehas"sacsess.exe"|extendLogonID=replace_string(extract(@"TargetLogonId.>[w|d]+",0,EventData),'TargetLogonId">',"")| distinct LogonID;Event| where Source == "Microsoft-Windows-Sysmon" and EventID == 1| extend LogonID = replace_string(extract(@"LogonId.>[w|d]+",0,EventData),'LogonId">',"")|whereLogonIDin(PIDs)|whereEventID==1// and EventData has "svchost"|extendProcessId=replace_string(replace_string(replace_string(extract(@"[S]+",0,EventData),'ProcessId">',""),@'<Data Name="',''),"",""),ProcessName=replace_string(replace_string(replace_string(extract(@".*?",0,EventData),'Image">',""),@'<Data Name="',''),"",""),ParentProcessName=replace_string(replace_string(replace_string(extract(@".*?",0,EventData),'ParentImage">',""),@'<Data Name="',''),"",""),CommandLine=replace_string(replace_string(replace_string(extract(@".*?",0,EventData),'CommandLine">',""),@'<Data Name="',''),"","")|whereCommandLinehas"powershell"
- Network Connections through processes initiated through Azure Serial Console:The following query identifies processes that are created using Azure Serial console and checks if there are any Sysmon Event ID:
3
events which are created when a network connection is initiated.letPIDs=Event|whereEventID==4624|extendLoginProcessName=replace_string(extract(@"Process Name:[t]+[w||:|.]+",0,RenderedDescription),"Process Name:","")|whereLoginProcessNamehas"sacsess.exe"|extendLogonID=replace_string(extract(@"TargetLogonId.>[w|d]+",0,EventData),'TargetLogonId">',"")| distinct LogonID;let ProcID =Event| where Source == "Microsoft-Windows-Sysmon" and EventID == 1| extend LogonID = replace_string(extract(@"LogonId.>[w|d]+",0,EventData),'LogonId">',"")|whereLogonIDin(PIDs)|whereEventID==1|extendProcessId=replace_string(replace_string(replace_string(extract(@"[S]+",0,EventData),'ProcessId">',""),@'<Data Name="',''),"",""),ProcessName=replace_string(replace_string(replace_string(extract(@".*?",0,EventData),'Image">',""),@'<Data Name="',''),"",""),ParentProcessName=replace_string(replace_string(replace_string(extract(@".*?",0,EventData),'ParentImage">',""),@'<Data Name="',''),"",""),CommandLine=replace_string(replace_string(replace_string(extract(@".*?",0,EventData),'CommandLine">',""),@'<Data Name="',''),"","")|distinctProcessId;Event|whereEventID==3|extendProcessId=replace_string(replace_string(replace_string(extract(@"[S]+",0,EventData),'ProcessId">',""),@'<Data Name="',''),"","")|whereProcessIdhas_any(ProcID)
- The following query determines whether sc is being used when creating services using Azure Serial Console (using command line parameters ). create services with exe.
letLolBins=externaldata(Name:string,Description:string,Author:string,Created:datetime,Commands:dynamic,FullPath:dynamic,Detection:dynamic)["https://lolbas-project.github.io/api/lolbas.json"]with(format="multijson");letExecLols=LolBins|mv-expandCommands|extendCategory=Commands['Category']|distinctName;letPIDs=Event|whereEventID==4624|extendLoginProcessName=replace_string(extract(@"Process Name:[t]+[w||:|.]+",0,RenderedDescription),"Process Name:","")|whereLoginProcessNamehas"sacsess.exe"|extendLogonID=replace_string(extract(@"TargetLogonId.>[w|d]+",0,EventData),'TargetLogonId">',"")| distinct LogonID;Event| where Source == "Microsoft-Windows-Sysmon" and EventID == 1| extend LogonID = replace_string(extract(@"LogonId.>[w|d]+",0,EventData),'LogonId">',"")|whereLogonIDin(PIDs)|whereEventID==1// and EventData has "svchost"|extendProcessId=replace_string(replace_string(replace_string(extract(@"[S]+",0,EventData),'ProcessId">',""),@'<Data Name="',''),"",""),ProcessName=replace_string(replace_string(replace_string(extract(@".*?",0,EventData),'Image">',""),@'<Data Name="',''),"",""),ParentProcessName=replace_string(replace_string(replace_string(extract(@".*?",0,EventData),'ParentImage">',""),@'<Data Name="',''),"",""),CommandLine=replace_string(replace_string(replace_string(extract(@".*?",0,EventData),'CommandLine">',""),@'<Data Name="',''),"","")|extendProcessName=split(ProcessName,@"")[-1]|whereProcessNamehas_any(ExecLols)
let PIDs = Event| where EventID == 4624| extend LoginProcessName = replace_string(extract(@"Process Name:[t]+[w||:|.]+",0,RenderedDescription),"Process Name:","")| where LoginProcessName has "sacsess.exe"| extend LogonID = replace_string(extract(@"TargetLogonId.>[w|d]+",0,EventData),'TargetLogonId">',"")| distinct LogonID;Event| where Source == "Microsoft-Windows-Sysmon" and EventID == 1| extend LogonID = replace_string(extract(@"LogonId.>[w|d]+",0,EventData),'LogonId">',"")| where LogonID in (PIDs)| where EventID == 1 // and EventData has "svchost"| extend ProcessId = replace_string(replace_string(replace_string(extract(@"[S]+",0,EventData),'ProcessId">',""),@'<Data Name="',''),"",""), ProcessName = replace_string(replace_string(replace_string(extract(@".*?",0,EventData),'Image">',""),@'<Data Name="',''),"",""), ParentProcessName = replace_string(replace_string(replace_string(extract(@".*?",0,EventData),'ParentImage">',""),@'<Data Name="',''),"",""), CommandLine = replace_string(replace_string(replace_string(extract(@".*?",0,EventData),'CommandLine">',""),@'<Data Name="',''),"","")| where CommandLine has "sc"
Best Practices
Here is a partial list of the best practices we advise for maintaining the security of Azure Serial Console:
- All users with” Virtual machine contributor” access should be forced to useMFA.
- To make sure the list of privileged users is current, regularly audit for RBAC permissions of users.
- Utilize Azure Activity and Host-based logs to regularly monitor activity using the Azure Serial console.
Conclusion
Although Azure Serial Console is a fantastic tool for administrators and developers to troubleshoot during difficult times, if it is n’t kept under surveillance and locked down, it could endanger security. We’ll discuss Azure Serial console attack and defense when using an OS with a Linux flavor in the following section.