Skip to content
Eye Security

Eye Security

labs.eye.security • October 23, 2026

Between November 2025 and March 2026, Eye Research actively disabled the vulnerable update mechanism used by the popular download client Popcorn Time (Time4Popcorn). This involved executing code on systems running the vulnerable software. This is the story of how we got here and why we took the unprecedented decision of taking matters into our own hands. The vulnerability was assigned CVE-2026-30612, which we published an advisory in June 2026.

It all started with a normal threat hunt. As an MSSP, we have lots of telemetry from our clients and we use this data to for known and unknown threats. We noticed a process called “Updater.exe” that was running on a laptop at one of our clients. This process was attempting to connect to a domain that wasn’t registered anymore: popcorntimeupd.xyz. It was also connecting to several other domains, some of which are marked as malicious on VirusTotal, so we thought it was worth investigating further.

Looking at the file path and VirusTotal , it quickly became clear that this file was part of Popcorn Time. Popcorn Time is a BitTorrent client that allows users to view movies downloaded from the internet. It was very popular around ten years ago, but the original version was shut down in 2014. This inspired several forks of the software, including one called Time4Popcorn . Confusingly, these forks (including Time4Popcorn) commonly used the Popcorn Time name when distributing the software. This means that it wasn’t always clear to users what version of the software they had installed. The ‘Updater.exe’ we found is part of the Time4Popcorn fork. This is a closed-source variant of the software, so no source code was available.

None of our clients were actively using the software. Most had installed it years ago and probably forgotten it. The Updater program was still running in the background, however, regularly checking if any updates were available.

Since early 2025, a new project started using the Popcorn Time name and is building a legal alternative. This research does not apply to that software.

Registering the domain

This software wasn’t all that common among our clients. Only a handful of them had it running. We run an MSSP for businesses, so people don’t usually run software that lets them illegally stream copyrighted material (although you’d be surprised how often detections result from end-users trying to install cracked software). Intrigued, we decided to register the domain and see what kind of requests were coming in.

We were a bit shocked to see the web server log growing and growing. 50 requests per second were coming in, mostly looking like this:

GET /?app_id=T4PSEC&hid=0a62d1fbddf387e1b37b5034f21049f6&ver=6.1.0.0&os=WIN060200

The ‘hid’ parameter seemed to contain a hardware ID, supposedly uniquely identifying the client. Over the six months, we saw over 3.8 million of these IDs. Half of them were running on Windows, with the rest running macOS (~45%) and Android (<5%).

Later, we would learn that counting clients based on hardware ID was not as reliable as we had hoped and we were underestimating the number of Windows systems and overestimating the ones running macOS.

Determining the impact

So now what? All we knew at that point was that this software was connecting to the domain and sending requests. All this was happening over unencrypted HTTP connections. Everything suggested that it was trying to fetch an update from the server, but we didn’t know if we could let the software execute one. Simply serving an executable didn’t seem to do anything. Even if we figured out how the process works, the software may check digital signatures, preventing abuse by third parties.

If we were able to send an update, we could potentially get code execution on millions of systems. Ransomware operators often use infected clients in a botnet to gain an initial foothold in corporate networks. Password-stealing malware also loves taking those passwords stored on devices, especially if companies allow end-users to log into corporate systems from personal devices. In other words: the impact would be severe if this were to fall into the wrong hands.

We could see the Updater.exe program was trying to connect to several other domains. At the time, we only owned one of them; the others were all registered by third parties. They all seemed to be claimed by bulk domain buyers and parked or for sale for thousands of dollars. None of the domains offered updates to connecting clients, so to determine how the process works, we had to reverse engineer the binary. The other platforms (Android, macOS) turned out to use different domains as well. Many of these domains were still unregistered.

