Skip to content

Instantly share code, notes, and snippets.

@joshfinley
Created August 9, 2024 16:24
Show Gist options
  • Save joshfinley/b2e121768b86ad6f270b466854d5da0f to your computer and use it in GitHub Desktop.
Save joshfinley/b2e121768b86ad6f270b466854d5da0f to your computer and use it in GitHub Desktop.
🥱
# 🥱 https://www.elastic.co/security-labs/get-injectedthreadex-detection-thread-creation-trampolines
import os
import pefile
import re
# Define the flag for CFG in DLL characteristics
IMAGE_DLLCHARACTERISTICS_GUARD_CF = 0x4000
# Define the flag for executable sections
IMAGE_SCN_MEM_EXECUTE = 0x20000000
def check_cfg_and_text_section(dll_path):
try:
pe = pefile.PE(dll_path)
# Check for valid text section
text_section = next((s for s in pe.sections if s.Name.decode().strip('\x00') == '.text'), None)
if not text_section:
return None, None, None
# Check if text section is executable
is_executable = text_section.Characteristics & IMAGE_SCN_MEM_EXECUTE != 0
# Check CFG
cfg_enabled = False
if hasattr(pe.OPTIONAL_HEADER, 'DllCharacteristics'):
if pe.OPTIONAL_HEADER.DllCharacteristics & IMAGE_DLLCHARACTERISTICS_GUARD_CF:
cfg_enabled = True
return cfg_enabled, is_executable, text_section.get_data()
except pefile.PEFormatError:
return None, None, None
def find_pattern_in_text_section(data, pattern):
return [hex(m.start()) for m in re.finditer(pattern, data)]
def check_dlls_in_folder(folder_path):
no_cfg_count = 0
pattern_match_count = 0
for root, dirs, files in os.walk(folder_path):
for file in files:
if file.lower().endswith('.dll'):
dll_path = os.path.join(root, file)
try:
cfg_enabled, is_executable, text_section_data = check_cfg_and_text_section(dll_path)
if cfg_enabled is None or not is_executable:
continue # Skip DLLs without a valid executable text section
if not cfg_enabled:
no_cfg_count += 1
if text_section_data:
pattern = b'\xff\xe1'
matches = find_pattern_in_text_section(text_section_data, pattern)
if matches:
pattern_match_count += 1
print(f'{dll_path}: No CFG, "ff e1" pattern at offsets: {", ".join(matches)}')
except PermissionError:
pass # Silently skip access denied files
except Exception as e:
pass # Silently skip other errors
return no_cfg_count, pattern_match_count
# Specify the folder to check
folder_to_check = r'C:\\'
no_cfg_count, pattern_match_count = check_dlls_in_folder(folder_to_check)
print(f'Found {no_cfg_count} DLLs without CFG in {folder_to_check}')
print(f'Of these, {pattern_match_count} DLLs also contain the "ff e1" pattern in an executable text section')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment