summaryrefslogtreecommitdiff
path: root/plugins/python/checksec/mitigations.py
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2018-12-27 22:35:39 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2018-12-27 22:35:39 (GMT)
commit865f6d87f3bce7f569343382c3dfd1bc68dcacee (patch)
tree64869be2c5e7ad9285829b48ba7f7b446d73e3ec /plugins/python/checksec/mitigations.py
parentd33e8935c5186ab2459dfa6c9340396377524fb1 (diff)
Displayed mitigations for Elf files using a new Python plugin.
Diffstat (limited to 'plugins/python/checksec/mitigations.py')
-rw-r--r--plugins/python/checksec/mitigations.py135
1 files changed, 135 insertions, 0 deletions
diff --git a/plugins/python/checksec/mitigations.py b/plugins/python/checksec/mitigations.py
new file mode 100644
index 0000000..1539fa7
--- /dev/null
+++ b/plugins/python/checksec/mitigations.py
@@ -0,0 +1,135 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+from pychrysalide.format.elf import ElfFormat
+
+
+class ElfMitigations():
+
+ def __init__(self, fmt):
+ """Look for mitigations in a loaded Elf format."""
+
+ self._fmt = fmt
+
+ self._nx = self._get_nx_status()
+
+ self._pie = self._get_pie_status()
+
+ self._relro = self._get_reloc_status()
+
+ self._canary = self._get_canary_status()
+
+
+ def _get_nx_status(self):
+ """Find information about the stack status."""
+
+ # Cf. https://wiki.gentoo.org/wiki/Hardened/GNU_stack_quickstart
+ # ...#Causes_of_executable_stack_markings
+
+ # -Wl,-z,execstack / -Wl,-z,noexecstack
+
+ stack = self._fmt.find_program_by_type(ElfFormat.PT_GNU_STACK)
+
+ status = stack is None or stack.p_flags & ElfFormat.PF_X
+
+ return 'No' if status else 'Yes'
+
+
+ def _get_pie_status(self):
+ """Check for taking advantage of ASLR."""
+
+ # Cf. https://stackoverflow.com/questions/2463150/what-is-the-fpie-option-for-position-independent-executables-in-gcc-and-ld/5030518#5030518
+
+ # -pie -fPIE
+
+ hdr = self._fmt.get_header()
+
+ status = hdr.e_type == ElfFormat.ET_DYN
+
+ return 'Yes' if status else 'No'
+
+
+ def _get_reloc_status(self):
+ """Track protections for the GOT."""
+
+ # Cf. https://wiki.debian.org/Hardening
+ # ...#DEB_BUILD_HARDENING_RELRO_.28ld_-z_relro.29
+
+ # -Wl,-z,relro / -Wl,-z,now
+
+ prgm = self._fmt.find_program_by_type(ElfFormat.PT_GNU_RELRO)
+
+ entry = self._fmt.find_dynamic_item_by_type(ElfFormat.DT_BIND_NOW)
+
+ if prgm is None and entry is None:
+ status = 'No'
+
+ elif not(prgm is None) and entry is None:
+ status = 'Partial'
+
+ elif prgm is None and not(entry is None):
+ status = 'Full'
+
+ else:
+ status = 'Unknown'
+
+ return status
+
+
+ def _get_canary_status(self):
+ """Look for a canary as stack protection."""
+
+ # Cf. https://outflux.net/blog/archives/2014*01/24/fstack-protector-strong/
+
+ # -fno-stack-protector / -fstack-protector / -fstack-protector-all / -fstack-protector-strong
+
+ sym = self._fmt.find_symbol_by_label('__stack_chk_fail@plt')
+
+ status = sym is None
+
+ return 'No' if status else 'Yes'
+
+
+ def __str__(self):
+ """Output a mitigation summary."""
+
+ desc = fmt.content.describe(True) + ':'
+
+ desc += '\n'
+
+ desc += '-' * (len(desc) - 1)
+
+ desc += '\n'
+
+ desc += 'NX: %s' % self._nx
+
+ desc += '\n'
+
+ desc += 'PIE: %s' % self._pie
+
+ desc += '\n'
+
+ desc += 'RelRO: %s' % self._relro
+
+ desc += '\n'
+
+ desc += 'Canary: %s' % self._canary
+
+ return desc
+
+
+if __name__ == '__main__':
+
+ from pychrysalide.features import *
+ import sys
+
+ cnt = FileContent(sys.argv[1])
+ fmt = ElfFormat(cnt)
+
+ binary = LoadedBinary(fmt)
+
+ status = binary.analyze_and_wait()
+
+ if status :
+ m = ElfMitigations(binary.format)
+ print(m)