The Updater executable was written using C++ and Boost 1.55 (released in 2013). C++ executables can be a bit annoying to reverse, especially if they use Boost, so it took us a while to figure out it was expecting a JSON response (probably could have guessed that). All we needed to do was supply a link to an executable and the program would download it and then execute it with high privileges (NT AUTHORITY\SYSTEM). There was no code signing and this process was all happening over HTTP.

On macOS, things were pretty much the same. We could push an update that would execute as root. The executable differs a lot from the Windows one though, and as I did not have any prior macOS-reversing experience, this took a while to figure out. For some reason, the author decided to obfuscate a lot of strings, and I may or may not have spent half a day reverse engineering a base64 implementation. The expected JSON was very different on the macOS version, but the result was the same: code execution with high privileges.

On both platforms, this was all happening in the background as the program started automatically. Many users had probably forgotten the software years ago and weren’t actively using it.

On Android, things are slightly different: there is no background process. The application checks for updates when it is opened by the user. The end-user is then asked if they want to install an APK.

So, we have millions of hosts that are connecting to different domains trying to get updates. How do we make them safe again? Normally, when finding vulnerabilities, we would the vendor, they would release a patch, and most people hopefully install this. In this case, the ‘vendor’ was a bunch of pirates (arrr). Even if we could them, what were they going to do it? They seemed to have lost control of the domains and would not have been able to push an update to clients anyway. The site that used to distribute the software hasn’t been active in years.

We thought trying to get control of all the domains. Looking at the landing pages, they seemed to be owned by several different people. One of the domains was hosting a personal blog. Some were selling the domains for thousands of dollars. We figured that, by spending a lot of money, we could probably get control of most of the domains, which could be worth it. However, if we were unable to buy one of the domains, the plan would not be very effective. Also, as updates were happening over unencrypted HTTP, end-users would still be at risk from attackers that could manipulate their internet traffic. In some countries, governments have used insecure update processes to install spyware on dissident PCs . For other users, simply connecting to an unencrypted Wi-Fi network could put them at risk.

Who are these people?

Given the nature of the software, most of these clients will be users. We mapped a sample of the IP addresses using kepler.gl and they were everywhere:

Most clients are connecting from end-user ISPs spread across the world, but we’re also seeing connections from various government and military networks around the world. We’re also seeing a lot of clients connecting from corporate networks. It’s hard to draw conclusions from this, but we think it’s safe to say criminals would be very interested in many of these systems.

Can we disable the updater remotely on connecting systems? Sure, we can offer an update to the clients that instructs the updater to disable itself. But is this ethical? Could we get into legal trouble? When systems are asking you for an update, can you give them one? Thankfully, our legal team enjoys a good challenge and was able to provide some advice.

The only real alternative we had was to do nothing, and this didn’t seem like it would make the world a better place. The update process wasn’t doing anything functional anyway, it was only creating risk for users. A somewhat similar case was Operation Ladybird , where the Dutch police deployed a software update to clients that were part of the Emotet botnet, neutralising the infections. Of course, those clients never intentionally became part of a botnet, while these users presumably voluntarily installed the software.

But while these users chose to install Popcorn Time, none of them chose to have a forgotten updater running in the background for years, ready to run any code with full privileges for whoever controlled one of its domains. With millions of systems affected and the software long abandoned, there was no vendor to fix this and no patch on the way: if we didn’t act, nobody would.

We figured there were two main risks:

We could make things worse by breaking something on the systems we would deploy the update to

Someone else could figure out what we were doing and would use this knowledge for malicious purposes

To mitigate the risks, we did extensive tests of the update and ran a small-scale test first. For our full-scale deployment, we made sure we were able to deploy updates on both Mac and Windows systems. We also built a system that granularly allowed us to deploy the update to specific systems.

On Windows systems, our update simply stops and disables the service via the Service Control Manager . That’s all it does, so no telemetry, no file deletion, nothing. You could achieve the same manually via the command line by executing these two commands:

sc.exe stop "Update service"

sc.exe config "Update service" start= disabled

