Malware, or code written for malicious purposes, is evolving.
Photo by Cécile Brasseur on Unsplash
Software developers face new threats from malicious code as their tools and processes have proven to be an effective and lucrative threat vector. Traditionally, software developers have protected themselves from malicious code like everyone else — by securing their devices, keeping programs updated, and following good security practices. However, recent attacks by advanced persistent threat (APT) groups have shown these longstanding security practices are no longer sufficient. To understand the new dangers malicious code poses to developers, it helps to take a brief look back at the history of malware.
Malicious Code: Origins
Malicious code, or malware, is intentionally written to disrupt, damage, or otherwise inflict undesirable effects on a target system. Often, like in the case of ransomware, malicious code both benefits the attacker and harms the victim. In other cases, like wipers, malicious code simply destroys data or inflicts other harm upon the target system. It is important to mention that intent drives the creation of malicious code for a specific purpose. This distinguishes it from software vulnerabilities which leave a system open for exploitation unintentionally.
The first known instance of malware was the relatively benign Creeper Worm created by Robert H. Thomas in 1971. The worm could move between hosts via the ARPANET but did not self-replicate until a later update by Ray Tomlinson. Creeper Worm laid the intellectual groundwork for larger experiments in self-replicating software, like the infamous Morris Worm of 1988. The Morris Worm, ostensibly created to map the internet, ultimately brought down roughly 6000 systems. The author, Robert Morris, became the first person convicted under the Computer Fraud and Abuse Act of 1986. He was fined over $10,000 and sentenced to three years of probation.
Early Internet
As the ARPANET evolved into the internet, connecting exponentially more computers throughout the world, malicious code likewise made advances. The simple worms of the earlier era paved the way for threats more familiar to modern-day users, including:
- Adware
- Ransomware
- Backdoors
- Trojans/Spyware
- Logic bombs
As new forms of malicious code appeared, an antivirus (AV) industry arose to tackle the challenge of detecting and responding to cyber threats. These early companies innovated various strategies to identify and stop attacks. One effective method involved generating unique file hashes, or signatures, of malicious code that could be cataloged for rapid identification. Unfortunately, making changes to malicious code could likewise change its signature — creating an indefinite cat-and-mouse game between attackers and defenders.
Other cybersecurity measures attempted to prevent the travel of malicious code or nullify its effects. Network control measures like firewalls, secure socket layer (SSL), and data loss prevention (DLP) tools sought to outmaneuver malicious code rather than directly combat it. While software developers faced no additional risk from malware during this time, trouble was lurking just around the corner.
The Cloud Era
In the mid-2000s, Amazon Web Services (AWS) launched a suite of business infrastructure services hosted in the cloud. Their lead was soon followed by Google, Microsoft, and others, who collectively ushered in the era of cloud-based services. Businesses and organizations adopted cloud computing for a number of reasons including cost savings, increased collaboration, loss prevention, and automatic software updates. However, the shift to cloud computing was not entirely without drawbacks. The practice of using remote resources and storage introduced a level of ambiguity to security responsibilities.
Ultimately, security responsibilities related to infrastructure were largely assumed by cloud providers while customers remained in charge of protecting their own data and on-prem resources. However, this arrangement left other responsibilities ill-defined, including endpoint protection, application-level controls, and identity and access management. Threat actors quickly realized the shared-responsibility model used by cloud services presented ample opportunities for exploitation. In areas where security responsibilities overlap, it only required one mistake by the cloud provider or the customer to facilitate a breach.
As more organizations migrated to the cloud, threat actors followed close behind. In 2019 attacks on cloud services doubled, demonstrating a significant shift in the focus of APT groups. More concerning, threat groups adopted the successful service model of the cloud and leveraged it to their benefit through offerings like Ransomware-as-a-Service (RaaS). Cloud-based ransomware services offer threat groups and their customers several advantages over traditional cyber attacks. For example, they provide a way for non-technical people to launch ransomware campaigns. They also provide cover for malicious actions from governments and organizations by introducing a layer of separation between the attackers and the attack source.
Modern Malicious Code Sets Sights on Supply Chain
RaaS offers one example of threat actors successfully adopting technology to spread malicious code, but the shift to cloud services introduced other dangers. Organizations that rely on cloud services explicitly trust their service providers. This trust allows managed service providers (MSPs) to push software updates to numerous customers without going through stringent security processes. Thus, an attacker who injects malicious code into an update pushed by an MSP can effectively compromise each client receiving the update.
This style of attack on the software supply chain is exactly what the world witnessed during the Solar Winds breach in 2019. Attackers gained access to the software repository for Orion, a monitoring and management tool for Solar Winds. The threat actors embedded malicious code into an Orion update, which Solar Winds then released to tens of thousands of customers. This technique lets attackers deliver malicious code to thousands of systems through a vector that security measures routinely ignore — a trusted vendor.
Similarly, Kaseya suffered a supply chain attack from the REvil threat group in July 2021. Kaseya provides Virtual System Administration (VSA) software to MSPs, who in turn offer cloud services to multiple customers. REvil compromised the VSA software and used it as a vehicle to launch ransomware attacks against approximately 1500 businesses. These attacks, like those affecting Solar Winds, relied on abusing the automatic software update system to spread malicious code.
Supply chain attacks are not limited to global IT service providers. The open-source community has fallen victim to these attacks as well. Open-source code is used in perhaps 96% of apps, and has long been known to be a source of vulnerabilities. In October 2021 the popular UA-parser.js project was subverted by a threat actor who managed to publish three versions containing malicious code. In this case the attacker spent time infiltrating the open-source organization and slipping test code into various builds before ultimately inserting malicious code.
Takeaway for Developers
Software developers are no longer facing the same threats from malicious code as everyone else. The nature of their work makes them targets for contemporary threat actors who seek to corrupt their tools, systems, and trustworthiness. Fortunately, there are some effective steps devs and organizations can take to protect themselves from propagating supply chain attacks:
- Developers cannot assume any code remains secure without testing. Consider running next-gen static application security testing as can be found in ShiftLeft CORE, and intelligent software composition analysis (I-SCA) on all code, including updates and open-source components.
- Teams creating applications for enterprise customers can be prime targets for supply chain attacks. If they have any concern that their code has been inadvertently exposed to outsiders either through a repo misconfiguration or an encounter with an untrusted party, they should consider an automation-enabled audit by AppSec experts like ShiftLeft Illuminate or if they have in-house experts should consider purchasing an advanced tool like ShiftLeft Ocular.
- Organizations should follow the principles of least privilege, restricting accounts to only being able to use necessary resources.
- Organizations should consider adopting a Zero Trust framework, which reduces threat vectors by ensuring interactions only occur between trusted entities.
Simply put, developers not only have to guard themselves against being attacked by malicious code, but also ensure they are not unknowingly spreading malware. For more information on effective ways to keep your code secure, visit shiftleft.io.
Top comments (0)