scripts: make security checks architecture independent

This paves the way for using and checking for architecture dependent
flags like -fcf-protection on x86_64 Linux and -mbranch-protection on 64
bit ARM.
pull/826/head
fanquake 3 years ago
parent d69af93223
commit b9898aeeaa
No known key found for this signature in database
GPG Key ID: 2EEB9F5CC09526C1

@ -12,6 +12,10 @@ from typing import List
import lief #type:ignore import lief #type:ignore
# temporary constant, to be replaced with lief.ELF.ARCH.RISCV
# https://github.com/lief-project/LIEF/pull/562
LIEF_ELF_ARCH_RISCV = lief.ELF.ARCH(243)
def check_ELF_RELRO(binary) -> bool: def check_ELF_RELRO(binary) -> bool:
''' '''
Check for read-only relocations. Check for read-only relocations.
@ -178,24 +182,24 @@ def check_control_flow(binary) -> bool:
return True return True
return False return False
BASE_ELF = [
CHECKS = {
lief.EXE_FORMATS.ELF: [
('PIE', check_PIE), ('PIE', check_PIE),
('NX', check_NX), ('NX', check_NX),
('RELRO', check_ELF_RELRO), ('RELRO', check_ELF_RELRO),
('Canary', check_ELF_Canary), ('Canary', check_ELF_Canary),
('separate_code', check_ELF_separate_code), ('separate_code', check_ELF_separate_code),
], ]
lief.EXE_FORMATS.PE: [
BASE_PE = [
('PIE', check_PIE), ('PIE', check_PIE),
('DYNAMIC_BASE', check_PE_DYNAMIC_BASE), ('DYNAMIC_BASE', check_PE_DYNAMIC_BASE),
('HIGH_ENTROPY_VA', check_PE_HIGH_ENTROPY_VA), ('HIGH_ENTROPY_VA', check_PE_HIGH_ENTROPY_VA),
('NX', check_NX), ('NX', check_NX),
('RELOC_SECTION', check_PE_RELOC_SECTION), ('RELOC_SECTION', check_PE_RELOC_SECTION),
('CONTROL_FLOW', check_PE_control_flow), ('CONTROL_FLOW', check_PE_control_flow),
], ]
lief.EXE_FORMATS.MACHO: [
BASE_MACHO = [
('PIE', check_PIE), ('PIE', check_PIE),
('NOUNDEFS', check_MACHO_NOUNDEFS), ('NOUNDEFS', check_MACHO_NOUNDEFS),
('NX', check_NX), ('NX', check_NX),
@ -203,6 +207,21 @@ lief.EXE_FORMATS.MACHO: [
('Canary', check_MACHO_Canary), ('Canary', check_MACHO_Canary),
('CONTROL_FLOW', check_control_flow), ('CONTROL_FLOW', check_control_flow),
] ]
CHECKS = {
lief.EXE_FORMATS.ELF: {
lief.ARCHITECTURES.X86: BASE_ELF,
lief.ARCHITECTURES.ARM: BASE_ELF,
lief.ARCHITECTURES.ARM64: BASE_ELF,
lief.ARCHITECTURES.PPC: BASE_ELF,
LIEF_ELF_ARCH_RISCV: BASE_ELF,
},
lief.EXE_FORMATS.PE: {
lief.ARCHITECTURES.X86: BASE_PE,
},
lief.EXE_FORMATS.MACHO: {
lief.ARCHITECTURES.X86: BASE_MACHO,
}
} }
if __name__ == '__main__': if __name__ == '__main__':
@ -211,13 +230,24 @@ if __name__ == '__main__':
try: try:
binary = lief.parse(filename) binary = lief.parse(filename)
etype = binary.format etype = binary.format
arch = binary.abstract.header.architecture
binary.concrete
if etype == lief.EXE_FORMATS.UNKNOWN: if etype == lief.EXE_FORMATS.UNKNOWN:
print(f'{filename}: unknown executable format') print(f'{filename}: unknown executable format')
retval = 1 retval = 1
continue continue
if arch == lief.ARCHITECTURES.NONE:
if binary.header.machine_type == LIEF_ELF_ARCH_RISCV:
arch = LIEF_ELF_ARCH_RISCV
else:
print(f'{filename}: unknown architecture')
retval = 1
continue
failed: List[str] = [] failed: List[str] = []
for (name, func) in CHECKS[etype]: for (name, func) in CHECKS[etype][arch]:
if not func(binary): if not func(binary):
failed.append(name) failed.append(name)
if failed: if failed:

Loading…
Cancel
Save