This Week In Security: Ubiquity Update, PHP Backdoor, And Netmask

Back in January, we covered the news that Ubiquiti had a breach of undisclosed severity. One reader pointed out the compromise of a handful of devices as potentially related. With no similar reports out there, I didn’t think too much of it at the time. Now, however, a whistleblower from Ubiquiti has given Krebs the juicy details.

The “third party cloud provider” the original disclosure referred to was Amazon Web Services (AWS). According to the whistleblower, just about everything was accessible, including the keys to log in to any Ubiquiti device on the internet, so long as it was cloud enabled. The attackers installed a couple of backdoors in Ubiquiti’s infrastructure, and sent a 50 bitcoin blackmail threat. To their credit, Ubiquiti ignored the blackmail and cleaned up the mess.

To the claim that there was no evidence attackers had accessed user accounts, it seems that the database in question simply has no logging enabled. There was no evidence, because nothing was watching. So far, I’ve only seen the one report of device compromise that was potentially a result of the attack. If you had a Ubiquiti device go rogue around December 2020 – January 2021, be sure to let us know.

Safe Mode Ransomware

This is a new trick — We usually use safe mode to fix computers, but one strain of malware is abusing it to break them. The idea seems to be that your antivirus probably isn’t running in safe mode, so the encryption process is more likely to succeed. On the other hand, safe mode might mean that your server’s shared folders aren’t accessible, limiting the destruction to a single computer.

The fancy trick to making this work is to put the payload in a RunOnce registry key, and prefix the key’s name with an asterisk. This incantation signals to Windows that it should run even in safe mode. The encryption process delays the launch of explorer.exe, so the machine will seem to hang at the blank “Safe Mode” screen.

PHP Git Breach

A malicious commit was sneaked into PHP’s code on the 27th, and reverted about five hours later. The developer account that pushed the bad code was assumed to be compromised, and access was revoked. A few hours later, the reversion was reverted by a different developer account. This time the bad code was present for less than two hours before it was reverted with the humorous commit message of Revert "Revert "Revert "[skip-ci] Fix typo""" The consensus is that the server hosting the PHP code was likely compromised in some way, and the decision was made to move the PHP development process to GitHub.

The malicious code was quite simple. It checked for a magic string in the useragent header, and executed PHP code from that header if found. If a PHP release had actually shipped with this code intact, the damage would be astounding, as this would be a simple-to-use backdoor in every web service using PHP. It is worth pointing out that the open source nature of the PHP project led to a very rapid discovery of the injected code, and because of that speed, the actual damage from this attack will probably be essentially nil. This doesn’t seem to be a particularly sophisticated attack, and it wasn’t even disguised to look like innocent code. Was it just a test run?

Via Phoronix

OpenSSL Flaws

OpenSSL just fixed a pair of serious bugs in their 1.1.1k release. The first is CVE-2021-3449, which allows a malicious renegotiation request to crash the OpenSSL server. It’s a null pointer dereference, which is notoriously difficult to turn into a full RCE, though not impossible.

The second bug, CVE-2021-3450, is less annoying, but potentially more serious. If OpenSSL is configured to verify a certificate, and a certain strict mode flag is enabled, then a self-signed certificate could be accepted as a signed one. This happens because the strict mode check can overwrite the results of the trusted CA check.

Netmask Woes

There is a little quirk in how IP addresses are written. We normally write an IP in the “dotted decimal” format. Consider the three following IP addresses:,, and 0x10.0.0.1. The first two are identical and the last one is an invalid address, right? Well, it depends. If you’re sticking to what is considered “standard” dotted-decimal, then yes. But an early BSD implementation of dotted decimal notation also included hexadecimal and octal. This has become something of a competing standard, and pops up from time to time. See the image to the right for a surprising example.

