Understanding the Behinder Tool: Dynamic Binary Encryption, Detection Approaches, and Traffic Analysis

Overview

Behinder is a new type of dynamic binary encryption website tool. Currently, there are six versions. There are mainly three approaches for detecting webshell’s network traffic on the network side. First: File restoration and sample analysis during the webshell upload process to detect if static files trigger any antivirus alerts. Second: Data communication traffic during the webshell’s online connection establishment process. Third: Data communication traffic during the remote control command execution process after the webshell has connected. This article analyzes multiple historical versions of Behinder and five scripts (asp|aspx|jsp|jspx|php) to identify the static characteristics of Behinder’s online detection using the second method and summarizes some snort rules.

Communication Principle of Behinder

Behinder uses AES encryption, which has been extensively explained in many articles and corresponding decryption scripts are available, hence not elaborated here.

Data Packet of Behinder Going Online (Click to read the original text at the bottom)

Behinder V1.0 Connection

The captured communication traffic is as follows:

Behinder tool >

Content-Type: application/octet-stream indicates data is transmitted as a binary stream. The GET request body returns a 16-character string consisting of uppercase and lowercase letters or numbers.

Behinder V1.1 Connection

Behinder tool >

The Behinder tool, starting from version V1.1 (including V1.1), introduced support for random UserAgent. Each session randomly selects from 17 common UserAgents. The pass (password) format in this version is different from other versions, with the password followed by 10 digits.

Behinder V2.0.1 Connection

PHP shell online data packet

ASP shell online data packet

Special Data Packets

Special Packet Type One

Found only when going online with PHP shell. Testing versions V2.0 and V2.0.1

When a PHP shell goes online, two POST requests and responses are generated. The first POST response has no response body, while the second POST response has a response body. Additional snort detection is needed here. Use flowbits for multi-packet union detection.

First POST response

Second POST response

Special Packet Type Two

Two very old Behinder packets couldn’t be matched by the written snort rules, and I forgot which version they were. Upon closer inspection, it turned out that there was no Content-Length field. In a PHP shell going online, the GET response surprisingly lacked the strong signature “Content-Length: 16”. According to materials, if it is chunked encoding, the content-length field might not be displayed. I chose to ignore this special type.

The following PHP GET response also lacks the strong signature “Content-Length: 16”. It seems like a few extra characters, but that’s a display issue, not actually more.

Static Characteristics

Weak Feature 1: URL Parameter during Key Transmission (Behinder tool)

Code language: javascriptCopy

"\.(php|jsp|asp|jspx|aspx)\?\w{1,8}=\d{1,10}HTTP/1\.1"

Here \w{1,8} represents the password length and can be adjusted according to actual needs and probe performance. \d{1,10} represents the length of the numbers following the password. To accommodate both V1.0 and V1.1, it is set to 1-10. If only detecting V2.1, it can be adjusted to \d{2,3}.

Weak Feature 2: URL Parameters during Encryption

During encrypted communication, there are no URL parameters. Yes, absence of parameters itself can be a feature.

Code language: javascriptCopy

"\.(php|jsp|asp|jspx|aspx) HTTP/1.1"

This feature is not used in this article.

Strong Feature 3: Accept Field (Bypassable)

Accept is a commonly used field in the HTTP protocol, yet the default value of the Accept field in Behinder is quite special. This feature can appear during any communication stage of Behinder.

Code language: javascriptCopy

