Ransomware Infects 100K PCs in China, Demands WeChat Payment

( original text by  )

Over 100,000 thousand computers in China have been infected in just a few days with poorly-written ransomware that encrypts local files and steals credentials for multiple Chinese online services.

The crooks demand the victim a ransom of 110 yuan ($16) in exchange for decrypting the files, payable via Tencent’s WeChat payment service by scanning a QR code.

A report from Chinese security firm Huorong, the malware, dubbed ‘WeChat Ransom’ in some reports, emerged on December 1 and the number of infected systems has grown to over 100,000 as of December 4.

The infection rate seems to have accelerated in one day, rising to the above number from just 20,000 yesterday.

The researchers say that the malware author used the Chinese social networking service Douban to send out commands. After analyzing the malware, they were able to access two servers used for storing data and found on one of them over 20,000 passwords for Taobao and Alipay accounts.

Credentials for other services are also targeted by the malware as it hunts for login information for Tmall, Aliwangwang, Alipay, 163 Mailbox, Baidu Cloud, Jingdong, and QQ.

Stolen data stats

According to information from Tencent, the malware propagated through a compromised popular application designed to manage multiple QQ accounts at the same time. Additional data reveals that the malware author poisoned at least 50 applications to spread the ransomware.

Telemetry data showed that a large part of the victims did not have a security solution installed on the system. This explains the sharp rise of infections despite security companies issuing warnings about the threat since its outbreak at the beginning of the month and updating their antivirus products to block it.

Malware fighters see no challenge

Chinese security companies analyzing the malware agree that it is far from a complex threat that can be easily defeated.

Although it claims to delete the decryption key if the victim fails to pay the ransom by a certain date, file recovery is still possible because the key is hardcoded in the malware.

The simplicity of the file encryption (XOR, not DES as the author claimed in the ransom note) also made it possible for decryption tools from several security companies including Qihoo, Tencent, and Huorong to become available.

Author leaves hard-to-miss trail

Experts from Huorong examining this ransomware string found some details that could lead to identifying and apprehending the malware author.

They discovered a name, a mobile phone number, a QQ account, and an email address that could help police catch the crook. Using the info present in the malware code, the researchers ran a domain lookup and found additional details that connected the dots and possibly leading to the identification of the author.

Tencent on December 1 banned the WeChat QR code for makingnd and control server. the ransom payments and closed the account associated with it. In its turn, the Douban platform deleted the page used by the malware as a command and control server.

A look under the hood of a decentralised VPN Application.

( original text byDonatas Kučinskas )

MysteriumVPN is the client application of Mysterium Network, a project focused on providing security and privacy to web 3 applications.

In this article, we will discuss the architecture of MysteriumVPN and how it integrates with Mysterium Node to ensure an encrypted end to end flow of data through Mysterium Network.

Cross-platform architecture

Usually, you need separate builds for each platform. Now that cross-platform technology has improved, this is no longer the case.

For desktop:

Electron is a framework which allows us to build cross-platform applications using common web technologies such as HTMLCSS and Javascript. We are using Electron which allows us to develop one application for two platforms for desktop — Windows and Mac OSLinux coming soon. Download our alpha.

Under the hood of an Electron application, sits a Chromium browser; A website, rendered by an embedded browser.

For mobile:

We are kicking off our mobile development for MysteriumVPN, with Android versions set to release shortly.

For this, we are using React Native for cross-platform applications.

Most of MysteriumVPN is written in Javascript, which is run in a separate process. Javascript generates the virtual structure of the user interface. This Javascript process communicates to native mobile processes which are responsible for rendering the actual user interface as you see it.

The architecture of MysteriumVPN Desktop Client Application

How MysteriumVPN works on desktop:

Since we are using Electron, we have two processes, MAIN and RENDERER.

MAIN is the first process which is started when the application starts. It is a NodeJS process which is responsible for managing the following functions:

  • Application state and internal operations
  • Tray
  • Kicking off the RENDERER process

