Find some weaknesses, Yara.

Intro

It’s not simple to find software vulnerabilities on its own. &nbsp, Manually performing this at cloud scale is very difficult, so tools are used to help us spot patterns or vulnerability signatures. One of those tools is Yara,nbsp.

Blue teams and malware researchers frequently use Yara, and for good reason. It’s very simple to create rules to find malicious patterns in large collections of files once they’ve been discovered.

We’ll talk about another way to use Yara from an AppSec/Red Team perspective in this article. We’ll examine how to develop guidelines that take various software vulnerabilities into account. Among the examples are deserialization vulnerabilities, which can cause arbitrary code execution, command injection flaws, and even loose regular expressions that can be avoided and possibly result in SSRFs.

This list is not meant to be comprehensive.

Examples

C#

We’ll examine a few instances of C# code that could be compromised below.

Formatter for binary

Let’s say we come across the following code:

staticstringGetClientEmail(){stringjson=GetData();BinaryFormatterformatter=newBinaryFormatter();FileStreamfs=File.Open(@"client.txt",FileMode.Open);objectobj=formatter.Deserialize(fs);Accountacobj=(Account)obj;returnacobj.Email;}

BinaryFormatter cannot be used with arbitrary or unreliable data, as in the aforementioned example. Because its Deserialize ( ) method checks the type provided in the file stream before performing any casts, the usage cannot be made secure. This feature will be used to execute malicious code by an arbitrary payload. &nbsp, SerializationBinder cannot be used to mitigate this, unlike other formatters. &nbsp, NET will not provide a mitigation to change this behavior because it is thought to be intentional.

NewtonSoft.Json

The Newtonsoft JSON library is used in the following vulnerability to deserialize an unreliableJSON payload. &nbsp, the JSON is permitted when TypeNameHandling is set to” Objects” or” All.” Check the object type in the provided data using the NET library:

