
Crafting malware with modern metals.
[ Music ]
David Bittner: Hello everyone and welcome to the CyberWire's Research Saturday. I'm Dave Bittner, and this is our weekly conversation with researchers and analysts tracking down the threats and vulnerabilities, solving some of the hard problems, and protecting ourselves in a rapidly evolving cyberspace. Thanks for joining us. [ Music ]
Nick Cerne: A lot of modern malware, or just malware in general, was traditionally written in the C languages.
David Bittner: Yeah.
Nick Cerne: However, recently there's been an emerging trend where threat actors have been using other languages like D, NEM, Golang, and Rust.
David Bittner: That's Nick Cerne, Security Consultant at Bishop Fox. The research we're discussing today is titled "Rust for Malware Development." [ Music ]
Nick Cerne: And so, Rust kind of appealed to me because it was a low-level language like C, but it also had some kind of cool features like memory safety guarantees and other nuances that I found interesting. So that's kind of why I picked Rust over, you know, like a traditional language like C or other programming languages.
David Bittner: I see. Well, in your research you recreated several common malware techniques using Rust. What were some of the challenges or surprises that you encountered during that process?
Nick Cerne: Yeah, so one of the challenges I found with developing Rust malware, as opposed to using a traditional language like C, is when using the Windows crate, which is provided by Microsoft, these are -- this is basically a library that provides bindings to Windows APIs, which are developed in C, and this is a little bit more challenging than just using a traditional -- or just using the traditional C libraries because there are some differences in calling those APIs as opposed to using the Rust-like wrapper or binding to that API. One of the things you mentioned in the report is that Rust's safety features can make detection more difficult, somewhat ironically. Can you explain how that works and why that matters for defenders? So before we get into that, I just want to talk quickly about like status quo reverse engineering tools.
David Bittner: Okay.
Nick Cerne: So Ghidra and IDA Pro are probably the most popular, or one of the most popular, sets of tools used in reverse engineering malware. And they were kind of developed to decompile C applications. So whenever you decompile a program, it's going to decompile the program into pseudo C, and this is where it gets kind of difficult because there's a lot of intricate differences between Rust and C, especially, as you've mentioned, with how it manages memory and also how the compiler optimizes code during compilation. So due to those intricate differences, when you decompile a Rust program in Ghidra or IDA Pro, it's going to produce a lot of garbled or nonsensical information that makes it a little bit more difficult to read the pseudocode, and I guess I can also dive into, quickly, one of the main differences in how memory is managed between C and Rust.
David Bittner: Yeah.
Nick Cerne: So Rust has a unique concept called ownership, which is part of the reason why I liked Rust as opposed to C because I thought it was a really cool concept. So in traditional C, when you want to, I guess, allocate memory, the end user has to explicitly call APIs to allocate and deallocate memory. And you can run into memory management issues if you forget to free up memory that is no longer being used, so that affects C explicitly. There's also other languages like Golang where you have garbage collectors, which will go through your running program, look for any memory that is no longer being used and reclaim that memory. Rust is different because it introduces this concept called ownership, and it doesn't use a garbage collector or require the user to explicitly free up memory. It basically does all of that automatically. I think it would help to give an example. So let's say you create a variable in Rust, and you assign a value to that variable. There is something in Rust called scope where a scope is basically just curly brackets. So you define this variable in curly brackets. Once you exit that scope, that variable and that value, they get dropped automatically by Rust. So you don't have to worry about freeing up memory or deallocating memory. Rust will do it automatically. So that's why it gets kind of difficult when you decompile a Rust program because it's going to decompile the pseudo C and pseudo C doesn't have these kinds of memory management concepts.
David Bittner: I see. So you sort of have to do your own kind of translation layer as you're looking through that pseudo C, right?
Nick Cerne: Yeah, and a lot of it really just doesn't make sense. You know, there's bits and pieces you can pick out, like symbols. So if you look at the decompiled Rust program, you can still see calls to some Windows APIs and stuff. So you can kind of get some sort of sense of what the Rust program is doing if you're a reverse engineer, but also, I mean, this is something I developed with no like code obfuscation or anything. So you can make it a lot more difficult to analyze that Rust program. Yeah, it's certainly more difficult to understand than the decompiled C program, which is also in the blog post. [ Music ]
David Bittner: We'll be right back. [ Music ] Well, how might the use of Rust affect how security teams detect and respond to threats? I mean, are the tools that we're using currently, are they prepared for, let's say, a shift?
Nick Cerne: That's a great question. I would say, if you have a dedicated malware reverse engineer, they're always going to figure out what the malware is doing, no matter what. As a malware author, you can take steps to make it more difficult or make it more time consuming. But I believe if you're a dedicated malware reverse engineer, you're going to figure out what that program is doing, no matter what language you choose. Now going to like endpoint detection or response solutions or antivirus solutions, yeah, it certainly could be more difficult to pick up malware that's developed in these languages, but I would say it really depends on how established or sophisticated the antivirus solution or EDR solution is, or how adept it is at detecting malicious behavior of a process or detecting signatures. It kind of depends on that.
David Bittner: So does this shift towards languages like Rust -- I think people look at these as being more modern languages? I have seen people kind of call them more legitimate languages than some of the older ones. Do you think this changes the profile or the skill level required for your average malware author?
Nick Cerne: Assuming your average malware author has a pretty good understanding of C and how memory works, I wouldn't say it would be terribly difficult for malware authors to pick up Rust as a new language. I think the most difficult part about learning Rust is understanding ownership. That concept we discussed earlier on managing how memory is managed in Rust. Understanding ownership is one of the most significant differences in Rust that separates it from other programming languages. So I'd say like once malware authors gain an understanding of how that works, it really shouldn't be that difficult to pick up, especially if they are coming from a background where they understand modern evasion techniques and, you know, the theory behind malware development.
David Bittner: Yeah. Well, I mean, let's flip the coin here. Are there ways that defenders can also benefit from Rust's capabilities in their own tools?
Nick Cerne: I haven't really thought about it from a defender's perspective. I would say when it comes to detecting malware, I would say it doesn't really matter so much what language you choose to develop, like an endpoint detection and response solution.
David Bittner: Right.
Nick Cerne: Maybe if you were going to write a more comprehensive Rust decompiler, that would be helpful, but for something like an EDR, I think the techniques kind of remain the same. These EDR solutions are still going to hook the Windows native API and look for malicious arguments. They can search through the memory of a process and look for malicious payloads, check Windows events for any malicious activity. I don't think any of that will really be different across languages, but if you wanted something more comprehensive for decompiling Rust programs, maybe reverse engineering Rust programs, I think maybe a better Rust decompiler could be something interesting.
David Bittner: Gotcha. Well, what are your takeaways here from this research, from this exercise? What do you hope people take away from it, having read it?
Nick Cerne: I think one thing or one of my biggest takeaways is kind of how easy it was to develop malware that bypasses Windows Defender, for instance, or an endpoint detection or response solution. A lot of antivirus software, they're signature based, so they kind of depend on malware that's already been signatured to kind of detect and stop that malware. Obviously, EDRs are a little bit harder to bypass because they do heuristic analysis. If your malware is doing or calling weird Windows APIs, it's going to pick up on that. Developing malware is very advantageous for red teams because, you know, you're essentially developing tooling that hasn't been signatured yet by antivirus endpoint detection and response solutions, as opposed to using something open source or closed source, which might be picked up better by those solutions. So I think that's another huge draw to malware development in general and how it can make your red team more effective. So I think that was one of my biggest takeaways was, I guess, not having to rely so much on open-source tooling or closed-source tooling for that matter, as opposed to, you know, being able to develop my own custom tooling to more effectively emulate a real adversary. [ Music ]
David Bittner: Our thanks to Nick Cerne from Bishop Fox for joining us. The research is titled "Rust for Malware Development." We'll have a link in the show notes. And that's Research Saturday brought to you by N2K Cyberwire. We'd love to know what you think of this podcast. Your feedback ensures we deliver the insights that keep you a step ahead in the rapidly changing world of cybersecurity. If you liked our show, please share a rating and review in your favorite podcast app. Please also fill out the survey in the show notes or send an email to cyberwire@n2k.com. This episode was produced by Liz Stokes. We're mixed by Elliot Peltzman and Tré Hester. Our executive producer is Jennifer Eiben. Peter Kilpe is our publisher, and I'm Dave Bittner. Thanks for listening. We'll see you back here next time. [ Music ]