The second process is RENDERER and it is responsible for displaying the graphical user interface for the application.

Communication between processes:

Both the MAIN and RENDERER processes need to communicate with each other to stay in sync. For this reason, we are using a standard approach of Inter-Process Communication (IPC).

Javascript is not type-safe, which isn’t very reliable. We use Flow static type checker which adds type-safety for Javascript. This especially applies to syncing data between processes — it becomes less reliable when using out-of-the-box IPC. To improve that, with custom implementation on top to have type-safety.


 describes a single typed message which is sent between processes. It creates alignment between both processes by introducing sender and receiver objects, ensuring that both sides expect the same arguments of this message.

Here is an implementation:

class MessageTransport<T> {
 _channel: string
 _messageBus: MessageBus
constructor (channel: string, messageBus: MessageBus) {
 this._channel = channel
 this._messageBus = messageBus
buildSender (): MessageSender<T> {
 return new MessageSender(this._channel, this._messageBus)
buildReceiver (): MessageReceiver<T> {
 return new MessageReceiver(this._channel, this._messageBus)
class MessageSender<T> {
 _channel: string
 _messageBus: MessageBus
constructor (channel: string, messageBus: MessageBus) {
 this._channel = channel
 this._messageBus = messageBus
send (data: T) {
 this._messageBus.send(this._channel, data)
class MessageReceiver<T> {
 _channel: string
 _messageBus: MessageBus
constructor (channel: string, messageBus: MessageBus) {
 this._channel = channel
 this._messageBus = messageBus
on (callback: T => void) {
 this._messageBus.on(this._channel, callback)
removeCallback (callback: T => void) {
 this._messageBus.removeCallback(this._channel, callback)

Here is an example of communication between both these MAIN and RENDERER processes:

Example: communicating country proposal updates between processes:

MAIN process is managing country proposals internally and it sends all updates:

this._countryList.onUpdate(countries => {

RENDERER process listens for country updates,

onCountriesUpdate (countries) {
  this.countriesAreLoading = false
  this.countryList = countries

Having such an abstraction layer ensures that communication is type-safe, reliable and features around it are simple to test.

How do we integrate Mysterium Node with MysteriumVPN Application?

Once we’ve rendered the application layer, we still need to connect MysteriumVPN to Mysterium NodeMysterium Nodeis a software that connects you to Mysterium Network where you are able to exchange value for bandwidth.

MysteriumVPN is a client application of Mysterium Network. The successful running of our dVPN on the network will attract other use cases from existing or future businesses that require end-to-end encryption of data, thereby expanding Mysterium Network’s ecosystem.

We require specific information to ensure the successful running of our dVPNservice.

Operation System Service
Since we are running Mysterium Node under the MysteriumVPN application we need to supervise the Mysterium Node to ensure that it works.

Our Data Protection Policy
We make a clear distinction between personal data and usage data. We do not collect information on who you are. We collect data on session and connection inputs and outputs. This is important data for us as it gives us visibility on how our technology fares against the realities of cyber oppression. Check out our privacy policy for more information.

Since we are integrating Mysterium Node into the MysteriumVPN application, the application itself gets quite complex. That’s why we have to be prepared to log errors from everywhere, — our application, Mysterium Node, and from Electron.

That means that there are three sources of inputs. When we are inspecting something, we need to understand that these errors can happen in three different places. We need to synchronise those and collect all relevant data from these sources.

Data management in the era of web 3 is complex and we hope to do so in an ethical and fair manner. Check out how our no logs policy protects your personal data.

Build on Mysterium Network

We have an npm package that allows for you to connect to Mysterium Nodeeasily. This is the same package that the MysteriumVPN uses to connect to Mysterium Network. This can be used for any application — it’s literally plug and play.

Interested in contributing to Mysterium Network? We are an open source project focused on bringing privacy, security and freedom to web 3. Check out our Github.


( original text by Fritz Sands )

The operating system kernel is the final goal for every great exploit chain. You can look at the entries in the Zero Day Initiative (ZDI) Pwn2Own contests over the years to see that process at work. The Windows kernel has been subject to many points of attack. One of my favorites is abuse of DeviceIoControl calls to various drivers since this allows access to so many drivers written by so many vendors, many of which are not all that well written or tested.

Over the years, most of the attacks to penetrate into the Windows kernel have gone through win32k.sys — a kernel-mode device driver that controls the Windows graphic and window management system. When Microsoft moved this functionality out of CSRSS and into the kernel twenty years ago, it instantly doubled or tripled the attack surface into the Windows kernel — and that has been a rich mine of vulnerabilities ever since.

Another large attack surface has opened up since WDDM (Windows Display Driver Model) supplanted the earlier XDDM over the last decade. Calls to initiate actions by the display system start by going through win32k.sys, but after that there are direct calls by user processes into dgxkrnl.sys and other drivers through entry points in GDIPlus. This expanded attack surface is an inviting target for researchers.

In the spring on 2018, the ZDI purchased five vulnerabilities from ChenNan and RanchoIce of Tencent ZhanluLab that target the DirectX kernel interfaces. These purchases resulted in four CVE’s from Microsoft. This post covers the vulnerabilities and provides Proof of Concept sources published on our site.

Additionally, one of the attacks (ZDI-18-946/CVE-2018-8405) was featured in a presentation by Rancho and ChenNan at the 44CON conference in September. I highly recommend that researchers review the slide deck from that presentation.

An overview of DirectX

Before diving into the vulnerabilities, let’s take a brief look at the DirectX interface and drivers.

The DirectX graphics kernel subsystem consists of three kernel-mode drivers: dxgkrnl.sys, dxgmms1.sys, and dxgmms2.sys. These drivers communicate to the user through win32k.sys and through their own set of interfaces. They also communicate with BasicRender.sys, BasicDisplay.sys, and the display miniport drivers.

DirectX defines a number of complex kernel objects, most of which have names that begin with DXG. The user interfaces with DirectX through a number of complex API entry points , many of which begin with D3DKMT and others of which begin with DXGK.

Here are a few of the more interesting entry points:

D3DKMTEscape — this entry point takes a completely user-controlled blob of data as an input. This data blob can be huge, and so there is a strong temptation to leave it in user memory instead of capturing it in the kernel during the transition to kernel processing. This pattern makes the invoked kernel routine a ripe candidate for forgetting try blocks and for time of check to time of use (TOC/TOU) vulnerabilities. The data is not in a standardized structure, so every driver has different definitions.

D3DKMTRender — this entry point is the heart of actually rendering graphic data. User-address commands and patch buffers are interpreted by the kernel drivers and are, in fact, passed to the miniport drivers. Again, this is ripe for race conditions. Additionally, rendering can spawn worker threads, which make race condition vulnerabilities more likely.

D3DKMTCreateAllocation — this entry point allocates memory. Issues (see ZDI-18-946 below) can arise because of the complex interplay between different flags and handles passed into the API call.

One excellent overview of WDDM from an attack perspective is a 2014 Black Hat presentation by Ilja van Sprundel of IOActive entitled «Windows Kernel Graphics Driver Attack Surface» [PDF]. I highly recommend reading it. The presentation goes into great detail on the complex attack surface of the kernel side of WDDM.

Walkthrough of the vulnerabilities

The Proof of Concept (PoC) sources are found here. If you are going to reproduce the crashes, you need to go back to a version of Windows before August 2018 (when Microsoft patched out the vulnerabilities). Remember to attach a kernel debugger to the machine under test and set special pool on the drivers under attack. I tested these vulnerability reports on Windows 10 x64.

ZDI-18-946/CVE-2018-8405 — D3DKMTCreateAllocation Type Confusion Vulnerability

The first vulnerability we’ll review is in the 


 method in dgxkrnl.sys, is exposed through the 


 method, and could allow a local attacker to escalate privileges to System. Our advisory for this can be found here, and the patch from Microsoft is located here. The bug results from the lack of proper validation of user-supplied data, which can result in a type confusion condition.

To see this in action, enable special pool on 


 before running the PoC. The type confusion results from inappropriate use of the 


 flag in an allocation. The PoC code uses a 


 flag of 0 for an allocation, and then passes the resultant handle into a second allocation in which it sets a 


 flag of 1.

And here is the blue screen analysis:

The faulting code is in 


 and is a classic type confusion walk off of the end of an allocation:

ZDI-18-947/CVE-2018-8406 — D3DKMTRender Type Confusion Vulnerability

The next vulnerability exists in the dxgmms2.sys driver, and is exposed through the 


 method. This vulnerability also could allow a local attacker to escalate privileges to System. Our advisory for this can be found here, and the patch from Microsoft is located here. Like the first example, this bug results in a type confusion condition. While similar in nature, these bugs have different root causes.

Again, you need to enable special pool on 




 to see these bugs, and, of course, attach a kernel debugger to your target machine. This type confusion results from allocation operation that gets confused between two different adapters.

Relevant PoC code:

PoC crash details:

Vulnerable code:

ZDI-18-950/CVE-2018-8400 — D3DKMTRender Untrusted Pointer Dereference Vulnerability

This next vulnerability is also exposed through the 


 routine. The vulnerability is in the DGXCONTEXT::ResizeUserModeBuffers method in dxgkrnl.sys. Our advisory for this can be found here, and the patch from Microsoft is located here. In this case, the bug is caused by the lack of proper validation of a user-supplied value prior to dereferencing it as a pointer. The resulting pointer dereference is due to the driver trusting a flag set by the user. Here are the relevant PoC details:

Which results in the crash:

Called from:

Vulnerable code:

Obviously, this flag from the user should not lead to an arbitrary dereference in the kernel.

ZDI-18-951/CVE-2018-8401 – BasicRender Race Condition Vulnerability

This final vulnerability is a bit more complex, as the vulnerability resides in the processing of the 


 API and the 


 API by the BasicRender driver. Our advisory for this can be found here, and the patch from Microsoft is located here. Shared resources are not properly secured, which can result in a memory corruption condition. An attacker can use this to escalate privileges to SYSTEM. This type of elevation is often used by malware to install itself once a user clicks something they shouldn’t. Note that Microsoft gave one CVE for this bug and for ZDI-18-949, indicating an identical root cause.

The PoC code for the two cases are related but differ.

Key part of first PoC:

Each call to 


 spawns a thread through 


. The call to 


 changes the state of the same objects and a race condition occurs.

Here is the resulting crash:

The race condition is between two modifications of the same location:

For ZDI-18-949, you can see the difference in the PoC code despite the same root cause. Here’s the key part of this PoC:

Executing this PoC causes a crash in the Run method:

Here’s the vulnerable code:

The vulnerable code crashes the second time through Run, but not the first time.


WDDM and the DirectX graphics kernel code allow for a very powerful and flexible graphics system for Windows. They do this through use of a number of very complex objects and by creating a number of new complicated interfaces to user code. The Proofs of Concept given here should give you some idea of the complexity of the objects implemented in DirectX and the scope available for future research in this area. I am quite sure that this pond is not fished out.

Direct static analysis could give you attack information. However, this is certainly a daunting task. Another possibility is to set up a fuzzing framework to set different values into different flags and call DirectX methods in different orders and look for a crash. Of course, you can also add multiple threads changing and freeing data to investigate the possibility of race conditions and TOC/TOU. Remember to set special pool on all of the relevant drivers.

As always, when you find new vulnerabilities, the Zero Day Initiative is interested in talking with you. Until then, you can find me on Twitter at @FritzSands, and follow the team for the latest in exploit techniques and security patches.