Всем привет!
В последнее время увлёкся написанием скриптов на Python и решил объединить это увлечение с интересом к ИБ. У меня возникла идея создать скрипт для анализа программного обеспечения и написать на эту тему статью для конкурса.
P.S. Я понимаю, что большинство постояльцев форума — профессионалы с огромным опытом, и моя статья может показаться слишком простой по сравнению с другими. Однако я все же решился опубликовать её, поскольку кого-то она может заинтересовать.
Введение.
Вредоносное ПО (или malware) представляет собой серьёзную угрозу для безопасности компьютерных систем. Анализ вредоносного ПО необходим для понимания его поведения, методов заражения и способов защиты. Python, благодаря своей простоте и богатому набору библиотек, становится всё более популярным инструментом для анализа вредоносного ПО. В этой статье я расскажу о методах анализа ПО с использованием Python. В качестве практического примера мы проведем анализ простого вредоносного скрипта на Python.
Преобразуем скрипт в исполняемый (exe) файл.
Эта функция принимает в качестве аргумента имя файла и загружает его как PE-файл
Эта часть скрипта выводит на экран заголовок DOS, который является первым компонентом PE-файла. Заголовок DOS содержит информацию, которая помогает понять, как файл загружается и выполняется.
Эта часть скрипта выводит информацию о секциях PE-файла. Каждая секция содержит различный тип данных, например, код или ресурсы. Скрипт выводит имя секции, виртуальный адрес, виртуальный размер и размер данных на диске.
Эта часть скрипта выводит информацию о DLL-файлах и функциях, которые импортируются PE-файлом. Она перечисляет все DLL, которые файл использует, и функции, импортируемые из этих DLL. Это важно для понимания, какие внешние библиотеки и функции требуются для выполнения файла.
Эта функция принимает имя файла (filename) и запускает его как новый процесс с помощью subprocess.Popen. Параметры stdout=subprocess.PIPE и stderr=subprocess.PIPE указывают, что нужно захватывать стандартный вывод и поток ошибок процесса.
Этот вывод демонстрирует выполнение действий, таких как создание, чтение и удаление файла. Здесь можно наглядно увидеть поведение вредоносного ПО.
В последнее время увлёкся написанием скриптов на Python и решил объединить это увлечение с интересом к ИБ. У меня возникла идея создать скрипт для анализа программного обеспечения и написать на эту тему статью для конкурса.
P.S. Я понимаю, что большинство постояльцев форума — профессионалы с огромным опытом, и моя статья может показаться слишком простой по сравнению с другими. Однако я все же решился опубликовать её, поскольку кого-то она может заинтересовать.
Введение.
Вредоносное ПО (или malware) представляет собой серьёзную угрозу для безопасности компьютерных систем. Анализ вредоносного ПО необходим для понимания его поведения, методов заражения и способов защиты. Python, благодаря своей простоте и богатому набору библиотек, становится всё более популярным инструментом для анализа вредоносного ПО. В этой статье я расскажу о методах анализа ПО с использованием Python. В качестве практического примера мы проведем анализ простого вредоносного скрипта на Python.
Создание демонстрационного скрипта.
Первым шагом для меня было создание демонстрационного скрипта на Python. Я решил написать простой скрипт-пустышку, который выполняет действия, характерные для вредоносного ПО, такие как создание, чтение и удаление файлов.
Python:
import os
def create_file():
print("Creating malicious file...")
with open("malicious_file.txt", "w") as file:
file.write("This is a malicious file.\n")
file.write("Your system has been compromised.\n")
print("File created.")
def read_file():
print("Reading malicious file...")
if os.path.exists("malicious_file.txt"):
with open("malicious_file.txt", "r") as file:
content = file.read()
print("File content:\n" + content)
def delete_file():
print("Deleting malicious file...")
if os.path.exists("malicious_file.txt"):
os.remove("malicious_file.txt")
print("File deleted.")
if __name__ == "__main__":
create_file()
read_file()
delete_file()
Преобразуем скрипт в исполняемый (exe) файл.
Bash:
pyinstaller --onefile malicious_script.py
Краткое описание методов анализа.
Анализ вредоносного ПО можно разделить на два основных типа: статический и динамический анализ.- Статический анализ включает изучение исходного кода или бинарного файла без его выполнения. Это позволяет выявить структуру программы, используемые библиотеки, вредоносные функции и т.д.
- Динамический анализ предполагает выполнение программы в контролируемой среде для наблюдения за её поведением. Это помогает выявить изменения в системе, сетевую активность, взаимодействие с файловой системой и т.д.
Статический анализ.
Чтобы написать скрипт для статического анализа, воспользуемся библиотекой pefile для анализа PE-файлов.
Python:
import pefile
def analyze_pe(filename):
pe = pefile.PE(filename)
print("DOS Header:")
print(pe.DOS_HEADER)
print("\nPE Sections:")
for section in pe.sections:
print(section.Name.decode().strip(), hex(section.VirtualAddress), hex(section.Misc_VirtualSize), section.SizeOfRawData)
print("\nImported DLLs and functions:")
for entry in pe.DIRECTORY_ENTRY_IMPORT:
print(entry.dll.decode())
for imp in entry.imports:
print('\t', imp.name.decode() if imp.name else None)
if __name__ == "__main__":
filename = 'dist/simple_malware.exe'
analyze_pe(filename)
Python:
def analyze_pe(filename):
pe = pefile.PE(filename)
Python:
print("DOS Header:")
print(pe.DOS_HEADER)
Python:
print("\nPE Sections:")
for section in pe.sections:
print(section.Name.decode().strip(), hex(section.VirtualAddress), hex(section.Misc_VirtualSize), section.SizeOfRawData)
Python:
print("\nImported DLLs and functions:")
for entry in pe.DIRECTORY_ENTRY_IMPORT:
print(entry.dll.decode())
for imp in entry.imports:
print('\t', imp.name.decode() if imp.name else None)
Результаты статического анализа:
Bash:
DOS Header:
[IMAGE_DOS_HEADER]
0x0 0x0 e_magic: 0x5A4D
0x2 0x2 e_cblp: 0x90
0x4 0x4 e_cp: 0x3
0x6 0x6 e_crlc: 0x0
0x8 0x8 e_cparhdr: 0x4
0xA 0xA e_minalloc: 0x0
0xC 0xC e_maxalloc: 0xFFFF
0xE 0xE e_ss: 0x0
0x10 0x10 e_sp: 0xB8
0x12 0x12 e_csum: 0x0
0x14 0x14 e_ip: 0x0
0x16 0x16 e_cs: 0x0
0x18 0x18 e_lfarlc: 0x40
0x1A 0x1A e_ovno: 0x0
0x1C 0x1C e_res:
0x24 0x24 e_oemid: 0x0
0x26 0x26 e_oeminfo: 0x0
0x28 0x28 e_res2:
0x3C 0x3C e_lfanew: 0x100
PE Sections:
.text 0x1000 0x2b150 176640
.rdata 0x2d000 0x12c26 77312
.data 0x40000 0x33b8 3584
.pdata 0x44000 0x2364 9216
_RDATA 0x47000 0x1f4 512
.rsrc 0x48000 0xef8c 61440
.reloc 0x57000 0x75c 2048
Imported DLLs and functions:
USER32.dll
GetWindowThreadProcessId
ShowWindow
KERNEL32.dll
CreateFileW
GetFinalPathNameByHandleW
CloseHandle
GetModuleFileNameW
CreateSymbolicLinkW
GetProcAddress
GetCommandLineW
GetEnvironmentVariableW
SetEnvironmentVariableW
ExpandEnvironmentStringsW
CreateDirectoryW
GetTempPathW
WaitForSingleObject
Sleep
SetDllDirectoryW
CreateProcessW
GetStartupInfoW
FreeLibrary
LoadLibraryExW
SetConsoleCtrlHandler
FindClose
FindFirstFileExW
GetCurrentProcess
GetCurrentProcessId
LocalFree
FormatMessageW
MultiByteToWideChar
WideCharToMultiByte
GetConsoleWindow
HeapSize
GetLastError
WriteConsoleW
SetEndOfFile
GetExitCodeProcess
TlsGetValue
RtlCaptureContext
RtlLookupFunctionEntry
RtlVirtualUnwind
UnhandledExceptionFilter
SetUnhandledExceptionFilter
TerminateProcess
IsProcessorFeaturePresent
QueryPerformanceCounter
GetCurrentThreadId
GetSystemTimeAsFileTime
InitializeSListHead
IsDebuggerPresent
GetModuleHandleW
RtlUnwindEx
SetLastError
EnterCriticalSection
LeaveCriticalSection
DeleteCriticalSection
InitializeCriticalSectionAndSpinCount
TlsAlloc
TlsSetValue
TlsFree
EncodePointer
RaiseException
RtlPcToFileHeader
GetCommandLineA
GetDriveTypeW
GetFileInformationByHandle
GetFileType
PeekNamedPipe
SystemTimeToTzSpecificLocalTime
FileTimeToSystemTime
GetFullPathNameW
RemoveDirectoryW
FindNextFileW
SetStdHandle
DeleteFileW
ReadFile
GetStdHandle
WriteFile
ExitProcess
GetModuleHandleExW
HeapFree
GetConsoleMode
ReadConsoleW
SetFilePointerEx
GetConsoleOutputCP
GetFileSizeEx
HeapAlloc
FlsAlloc
FlsGetValue
FlsSetValue
FlsFree
CompareStringW
LCMapStringW
GetCurrentDirectoryW
FlushFileBuffers
HeapReAlloc
GetFileAttributesExW
GetStringTypeW
IsValidCodePage
GetACP
GetOEMCP
GetCPInfo
GetEnvironmentStringsW
FreeEnvironmentStringsW
GetProcessHeap
GetTimeZoneInformation
ADVAPI32.dll
ConvertSidToStringSidW
GetTokenInformation
OpenProcessToken
ConvertStringSecurityDescriptorToSecurityDescriptorW
Подозрительные функции:
- CreateFileW и WriteFile: Используются для создания и записи в файлы. Вредоносное ПО может использовать эти функции для записи своих компонентов на диск.
- CreateProcessW: Используется для создания новых процессов. Вредоносное ПО может использовать эту функцию для запуска дополнительных вредоносных компонентов.
- GetProcAddress и LoadLibraryExW: Эти функции позволяют динамически загружать библиотеки и получать адреса функций, что может использоваться для обхода защитных механизмов.
- VirtualAlloc и WriteProcessMemory: Используются для выделения памяти и записи в память других процессов, что может быть признаком внедрения кода (инъекции).
- IsDebuggerPresent: Используется для проверки наличия отладчика, что часто используется вредоносным ПО для избегания анализа.
- OpenProcessToken и AdjustTokenPrivileges: Используются для управления токенами безопасности процессов, что может указывать на попытки повышения привилегий.
Ссылка скрыта от гостей
, а пока двигаемся дальше.Динамический анализ.
Динамический анализ позволяет изучить поведение исполняемого файла во время его выполнения. Напишем скрипт, который запускает исполняемый файл и выводит его стандартный вывод и поток ошибок.
Python:
import subprocess
def run_and_monitor(filename):
proc = subprocess.Popen([filename], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
try:
stdout, stderr = proc.communicate(timeout=10)
print("STDOUT:\n", stdout.decode('utf-8', errors='ignore'))
print("STDERR:\n", stderr.decode('utf-8', errors='ignore'))
except subprocess.TimeoutExpired:
proc.kill()
print("Execution timed out")
if __name__ == "__main__":
filename = 'dist/malicious_script.exe'
run_and_monitor(filename)
Python:
def run_and_monitor(filename):
proc = subprocess.Popen([filename], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
Python:
try:
stdout, stderr = proc.communicate(timeout=10)
print("STDOUT:\n", stdout.decode('utf-8', errors='ignore'))
print("STDERR:\n", stderr.decode('utf-8', errors='ignore'))
except subprocess.TimeoutExpired:
proc.kill()
print("Execution timed out")
- proc.communicate(timeout=10): Эта строка ждет до 10 секунд, пока процесс завершится, и захватывает его стандартный вывод и поток ошибок. Если процесс не завершится за 10 секунд, выдаст ошибку TimeoutExpired.
- print("STDOUT:\n", stdout.decode('utf-8', errors='ignore')): Выводит стандартный вывод процесса, декодируя его из байтов в строку.
- print("STDERR:\n", stderr.decode('utf-8', errors='ignore')): Выводит поток ошибок процесса, декодируя его из байтов в строку.
- proc.kill(): Если процесс не завершился в течение 10 секунд, он будет принудительно завершен.
Результаты динамического анализа:
Bash:
STDOUT:
Creating malicious file...
File created.
Reading malicious file...
File content:
This is a malicious file.
Your system has been compromised.
Deleting malicious file...
File deleted.
STDERR:
Этот вывод демонстрирует выполнение действий, таких как создание, чтение и удаление файла. Здесь можно наглядно увидеть поведение вредоносного ПО.
Заключение.
В этой статье я поделился своим опытом создания и анализа вредоносного ПО на Python. Мы рассмотрели процесс написания вредоносного скрипта, его преобразования в исполняемый файл, а также методы статического и динамического анализа. Функционал скриптов для анализа можно разносторонне расширять (добавить функции мониторинга системных ресурсов, создать список из подозрительных функций и т.п.) Надеюсь, эта статья будет кому-то интересна, а так-же поможет лучше понять принципы работы и анализа ПО.
Последнее редактирование: