mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-02 09:46:52 -05:00
contrib: use LIEF for macOS security checks
This commit is contained in:
parent
7e7eae7aa8
commit
a25b2e965c
1 changed files with 12 additions and 42 deletions
|
@ -6,17 +6,17 @@
|
|||
Perform basic security checks on a series of executables.
|
||||
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.
|
||||
Needs `objdump` (for PE) and `otool` (for MACHO).
|
||||
Needs `objdump` (for PE).
|
||||
'''
|
||||
import subprocess
|
||||
import sys
|
||||
import os
|
||||
from typing import List, Optional
|
||||
|
||||
import lief
|
||||
import pixie
|
||||
|
||||
OBJDUMP_CMD = os.getenv('OBJDUMP', '/usr/bin/objdump')
|
||||
OTOOL_CMD = os.getenv('OTOOL', '/usr/bin/otool')
|
||||
|
||||
def run_command(command) -> str:
|
||||
p = subprocess.run(command, stdout=subprocess.PIPE, check=True, universal_newlines=True)
|
||||
|
@ -184,71 +184,41 @@ def check_PE_NX(executable) -> bool:
|
|||
bits = get_PE_dll_characteristics(executable)
|
||||
return (bits & IMAGE_DLL_CHARACTERISTICS_NX_COMPAT) == IMAGE_DLL_CHARACTERISTICS_NX_COMPAT
|
||||
|
||||
def get_MACHO_executable_flags(executable) -> List[str]:
|
||||
stdout = run_command([OTOOL_CMD, '-vh', executable])
|
||||
|
||||
flags: List[str] = []
|
||||
for line in stdout.splitlines():
|
||||
tokens = line.split()
|
||||
# filter first two header lines
|
||||
if 'magic' in tokens or 'Mach' in tokens:
|
||||
continue
|
||||
# filter ncmds and sizeofcmds values
|
||||
flags += [t for t in tokens if not t.isdigit()]
|
||||
return flags
|
||||
|
||||
def check_MACHO_PIE(executable) -> bool:
|
||||
'''
|
||||
Check for position independent executable (PIE), allowing for address space randomization.
|
||||
'''
|
||||
flags = get_MACHO_executable_flags(executable)
|
||||
if 'PIE' in flags:
|
||||
return True
|
||||
return False
|
||||
binary = lief.parse(executable)
|
||||
return binary.is_pie
|
||||
|
||||
def check_MACHO_NOUNDEFS(executable) -> bool:
|
||||
'''
|
||||
Check for no undefined references.
|
||||
'''
|
||||
flags = get_MACHO_executable_flags(executable)
|
||||
if 'NOUNDEFS' in flags:
|
||||
return True
|
||||
return False
|
||||
binary = lief.parse(executable)
|
||||
return binary.header.has(lief.MachO.HEADER_FLAGS.NOUNDEFS)
|
||||
|
||||
def check_MACHO_NX(executable) -> bool:
|
||||
'''
|
||||
Check for no stack execution
|
||||
'''
|
||||
flags = get_MACHO_executable_flags(executable)
|
||||
if 'ALLOW_STACK_EXECUTION' in flags:
|
||||
return False
|
||||
return True
|
||||
binary = lief.parse(executable)
|
||||
return binary.has_nx
|
||||
|
||||
def check_MACHO_LAZY_BINDINGS(executable) -> bool:
|
||||
'''
|
||||
Check for no lazy bindings.
|
||||
We don't use or check for MH_BINDATLOAD. See #18295.
|
||||
'''
|
||||
stdout = run_command([OTOOL_CMD, '-l', executable])
|
||||
|
||||
for line in stdout.splitlines():
|
||||
tokens = line.split()
|
||||
if 'lazy_bind_off' in tokens or 'lazy_bind_size' in tokens:
|
||||
if tokens[1] != '0':
|
||||
return False
|
||||
return True
|
||||
binary = lief.parse(executable)
|
||||
return binary.dyld_info.lazy_bind == (0,0)
|
||||
|
||||
def check_MACHO_Canary(executable) -> bool:
|
||||
'''
|
||||
Check for use of stack canary
|
||||
'''
|
||||
stdout = run_command([OTOOL_CMD, '-Iv', executable])
|
||||
|
||||
ok = False
|
||||
for line in stdout.splitlines():
|
||||
if '___stack_chk_fail' in line:
|
||||
ok = True
|
||||
return ok
|
||||
binary = lief.parse(executable)
|
||||
return binary.has_symbol('___stack_chk_fail')
|
||||
|
||||
CHECKS = {
|
||||
'ELF': [
|
||||
|
|
Loading…
Add table
Reference in a new issue