This Week In Security: Mysterious Mac Malware, An Elegant VMware RCE, And A JSON Mess

There’s a new malware strain targeting MacOS, Silver Sparrow, and it’s unusual for a couple reasons. First, it’s one of the few pieces of malware that targets the new M1 ARM64 processors. Just a reminder, that is Apple’s new in-house silicon design. It’s unusual for a second reason — it’s not doing anything. More precisely, while researchers have been watching, the command and control infrastructure didn’t provide a payload. Silver Sparrow has been positively found on nearly 30,000 machines.

The malware also has an intentional kill switch, where the presence of a particular file triggers a complete removal of the malware package. Researchers at Red Canary point out that this package behaves very much like a legitimate program, difficult to pick out as malware. Ars Technica got an off-the-record statement from Apple, indicating that they are tracking the situation, and have revoked the developer’s certificate used to sign the malware. It’s not entirely clear whether this prevents the malware running on already compromised machines, or just stops new infections.

So who’s behind Silver Sparrow? The observed stealth mode and other complexities suggest that this is more than a simple adware or ransomware campaign. Since it was discovered before the payload was delivered, we may never know what the purpose is. It may have been a government created campaign, targeting something specific.

VMware RCE

The details of a VMware vulnerability were published this week, and the attack struck me as rather elegant. CVE-2021-21972 is a combination of two problems. The first is that the VMware web interface exposes an HTTP endpoint that doesn’t enforce user authentication. One of the functions of this endpoint is to allow the upload of an archive file, and extract this in the /tmp directory. The second problem is that the extraction function didn’t properly sanitize the names of the extracted files. Hence, it was possible to create an archive with a path transversal attack.

Here we have two very simple flaws, and when put together, allow a completely unauthenticated actor to easily get arbitrary code execution on the machine running VMware. The attack works on Linux and Windows servers, with expected implementation variations.

Inside a Wireless Security System

Ever wonder just how secure a residential security system is? [Nick Miles] and [Chris Lyne], a pair of researchers from Tenable, wondered the same thing, and decided to tear apart a SimpliSafe system, wringing out all of its secrets. They started with logic analyzers, and went as far as paying for functional decapping of the chips, to recover the firmware.

The step-by-step process is worth reading, but the conclusion is that the system is relatively well put together. Each device has an immutable AES key, and that represents an attack surface that wouldn’t be present with a more robust key exchange.

For the curious, [Nick] did a detailed analysis of a Ring system just a few months back.

Proper Exploit Attribution, The Story of Jian

I’ve been known to be a bit skeptical when an attack or exploit is attributed to a foreign nation, but no real evidence is presented. A story caught my eye this week, because it’s a wonderful example of what proper attribution looks like, not to mention a great example of unraveling a malware mystery. Check Point Research looked deep into an exploit used by APT31, believed to be a part of the Chinese government.

There are way too many details to dive into here, go read the post for the particulars, but we’ll cover the high points. Remember the Shadow Brokers leak, back in 2017? That was a collection of impressive 0-days that is universally recognized as produced by the Equation Group, part of the NSA. One of the tools exposed in that lead was “EpMe”, which leveraged CVE-2017-0005. Jian, an exploit produced by APT31 also targeted this CVE, and was probably created in 2014.

The kicker here is that Checkpoint makes a very convincing case that it was no accident that both exploits targeted the same CVE, but that the Chinese exploit was based on a captured sample of the NSA-produced tool. Essentially, they reverse-engineered the exploit and used it in their own operations, even before the tool was exposed by the Shadow Brokers.

Firefox State Partitioning

Allow cross-site cookiesMozilla has released a new privacy feature, State Partitioning, a way to authoritatively stop cookie-based tracking online. The concept is deceptively simple. Every domain you visit has its own “cookie jar”. Many websites have Facebook iframes or embedded images. State partitioning would isolate the cookies created by each of those iframes, meaning your browser is anonymous to Facebook on each of those sites.

Hand-in-hand is a new API that allows a website to request cross-site cookie access. This is important for the handful of uses where access is needed for legitimate uses, like Single Sign-On services. For now, partitioning is off by default, and can be turned on via the Enhanced Tracking Protection strict setting.

JSON Undefined Behavior

[Jake Miller] of Bishop Fox Labs wrote a great intro to a subject I’ve never considered: odd JSON constructions, and how different implementations handle them. An example will help.


obj = {"test": 1, "test": 2}

