mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-05-19 16:30:50 +02:00
contrib: use LIEF for PE security checks
This commit is contained in:
parent
a25b2e965c
commit
8e1f40dd9a
@ -6,22 +6,13 @@
|
|||||||
Perform basic security checks on a series of executables.
|
Perform basic security checks on a series of executables.
|
||||||
Exit status will be 0 if successful, and the program will be silent.
|
Exit status will be 0 if successful, and the program will be silent.
|
||||||
Otherwise the exit status will be 1 and it will log which executables failed which checks.
|
Otherwise the exit status will be 1 and it will log which executables failed which checks.
|
||||||
Needs `objdump` (for PE).
|
|
||||||
'''
|
'''
|
||||||
import subprocess
|
|
||||||
import sys
|
import sys
|
||||||
import os
|
|
||||||
from typing import List, Optional
|
from typing import List, Optional
|
||||||
|
|
||||||
import lief
|
import lief
|
||||||
import pixie
|
import pixie
|
||||||
|
|
||||||
OBJDUMP_CMD = os.getenv('OBJDUMP', '/usr/bin/objdump')
|
|
||||||
|
|
||||||
def run_command(command) -> str:
|
|
||||||
p = subprocess.run(command, stdout=subprocess.PIPE, check=True, universal_newlines=True)
|
|
||||||
return p.stdout
|
|
||||||
|
|
||||||
def check_ELF_PIE(executable) -> bool:
|
def check_ELF_PIE(executable) -> bool:
|
||||||
'''
|
'''
|
||||||
Check for position independent executable (PIE), allowing for address space randomization.
|
Check for position independent executable (PIE), allowing for address space randomization.
|
||||||
@ -143,46 +134,27 @@ def check_ELF_separate_code(executable):
|
|||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def get_PE_dll_characteristics(executable) -> int:
|
|
||||||
'''Get PE DllCharacteristics bits'''
|
|
||||||
stdout = run_command([OBJDUMP_CMD, '-x', executable])
|
|
||||||
|
|
||||||
bits = 0
|
|
||||||
for line in stdout.splitlines():
|
|
||||||
tokens = line.split()
|
|
||||||
if len(tokens)>=2 and tokens[0] == 'DllCharacteristics':
|
|
||||||
bits = int(tokens[1],16)
|
|
||||||
return bits
|
|
||||||
|
|
||||||
IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA = 0x0020
|
|
||||||
IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE = 0x0040
|
|
||||||
IMAGE_DLL_CHARACTERISTICS_NX_COMPAT = 0x0100
|
|
||||||
|
|
||||||
def check_PE_DYNAMIC_BASE(executable) -> bool:
|
def check_PE_DYNAMIC_BASE(executable) -> bool:
|
||||||
'''PIE: DllCharacteristics bit 0x40 signifies dynamicbase (ASLR)'''
|
'''PIE: DllCharacteristics bit 0x40 signifies dynamicbase (ASLR)'''
|
||||||
bits = get_PE_dll_characteristics(executable)
|
binary = lief.parse(executable)
|
||||||
return (bits & IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE) == IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE
|
return lief.PE.DLL_CHARACTERISTICS.DYNAMIC_BASE in binary.optional_header.dll_characteristics_lists
|
||||||
|
|
||||||
# Must support high-entropy 64-bit address space layout randomization
|
# Must support high-entropy 64-bit address space layout randomization
|
||||||
# in addition to DYNAMIC_BASE to have secure ASLR.
|
# in addition to DYNAMIC_BASE to have secure ASLR.
|
||||||
def check_PE_HIGH_ENTROPY_VA(executable) -> bool:
|
def check_PE_HIGH_ENTROPY_VA(executable) -> bool:
|
||||||
'''PIE: DllCharacteristics bit 0x20 signifies high-entropy ASLR'''
|
'''PIE: DllCharacteristics bit 0x20 signifies high-entropy ASLR'''
|
||||||
bits = get_PE_dll_characteristics(executable)
|
binary = lief.parse(executable)
|
||||||
return (bits & IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA) == IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA
|
return lief.PE.DLL_CHARACTERISTICS.HIGH_ENTROPY_VA in binary.optional_header.dll_characteristics_lists
|
||||||
|
|
||||||
def check_PE_RELOC_SECTION(executable) -> bool:
|
def check_PE_RELOC_SECTION(executable) -> bool:
|
||||||
'''Check for a reloc section. This is required for functional ASLR.'''
|
'''Check for a reloc section. This is required for functional ASLR.'''
|
||||||
stdout = run_command([OBJDUMP_CMD, '-h', executable])
|
binary = lief.parse(executable)
|
||||||
|
return binary.has_relocations
|
||||||
for line in stdout.splitlines():
|
|
||||||
if '.reloc' in line:
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
def check_PE_NX(executable) -> bool:
|
def check_PE_NX(executable) -> bool:
|
||||||
'''NX: DllCharacteristics bit 0x100 signifies nxcompat (DEP)'''
|
'''NX: DllCharacteristics bit 0x100 signifies nxcompat (DEP)'''
|
||||||
bits = get_PE_dll_characteristics(executable)
|
binary = lief.parse(executable)
|
||||||
return (bits & IMAGE_DLL_CHARACTERISTICS_NX_COMPAT) == IMAGE_DLL_CHARACTERISTICS_NX_COMPAT
|
return binary.has_nx
|
||||||
|
|
||||||
def check_MACHO_PIE(executable) -> bool:
|
def check_MACHO_PIE(executable) -> bool:
|
||||||
'''
|
'''
|
||||||
|
Loading…
x
Reference in New Issue
Block a user