Didatic Ransomware Payload
#1
Good morning guys, how are you?

In the past few weeks I've worked on a very simple ransomware payload. I think it is the most simple possible, and it is perfect for study, specially for newbies (like me). It has only the most obvious functions:
  • Search for specific files on the system. Configurable by extensions.
  • Send copies of originals to a central server. If the server is unavailable (has been brought down, for example), there is a function that uses Bitcoin transactions to derive a new address owned by the operator.
  • Encrypt the original files on the infected machine.
  • Shows a small user interface asking for the key to decrypt them.
As it is didactic, it has some security mechanisms in the code. For example, it does not infect other machines on the network or connected external devices. It also does not exploit any vulnerabilities to gain privileges. I'm learning a lot in the process, and if it's useful to anyone, the code is available on Github. Enjoy yourselves, but with care.
Reply
#2
Good work. I wouldn't have done it the route you did, but over all good job.

Personally I would improve the server side a lot more, with a database to save the decryption and encryption keys. I would also delete the keys from the memory of the computer entirely.

The payload is decent, however I don't know how I feel about using python for a ransomware payload. I am not too well versed in python, however I would think about maybe swapping to C# or C/C++ for this? Sadly C# wouldn't work on devices not running .NET but in our case, that is a very very small pool of people.
Reply
#3
Thank you. I would rather have done it in C or C++, but I still don't know how to program in these languages enough. Do you think having a bank with all the keys would be ideal? Maybe even with the IP of the machine in question. I would have to improve data transmission between nodes and the server, in this case, point noted to study.

And what else could be done to delete the keys from the infected machine? In the texts I found, the suggestions are to generate and delete data randomly until the memory location is rewritten, I didn't include anything like that for two reasons:

1) I researched, but I still don't understand how I can know if something that was at an address X in memory has already been rewritten.
2) I only have a notebook with 4GB of ram to test. Hence the various sleep(), to prevent my machine from crashing.

About C#, it's still an option (when I learn that too haha). My idea is to use the trail-blazer file as an infection method. It would pull a specific payload for that operating system into the machine.
Reply
#4
(07-05-2021, 05:57 PM)Corvo Wrote: Thank you. I would rather have done it in C or C++, but I still don't know how to program in these languages enough. Do you think having a bank with all the keys would be ideal? Maybe even with the IP of the machine in question. I would have to improve data transmission between nodes and the server, in this case, point noted to study.

And what else could be done to delete the keys from the infected machine? In the texts I found, the suggestions are to generate and delete data randomly until the memory location is rewritten, I didn't include anything like that for two reasons:

1) I researched, but I still don't understand how I can know if something that was at an address X in memory has already been rewritten.
2) I only have a notebook with 4GB of ram to test. Hence the various sleep(), to prevent my machine from crashing.

About C#, it's still an option (when I learn that too haha). My idea is to use the trail-blazer file as an infection method. It would pull a specific payload for that operating system into the machine.

Well I am at some point planning on doing a ransomware writeup. I have written them already being PHP the server, and C# the client. Encryption was AES-256. The only difference between yours and mine is yours actually backed up the data. I might have to look into this. I was thinking of embedding a stealer into the payload, so the ransomware panel would be sent all passwords, cookies, etc off the machine.

For the HWID of the machine I used the GUID. the HWID (hardware id) is the ID I use to identify the machine. Using an IP address to identify the device wouldn't be a great idea. This is because some IPs can be dynamic, meaning their IP can change very easily. Not only this, if you infect a company and have loads of their computers; they all use the same IP address. I would suggest looking into a way to fetch a unique ID using the hardware information.

In terms of deleting the key from memory, this is very easy in C#. I don't know about python tho. Seems a little harder from what you're saying. The goal here is to make 100% sure they can't decrypt the data (otherwise it would defeat the purpose right?). Once the files are encrypted, you could do all you can to clean up any trace of the encryption key in memory, then force a reboot. After this happens, there is nothing they can do. Even if they delete the program from the computer, they still cant decrypt the files. This means we no longer have to worry about persistence. It is in the victims best interest to keep the software on the PC.