Now, what about a library like NPM’s netmask, which checks whether a given IP address is part of a defined network? Netmask’s .contains function takes a dotted string as input, and returns true or false based on whether the IP is in the given subnet. In versions prior to 2.0.0, it understood decimal notation, and hexadecimal notation, but ignored the leading “0” otherwise. This means that an octal representation would instead be understood as decimal. This is a problem when other parts of your application see the IP as octal. The netmask sanity check thinks the IP is part of the local network (, when it really belongs to Level 3 Communications ( The security front-end sees the connection as coming from the local network, when it’s really coming from outside.

This little quirk was discovered by [Victor Viale], and fixed by a cadre of researchers who’s work we’ve looked at before. In fact, it was the earlier fixes to the private-ip package that led to this discovery. That package considers 0127.0.0.1 to be a private address. That’s correct… unless your code understands 0127.0.0.1 to be equivalent to Let’s do a little experiment. Try to navigate to, or ping that IP address with the leading 0. What does your browser or terminal understand it as? The octal format is surprisingly widely accepted.

Now here’s the kicker. How do you fix this? Remember, there isn’t an RFC that explicitly defines how dotted notation of IPs works. I’m confident that some packages on NPM ignore leading zeros in IP addresses, and some OSes likely do the same. If you change netmask to understand octal notation, then those applications are now vulnerable in exactly the way you’re trying to fix. No matter what, something is going to break.

Semantic Versioning helps here, though it isn’t a silver bullet. NPM uses a 3-number system, starting with 1.0.0 for initial releases. For bug fixes that are otherwise backwards compatible, increment the third number. For updates with new features, but that don’t break compatibility, increment the second number. And finally, for major changes that do break backwards compatibility, the first number gets the bump. Netmask is no longer backwards compatible, so the fix was released as 2.0.0. Many applications are written with a flexible dependency section, allowing automatic updating on-the-fly when bug fixes are released, but not automatically switching major versions. It doesn’t automatically fix the problem, but again, that wasn’t really possible.

Ransomware Refund?

Bleeping Computer brings the story of a ransomware campaign that’s doing something unexpected — paying the ransom back to the victims. Well, that is the claim. No bitcoin has been paid back yet. The claim is that the malware authors are afraid of law enforcement action, and plan to become legitimate researchers after paying back the ransom. You’ll excuse me if I’m a bit skeptical, but this sounds too good to be true. Time will tell whether this is a second scam, or a true change of heart.

Researcher Campaign Redux

Remember the North Korean APT that was targeting researchers with a fake security company and malicious links? The folks at Google who keep track of these things, the Threat Actor Group, have warned that this campaign is back under a different name. “SecuriElite” is the new bogus company, and a new gang of fake researchers are active on Twitter and LinkedIn. That is, they were active until Google’s TAG raised the alarm. The attackers will likely go to ground for a week or two, and then pop up somewhere else.

11 thoughts on “This Week In Security: Ubiquity Update, PHP Backdoor, And Netmask

  1. There is no *significant*, *legitimate* usage of hex, octal, leading zeroes, or less-than-four-components in actual IPv4 address encoding. Some people may claim that those things are *legal*, but nobody *uses* them. All real text-encoded IPv4 addresses are exactly four components, separated with single periods, with no leading or trailing periods, and each component consisting only of decimal digits encoding a number between 0 and 255, with no leading zeroes, and with the whole thing containing no characters other than periods and decimal digits.

    If you get anything else, then there’s a 99.999999 percent chance that it’s a deliberate security attack. Somebody is trying either to confuse you, or to confuse other software.

    The right fix is always to return “that’s not an IPv4 address” on anything that doesn’t follow the absolute most rigid, restrictive template.

    The owners of the 5 systems in the universe that will break on that will just have to fix them.

      1. That’s not what [Sok Puppette] said. Yes, Firefox and Chrome weirdly accept those addresses, but removing this compatibility will probably not break anything for anyone.

        1. Any application using standard library (at least under Linux) accepts those, so why wouldn’t Firefox and Chrome? Not to mention the pre-CIDR notation like 127.16777215 being treated as That’s why I always chuckle whenever I see blacklisting IP addresses with regular expressions.

          1. Again, that’s not the *point*. The libraries have this ‘feature’, Firefox and Chrome have this ‘feature’, but does anyone beyond maybe five people in the world actually *make use of* that feature? A feature being widely supported, but unused, is not an argument in favor of keeping or maintaining that support. Quite the opposite, in fact.

            By way of a car analogy, suppose there’s a ‘feature’ that cars have where if you press some buttons on the dash in a certain way, the car explodes. It maybe a feature that the car *has*, but is anyone actually using it, no, probably not. So if the feature were removed, it would not be missed.

    1. Yup, the fix would seem to be to throw an error on an address with leading zeros. You protect the currently vulnerable systems, and if someone is deliberately using octal, you don’t make them vulnerable.

  2. > then a self-signed certificate could be accepted as a signed one

    A self-signed certificate is a signed certificate. (Indeed, by their very nature, all certificates are signed). I believe you mean to say a CA- or trusted CA-signed certificate.

Leave a Reply

Please be kind and respectful to help make the comments section excellent. (Comment Policy)

This site uses Akismet to reduce spam. Learn how your comment data is processed.