Accept: text/html,image/gif, image/jpeg, *; q=.2, */*;q=.2

Behinder supports custom HTTP Headers, so this feature can be bypassed.

Special detection can be made for this feature, because most users do not modify Accept habits.

This feature is not used in this article.

Strong Feature 4: UserAgent Field (Bypassable)

Starting from version V1.1 (including V1.1), Behinder introduced support for random UserAgent, where each session selects randomly from 17 common (older) UserAgents.

If historical traffic from the same source IP visiting a URL hits multiple UserAgents from the following list (download link), it’s almost certainly Behinder.

Most users do not modify Accept habits, but Behinder supports custom UA, so this feature can be bypassed.

This feature is not used in this article.

Strong Feature 5: Transmitted Key

The encryption key is a 16-character random string composed of uppercase and lowercase letters and numbers. During the key transmission stage, the key exists in the response body of the get request. Importantly, regardless of the type of Behinder script shell, the client must negotiate with the server twice during the online process, meaning two get requests are sent, each time returning a 16-character key.

The key feature is thus as follows:

Code language: javascriptCopy

"\r\n\r\n[A-Za-z0-9]{16}$"

Another feature is that the response body length of the get request is exactly 16 characters.

Code language: javascriptCopy

"Content-Length: 16"

Weak Feature 6: Encrypted Data Upstream

Characteristics of encrypted data upstream for jsp|php|jspx are as follows:

Code language: javascriptCopy

"\r\n\r\n[a-zA-Z\d\+\/]{10,}\/[a-zA-Z\d\/]{50}"

The number 50 denotes that at least 50 characters must appear to match, and can be adjusted according to the actual situation and needs of the IDS device.

jsp encrypted traffic upstream

php encrypted traffic upstream

jspx encrypted traffic upstream

asp, aspx cannot use the above characteristics.

Aspx encrypted upstream traffic is unique. To reduce false positives, it is recommended to check both encoded upstream and downstream, as this characteristic also applies to aspx encrypted downstream traffic.

The “.” in the data packet is actually an invisible character.

Code language: javascriptCopy

"[^\w\s><=\-'"\:\;\,\!\(\)\{\}]”

asp encrypted traffic upstream

aspx encrypted traffic upstream

Weak Feature 7: Encrypted Data Downstream

jsp encrypted traffic downstream

Here, the binary uncommon characters are matched with a regex “not”.

Code language: javascriptCopy

" [^\w\s><=\-'"\:\;\,\!\(\)\{\}][\w]{2}[^\w\s><=\-'"\.\:\;\,\!\(\)\{\}][a-zA-Z\d]{2}"

[^\w\s><=-‘“\:\;\,!(){}] represents invisible characters

[\w]{2} denotes that there are at least two characters before the special symbol. After extensive comparative analysis, identifiable strings include:

“Invisible Character” + “VO?ES”

“Invisible Character” + “Fl#fB”

“Invisible Character” + “9w+rv”

“Invisible Character” + “6G/SW”

“Invisible Character” + “mN]ss”

“Invisible Character” + “ss[ss”

“Invisible Character” + “gV|05”

“Invisible Character” + “Iz\8o”





And it returns status code 200 OK.

Additionally, for php|jsp|asp|aspx, the response type characteristic includes

“Content-Type: text/html”

jspx is somewhat special.

jspx encrypted traffic downstream

Code language: javascriptCopy

"Content-Type:text/xml"

Weak Feature 8: Long Connection (Bypassable)

Behinder communication uses long connections by default to avoid resource overhead caused by frequent handshakes. Therefore, by default, request headers and response headers will contain:

Code language: javascriptCopy

Connection: Keep-Alive

This feature is present in any communication stage of Behinder.

This feature is not used in this article.

Behinder Snort Rules Detection Idea

One. Start detecting from the response body of the first GET request establishing the connection,

1. The response body must be a 16-character string consisting of uppercase and lowercase letters or numbers,2. Return status code 200 OK

It can act as the entry regex for IDS to prevent too much traffic from impacting IDS performance.

Two. After that, detect the second GET request,

1. Satisfy the weak characteristics extracted from the GET request above

Three. Detect the characteristics of the response body of the second GET, which are consistent with those in step one, but should maintain a progressive relationship.

Four. Here are two scenarios,

The first scenario,

1. Detect common POST request characteristics 2. Detect POST response characteristics. If matched, determine that it is Behinder asp|jsp|aspx|php going online.

The second scenario (not meeting the first scenario),

1. Detect POST request jspx characteristics2. Detect POST response jspx characteristics

Summary of Behinder Snort Rules

In conclusion,

Code language: javascriptCopy

alert http any any -> any any(msg:"MALWARE-BACKDOOR Behinder webshell online detected"; flow:established,to_client; pcre: "/\r\n\r\n[A-Za-z0-9]{16}$/"; content:"200 OK"; content: "Content-Length: 16"; fast_pattern;nocase; flowbits: set, bx_first_get_resp; noalert; classtype:web-attack;sid:3000021; rev:1; metadata:created_at 2019_11_20, updated_at 2019_11_20;)    alert http any any -> any any(msg:"MALWARE-BACKDOOR Behinder webshell online detected"; flow:established,to_server; content:"GET"; http_method; pcre:"/\.(php|jsp|asp|jspx|aspx)\?\w{1,8}=\d{1,10} HTTP/1\.1/";flowbits:isset, bx_first_get_resp; flowbits:set, bx_second_get_req; noalert;classtype:web-attack; sid:3000022; rev:1; metadata:created_at 2019_11_20,updated_at 2019_11_20;)    alert http any any -> any any(msg:"MALWARE-BACKDOOR Behinder webshell online detected"; flow:established,to_client; pcre: "/\r\n\r\n[A-Za-z0-9]{16}$/"; content:"Content-Length: 16"; fast_pattern; nocase; flowbits: isset,bx_second_get_req; flowbits:set, bx_second_get_resp; noalert;classtype:web-attack; sid:3000023; rev:1; metadata:created_at 2019_11_20,updated_at 2019_11_20;)    alert http any any -> any any(msg:"MALWARE-BACKDOOR Behinder webshell online detected"; flow:established,to_server; content:"POST"; http_method; pcre:"/\.(php|jsp|asp|jspx|aspx) HTTP/1\.1/"; flowbits:isset, bx_second_get_resp;flowbits:set, bx_first_post_req; noalert; classtype:web-attack; sid:3000024;rev:1; metadata:created_at 2019_11_20, updated_at 2019_11_20;)    alert http any any -> any any(msg:"MALWARE-BACKDOOR Behinder webshell online detected"; flow:established,to_client; pcre: "/[^\w\s><=\-'"\:\;\,\!\(\)\{\}][\w]{2}[^\w\s><=\-'"\.\:\;\,\!\(\)\{\}][a-zA-Z\d]{2}/";content: "200 OK"; content: "Content-Type: text/html";flowbits: isset, bx_first_post_req; classtype:web-attack; sid:3000025; rev:1;metadata:created_at 2019_11_20, updated_at 2019_11_20;)    alert http any any -> any any(msg:"MALWARE-BACKDOOR Behinder webshell-jspx online"; flow:established,to_server; pcre:"/\r\n\r\n[a-zA-Z\d\+\/]{10,}\/[a-zA-Z\d\/]{50}/"; content:"Content-Type: application/octet-stream"; fast_pattern; flowbits:isset, bx_second_get_resp; flowbits: set, bx_req_jspx; noalert;classtype:web-attack; sid:3000026; rev:1; metadata:created_at 2019_11_20,updated_at 2019_11_20;)    alert http any any -> any any(msg:"MALWARE-BACKDOOR Behinder webshell-jspx online"; flow:established,to_client; pcre:"/[^\w\s><=\-'"\:\;\,\!\(\)\{\}][\w]{2}[^\w\s><=\-'"\.\:\;\,\!\(\)\{\}][a-zA-Z\d]{2}/";content: "200 OK"; content: "Content-Type: text/xml";fast_pattern; flowbits: isset, bx_req_jspx; classtype:web-attack; sid:3000027;rev:1; metadata:created_at 2019_11_20, updated_at 2019_11_20;)