Balada Injector
Balada, also known as Balada Injector, is a malware campaign that targets and injects malicious PHP code into WordPress websites. Researchers have observed recent campaigns exploiting two vulnerabilities within WordPress plugins to inject the initial set of malicious code.
The first vulnerability exploited was CVE-2023-3169 (Pulsedive), which allowed for Unauthenticated Stored XSS attacks against versions of the tagDiv Composer plugin. CVE-2023-3169 allowed attackers to inject scripts into the HTML code of the website. Another vulnerability abused in the Balada injector campaign was CVE-2023-6000 (Pulsedive). CVE-2023-6000 was in the Popup Builder plugin that also allowed for XSS attacks. The scripts and code described in this blog focus on intrusions that used CVE-2023-6000 to start the infection. Below is an overview on:
- How Balada infects websites
- Scripts used within the campaign
- Some of the functionality within the scripts.
How Balada Spreads
The latest iteration of Balada campaigns exploited CVE-2023-6000 to inject the first stage of malicious code into websites. This CVE impacted versions of the Popup Builder WordPress plugin before 4.2.3. Successful exploitation of this vulnerability meant that attackers could inject code into the website and have it there permanently. This type of attack is called a Stored XSS attack.
Researchers at Securi identified several versions of the injected code. More recent versions of the code use meaningless comments to make reading the code more difficult, while earlier versions did not include comments.
Injected Script
The first piece of injected code is used to retrieve additional code from an adversary-controlled domain. This externally stored code is added to the website by creating a new script element.
A screenshot of a website infected with Balada is shown below. Note: the popup with injected code is not shown.
The code injected into the website was pulled using DevTools in Google Chrome and is displayed below.
The code uses comments to break up commands and make it more difficult for analysts to understand what the code is doing simply by reading it. Even though the code is somewhat obfuscated, analysts can gain insight into what may happen based on the plaintext code. Key code elements that provide insights are the eval and atob statements. The eval function shows that some code may be executed while the atob function is used to decode base64 encoded data. By combining these using the statements using the assignment below, we see that base64 encoded data will be passed to the eval function.
var lziecpcc=eval; var rlnubtgnd=atob; lziecpcc(rlnubtgnd( |
Moreover, this part of the code is only executed if the popupId value is equal to 4248. The popup value will differ on every compromised website as it requires the id of the popup that will be used during the code. Active popups will have their IDs included in the HTML code. This can be used to obtain the id.
The following CyberChef recipe cleans up the code shown in Figure 3.
Find_/_Replace({'option':'Regex','string':'\\/\\*\\w+\\*\\/'},'',true,false,true,false) Subsection('{var.*',true,true,false) Find_/_Replace({'option':'Regex','string':'\\"'},'',true,false,true,false) Find_/_Replace({'option':'Regex','string':'\\+'},'',true,false,true,false) Merge(true) Generic_Code_Beautify() Syntax_highlighter('auto detect') |
The CyberChef recipe can be further expanded to decode the base64 data and get the executed code. The additions are to extract the variables that hold the eval and atob functions, identify the base64 string, and decode it. The last step of the recipe is to replace the variables with the actual value they hold. For example, in Figure 4, lziepcc
will be replaced by eval in the final string.
Find_/_Replace({'option':'Regex','string':'\\/\\*\\w+\\*\\/'},'',true,false,true,false) Subsection('{var.*',true,true,false) Find_/_Replace({'option':'Regex','string':'\\"'},'',true,false,true,false) Find_/_Replace({'option':'Regex','string':'\\+'},'',true,false,true,false) Merge(true) Generic_Code_Beautify() Register('var (\\w+) = eval;',true,false,false) Register('var (\\w+) = atob;',true,false,false) Subsection('$R1\\((.*)\\)',true,true,false) From_Base64('A-Za-z0-9+/=',true,false) Merge(true) Find_/_Replace({'option':'Regex','string':'$R0\\($R1'},'eval',true,false,true,false) Syntax_highlighter('auto detect') |
The decoded code shows that the evaluated section of the script creates a new script element and gets the text for that element from an external URL - hxxps[://]soft[.]specialcraftbox[.]com/JZFYbC. WHOIS data indicates that the domain specialcraftbox[.]com was registered on 2023-12-13 with Nicenic, a domain registrar and web hosting service operating out of Hong Kong, China.
The URL, hxxps[://]soft[.]specialcraftbox[.]com/JZFYbC, contains the obfuscated code shown in the Figure 8 below:
Based on research from Sucuri, the injected script works to establish persistence by dropping a backdoor. The new script checks for keywords related to cookies present with users with admin privileges. If the cookies are not present, additional scripts may be loaded to redirect users to push notification scams.
However, if cookies for admin users are detected, the script appends additional parameters to the URL and executes several network requests that are used to install a malicious WordPress plugin.
Once the plugin has been installed, the URL is sent back to adversary-controlled infrastructure in the form of a GET request where the compromised URL is included in the URL as a parameter.
Backdoor Functionality
The wp-felody.php backdoor can check if the backdoor is installed and able to upload files to the server.
The first check an adversary can make is to confirm that the backdoor is still active. This is done by sending a POST request to the wp-felody.php endpoint with the parameter w33. If the value of the parameter is w33, then the backdoor echoes the hash of the value received.
The other parameters that can be sent are the q33 and q34 values used to upload files to a temporary directory. The md5 hash of the POST Request parameter q33 is hashed again before being compared to a hardcoded value; if the received value matches the hardcoded value, then a file is written to a temporary directory. The content of the file is the base64 decoded data sent in the q34 parameter. Once executed, the file is deleted from the server. In certain intrusions, the wp-felody.php backdoor is used to download additional malicious files.
Conclusion
Security researchers estimate that in its most recent campaign, Balada infected over 6,000 websites. This campaign allowed additional malware to be uploaded to compromised sites or redirected users to other types of phishing attempts. Additional backdoors installed on infected hosts offer threat actors expanded functionality on the compromised sites.
WordPress is one of the most popular CMS providers in the world, used by millions to create hundreds of millions of websites. Its popularity is due to the flexibility offered by its plugins that augment out-of-the-box functionality with additional features and ease of use. While WordPress is great for website development, it also poses a risk to users since vulnerabilities within plugins may not be patched as quickly as in other servers. Expect exploitation of WordPress components to continue as the popularity of the technology means a rich target environment for attackers.
Recommendations
- Vulnerability Management
- Periodically check for updates within all WordPress components and update them accordingly.
- Monitor for Suspicious User Accounts
- Some malware variants that target WordPress sites will attempt to establish persistence by creating admin users. Monitor users with access to admin consoles to ensure that only required users are granted access.
Indicators of Compromise
The table below contains a list of Baladanetwork IoCs identified and added to the Pulsedive platform. This data can be queried in Pulsedive using the Explore query threat="Balada" and is available for export in multiple formats (CSV, STIX 2.1, JSON).
Balada Injector IOCs |
specialcraftbox[.]com |
from[.]forwardstarlight[.]com |
page[.]bridgelinering[.]com |
lineferaline[.]com |
colorschemeas[.]com |
statisticsong[.]com |
north[.]statisticplatform[.]com |
decentralappps[.]com |
promsmotion[.]com |
stablelightway[.]com |
And more, retrieve all indicators here |
MITRE ATT&CK TTPs
Tactic | Technique |
Command and Control | Data Obfuscation (T1001) |
Defense Evasion | File Deletion (T1070.004) |
Execution | Exploitation for Client Execution (T1203) |
Initial Access | Drive-by Compromise (T1189) |
Exploit Public-Facing Application (T1190) | |
Phishing (T1566) | |
Persistence | Create Account (T1136) |
Server Software Component (T1505) | |
Web Shell (T1505.003) | |
Privilege Escalation | Web Shell (T1505.003) |
Resource Development | Develop Capabilities (T1587) |
Malware (T1587.001) | |
Stage Capabilities (T1608) | |
Upload Malware (T1608.001) |
References
https://blog.sucuri.net/2019/04/from-tk-redirects-to-pushka-browser-notification-scam.html
https://wpscan.com/blog/stored-xss-fixed-in-popup-builder-4-2-3/
https://wpscan.com/vulnerability/e6d8216d-ace4-48ba-afca-74da0dc5abb5/
https://www.geoedge.com/balda-injectors-2-0-evading-detection-gaining-persistence/