On Mac systems, we use a shell script and execute this command:

launchctl unload -w /Library/LaunchDaemons/PT.updd.plist

This stops and disables the launch daemon that would start the PT.updd process when the system boots.

We also didn’t want bad actors to start doing the same thing. To prevent this, we initially only offered the update to hardware IDs we had seen before. This made it harder to investigate how the update process worked by setting up a test system. Each ID would only be served the update a single time. We also redirected clients to HTTPS where possible. After a few weeks we relaxed all of these restrictions to get our update to as many systems as possible. Some hosts weren’t following our HTTPS redirects, and, as we later learned, relying on hardware IDs to uniquely identify clients wasn’t ideal.

those ‘hardware’ IDs

In our small-scale tests, we noticed some peculiarities. The Windows devices we were updating were getting the update more than once. This was the trigger we used to determine if our update was failing and it seemed to be failing a lot. Did our code suck? Did we have some endpoint protection product blocking it?

When we looked closer, we saw devices with the same ‘hid’ requesting the update multiple times a day. However, the requests almost always came from different IP addresses, all over the globe. Also, some clients were reporting several different operating system and application versions. This led us to believe that at least on Windows, large numbers of systems were using the same ‘hid’.

When looking at the generation of the ‘hid’ value by Updater.exe, in our reversing we had seen that the software created an MD5 hash of three combined elements:

The volume serial number of the C-drive (32-bit value)

The volume GUID of the C-drive

The MachineGuid stored in HKLM\SOFTWARE\Microsoft\Cryptography

This didn’t sound too bad. It’s not really tied to the hardware, but unless a machine is cloned, this should result in a unique value. We did find some reports of people finding duplicate MachineGuid values, but it shouldn’t happen on the scale we were seeing.

I guess it’s time to open Binary Ninja again. A bit of debugging led us to this snippet of the code that was generating the hid:

This code is trying to fetch the MachineGuid from the registry and then add it to the MD5 hash. RegQueryValueExA and RegCloseKey both return 0 upon success, however the error check is reversed for these functions (jne vs je). If RegCloseKey returns 0, it will jump over the md5_update call and the MachineGuid will not be added to the hash. The only way this entropy will be added is if RegQueryValueExA succeeds and RegCloseKey fails, which is an unlikely scenario.

In other words: the hid values only use the disk metadata as input for the MD5 function. This brings us to the rabbit hole: how random is this?

Back to that EDR telemetry. In the telemetry we could see those disk GUIDs, so we could get a nice overview of them. Well, there are a lot of duplicates. For example: we could see the volume GUID of ‘a4ff4960-8e16-4b10-a74d-8c389ac860b8’ on hundreds of hosts, spread over many different customers. They also all had the same volume serial number. These were all HP EliteBook and ProBook G9 laptops. HP had deployed these with their standard image, made the important bits (like the MachineGuid) unique and shipped them to customers. This is all totally fine, until someone starts to try to identify machines based on this non-unique information. If these users were to install Popcorn Time, their systems would all have the same hid value.

In short: on Windows systems, the hid is often unique, but if you or your PC manufacturer cloned the C-partition, it will probably be the same across many machines. It is unlikely to change though, unless you reinstall the operating system. This means there are probably a lot more Windows systems with this software than we initially determined. We estimate we encountered 2.5-3.0 million hosts.

What hardware IDs on macOS?

We weren’t seeing the same signs on macOS. Most systems were just downloading the update, and we would never see them again, perfect.

On macOS, the hid is generated based on:

Hardware addresses of network interfaces (en0, en1 etc.)

Ok, those hardware addresses are supposed to be unique. Combined with the hostname, it seems unlikely that two hosts would have the same hid. The CPU type only adds a few bits of entropy.

We did notice we would often see hid values only once, which seemed odd. We thought looking at IP addresses only wasn’t that accurate, as most users won’t come from the same IP address all the time, but started looking at IP addresses that had a lot of different hid values behind them.

