Scripting attacks are emerging as a primary vector for cybercriminals. In fact, in the U.S., scripting attacks have become almost as common as malware, and, in EMEA, scripting accounts for by far the majority of cyberattacks, according to the most recent CrowdStrike Global Threat Report. Malicious scripts have even been leveraged by state-sponsored hacking organizations such as China’s Deep Panda and as a key element of multi-faceted attacks, such as the Emotet trojan. Iran used a MechaFlounder Python backdoor attack against Turkey last year.
It’s no wonder that they’ve become such a powerful vector. With very little effort, fewer than 100 lines of script — whether it’s Python, PowerShell, or some other scripting language — can gain a foothold in the network, create a backdoor and gain essentially all the access of an administrator.
While there are many scripting languages out there, Python is a favorite of cybercriminals for many reasons. For one, it’s pervasive. On most *NIX systems, it’s installed by default. It’s also simple to use. It includes persistence, so even if you kill the process, it will start itself back up, and it obfuscates communications both internally and with external servers. In fact, you don’t have to write any code to launch an attack. Python backdoor scripts are everywhere. We did a simple GitHub search and came up with 230.
Scripting attacks are also hard to detect. Because Python is so heavily used by admins, the traffic these attacks create look exactly like that produced by ordinary, day-to-day tools. There’s no clear signature, so it typically bypasses endpoint detection and response (EDR) systems.
What’s more, getting those scripts into a network isn’t very hard. A simple ruse is to inject a malicious script into a commonly used library and then adjust the file name to a common typo for the real one, which is why it’s so critical to use TLS-based connections, package signing, SHA-256 verification and other means to ensure that you’re connecting to and downloading the genuine file. But even if you don’t use that particular compromised library, the malicious script could show up in perfectly legitimate libraries that somewhere down the chain incurred a dependency on a compromised library. It doesn’t take much, given how massive the list of dependencies can be in many libraries.
But attackers can get even more sneaky. For example, let’s say I’m targeting you and know your username at StackOverflow. All I need to do is wait for you to ask a question and quickly respond with a Python code snippet that looks completely benign, ready to cut-and-paste into your work. After all, plenty of startups have trained us to copy and paste code to download and install their software. We all know it’s a risky practice, but in the interest of time and convenience, many of us do so anyway.
Once the script is running inside your system, it can set up persistence by, say, establishing a crontab that restarts the script, even if it’s killed. As a result, you’ll need to kill the process and the crontab in the right sequence at exactly the right time to get rid of it for good. It won’t have much difficulty establishing command and control either, as there are myriad ways to obfuscate traffic, both internal and outbound, so that communications look completely normal. From here, it can set up to do just about anything an admin can do, including retrieving malware and depositing it throughout your environment.
Traditional defenses aren’t very effective in fighting scripting attacks. As already discussed, EDR has difficulty detecting them, and firewalls won’t be of much use in stopping the attack from moving throughout the environment. That’s because firewalls depend on network addresses to determine whether traffic is “safe.” Unfortunately, though, they can’t verify exactly what is communicating on either end, so it’s not hard for malicious software and scripts to piggyback on “safe” network addresses.
The best way to protect yourself against scripting attacks is to adopt a true zero trust approach. I say “true” zero trust, because any approach that uses network addresses to create policies cannot be effective. It’s critical to verify what is communicating, whether it’s a device, software, or a script, and at Zscaler, that’s exactly what we do.
Our zero trust platform, the Zero Trust Exchange, uses an identity-based approach, which means the platform creates a unique identity for each workload. These “fingerprints” are made up of dozens of immutable properties, such as the SHA-256 hash of a binary, the UUID of the bios, or a cryptographic hash of a script. In this way, we can decouple segments and policies from the network, which enables us to provide 100 percent protection for any segment with no more than seven policies.
These policies state explicitly which devices, software, and scripts are allowed to communicate with one another, and all other traffic is blocked by default. In this way, we can prevent scripts from establishing backdoors, accessing sensitive assets, and deploying malware throughout the environment.
Identity-based zero trust is the simplest way to protect your business against scripting attacks, and Zscaler can microsegment and create policies for your environment in just one click.