Malware bazaar
Member
Hello Cyber Souls In this article, I'll show you how to write a simple remote-access trojan in Python, and for greater stealth, we'll build it into the game. Even if you do not know Python, you can better understand how such malware works and practice programming.
Of course, the scripts given in the article are in no way suitable for use in combat conditions: there is no obfuscation in them, the principles of operation are simple as a stick, and there are no malicious functions at all. Nevertheless, with some ingenuity, they can be used for simple dirty tricks - for example, knocking out someone's computer in class (or in the office, if you haven't played enough in class).
The logic of such an infection is that the user himself downloads malware to his computer (for example, under the guise of a cracked program), disables the protection mechanisms himself (after all, the program looks good) and wants to leave it for a long time. Hackers are on the alert here, so the news now and then flashes reports of new victims of pirated software and ransomware that amaze freebie lovers. But we know that free cheese is only in the trash, and today we will learn how to stuff the same cheese with something not quite expected.
Let's start writing code. Immediately import the libraries:
Both libraries are not shipped with Python, so if you don't have them, you need to install them with pip.
If you see an error that you don't have pip, you first need to install it from pypi.org . Curiously, the recommended way to install pip is via pip, which is of course very useful when you don't have one.
The code for obtaining external and internal addresses will be as follows. Note that if the victim has multiple network interfaces (for example, Wi-Fi and Ethernet at the same time), this code may not behave correctly.
If everything is more or less simple with the local address - we find the device name on the network and look at the IP by the device name - then with the public IP everything is a little more complicated.
I chose the site api.ipify.org, since we only get one line in the output - our external IP. From the public + local IP bundle, we get an almost exact device address.
Displaying information is even easier:
Never seen constructions like print(f'{}')? The letter f stands for formatted string literals. In simple words - program inserts directly into the line.
String literals not only look good in code, but also help to avoid errors like adding strings and numbers (Python is for you in JavaScript!).
Final code:
By running this script, we can determine the IP address of our (or someone else's) computer.
Import new libraries (both need to be pre-installed via pip install):
We write basic information about ourselves:
Let's create a letter:
The final touch is to set up a connection to the mail service. I use Yandex.Mail, so I set the settings for it
In the server.ehlo(email) line, we use the EHLO command. Most SMTP servers support ESMTP and EHLO. If the server you are trying to connect to does not support EHLO, you can use HELO.
The full code for this part of the Trojan:
By running this script, we will get a letter with ip.
I checked this script on VirusTotal. Screenshot result.
As usual, let's start with the libraries:
First, let's write the game "Guess the number". Everything is extremely simple here, so I will not linger for a long time.
Why so much complexity with checking for a number? You could have just written guess = int(input('Enter a number: ')). If we wrote it this way, then entering anything other than a number would throw an error, and this cannot be allowed, since an error will force the program to stop and cut off the connection.
Here is the code for our trojan. Below we will understand how it works, so as not to repeat the basic things.
First you need to figure out what a socket is and what it is eaten with. A socket in simple terms is a conditional plug or socket for programs. There are client and server sockets: the server socket listens on a specific port (socket), and the client connects to the server (plug). Once a connection is established, data exchange begins.
So, the line client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) creates an echo server (sent a request - received a response). AF_INET means to work with IPv4 addressing, and SOCK_STREAM indicates that we are using a TCP connection instead of UDP, where the packet is sent to the network and is not monitored further.
The line client.connect((HOST, PORT)) specifies the host IP address and port on which the connection will be made, and connects immediately.
The client.recv(1024) function receives data from a socket and is a so-called "blocking call". The meaning of such a call is that until the command is transmitted or rejected by the other side, the call will continue to be executed. 1024 is the number of bytes used for the receive buffer. It will be impossible to accept more than 1024 bytes (1 KB) at a time, but we don’t need it: do you often manually enter more than 1000 characters into the console? There is no need to try to repeatedly increase the buffer size - this is costly and useless, since a large buffer is needed about once in never.
The decode('cp866') command decodes the received byte buffer into a text string according to the specified encoding (we have 866). But why exactly cp866? Let's go to the command line and enter the chcp command.
.
Current code page
The default encoding for Russian-speaking devices is 866, where Cyrillic is added to Latin. The English language versions of the system use normal Unicode, i.e. utf-8 in Python. We speak Russian, so we simply need to support it.
If desired, the encoding can be changed on the command line by typing its number after chcp. Unicode number is 65001.
When receiving a command, you need to determine if it is a service one. If so, we perform certain actions, otherwise, if the terminal is enabled, we redirect the command there. The disadvantage is that the result of the execution remains unprocessed, and it would be good to send it to us. This will be your homework: you can implement this function on the strength of about fifteen minutes, even if you google every step.
The result of checking the client on VirusTotal pleased.
The basic Trojan has been written, and now you can do a lot on the attacked machine, because we have access to the command line. But why don't we expand the feature set? Let's steal Wi-Fi passwords!
Let's get started. Import libraries:
The subprocess module is needed to create new processes and connect to standard input-output streams, as well as to receive return codes from these processes.
So, the script for extracting Wi-Fi passwords:
By typing the netsh wlan show profiles command at the command prompt, we get the following.
netsh wlan show profiles
If you parse the output above and substitute the network name in the command netsh wlan show profile [имя сети] key=clear, the result will be as in the picture. You can disassemble it and pull out the password from the network.
netsh wlan show profile ASUS key=clear
VirusTotal's verdict
One problem remains: our original idea was to take the passwords for ourselves, and not show them to the user. Let's fix this.
Let's add another version of the command to the script, where we process our commands from the network.
This script is as simple as two rubles and expects to see a Russian-language system. This will not work in other languages, but you can fix the behavior of the script by simply selecting a separator from the dictionary, where the key is the language found on the computer, and the value is the required phrase in the desired language.
All the commands of this script have already been analyzed in detail, so I will not repeat myself, but just show a screenshot from my mail.
Result
And of course, it is highly desirable to package the virus itself using PyInstaller, so as not to drag the python and all dependencies onto the victim's machine. A game that requires you to install a module for working with mail in order to work - what can inspire more confidence?
As homework, I recommend trying to implement a two-way terminal and data encryption using at least XOR. Such a Trojan will already be much more interesting, but, of course, we do not call for using it in the wild. Be careful!
Of course, the scripts given in the article are in no way suitable for use in combat conditions: there is no obfuscation in them, the principles of operation are simple as a stick, and there are no malicious functions at all. Nevertheless, with some ingenuity, they can be used for simple dirty tricks - for example, knocking out someone's computer in class (or in the office, if you haven't played enough in class).
THEORY
So what is a Trojan anyway? A virus is a program whose main task is to copy itself. The worm is actively spreading over the network (Petya and WannaCry are typical examples), while the Trojan is a hidden malware masquerading as “good” software.The logic of such an infection is that the user himself downloads malware to his computer (for example, under the guise of a cracked program), disables the protection mechanisms himself (after all, the program looks good) and wants to leave it for a long time. Hackers are on the alert here, so the news now and then flashes reports of new victims of pirated software and ransomware that amaze freebie lovers. But we know that free cheese is only in the trash, and today we will learn how to stuff the same cheese with something not quite expected.
DETERMINING IP
First, we (that is, our Trojan) need to decide where it ended up. An important piece of your information is the IP address that can be used to connect to the infected machine in the future.Let's start writing code. Immediately import the libraries:
You must reply before you can see the hidden data contained here.
You must reply before you can see the hidden data contained here.
The code for obtaining external and internal addresses will be as follows. Note that if the victim has multiple network interfaces (for example, Wi-Fi and Ethernet at the same time), this code may not behave correctly.
You must reply before you can see the hidden data contained here.
I chose the site api.ipify.org, since we only get one line in the output - our external IP. From the public + local IP bundle, we get an almost exact device address.
Displaying information is even easier:
You must reply before you can see the hidden data contained here.
String literals not only look good in code, but also help to avoid errors like adding strings and numbers (Python is for you in JavaScript!).
Final code:
You must reply before you can see the hidden data contained here.
BACKCONNECT BY MAIL
Now let's write a script that will send us an email.Import new libraries (both need to be pre-installed via pip install):
You must reply before you can see the hidden data contained here.
You must reply before you can see the hidden data contained here.
You must reply before you can see the hidden data contained here.
You must reply before you can see the hidden data contained here.
The full code for this part of the Trojan:
You must reply before you can see the hidden data contained here.
I checked this script on VirusTotal. Screenshot result.
TROYAN
As planned, a Trojan is a client-server application with a client on the attacker's machine and a server on the launching machine. The maximum remote access to the system should be implemented.As usual, let's start with the libraries:
You must reply before you can see the hidden data contained here.
You must reply before you can see the hidden data contained here.
Here is the code for our trojan. Below we will understand how it works, so as not to repeat the basic things.
You must reply before you can see the hidden data contained here.
So, the line client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) creates an echo server (sent a request - received a response). AF_INET means to work with IPv4 addressing, and SOCK_STREAM indicates that we are using a TCP connection instead of UDP, where the packet is sent to the network and is not monitored further.
The line client.connect((HOST, PORT)) specifies the host IP address and port on which the connection will be made, and connects immediately.
The client.recv(1024) function receives data from a socket and is a so-called "blocking call". The meaning of such a call is that until the command is transmitted or rejected by the other side, the call will continue to be executed. 1024 is the number of bytes used for the receive buffer. It will be impossible to accept more than 1024 bytes (1 KB) at a time, but we don’t need it: do you often manually enter more than 1000 characters into the console? There is no need to try to repeatedly increase the buffer size - this is costly and useless, since a large buffer is needed about once in never.
The decode('cp866') command decodes the received byte buffer into a text string according to the specified encoding (we have 866). But why exactly cp866? Let's go to the command line and enter the chcp command.
.
Current code page
The default encoding for Russian-speaking devices is 866, where Cyrillic is added to Latin. The English language versions of the system use normal Unicode, i.e. utf-8 in Python. We speak Russian, so we simply need to support it.
If desired, the encoding can be changed on the command line by typing its number after chcp. Unicode number is 65001.
When receiving a command, you need to determine if it is a service one. If so, we perform certain actions, otherwise, if the terminal is enabled, we redirect the command there. The disadvantage is that the result of the execution remains unprocessed, and it would be good to send it to us. This will be your homework: you can implement this function on the strength of about fifteen minutes, even if you google every step.
The result of checking the client on VirusTotal pleased.
The basic Trojan has been written, and now you can do a lot on the attacked machine, because we have access to the command line. But why don't we expand the feature set? Let's steal Wi-Fi passwords!
WI-FI-STYLER
The task is to create a script that will find out all the passwords from available Wi-Fi networks from the command line.Let's get started. Import libraries:
You must reply before you can see the hidden data contained here.
So, the script for extracting Wi-Fi passwords:
You must reply before you can see the hidden data contained here.
netsh wlan show profiles
If you parse the output above and substitute the network name in the command netsh wlan show profile [имя сети] key=clear, the result will be as in the picture. You can disassemble it and pull out the password from the network.
netsh wlan show profile ASUS key=clear
VirusTotal's verdict
One problem remains: our original idea was to take the passwords for ourselves, and not show them to the user. Let's fix this.
Let's add another version of the command to the script, where we process our commands from the network.
You must reply before you can see the hidden data contained here.
All the commands of this script have already been analyzed in detail, so I will not repeat myself, but just show a screenshot from my mail.
Result
Improvements
Of course, just about everything can be improved here - from protecting the transmission channel to protecting the very code of our malware. Methods of communication with the attacker's command and control servers are also usually used differently, and the operation of the malware does not depend on the language of the operating system.And of course, it is highly desirable to package the virus itself using PyInstaller, so as not to drag the python and all dependencies onto the victim's machine. A game that requires you to install a module for working with mail in order to work - what can inspire more confidence?
CONCLUSION
Today's Trojan is so simple that it can't be called combat. However, it is useful for learning the basics of the Python language and understanding how more complex malware works. We hope that you respect the law and that you will never need your knowledge of Trojans.As homework, I recommend trying to implement a two-way terminal and data encryption using at least XOR. Such a Trojan will already be much more interesting, but, of course, we do not call for using it in the wild. Be careful!