Hiding your server is also a problem a lot of ransomware has. In my POC I used a darknet endpoint over tor. I then embedded a tor http client into the actual payload to communicate with the server. This is prob not the best way of doing it, but I am sure it is fine for now. I was investigating some domain registrars that are "bulletproof". This means they don't care what you host on the domain. If you can get ahold of one of these, you can run your C2 over the clearnet. I would still have a reverse proxy in-between the domain and the origin server for safety. I have heard .ru domains are one of the best for this. (.to is also a worthy note, but I wouldn't trust it over .ru honestly)

Having custom payloads for each machine isn't a bad idea. I have seen this before, but I wonder if there is a better way of doing this? I will have to look into it one day.
Reply
#5
Hey Corvo, a quick note before we get technical. Graphic design is a hobby of mine and i absolutely love your GH logo. Without further ado:

(07-05-2021, 05:34 PM)Lewis Wrote: Good work. I wouldn't have done it the route you did, but over all good job.

Personally I would improve the server side a lot more, with a database to save the decryption and encryption keys. I would also delete the keys from the memory of the computer entirely.

The payload is decent, however I don't know how I feel about using python for a ransomware payload. I am not too well versed in python, however I would think about maybe swapping to C# or C/C++ for this? Sadly C# wouldn't work on devices not running .NET but in our case, that is a very very small pool of people.

I hear this a lot about not just ransomware but malware in general. Python was my first language and i have been using it for about 8 years now. In the mean time a learned a bunch of other langs and each has strengths and weaknesses.

Python is very versatile, And as someone who enjoys MalDev i write the occasional malware in Python, Not only because it's fun but it has a lot to offer, For one you can write pure Python so you don't have as many dependencies as a regular Python program. If you don't mind your binaries being slightly larger libraries like `pwntools`, `LIEF` and `ctypes` basically give you all that you need to design a perfectly viable malware of any kind. And like Corvo wrote in his README,md it's cross platform, If you write a Python based malware for Linux chances are it'll run perfectly fine right off the bat since every Distro  i can think of comes with the Python Interpreter pre-installed. LIEF and ctypes allow you to manipulate ELF files on linux too and ELF Malware can be pretty deadly if done right.

(07-05-2021, 05:57 PM)Corvo Wrote: Thank you. I would rather have done it in C or C++, but I still don't know how to program in these languages enough. Do you think having a bank with all the keys would be ideal? Maybe even with the IP of the machine in question. I would have to improve data transmission between nodes and the server, in this case, point noted to study.

And what else could be done to delete the keys from the infected machine? In the texts I found, the suggestions are to generate and delete data randomly until the memory location is rewritten, I didn't include anything like that for two reasons:

1) I researched, but I still don't understand how I can know if something that was at an address X in memory has already been rewritten.
2) I only have a notebook with 4GB of ram to test. Hence the various sleep(), to prevent my machine from crashing.

About C#, it's still an option (when I learn that too haha). My idea is to use the trail-blazer file as an infection method. It would pull a specific payload for that operating system into the machine.

First thing that comes to mind with regards to Memory manipulation is Assembly. However i assume it's still on your 'to learn' list as well. As it happens Bleachbit as far as i know is written in Python as well. And there is an option in Bleachbit that allows you to delete what's in the Memory. My suggestion would be, find the source code of Bleachbit and go through it until you find what i was talking about. Study it, and based on that write your own implementation of that specific functionality.

On a different note, the lightest ransomware you could create would just be the Crypto Trojan itself, forget  about a C2 server or saving a backup of the files or even saving the key for that matter. The target doesn't know you're lying when you say you'll give them their files back after they pay. If you want to be a little bit more discreet about it, have an automated email set up for when the bitcoin is transferred. You have the email send a specific string and say it's the password but what you'd do is check against the string, if it is entered into the part of the GUI that says 'decrypt', then fake an exception.

So the victim gets a fake error message, and then you close the GUI as if it's crashed. You could even pop a window and have it say something like "Program File Decrypter exited with error code 'SG34-9966' or whatever.

In any case i went over the source in your repo and it looks pretty good. Are you pinging the server to see if it's up? If so that's fine, but real world you'd have your C2 server ready to go.

