PE Security Checker

Tra le tecniche utilizzate per mitigare le vulnerabilità zero-day, e rendere più difficile agli hacker sfruttare questi insidiosi vettori di attacco, sono state sviluppate diverse tecniche, tra le quali DEP e ASLR.

Queste tecniche devono essere esplicitamente attivate al momento della compilazione del programma. Come sapere se un particolare programma è protetto con DEP e ASLR? Possiamo scrivere un piccolo programma che ce lo dice.

I file eseguibili, ma anche le librerie dinamiche (DLL), sono generati seguendo un particolare formato, conosciuto come PE (Portable Executable). Si tratta di un formato abbastanza complesso, virus-writers e analisti di malware ne conoscono a memoria ogni aspetto più oscuro; a noi basti sapere che in questo formato esiste una particolare struttura, denominata IMAGE_OPTIONAL_HEADER.

Questa struttura contiene alcune informazioni sull’eseguibile; in particolar modo, il campo DllCharacteristics ci dice se il programma è protetto da DEP e ASLR. Infatti, analizzando questo campo, secondo quello che indica la documentazione Microsoft, saremo in grado di stabilire con precisione se il programma è protetto o meno:

IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE = 0x0040
IMAGE_DLLCHARACTERISTICS_NX_COMPAT = 0x0100

A questo punto siamo in grado di scrivere un programmino in Python, in grado di svelare automaticamente queste informazioni. L’unica cosa che ci manca è una libreria che ci permetta di decodificare senza fatica il formato PE: PEFile fa al caso nostro.

Il codice che segue fa esattamente questo:

import os.path
import sys
import pefile

class PESecurityCheck:

  # IMAGE_OPTIONAL_HEADER structure
  # http://msdn.microsoft.com/en-us/library/windows/desktop/ms680339(v=vs.85).aspx
  IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE = 0x0040  # http://en.wikipedia.org/wiki/Address_space_layout_randomization
  IMAGE_DLLCHARACTERISTICS_NX_COMPAT = 0x0100     # http://en.wikipedia.org/wiki/Data_Execution_Prevention
  IMAGE_DLLCHARACTERISTICS_NO_SEH = 0x0400        # ttp://en.wikipedia.org/wiki/Microsoft-specific_exception_handling_mechanisms

  def __init__(self,pe):
    self.pe = pe

  def aslr(self):
    return bool(self.pe.OPTIONAL_HEADER.DllCharacteristics & self.IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE)

  def dep(self):
    return bool(self.pe.OPTIONAL_HEADER.DllCharacteristics & self.IMAGE_DLLCHARACTERISTICS_NX_COMPAT)

  def seh(self):
    return bool(self.pe.OPTIONAL_HEADER.DllCharacteristics & self.IMAGE_DLLCHARACTERISTICS_NO_SEH)

if len(sys.argv) < 2:
  print 'Usage: %s <file_path>' % sys.argv[0]
  sys.exit()

def main():
  file_path = sys.argv[1]   

  try:
    if os.path.isfile(file_path):
      pe = pefile.PE(file_path,True)
    else:
      print "File '%s' not found!" % file_path
      sys.exit(0)
  except pefile.PEFormatError:
    print "Not a PE file!"
    sys.exit(0)  

  ps = PESecurityCheck(pe)

  if ps.aslr():
    print "[+] ASLR Enabled"
  else:
    print "[-] ASLR Not Enabled"

  if ps.dep():
    print "[+] DEP Enabled"
  else:
    print "[-] DEP Not Enabled"

  if ps.seh():
    print "[+] SEH Enabled"
  else:
    print "[-] SEH Not Enabled"

if __name__ == '__main__':
  main()

Per utilizzarlo, lanciarlo da linea di comando, specificando il path del programma da verificare:

C:\>pescheck.py C:\Windows\system32\cmd.exe
[+] ASLR Enabled
[+] DEP Enabled
[-] SEH Not Enabled

Questo script è disponibile su Github.