Prependers and Postpenders
Binary modifying viruses
Last updated
Binary modifying viruses
Last updated
What's a prepender you ask? Well, at the time of writing this section, I found an article by @guitmz titled: "Linux.Fe2O3: a Rust virus" while looking for malware written in Rust (PoC mostly). This is where I encountered the term "prepender". As the name suggests the program aims to pre-append something to something. Long story short, it's essentially a kind of binary-infector/code-injector. A prepender injects some binary instructions at the beginning of the program, while a postpender would inject the same at the end of the program. Sounds lame, but it can really do some damage if paired with other types of malware.
Anyways, this is a nice bit of insight on how one may inject binary instructions into an executable (not quite that since we're literally just placing them on one side of the executable rather than actually injecting them) and cause it to do all kinda cool stuff, heck, you can probably compile a fork bomb and inject those instructions straight into something common like cat
or explorer.exe
and enjoy the show! Every time the user would try and use these basic commands, their systems would hang/crash.
As @guitmz mentions in his blog, A prepender works by appending its code to the start of the host file, and during execution, it runs itself and the host file. There're a lot of ways we could go about making a prepended program. It's usually useful to have a look at how stuff could be done before implementing an automated solution. Here are some of the approaches:
We could manually extract binary instructions from the target and payload executable files and hard code them into a single program, which can then be compiled and replace the target program.
As done in the blog, we could make a temporary file and then insert the payload's instructions first, followed by the target program's instructions. This can be run when we run the prepender program.
We could just prepend the payload instructions to the target, thus permanently changing/modifying the target (destructive approach)
Make a self-modifying program that uses some sort of shellcode-y approach to modify itself so as to integrate the target and payload instructions within itself and destroy itself once the program execution is done. (self-destructive program)
To keep things simple and to get some content out there, I'll just do a blend of Approach 2 and Approach 3. Here's how it works:
Get the payload instructions
Write the payload instructions to a temporary file and execute it.
Execute the target program.
I'm making it so that it does not modify either the payload or the target. However, we can make a slight change and make it into a destructive approach (keep reading if you wanna know )
Let's keep the target and payload programs simple:
These could quickly be compiled like so:
I too, will be using the good ol' rust (I'm currently working on a zig implementation but that language documentation will be the end of me). First comes including the instructions from the payload using the std::
include_bytes!
macro:
You can also manually read the file too, but this is simpler and easier so I'm using it :P
Next, we need some program logic that places this data into a temporary file and executes it. Here's what I have for that:
Using this, we can quickly execute the payload with:
Next comes the execution of the target/host executable:
So the final program looks something like:
That's all! Here's the Cargo.toml
file:
If you're curious about the release profile, check this SO post and this GitHub repo. But when we run the program, we can see that the payload is successfully executed before the target:
An improvement to this would be to include the instructions from the target rather than the payload, this way, we can replace the target. For converting this into a postpender, simply move the execute_payload
function call, like so:
Also, the extra try_wait
is just for good measure since it's possible that our payload may get executed before the host/target finishes executing.
Be sure to be on a lookout for the zig implementation~