Scuba Gear from CISA, ROBLOX Malware Campaign, and RUST backdoo-rs
Hello, this week Jordan_Zebor is your editor looking at the notable security news for Scuba Gear from CISA, a ROBLOX Malware Campaign, & a Rust based meterpreter named Backdoo-rs. Scuba Gear from CISA ScubaGear is a CISA-developed tool designed to assess and verify whether a Microsoft 365 (M365) tenant’s configuration aligns with the Secure Cloud Business Applications (SCuBA) Security Configuration Baseline. This tool ensures that organizations are following CISA’s recommended security settings for cloud environments, helping to identify vulnerabilities or misconfigurations in their M365 setup. The value of running ScubaGear lies in its ability to enhance an organization’s cybersecurity posture, mitigate risks, and maintain compliance with security standards, which is crucial for protecting sensitive data in cloud-based systems. ScubaGear addresses the growing need for secure cloud deployments by automating the assessment process, making it easier for IT and security teams to identify gaps and take corrective actions. Regular assessments with this tool can help reduce the chances of data breaches, unauthorized access, and other security threats, thereby maintaining the integrity and confidentiality of business operations. Additionally, it supports organizations in staying ahead of compliance requirements by ensuring they meet the security baselines recommended by CISA. ROBLOX Malware Campaign Checkmarx recently discovered a year-long malware campaign targeting Roblox developers through malicious npm packages that mimic the popular “noblox.js” library. The attackers used tactics like brandjacking and typosquatting to create malicious packages that appeared legitimate, aiming to steal sensitive data like Discord tokens, deploy additional payloads, and maintain persistence on compromised systems. Despite efforts to remove these packages, new versions keep appearing on the npm registry, indicating an ongoing threat. RUST backdoo-rs The article "Learning Rust for Fun and backdoo-rs" describes the author's journey of learning Rust by developing a custom meterpreter. While Rust is designed to avoid common programming errors, ensuring software is secure from the outset, the choice of using it to create red teaming tools is also a great use case. A key aspectI covered recently is how Rust helps eliminate vulnerabilities like buffer overflows and use-after-free errors. These are traditionally common in C and C++, but Rust's ownership model prevents such risks by ensuring safe memory usage. In addition, Rust's growing adoption in the cybersecurity community, driven by companies like Google and Microsoft, emphasizes its role in secure software development, underscoring the "secure by design" principles that CISA advocates for. Projects like "backdoo-rs" demonstrate Rust’s potential for secure, reliable development in any context.158Views2likes0CommentsWAF evasion techniques for Command Injection
Let’s talk about Command Injection; I’m going to talk about this specifically from the perspective of Web Application Firewalls (like BIG-IP Advanced WAF, BIG-IP Next WAF, F5 Distributed Cloud WAF and so on) but these concepts are generally applicable anywhere user-input is used to construct commands run on the system, directly or indirectly. So, what is Command Injection? To quote OWASP, who put it very nicely: Command injection is an attack in which the goal is execution of arbitrary commands on the host operating system via a vulnerable application. Command injection attacks are possible when an application passes unsafe user supplied data (forms, cookies, HTTP headers etc.) to a system shell. In this attack, the attacker-supplied operating system commands are usually executed with the privileges of the vulnerable application. Command injection attacks are possible largely due to insufficient input validation. This attack differs from Code Injection, in that code injection allows the attacker to add their own code that is then executed by the application. In Command Injection, the attacker extends the default functionality of the application, which execute system commands, without the necessity of injecting code. Like I say, in this case I’m going to talk about command injection to web applications, but they can happen in almost any piece of software that works on untrusted user input. Perhaps the most famous example of a command injection vulnerability is Shellshock, a suite of vulnerabilities in the Unix Bash shell and if you needed any proof that they can be hard things to find as a defender, Shellshock lived, undiscovered (or at least undisclosed, we’ve no way of proving that no malicious entities knew of the bug!) for 25 years from 1989 to 2014, in one of the most widely used pieces of software in the world. The original Shellshock vulnerability involved a maliciously crafted environment variable containing (malicious) commands after a function definition, e.g. env x=’() { :;}; echo vulnerable’ bash -c “echo test” On a vulnerable system, running the above commands would display “vulnerable” because of Bash continuing to execute the (injected) commands following the function definition. Injecting a command here requires the"| use of two specific characters plus the command, the semi-colon and space characters. If you imagine a web application passing commands to bash on a vulnerable system, you’ll see that it would be possible to block this attack simply by blocking requests containing semi-colon or space (or indeed having a signature for the full function definition and trailing semi-colon of “{ :;};”) Bypassing protections Any time there is a WAF in front of a vulnerable system – and sometimes even when there isn’t – an attacker must try to evade the rules preventing them from simply injecting their chosen command. You’ll often see this when attackers or scanners are looking for SQL injection vulnerabilities in web applications, replacing characters like ‘ with %27 or the space with %20 (and many other tricks), or using chunks of existing text with the SUBSTRING() function to construct queries without having to use the actual text. Many of the same tricks work for command injection vulnerabilities, and I’d like to talk about a specific example here because it’s one I hadn’t considered until it turned up in some real life traffic.. Bypassing WAF signatures using Environment Variables Remember I just said you could construct SQL queries using sub-strings of existing text? Well, if your target system is Windows-based and you know there’s a command injection vulnerability but you’re unable to exploit it due to character blocks or similar restrictions, then good news! Windows environment variables might be what you’re looking for.. Environment variables exist in most operating systems, and Microsoft ones are no exception – they date back to DOS and were one of the enhancements Microsoft brought to the table over and above CP/M (unlike the 8.3 filenames, which came right from CP/M!); their behaviour has been pretty much the same throughout, and there have always been a number of ‘default’ environment variables like the PATH, TMP & TEMP. Current versions of Windows add a number of additional default environment variables like PROGRAMDATA, PROGRAMFILES etc. Windows also allows the shell to return just a part of the environment variable value using the following syntax: %VARIABLE:~start_pos,end_pos% How is this useful to us, you ask? Let’s say you know you can inject a command, but you need a space in your command line; you want to inject “ping 127.0.0.1” but the space is dropped or the request is blocked by a WAF looking for “ping <IP>”, well then you just need an environment variable you know will have a space in it! %PROGRAMFILES%, by default, is going to be set to C:\Program Files on most systems, which has a space right there in the middle! All we need to do to get to it is use it as %PROGRAMFILES:~10,1%, for example: ping%PROGRAMFILES:~10,1%127.0.0.1 Go ahead, fire up a command prompt, and try it out! You could even construct the whole command that way: %PROGRAMFILES:~3,1%%SYSTEMROOT:~4,2%%PROGRAMFILES:~6,1%%PROGRAMFILES:~10,1%127.0.0.1 Again, fire up a command prompt and give that a try! Protect against bypasses with BIG-IP Advanced WAF Now here’s the good news: ASM includes signatures, by default, for all of those useful Windows environment variables (and the same for many other systems, too), so if you were to try the above on a vulnerable system with the right signatures in the policy, you’d still be blocked – like this: All these signatures are part of the Predictable Resource Location Signatures signature set, so you’ll want to make sure you either have all signatures of Medium or above, or at least this set assigned to your policy: Summary Command Injection is a huge topic, much bigger than I can talk about in one blog post here, but hopefully this shows you one way an attacker might try to evade protection in front of a vulnerable Windows system, and some ways in which you can protect it — BIG-IP Advanced WAF or F5 Distributed Cloud WAF both have signatures for this kind of evasion.141Views2likes0CommentsEnhancing Software Security with Rust: A Solution to Common Vulnerabilities
Introduction The digital landscape is continually evolving, with cybersecurity threats growing both in sophistication and number. Among these threats, memory safety vulnerabilities stand out, contributing to a significant portion of software security issues today. Supported by guidance from CISA, NSA, and many other security minded individuals, there is an urgent need for programming practices that inherently mitigate memory safety risks. Addressing Memory Safety with Rust Rust is an open-source programming language renowned for its dedication to safety and performance. It effectively addresses common challenges related to memory safety and concurrency without sacrificing execution speed. In this article, we will explore the top three Common Weakness Enumerations (CWEs) from the 2023 Known Exploited Vulnerabilities list: Use After Free, Heap-based Buffer Overflow, and Out-of-bounds Write. All these CWEs directly relate to memory safety problems. Throughout this article, we will demonstrate how Rust’s unique capabilities serve as effective safeguards against these widespread concerns. Note: While Rust also mitigates other critical issues such as double-free, dangling pointers, and concurrency issues like race conditions, deadlocks, and improper synchronization, these will not be covered in detail in this article. CWE-416: Use After Free This vulnerability occurs when a program continues to use a memory location after it has been freed, potentially leading to application crashes or in more severe scenarios, arbitrary code execution. Languages that require manual memory management, such as C and C++, are typically vulnerable to this issue, as developers must explicitly manage memory allocation and deallocation. Rust uniquely addresses CWE-416 through itsownership, borrowing, and lifetimes systems, catching potential vulnerabilities at compile time. Ownership rules enforce that each piece of data is owned by a single entity. When this owner or piece of data goes out of scope, Rust automatically deallocates the memory associated with it, thereby eliminating the risk of accessing freed memory. Borrowingallows functions to access data via references without taking ownership, a process carefully scrutinized by the borrow checker. This component of the compiler ensures that all borrowed references adhere strictly to lifetime rules, preventing them from outliving the data they reference, thereby avoiding use-after-free vulnerabilities. Lifetimes specify the scope for which a reference is valid, enabling the compiler to track and manage the lifespan of data throughout the program. By requiring explicit lifetime annotations where necessary, Rust enforces a clear contract for how long data can be safely borrowed, further strengthening its memory safety by preventing dangling references that could lead to vulnerabilities. CWE-122: Heap-based Buffer Overflow Heap-based buffer overflows occur when data exceeds its allocated memory in the heap, potentially allowing attackers to read or write memory they shouldn't have access to. This can result in crashing the application or enabling arbitrary code execution. Such vulnerabilities are particularly prevalent in languages like C and C++, which do not automatically enforce bounds checking. Rust effectively addresses CWE-122 through multiple security measures, including a type system, the principle of immutability by default, and robust memory safety abstractions. Type systems are critical for security, and Rust's system exemplifies this by being both statically and strongly typed. Static typing ensures all data types are defined before runtime, allowing the compiler to catch type errors early and mitigate related vulnerabilities. Strong typing in Rust requires explicit type conversions, guarding against unsafe coercions that could lead to issues like buffer overflows. Additionally, Rust enforces runtime bounds checking, which actively prevents heap-based buffer overflows and out-of-bounds writes by causing errors to panic rather than fail silently or behave unpredictably. Together, these features not only enhance security by enforcing strict type safety and data integrity but also by ensuring reliable and predictable error handling. Immutability by Default ensures that all data is immutable unless explicitly declared mutable. This design significantly reduces the risk of unintended data modifications that could lead to buffer overflows. By default, this immutability prevents many common programming errors associated with memory corruption. Memory Safety Abstractions provide high-level abstractions such as Vec<T> for managing dynamic arrays and Box<T> for smart pointers. These abstractions come with built-in bounds checking, which are enforced at runtime. When data operations exceed their allocated bounds, Rust's approach ensures that these operations result in controlled runtime panics, thus preventing unsafe memory access and preserving application integrity. Additionally, Rust promotes using iterators when working with collections. Iterators are both safe and efficient because they abstract away the need for manual bounds checking. This not only simplifies the code but also eliminates a common source of errors associated with direct index access, further enhancing safety and performance. CWE-787: Out-of-bounds Write This vulnerability involves writing data past the bounds of allocated memory, which can corrupt data, crash the application, or lead to code execution. It predominantly affects languages like C and C++ where bounds checking is not enforced automatically by the language, requiring manual oversight by developers. Rust addresses CWE-787: Out-of-bounds Write through its robust memory safety protocols, including automatic bounds checking for all memory write operations. This ensures that data stays within safe operational limits at both compilation and runtime stages, preventing potential security breaches. Additionally, features like the Option enum and fearless concurrency further safeguard against out-of-bounds writes by enforcing strict data handling and thread-safe access. Automatic bounds checking for all memory write operations, effectively preventing data from being written outside allocated segments. This safety measure operates during both compilation and runtime, where Rust ensures safe failure modes through structured error handling and panics rather than allowing undefined behavior. Option enum is special in Rust and its use ensures proper management of data safely, helping developers avoid The Billion Dollar Mistake. Unlike many other languages, Rust does not have null values for any data types and using the Option enum requires developers to explicitly handle cases of Some (data present) and None (data absent), promoting deliberate and safe data access patterns. This forces developers to handle cases which may otherwise go undefined in other languages. Fearless Concurrencyis another defining feature of Rust that guarantees thread-safe data access, effectively eliminating the risk of data races that could lead to out-of-bounds writes. This is achieved through Rust’s ownership and borrowing rules (described earlier), which ensure that data is accessed by only one thread at a time unless explicitly shared in a thread-safe manner. By leveraging these strict concurrency controls, Rust allows developers to build highly concurrent applications without the typical safety compromises seen in other languages, enhancing both performance and security and avoiding difficult to detect and reproduce defects. Conclusion The future of programming, particularly in systems and kernel development, is trending towards languages that provide strong memory safety guarantees. Rust's integration into system programming and even parts of the Linux kernel highlights a significant shift in software development paradigms. While Rust represents the future of secure programming, it's crucial to recognize the enduring legacy of languages like C. The Linux kernel and widely-used software such as OpenSSL and NGINX are predominantly written in C, illustrating that an immediate wholesale transition to Rust across all development sectors isn't practical. However, as we move forward, Rust's role in fostering more secure software is poised to expand with its focus on memory safety becoming a cornerstone of modern system software. The adoption of memory-safe languages like Rust isn't just about addressing current vulnerabilities; it's about reshaping software development practices to prioritize security from the ground up. This evolution marks a future where software inherently withstands a wide range of cybersecurity threats, greatly enhancing the resilience of our digital infrastructure against new challenges.132Views1like0Comments