privatestaticJsonSerializerSettingsjsonSerializerSettings=newJsonSerializerSettings{TypeNameHandling=TypeNameHandling.All;// As a side note, this also works if we use Objects instead of All. TypeNameHandling=TypeNameHandling.Objects;};

Malicious object types that can be used to carry out arbitrary commands may be added if an attacker has the ability to modify the serialized data. The DeserializeObject function in the examples below does not check the type of the string supplied as input ( ‘json’) in order to ensure that no unsafe types given as user input are deseriedized if this setting has been set to” None” or has not been specified at all ( in which case it will default to’ None’ ).

First illustration:

staticstringGetClientEmail(){stringjson=GetData();varacobj=JsonConvert.DeserializeObject<Object>(json,jsonSerializerSettings);Accountaccount=(Account)acobj;returnaccount.Email;}

Second example:

staticstringGetClientEmail(){stringjson=GetData();varacobj=(Account)JsonConvert.DeserializeObject<Object>(json,jsonSerializerSettings);Accountaccount=(Account)acobj;returnaccount.Email;}

Both the examples above try to convert the object to our custom type ‘Account’: however, this isn’t successful as the malicious payload already executes before that happens. This is because whenever we have generic types such as ‘var’ or , the JsonConvert function looks into the payload string and tries to guess the type and then tries to deserialize it. When deserializing certain objects such as the generic ones in this example, their constructors get called first which can contain malicious executables.

3. An illustration

staticstringGetClientEmail(){stringjson=GetData();Accountacobj=(Account)JsonConvert.DeserializeObject<Account>(json,jsonSerializerSettings);returnacobj.Email;}

If our type” Account” contains any public generic objects or any classes that may in turn contain general objects, the code above may still be susceptible to unsafe deserialization:

publicclassAccount{publicstringEmail{get;set;}publicstringActive{get;set;}publicobjectDetails;publicXYZx;}publicclassXYZ{publicobjectz;}

injection of code

Here is an example in C# of unsafe user input for the GET parameter” FirePath” ( since there is no sanitization to identify/remove things like” .. /”,” &amp, andamp,” or” |” ) passed to System. diagnostics. Command injection is caused by ProcessStartInfo ( ):

publicasyncTask<IActionResult>compressAndDownloadFile(){stringfilePath=Request.Query["filePath"];processStartInfo=newSystem.Diagnostics.ProcessStartInfo("/bin/bash",$"-c "cat{filePath}|gzip>{filePath}.gz"");System.Diagnostics.Processproc=newSystem.Diagnostics.Process();proc.StartInfo=processStartInfo;proc.Start();returnFile($"{filePath}.gz","application/gzip");}

loosen your facial expression

It’s particularly intriguing when there is loose regex in the code because it might result in different vulnerabilities. This validation, for instance, can be avoided if the user is only permitted to visit specific subdomains in Azure or any domain of your choice using the code shown below:

First illustration:

stringurl_pattern=@".*yourdomain.com";// Create a RegexRegexurl_check=newRegex(url_pattern);

This enables subdomains of the following patterns, which may result in prefixes provided by attackers as input:

  1. “.*azure.com”
  2. “.*.azure.com”
  3. “.*.azure.com”

Here, the terms ( 1 ) and ( 2 ) can be used to access malicious websites like maliciousazure .com.

Additionally, ( 3 ) allows access to malicious.com/. azure

Second example:

When client certificates are used for Service to Service ( S2S ) authentication, we occasionally see loose regular expressions being misused. Any trusted certificate with the correct prefix is authorized if the code’s containment check rather than equality check is applied to the common names in a client certificate.

Guest Common Name has been approved. azure .com

Guest: Bypassed Common Name. azure .com. malicious- domain.com

PHP

Of course, Yara does n’t just find C# code that is vulnerable. We’ll see a few examples of PHP code fragments that are vulnerable below.

Let’s say you come across a code that uses the POST parameter to create an SQL query and is similar to the code below. This is a classic instance of SQL injection because sanitization is not being done.

First example

publicfunctionget_translation(){[]$query="SELECT id, type, status FROM `".$_POST[“language_code”].[]

A rule like the following can be used to identify the vulnerable code:

$s1=/SELECT[^"]+"s*.[^"]+$_POST/

Although it is still very specific, this will identify this specific vulnerable code as well as some other variants. What happens if the parameter is sent via GET rather than a POST request? What if the SQL query is an insert rather than a SELECT?

To handle other situations, we can either modify the existing rule or add more that are similar:

$s1=/w+s*=s*"(SELECT|INSERT|UPDATE)[^"]+"s*.[^"]+$_(GET|POST|REQUEST)/

Everything in the second example is path variable-dependent.

Second example

$path=$_POST[“filepath”];[]$command="$path xtag 2>&1";exec($command,$output,$result);

As the attacker manages the filepath POST parameter, this is a classic instance of command injection. A Yara rule can be made fairly easily to identify this particular case, but it’s sometimes preferable to review functions that run external programs case by case.

For instance, if we’re looking for PHP functions that run commands and start with a variable:

/(escapeshellcmd|exec|system|passthru|popen)s*([^(,]*$/

If you discover that there are too many false positives, you can modify and add additional checks ( such as those for the presence of$ GET,$ POST, or$ REQUEST strings ).

Third example (account takeover )

The implementation has a significant impact on this detection. Here, a hash function that uses the current time as an argument is the focus of our attention. Depending on its intended use, this may result in account takeover.

Let’s assume that a website offers the option to change an account user password in the event that they forget it. The attacker can generate the password locally, as they already knew when they made the request, force a reset for an arbitrary account, and then log in using the temporary password, if they are aware that temporary functions are produced by using an implementation similar to the example below.

functionreset_password(){[]$temp_pass=md5(time());

4 as an example

publicfunctionrenderNav(){[]echo'<input type="hidden" name="pagename" value="'.$_GET['page'].'"/>';

A classic example of XSS ( cross-site scripting ) is this.

The HTML code directly renders the value of the page GET variable. If there is no CORS, nothing prevents an attacker from injecting random HTML or JS code.

JavaScript

Cross- Origin Resource Sharing Validation Is Missing

window. A safe method for cross-originating communication that gets around the Same Origin Policy is offered by postMessage. This is expressed in the following syntax:

Window.postMessage(message,targetOrigin)Window.postMessage(message,targetOrigin,transfer)

However, if we specify the targetOrigin as” *,” any malicious website attempting to intercept our traffic may be made aware of the data being sent from our website:

Window.postMessage(message,"*")Window.postMessage(message,"*",transfer)

Yara is in charge.

Below we’ll present a fewYara is in charge.to detect some of the vulnerabilities we’ve already discussed.

This fundamental format will be followed by all rules:

rule { strings: $ = “” $ = “” condition: any of ($*)}

By including comments, metadata, new variable names (you might need to modify the condition to reflect those names ), etc., you can easily expand this template. On how to do that, there is&nbsp, excellent documentation.

Happy hunting!

rule ProcessStart_Method{ strings: $s1 = "Process.Start" $s2 = "ProcessStartInfo" $s3 = "UseShellExecute" $s4 = ".Shell" $s5 = "system(" $s6 = "ProcessEx" condition: any of ($s*)}
rule has_LooseRegex{ strings: $s1 = ".*" condition: any of ($s*)}
rule BinaryFormatter_Deserialization{ strings: $s1 = "new BinaryFormatter(" $s2 = "TextFormattingRunProperties" condition: any of ($s*)}
rule LosFormatter_Deserialization{ strings: $s1 = "new LosFormatter(" condition: any of ($s*)}
rule SoapFormatter_Deserialization{ strings: $s1 = "new SoapFormatter(" condition: any of ($s*)}
rule NetDataContractSerializer_Deserialization{ strings: $s1 = "new NetDataContractSerializer(" condition: any of ($s*)}
rule ObjectStateFormatter_Deserialization{ strings: $s1 = "new ObjectStateFormatter(" condition: any of ($s*)}
rule JsonConvert_Deserialization_newtonsoft{ strings: $s1 = "JsonConvert.DeserializeObject<Object" condition: any of ($s*)}

PHP

rulePHP_SQLinj{strings:// match var = "SELECT FROM x WHERE pass=" . $_$s1=/w+s*=s*"(SELECT|INSERT|UPDATE)[^"]+"s*.[^"]+$_(GET|POST|REQUEST)/ condition: any of ($s*)}
rulePHP_XSSConcat{strings:$s1=/echos[^rn]*.[^"rn(]*$_(GET|POST|REQUEST)/ condition: any of ($s*)}
rulePHP_RCE{strings:$s1=/w+s*=s*(escapeshellcmd|exec|system|passthru|popen)s*([^(,]*$/$s2=/[rn]+s*(escapeshellcmd|exec|system|passthru|popen)s*([^(,]*$/condition:anyof($s*)}
rulePHP_Time_Hash{strings:$s1=/(md5|shad+)(s*time()s*);/condition:anyof($s*)}
rulePHP_FileInclusion{strings:$s1=/include([^)]*$_(REQUEST|GET|POST|COOKIE|SERVER|FILES)[/condition:anyof($s*)}
rulemissingCORS_js{strings:$s1=/Window.postMessages*(w+,s*["']+*["']+s*[,)]+/nocasecondition:anyof($s*)}
Skip to content