So what’s the value of obj["test"]? It’s complicated. Some JSON parsers will choose the first definition of a key, while others choose the last. Still others will throw an error in response. What makes this a particularly serious problem is that the same data may be parsed by different implementations in a single transaction. The example given in the post is of an online store, where the payment processing is handled by a third party.

The attack works by manipulating the JSON object sent by the browser, injecting a second value definition for the quantity of items purchased. The store itself sees the higher value, which determines the actual items shipped. The payment backend uses a different JSON parser, which sees the smaller value. The backend actually handles payment processing, so the amount charged is that of the smaller quantity.

The article goes on to describe issues with invalid unicode embedded in JSON and valid keypairs that have been /*commented out*/, and what happens when you re-serialize this quirky data. Another interesting edge case is the handling of very large numbers, where some parsers return 0, others return a null, and some an approximation in scientific notation.

All told, JSON deserialization is a mess. There’s sure to be many hard-to-spot bugs in web applications that use multiple parsers. The author makes a few recommendations at the end of the post. The most important is that parsers should produce a fatal error on particular quirky JSON input, rather than returning a guess at what data was intended.

10 thoughts on “This Week In Security: Mysterious Mac Malware, An Elegant VMware RCE, And A JSON Mess

      1. I agree, but it takes ingenuity to come up with a way to use it, like for the quantity on an order.

        Sanitize your inputs, sanitize your hands, and have a great weekend everybody!

        1. You are correct, Russia does exactly what you describe, as does China, North Korea, the United States, and every other major power in the world.

          It will be appropriate to treat cyber attacks as acts of war when those cyber attacks are actually killing people en masse.

  1. Although it’s API is a bit esoteric at times RapidJson is the most complete and compliant library. It also supports Json schema. If you can use this library, do so, and save yourself time rolling your own bugged version.

  2. JSON (XML, REST etc) are just request protocols to (often publicly exposed) API servers.

    Security is not a function of the request method or protocol. Instead security is a function of the API (whitelisted and defined functions, types, values, units).

    Rule #1: never trust anything that (supposedly) comes from a browser, or in the case of a publicly exposed API server: never trust any information that forms part of the request (without sanitation and whitelisting).

    So if your code is accessing ENV_REQUEST ENV_GET ENV_POST ENV_anything or any derivatives like REQUEST_URI REQUEST_URL SCRIPT_NAME etc then think carefully of what your doing.

    Consider this –

    api-server-under-attack.com/public_api?test=”1″&test=2

    or

    api-server-under-attack.com/public_api?JSON=”{%22test%22: 1, %22test%22: 2}”

    It’s ridiculously easy to do even with a browser, let alone how easy it is with a http request script.

    If your API is breaking because of malformed JSON then it’s not the JSON at fault but rather the API. The same thing could happen with XML, REST etc.

    Sure you can use a JSON parser to get from the request JSON string to an intermediate object BUT then the API is responsible for validating (sanitizing) the resulting object.

    Anyway I’m sure there will be a isValidJSON(object) out there somewhere which will just reintroduce the problem at a later time.

      1. OK, Security is not about JSON.

        Sure there are ways to “attempt” to validate JSON (or whatever protocol). For example you could use standard libraries to parse the JSON to an object and then use standard libraries to parse the object back to JSON and then compare the new JSON to the original JSON. If there different then reject the request.

        But wait! that’s exactly how this “security” problem came to be in the first place … differences in standard libraries. This is what happens when you try to blacklist activities, someone finds a hole in it! It’s an attack surface waiting for the correct attack vector.

        A secure API does the exact opposite. It whitelists activities so that only those whitelisted activities can be conducted.

        The way I do it is to have a security object that defines the access for the current authentication token. This is derived from a granulated-authorization database record.

        The security object defines the command elements available to the user, the associated data fields and the parameters for validating those data fields. Any variation from this is rejected.

        A subsection may look like this –

        [update_username][username[‘mode’, ‘required’]]
        [update_username][username[‘validate_method’, ‘regex’]]
        [update_username][username[‘validate_regex’, ‘…’]]
        [update_username][password[‘mode’, ‘required’]]
        [update_username][password[‘validate_method’, ‘match_md3’]]
        [update_username][password[‘validate_md3’, ‘….’]]

        So in short, don’t use the structure of the submitted object, JSON in this example. Instead build a whitelisted data object and transfer only validated data fields, then if all fields are validated and no extra fields exist then process the request.

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.