Skip to content

Instantly share code, notes, and snippets.

@Neo23x0
Last active January 12, 2023 08:12
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Neo23x0/577926e34183b4cedd76aa33f6e4dfa3 to your computer and use it in GitHub Desktop.
Save Neo23x0/577926e34183b4cedd76aa33f6e4dfa3 to your computer and use it in GitHub Desktop.
YARA Rule Hash Generator
import hashlib
import re
import plyara
# Florian Roth, Christian Burkard
# Version 3.0
# January 2023
#
# Known issues: fails in some cases in which 'private' rules are used
def calculate_rule_hash(rule):
"""
Calculates a hash over the relevant YARA rule content (string contents, sorted condition)
Requires a YARA rule object as generated by 'plyara': https://github.com/plyara/plyara
:param rule: yara rule object
:return hash: generated hash
"""
hash_strings = []
m = hashlib.md5()
# Adding all string contents to the list
if 'strings' in rule:
# Loop over strings
for s in rule['strings']:
# String to work with
string_value = s['value']
# List of modifiers
modifiers = []
# Byte chains
if s['type'] == "byte":
hash_strings.append(re.sub(r'[^a-fA-F\?0-9]+', '', string_value))
# Others: strings, regex
else:
# If modifiers exist, just use them
if 'modifiers' in s:
modifiers = s['modifiers']
# One exception: if no 'wide' modifier is set, add an 'ascii' modifier
if not 'wide' in modifiers and not 'ascii' in modifiers:
modifiers.append('ascii')
# If nocase in list, lowercase the string
if 'nocase' in modifiers:
string_value = string_value.lower()
# Sort all modifiers
modifiers = sorted(modifiers)
# Now add it to the string to hash
hash_strings.append("{0}|{1}".format(string_value, ":".join(modifiers)))
# Adding the components of the condition to the list (except the variables)
for e in rule['condition_terms']:
if not e.startswith("$") and not e.startswith("#"):
hash_strings.append(e)
# Empty
if len(hash_strings) == 0:
return ""
# Generate a hash from the sorted contents
hash_strings.sort()
print(hash_strings)
m.update("".join(hash_strings).encode("ascii"))
return m.hexdigest()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment