Attack campaign targeting Apache Struts2 vulnerability

Authors: Roberto Paleari (@rpaleari), Claudio Moletta (@redr2e) and Luca Giancane

At the beginning of March, a security advisory was published about two high-impact issues affecting Apache Struts2, a widely-used framework to create Java web applications. Despite they can be exploited to cause either a DoS (CVE-2014-0050) or to gain remote code execution on the affected server (CVE-2014-0094), these vulnerabilities have not raised much interest until a proof-of-concept exploit was published on a Chinese blog in April, followed by a more detailed write-up describing the technical details of the attack. In addition, on April 24th, researchers from Vulnhunt showed the inefficacy of the countermeasures initially proposed as a workaround to address the bugs.

As usually happens in these cases, after the publication of the PoC attackers started to mass-scan the Internet, searching for vulnerable servers. As a consequence, in these days we observed automated attacks trying to exploit CVE-2014-0094. All the attacks we observed so far are originated from a single source IP, namely

Anatomy of the attack

The attacks we observed start with a single HTTP GET request to rebase the application to a remote directory, using a UNC path that points to a SMB shared folder on the attacker's machine. The request logged by the target web server is the following:


By listing SMB services available on, we can confirm the presence of a share named "toplel", as shown in the figure below.

SMB share toplel, on the attacker's host
The toplel share accepts anonymous connections and contains several JSP pages, all containing the following HTML fragment:

gayfgt 696969

No active nor malicious code was found in any of these JSPs. Thus, our hypothesis is that some of these pages are invoked by the attacker to verify if the exploit succeeded, by checking the page returned actually matches the expected content. Unfortunately, at the time of writing we were not able to record any additional request sent by the attacker, beyond the initial one that triggers the Apache Struts2 vulnerability.

In addition to the anonymous SMB share, the attacker's machine exposes a web server configured to enable a directory listing on the root directory. This allowed us to inspect its contents and continue our analysis.

Directory listing on

We speculate the goal of the attacker is to leverage CVE-2014-0094 to eventually execute some of the binaries hosted on this server, as discussed in the next section. In addition to these malicious application, the server also hosts some warez and even a Torrent client with a web-based interface.

Warez folder on the attacker's host

Web-based Torrent client

Despite we still miss the joining link between the initial attacker's request and the request that drops and installs the malicious payload, we speculate the aim of the attacker is to execute one of two possible malicious applications, depending on the OS running on the compromised host:
  • besh, a shell script for Linux hosts.
  • toplel.exe, a binary application targeted for Windows machines.
The behavior of both the Linux and Windows payloads is described in the next paragraphs.

Linux payload

Analysis of the Linux payload (the script named "besh") is trivial: after collecting some information about the compromised machine, the script downloads and executes two additional binaries, yolo-x64 and yolo-x86 binaries; as you can probably imagine, these are 64-bit and 32-bit ELF applications, respectively.

Dropped binaries are a repackaged version of xptMiner, an open-source coin miner. As can be seen from the script contents, the application is configured to connect to, with username "Seegee.lin" and password "1"; at the time of writing, this URL was still active. On a compromised machine, the coin miner will be saved to /tmp/.HOLDMYWEEVE. In addition, the script also takes care of terminating any instance of the stratum process, another open-source coin miner.

Contents of the "besh" shell script

Windows payload

The goal of the Windows payload is the same as the Linux version, i.e., to install xptMiner on the victim's host. In this case, the dropper (ok.exe, MD5 hash 1467e41283f01c0f80568dd4b60b2484) is slightly obfuscated using very standard techniques: strings are encoded in base64 form and library functions are resolved starting from hard-coded hash values.

Upon execution, the binary checks if it is running on a 64-bit Windows system by leveraging the IsWow64Process() API. According to the result, either the yolo.exe (cb6799b63dbf3ddd1e7e0e05e579fe89) or swog.exe (5ace2dbc44e19d16bff7ce277bcdde2f) binaries are downloaded.

Generation of the HTTP request to download the second stage

As with the Linux version, dropped binaries are actually the xptMiner miner, that is then saved to local path %APPDATA%\ok.exe and finally executed with a command-line similar to the following:

%APPDATA%\ok.exe -o -u Seegee.toplel -p 1


In this post we briefly described an attack currently running "in the wild", which exploits Apache Struts2 vulnerability CVE-2014-0094 to execute arbitrary commands on a vulnerable web server. Apparently, the goal of the attacker is to drop an executable that eventually installs a coin miner.


Sitecom firmware encryption and wireless keys

Authors: Roberto Paleari (@rpaleari) and Alessandro Di Pinto (@adipinto)

Last year we blogged about multiple security issues affecting Sitecom device models WLM-3500 and WLM-5500. One of these issues allowed attackers to obtain the default wireless passphrase of a vulnerable device in a "single shot", as the wireless key was derived from the device MAC address using an algorithm included inside the device firmware. This is a very serious issue, as many users never change the default Wi-Fi passphrase and keep using the one set by the device manufacturer.

We recently had the opportunity to analyze some other Sitecom routers, more precisely models WLR-4000 and WLR-4004. We were first attracted by this models due to the introduction of some mechanism to encrypt the firmware image distributed through Sitecom web site. To make a long story short, we soon realized the encryption layer could be easily circumvented; in addition, these routers were affected by the very same issue concerning the wireless passphrase: also for these models the key is derived from the MAC address, thus attackers can easily generate the default wireless key and access the LAN of a victim user.

Analysis of the firmware layout

In the following we briefly describe the analysis of the WLR-4004 firmware image (v1.23), but WLR-4000 differs only in minor details.

