mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-07-08 01:10:43 +02:00
scripts: add CONTROL_FLOW to ELF security checks
This commit is contained in:
@ -111,6 +111,17 @@ def check_ELF_separate_code(binary):
|
|||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def check_ELF_control_flow(binary) -> bool:
|
||||||
|
'''
|
||||||
|
Check for control flow instrumentation
|
||||||
|
'''
|
||||||
|
main = binary.get_function_address('main')
|
||||||
|
content = binary.get_content_from_virtual_address(main, 4, lief.Binary.VA_TYPES.AUTO)
|
||||||
|
|
||||||
|
if content == [243, 15, 30, 250]: # endbr64
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
def check_PE_DYNAMIC_BASE(binary) -> bool:
|
def check_PE_DYNAMIC_BASE(binary) -> bool:
|
||||||
'''PIE: DllCharacteristics bit 0x40 signifies dynamicbase (ASLR)'''
|
'''PIE: DllCharacteristics bit 0x40 signifies dynamicbase (ASLR)'''
|
||||||
return lief.PE.DLL_CHARACTERISTICS.DYNAMIC_BASE in binary.optional_header.dll_characteristics_lists
|
return lief.PE.DLL_CHARACTERISTICS.DYNAMIC_BASE in binary.optional_header.dll_characteristics_lists
|
||||||
@ -210,7 +221,7 @@ BASE_MACHO = [
|
|||||||
|
|
||||||
CHECKS = {
|
CHECKS = {
|
||||||
lief.EXE_FORMATS.ELF: {
|
lief.EXE_FORMATS.ELF: {
|
||||||
lief.ARCHITECTURES.X86: BASE_ELF,
|
lief.ARCHITECTURES.X86: BASE_ELF + [('CONTROL_FLOW', check_ELF_control_flow)],
|
||||||
lief.ARCHITECTURES.ARM: BASE_ELF,
|
lief.ARCHITECTURES.ARM: BASE_ELF,
|
||||||
lief.ARCHITECTURES.ARM64: BASE_ELF,
|
lief.ARCHITECTURES.ARM64: BASE_ELF,
|
||||||
lief.ARCHITECTURES.PPC: BASE_ELF,
|
lief.ARCHITECTURES.PPC: BASE_ELF,
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
'''
|
'''
|
||||||
Test script for security-check.py
|
Test script for security-check.py
|
||||||
'''
|
'''
|
||||||
|
import lief #type:ignore
|
||||||
import os
|
import os
|
||||||
import subprocess
|
import subprocess
|
||||||
from typing import List
|
from typing import List
|
||||||
@ -41,13 +42,37 @@ def call_security_check(cc, source, executable, options):
|
|||||||
p = subprocess.run(['./contrib/devtools/security-check.py',executable], stdout=subprocess.PIPE, universal_newlines=True)
|
p = subprocess.run(['./contrib/devtools/security-check.py',executable], stdout=subprocess.PIPE, universal_newlines=True)
|
||||||
return (p.returncode, p.stdout.rstrip())
|
return (p.returncode, p.stdout.rstrip())
|
||||||
|
|
||||||
|
def get_arch(cc, source, executable):
|
||||||
|
subprocess.run([*cc, source, '-o', executable], check=True)
|
||||||
|
binary = lief.parse(executable)
|
||||||
|
arch = binary.abstract.header.architecture
|
||||||
|
os.remove(executable)
|
||||||
|
return arch
|
||||||
|
|
||||||
class TestSecurityChecks(unittest.TestCase):
|
class TestSecurityChecks(unittest.TestCase):
|
||||||
def test_ELF(self):
|
def test_ELF(self):
|
||||||
source = 'test1.c'
|
source = 'test1.c'
|
||||||
executable = 'test1'
|
executable = 'test1'
|
||||||
cc = determine_wellknown_cmd('CC', 'gcc')
|
cc = determine_wellknown_cmd('CC', 'gcc')
|
||||||
write_testcode(source)
|
write_testcode(source)
|
||||||
|
arch = get_arch(cc, source, executable)
|
||||||
|
|
||||||
|
if arch == lief.ARCHITECTURES.X86:
|
||||||
|
self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-zexecstack','-fno-stack-protector','-Wl,-znorelro','-no-pie','-fno-PIE', '-Wl,-z,separate-code']),
|
||||||
|
(1, executable+': failed PIE NX RELRO Canary CONTROL_FLOW'))
|
||||||
|
self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-znoexecstack','-fno-stack-protector','-Wl,-znorelro','-no-pie','-fno-PIE', '-Wl,-z,separate-code']),
|
||||||
|
(1, executable+': failed PIE RELRO Canary CONTROL_FLOW'))
|
||||||
|
self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-znoexecstack','-fstack-protector-all','-Wl,-znorelro','-no-pie','-fno-PIE', '-Wl,-z,separate-code']),
|
||||||
|
(1, executable+': failed PIE RELRO CONTROL_FLOW'))
|
||||||
|
self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-znoexecstack','-fstack-protector-all','-Wl,-znorelro','-pie','-fPIE', '-Wl,-z,separate-code']),
|
||||||
|
(1, executable+': failed RELRO CONTROL_FLOW'))
|
||||||
|
self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-znoexecstack','-fstack-protector-all','-Wl,-zrelro','-Wl,-z,now','-pie','-fPIE', '-Wl,-z,noseparate-code']),
|
||||||
|
(1, executable+': failed separate_code CONTROL_FLOW'))
|
||||||
|
self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-znoexecstack','-fstack-protector-all','-Wl,-zrelro','-Wl,-z,now','-pie','-fPIE', '-Wl,-z,separate-code']),
|
||||||
|
(1, executable+': failed CONTROL_FLOW'))
|
||||||
|
self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-znoexecstack','-fstack-protector-all','-Wl,-zrelro','-Wl,-z,now','-pie','-fPIE', '-Wl,-z,separate-code', '-fcf-protection=full']),
|
||||||
|
(0, ''))
|
||||||
|
else:
|
||||||
self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-zexecstack','-fno-stack-protector','-Wl,-znorelro','-no-pie','-fno-PIE', '-Wl,-z,separate-code']),
|
self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-zexecstack','-fno-stack-protector','-Wl,-znorelro','-no-pie','-fno-PIE', '-Wl,-z,separate-code']),
|
||||||
(1, executable+': failed PIE NX RELRO Canary'))
|
(1, executable+': failed PIE NX RELRO Canary'))
|
||||||
self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-znoexecstack','-fno-stack-protector','-Wl,-znorelro','-no-pie','-fno-PIE', '-Wl,-z,separate-code']),
|
self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-znoexecstack','-fno-stack-protector','-Wl,-znorelro','-no-pie','-fno-PIE', '-Wl,-z,separate-code']),
|
||||||
|
Reference in New Issue
Block a user