In the most extreme case, we would see an IP address reporting 11 different hid values in a single day. This didn’t seem to be someone with a lot of devices, as when the hid changed, we would never see it again. We would sometimes see the same value a couple times in a row.

We believe the hostname is the most likely culprit here. We found several accounts of users experiencing hostname changes on their macOS systems, due to it being pushed via DHCP or detecting a duplicate on the network. In other words: hostnames are somewhat likely to change on macOS systems. When they do, the hid that PT.updd generates will change, which makes it look like a new unique system has just shown up. Another possibility is that users are using something like LinkLiar , a piece of third-party software that can randomise the ethernet hardware addresses automatically when the device enters sleep mode. In macOS Sequoia 15 Apple introduced a built-in feature that can randomise hardware addresses.

Most hosts seemed to have stable hid values, but the ones that didn’t significantly inflated our numbers. Where we initially thought there were 1.7M macOS hosts, this number is probably a lot lower. Our best guess would be 250-350k.

Wait, now we’re the bad guys?

Shortly after we started offering our update, someone uploaded it to VirusTotal. A week later 11 different vendors were detecting our update as malicious, as was the VirusTotal AI summary:

Technically, that’s a perfect description of what our update does. We were a little offended by the word “malware”, but the real problem was practical: every endpoint product that blocked our update left the vulnerable updater running, and that system exposed. Reporting false positives to every vendor would have taken weeks. So, we downloaded some of the products and started tweaking our code to evade their signatures. Eventually we ended up with an executable that was only detected by a single vendor.

After a month, in December 2025, we had already deployed an update to more than a million systems. This resulted in a 90% reduction of update requests to our domains after a few weeks. On March 1, 2026, we were still sending 5000 updates per day, which amounts to a 98% reduction. Given these (relatively) small numbers, we feel the interest for any botnet operator would probably be too limited to make large investments. Therefore, we decided to stop offering the update and begin the process of transferring the domains to a trusted third party. At that point, we had sent out over 2 million update downloads.

In late March, we transferred the 15 domains we owned to The Shadowserver Foundation , as we felt they should be sinkholed by a trusted third party instead of remaining in our possession. We could only transfer the domains we were able to register, some domains are still owned by third parties.

We did not deploy any updates to Android systems. Unlike on Windows and macOS, there is user interaction required to install the update, so it doesn’t happen silently in the background. Also, the updater is part of the main application on Android so it can’t be independently disabled.

What the application itself?

With the updater disabled, is Popcorn Time safe to use? We didn’t look at the main application as closely as the updater, but what we found was enough to answer that question: no.

The application is built on a Chrome engine from 2014, with the sandbox disabled. Any of the many browser vulnerabilities fixed in the past decade could give an attacker code execution on the user’s system. And attackers wouldn’t have to try very hard to deliver one. Just like the updater, the application uses unencrypted HTTP, so anyone who can see a user’s network traffic can tamper with what it loads. Worse, the application loads JavaScript from domains that had been abandoned. We registered those domains as well, which means we could have run our own JavaScript inside the application on every system where it was opened. We didn’t, and these domains were transferred to The Shadowserver Foundation along with the others.

Our update only disabled the updater. The rest of the application is unchanged, so these risks remain for anyone who still uses Popcorn Time. We already created a proof of concept that executes calc.exe via JavaScript, so the risk is real. That’s why our advice is simple: uninstall it.

If you’re still using Popcorn Time, we think it’s time to move on. This software from 2014 was innovative back then but it just isn’t safe to use anymore.

If you work in a Security Operations Centre, you can check the IOCs listed below to see if this software is present in your environment.

If you’re an Endpoint Security vendor, we recommend marking the Updater.exe (Windows) and PT.updd (macOS) file hashes as Potentially Unwanted Programs and removing the files from systems.

Extracted Entities