Developing Undetectable Malware with Dart

João Fontoura
5 min readOct 19, 2022

In this article, I will briefly explain how to start developing malware that is undetectable and cross-platform using the dart language. The aim is to use it as a study and perhaps as a simpler tool in cases of pentesting, since lower-level languages ​​such as C++ are recommended for complex malware.

https://media.giphy.com/media/GFLB1pCmhgvIDSJTvp/giphy.gif

What is a Malware?

Malware, or “malicious software,” refers to any unwanted software intended to cause harm. Examples of common types of malware include viruses, worms, trojan, viruses, spyware, adware, and ransomware. Hybrid malware consists of malicious software composed of more than one type, the most common combination lately is ransomware and worm.

Fully UnDetectable (FUD)

Malware that is not detected by security programs such as antivirus. Malware detection is usually done using virus signatures in a database, there are also programs that use heuristics based on behavior.

Evasion Techniques

There are a few ways to built a malware fud, the main ones being Packers, and Crypters.

  • Packers modifies virus signature by zipping and unzipping executable in memory.
  • Crypters use encryption to change your signature and make the software harder to read.

While the two techniques mentioned above are really useful, particularly to protect yourself from reverse engineering, the best strategy to stay hidden from antiviruses is to create a unique encoding for your malware, focused on your target.

How to know if malware is really undetectable?

The simplest way is to upload your compilation to a site that tests on several antivirus software at the same time, the most famous is the VirusTotal, but be careful, as they share the result of your upload with security companies. The best way is to simulate your target in a VM and test if your malware really goes unnoticed.

Result of infected client when examined in VirusTotal

Backdoor

Our malware will consist of a module responsible for maintaining a backdoor connection with our command and control server, allowing each command received by the socket client to be executed on the infected machine.

Client-Server Model(TCP/IP)

"It is necessary to put your hands in the dough"

We are almost getting our hands on the code, but first I would like to point out that we will not cover how to keep the connection persistent after an infected machine reboots, there are many ways to do this, I will be implementing this in the near future on MART. If you want a second part of the article developing persistence, ransomware and other modules, leave a comment 😄.

Prerequisites

  • Dart installed on your local machine (the version used during this article is 2.18.2 stable).
  • Basic knowledge of networks and systems development

1 . First Step: Create a C&C Server

Let’s start by creating a command line application. Choose your favorite terminal and run the command below to create a project using a template, this will result in a folder called server, which will contain the C&C server code.

$ dart create -t console server

Since we won’t cover testing in this article, we can start by deleting the ./test folder and deleting the ./lib folder which won’t be useful here.

Insert the code snippet below in the bin/server.dart file, in it we start by defining the address and the port on which our server should listen, if your user is not the administrator, choose a port greater than 1024, or may have permission issues. To deal with connections from outside the local network, you need a few steps that I won’t cover here, but basically you need to release the port on your router, change permissions on the firewall and choose a fixed ip or domain as an address.

./bin/server.dart

Our server code is divided by three functions, main , which is responsible for instantiating the serve, listening for new connections and sending keyboard input to last client connected, listenKeyboardInput is responsible for listening to the console input bytes and transform to text, and we have the listenClientMessagesReceived that prints to the console the bytes received by the socket client in text format.

To start our server, just run the command below inside the server folder.

$ dart run bin/server.dart

2. Create a client

Let’s create a new project to contain the client’s malicious code, this application will be compiled and sent to the target, it’s the same as the previous step, we generate a folder called client using the command below, do not forget to delete the folders ./test and ./lib .

$ dart create -t console client

This code snippet is longer, The first instruction is to set the server address and port.

./bin/client.dart

We have 5 functions, main just calls the connectServer recursive function, it tries to create a socket with the server, if it fails or is finished it calls retryConnectToServer which calls connectServer again every 2 seconds, if it succeeds it adds the listenerData function to listen the received bytes, transform into text and send the response of runCommand that will execute the commands in the shell.

How do i run this?

to run this malicious client there are a few ways, do you want to run it for testing? just run the command below inside the client folder.

$ dart run bin/client.dart

In practice you will probably want to compile to binary, this can be achieved with the dart-compile command, below I will leave an example compiling to “.exe”, remembering that do not support cross-compilation, this means that the compiler can create machine code only for the operating system you are compiling on.

$ dart compile exe bin/client.dart -o safe_file.exe

You can find the malware’s full code here, it has ransomware functionalities, as well as an interactive menu to switch between connected clients, and a beta client in flutter.

That’s all. Thanks for reading.

Links

--

--