If you're interested, i made a proof of concept ransomware a good while ago, and i made the server components in collaboration with a friend of mine in PHP as well.

The ransomware source can be found here and;
Find the server files here
Reply
#6
(07-05-2021, 09:57 PM)Lewis Wrote: [...]

You're totally right, I hadn't thought of that. What would be the best method of identifying a machine? Would using the MAC address (or a hash of it) be ideal? My current issue here would be that my payload still doesn't scale privileges on the system. So it is able to only affect the current user at the time of infection. If there is more than one on the machine, the others would not be affected. So it might be better to use a Hardware identifier along with the user identifier.

Deleting the key shouldn't be complicated, I just don't know enough yet. You see, I haven't studied much about memory management and the like yet. But it's already on my list, I'll see what I find as soon as possible. The server is really a problem. Initially I thought about not using domains, but IPs directly. But I couldn't come up with an efficient (and not too obvious) method of "embedding an IP" in a Bitcoin transaction. I could send the numbers (IPv4) in satoshis, but in this case the server wouldn't last half an hour.

About multiple payloads, my idea is that a file that just downloads another one would be harder to identify as a threat by antivirus. In addition to not having a relevant signature, the file is smaller and perhaps easier to hide. But I haven't tested it yet, I could be quite wrong.


Vector, sorry. I couldn't quote your message because it was already on the editing screen. Thank you very much for the compliments. Big Grin
The repositories I follow do not have Bleachbit samples as far as I know. But I will certainly go after him, thank you very much for the nomination. As a matter of fact I have some (the ones posted by vx-underground), like RedKeeper's. But most of the ones I have are Windows specific and I would like a universal solution.

About simplifying it even more, yeah. But I would also like my payload to fulfill the word haha. I mean, if it says it decodes the files, then it has to. But it's my perfectionism, there's really no need. Ping is a consequence of living in Latin America. It's not the server that worries me, it's the user having a working connection. xD Thanks for the recommendations, I've already starred your repositories and will study the code later today!
Reply
#7
Hey no problem. I starred your project and am following you on github now as well. If you have any more questions not just on this project but on malware development in general be sure to post them in this section of the forum. I do a lot of MalDev and wouldn't mind helping at all.
Reply
#8
(07-05-2021, 10:42 PM)Vector Wrote: First thing that comes to mind with regards to Memory manipulation is Assembly. However i assume it's still on your 'to learn' list as well. As it happens Bleachbit as far as i know is written in Python as well. And there is an option in Bleachbit that allows you to delete what's in the Memory. My suggestion would be, find the source code of Bleachbit and go through it until you find what i was talking about. Study it, and based on that write your own implementation of that specific functionality.

extremely overkill tbh
getting pointer to key then writing 0xff over each byte then xor'ing itself then calling free() is sufficient and also probably overkill, not to mention its like 5 instructions compiled or smth?

Code:
mov rcx XXXX ;this would be buffer size
loop:
    or byte ptr [ebp + 100 + rcx] 0xff ;assuming key is somewhere on the stack
    xor byte ptr [ebp + 100 + rcx] byte ptr [ebp + 100 + rcx]
    dec rcx
    jnz loop
; and the code continues...