As a first step, to analyze an embedded device we typically try to download the firmware (when available) and inspect its contents. With WLR-4000/WLR-4004 devices we were lucky enough to find the firmware image on Sitecom web site. However, a preliminary analysis of the firmware  using binwalk provided no information about its internal structure:

$ binwalk 4004-FW-V1-23.bin

This can be a symptom of a weird image format or, more often, an encrypted/obfuscated firmware. After we gave a quick look at the file entropy, we started to opt for the latter hypothesis. As an example, consider the low-entropy areas around 1.4MB and at the very end of the file:

File entropy for the WLR-4004 firmware image

A closer look to these regions provided some clues about the actual structure of the firmware image. As can be seen from the hex dump below, the final low-entropy area is due to the very same 8-byte sequence (88 44 a2 d1 68 b4 5a 2d, highlighted in red) that repeats until the end of the file.

$ dd if=4004-FW-V1-23.bin bs=$((0x0339720)) skip=1 | xxd | head
0000000: 00c6 ece0 c8f2 402e bdaa db83 d91d d987  ......@.........
0000010: b47d 4da1 987d 0f0d d64f 901a a6ae 056a  .}M..}...O.....j
0000020: 6d68 0219 3648 7980 4073 c849 ee04 5a2d  mh..6Hy.@s.I..Z-
0000030: ef9c ae4f 68b5 f52f 104c a2d1 1d08 620a  ...Oh../.L....b.
0000040: b674 af5a 6ab4 5a2d 8845 fb8b fe71 472d  .t.Zj.Z-.E...qG-
0000050: 8844 a2d1 6c34 5a2d 8844 5617 75b4 5a2d  .D..l4Z-.DV.u.Z-
0000060: 8844 a2d1 68b4 5a2d 8844 a2d1 68b4 5a2d  .D..h.Z-.D..h.Z-
0000070: 8844 a2d1 68b4 5a2d 8844 a2d1 68b4 5a2d  .D..h.Z-.D..h.Z-
0000080: 8844 a2d1 68b4 5a2d 8844 a2d1 68b4 5a2d  .D..h.Z-.D..h.Z-
0000090: 8844 a2d1 68b4 5a2d 8844 a2d1 68b4 5a2d  .D..h.Z-.D..h.Z-

In an unencrypted firmware, the final bytes of the image are often used for padding and are thus initialized to zero (or to 0xff). But assuming our Sitecom firmware has been encrypted using some standard scheme, which algorithm would produce such a recurring pattern?

Our first attempt was to try with a basic XOR encryption, assuming a 8-byte key equal to byte sequence we observed before. The following Python snippet reads the encrypted image from standard input, performs the XOR and writes the result to standard output.

Firmware decryption routine for WLM-4004 images

After decrypting the firmware image we tried again to use binwalk to analyze the firmware. The results confirmed our hypothesis about a XOR algorithm being used to cipher the image: this time binwalk identified all the main components of a standard firmware image, including the kernel image (at offset 0xc0) and the root file system (offset 0x15d080).

$ cat 4004-FW-V1-23.bin | python > decrypted.bin
$ binwalk decrypted.bin

128           0x80          uImage header, header size: 64 bytes, header CRC: 0xAAB37DFB, created: Wed Jan 15 06:15:01 2014, ...
192           0xC0          LZMA compressed data, properties: 0x5D, dictionary size: 33554432 bytes, uncompressed size: 4240232 bytes
1429632       0x15D080      Squashfs filesystem, little endian, version 4.0, compression:  size: 1951490 bytes,  131 inodes, blocksize: 131072 bytes, created: Wed Jan 15 06:14:03 2014


Generation of the wireless key

We were finally able to analyze the contents of the firmware image (and, in particular, of the root file system) to search for any evidence of the wireless key generation algorithm. We were soon attracted by a rather "suspect" function exported by a shared library named; the function itself was named generate_wpa2_key_based_on_mac(). And yes, as you can probably imagine this is exactly the function we were looking for :-)

Function generate_wpa2_key_based_on_mac(), exported by

Similarly to the algorithm we found in WLM devices last year, the scheme used in WLR routers is also based on "scrambling" the MAC address and apply some character substitutions leveraging a hard-coded charset. The WLR-4000 and WLR-4004 only differ in the actual charset being used. More in detail, the algorithm is sketched out in the next figure.

A fragment of the key generation algorithm

As usual, we wrote a Python script that implements the attack (available here). The script receives in input the MAC address of the vulnerable Wi-Fi network and the router model name ("4000" for WLR-4000 and "4004" for WLR-4004) and generates the corresponding Wi-Fi key. A usage example is shown below.

$ python -m 4000 aa:bb:cc:dd:ee:ff
MAC:  aa:bb:cc:dd:ee:ff

$ python -m 4004 aa:bb:cc:dd:ee:ff
MAC:  aa:bb:cc:dd:ee:ff


Is not so uncommon for embedded device makers to rely on some obscure, and often custom-made, algorithms in order to generate secrets (e.g., Wi-Fi keys, admin passwords) starting from public details (e.g., MAC addresses, wireless SSID). Such approaches are quite handy for testing, debugging and manufacturing purposes. Even if it could be a very bad security practice, as long as the algorithm is sufficiently robust and is not leaked, no big issues arise.

However, in this blog post we shown how things can change when developers "forget" to remove an implementation of the algorithm from the final version of the device firmware: in these cases, it is just a matter of time until the code is found, analyzed and a key generator is developed, even when the device firmware image is "protected" by some obfuscation or encryption scheme.