asm-like pseudocode at least
free() isnt needed because we are changing the stack directly; free() is more of a formality so that the c compiler knows what memory is being used and what isn't for the sake of safety, but sometimes we need to get our hands dirty anyway
(don't forget that c supports inline asm too so we can just call free() after)

also bleachbit doesnt do selective memory wiping, i.e. specifying an address or wiping a selected process's memory. it only writes nullbytes over everything that's unallocated (or for linux devices, the entire swap partition as well.
https://github.com/bleachbit/bleachbit/b.../Memory.py

but yeah python good or w/e
sometimes you just gotta bite the bullet and realize that even your ctypes wont help you here

edit: before anyone mentions the `del` keyword in python, you need to understand that the data will still exist in memory until it's overwritten, since `del` is essentially just a call to some generic form of free() that python has in its source, since it's just a way to trigger the garbage collector explicitly, and the garbage collector doesnt overwrite memory
Reply
#9
(07-05-2021, 11:12 PM)Corvo Wrote:
(07-05-2021, 09:57 PM)Lewis Wrote: [...]

You're totally right, I hadn't thought of that. What would be the best method of identifying a machine? Would using the MAC address (or a hash of it) be ideal? My current issue here would be that my payload still doesn't scale privileges on the system. So it is able to only affect the current user at the time of infection. If there is more than one on the machine, the others would not be affected. So it might be better to use a Hardware identifier along with the user identifier.

Deleting the key shouldn't be complicated, I just don't know enough yet. You see, I haven't studied much about memory management and the like yet. But it's already on my list, I'll see what I find as soon as possible. The server is really a problem. Initially I thought about not using domains, but IPs directly. But I couldn't come up with an efficient (and not too obvious) method of "embedding an IP" in a Bitcoin transaction. I could send the numbers (IPv4) in satoshis, but in this case the server wouldn't last half an hour.

About multiple payloads, my idea is that a file that just downloads another one would be harder to identify as a threat by antivirus. In addition to not having a relevant signature, the file is smaller and perhaps easier to hide. But I haven't tested it yet, I could be quite wrong.


Vector, sorry. I couldn't quote your message because it was already on the editing screen. Thank you very much for the compliments. Big Grin
The repositories I follow do not have Bleachbit samples as far as I know. But I will certainly go after him, thank you very much for the nomination. As a matter of fact I have some (the ones posted by vx-underground), like RedKeeper's. But most of the ones I have are Windows specific and I would like a universal solution.

About simplifying it even more, yeah. But I would also like my payload to fulfill the word haha. I mean, if it says it decodes the files, then it has to. But it's my perfectionism, there's really no need. Ping is a consequence of living in Latin America. It's not the server that worries me, it's the user having a working connection. xD Thanks for the recommendations, I've already starred your repositories and will study the code later today!

In terms of downloading a new file, I wouldn't do this. I would self inject the payload bytes into the host process. You want to avoid dropping to the HDD/SDD as much as possible.

Using the blockchain to deliver IPs isn't a bad idea. I was investigating bloackchain domain names, you should have a look too.

MAC Addresses can be changed very easily on a machine by the host. I don't know why they would want to do this, but I wouldn't trust it none the less. You could go with a BIOS string or something?
Reply
#10
* Vector

Thank you very much. As I said, I'm quite a beginner, so I'll ask a lot. Big Grin

* poppopret

Wow, thanks for the explanation. I didn't know about BleachBit and I've been looking for it as if it were malware. *facepalm* This will definitely help. And in case I don't get a full clean, I'll do as suggested by Lewis and try to force a reboot.

* Lewis

Hey, this idea is better. As you said, malware only needs to actually run once, so I don't need to save the file to the machine. About BIOS strings, I think something here could help. Apparently, the only immutable string would be the GPU ID (at the end of the text) and the maximum and minimum processor frequencies (at the beginning). But the example certainly doesn't show much, I'll look for other options and see what the best combination is.

Now, the Blockchain point is not my idea. I can't say who started it, but earlier this year (or was it last December?) some ransomware popped up doing exactly the same thing. If their server goes down, they use one wallet's most recent transaction to look for the next one. The big idea here is that eventually some analyst will discover this function. Then, after taking down a server, the only way to stop the ransomware operator from updating the nodes is to send another transaction to the wallet, replacing the most recent place.

Hence, the only way to stop the ransomware from reconnecting is to send money to it. That's why there's that value check. So that very small transactions are ignored, so you can only disrupt communication by sending a considerable amount.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Disposable Payload Generator for Ransomware Corvo 0 1,734 01-26-2022, 03:18 PM
Last Post: Corvo
   Payload Encryption In C V0rT3x7 1 3,646 12-28-2021, 09:56 AM
Last Post: _BNM57_
  Successfully delivering a payload? Jonno249 2 6,585 11-10-2021, 05:17 PM
Last Post: Jonno249
  primitive ransomware experiment neftis 3 10,229 08-19-2021, 08:54 PM
Last Post: zzeuss