diff options
| -rwxr-xr-x | php-malware-finder/utils/mass_whitelist.py | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/php-malware-finder/utils/mass_whitelist.py b/php-malware-finder/utils/mass_whitelist.py index 82733fa..ef7e39d 100755 --- a/php-malware-finder/utils/mass_whitelist.py +++ b/php-malware-finder/utils/mass_whitelist.py | |||
| @@ -1,6 +1,8 @@ | |||
| 1 | #!/usr/bin/env python | 1 | #!/usr/bin/env python |
| 2 | # -*- coding: utf-8 -*- | 2 | # -*- coding: utf-8 -*- |
| 3 | 3 | ||
| 4 | from __future__ import print_function | ||
| 5 | |||
| 4 | import sys | 6 | import sys |
| 5 | import tarfile | 7 | import tarfile |
| 6 | from copy import copy | 8 | from copy import copy |
| @@ -65,7 +67,8 @@ def generate_whitelist(version): | |||
| 65 | dl_failed = False | 67 | dl_failed = False |
| 66 | download_url = Opts.URL_PATTERN.replace('__version__', version) | 68 | download_url = Opts.URL_PATTERN.replace('__version__', version) |
| 67 | download_url_str = Opts.URL_PATTERN.replace('__version__', '\x1b[1;33m%s\x1b[0m' % version) | 69 | download_url_str = Opts.URL_PATTERN.replace('__version__', '\x1b[1;33m%s\x1b[0m' % version) |
| 68 | print "[+] Downloading %s... " % download_url_str, | 70 | print("[+] Downloading %s... " % download_url_str, end='') |
| 71 | sys.stdout.flush() | ||
| 69 | try: | 72 | try: |
| 70 | resp = urlopen(download_url) | 73 | resp = urlopen(download_url) |
| 71 | resp_code = resp.code | 74 | resp_code = resp.code |
| @@ -73,13 +76,15 @@ def generate_whitelist(version): | |||
| 73 | dl_failed = True | 76 | dl_failed = True |
| 74 | resp_code = err.code | 77 | resp_code = err.code |
| 75 | if dl_failed or (resp_code != 200): | 78 | if dl_failed or (resp_code != 200): |
| 76 | print "\x1b[1;31mFAILED (%d)\x1b[0m" % resp_code | 79 | print("\x1b[1;31mFAILED (%d)\x1b[0m" % resp_code) |
| 77 | return None | 80 | return None |
| 78 | data = StringIO(resp.read()) | 81 | data = StringIO(resp.read()) |
| 79 | data.seek(0) | 82 | data.seek(0) |
| 80 | print "\x1b[1;32mOK\x1b[0m" | 83 | print("\x1b[1;32mOK\x1b[0m") |
| 81 | 84 | ||
| 82 | # extract archive and check against YARA signatures (in-memory) | 85 | # extract archive and check against YARA signatures (in-memory) |
| 86 | print("[-] Generating whitelist... ", end='') | ||
| 87 | sys.stdout.flush() | ||
| 83 | tar = tarfile.open(mode='r:gz', fileobj=data) | 88 | tar = tarfile.open(mode='r:gz', fileobj=data) |
| 84 | for entry in tar.getnames(): | 89 | for entry in tar.getnames(): |
| 85 | entry_fd = tar.extractfile(entry) | 90 | entry_fd = tar.extractfile(entry) |
| @@ -89,6 +94,7 @@ def generate_whitelist(version): | |||
| 89 | matches = Opts.YARA_RULES.match(data=entry_data, fast=True) | 94 | matches = Opts.YARA_RULES.match(data=entry_data, fast=True) |
| 90 | if matches: | 95 | if matches: |
| 91 | rules['/'.join(entry.split('/')[1:])] = sha1(entry_data).hexdigest() | 96 | rules['/'.join(entry.split('/')[1:])] = sha1(entry_data).hexdigest() |
| 97 | print("\x1b[1;32mDONE\x1b[0m") | ||
| 92 | 98 | ||
| 93 | return rules | 99 | return rules |
| 94 | 100 | ||
| @@ -148,6 +154,7 @@ for vmajor in range(Opts.MIN_MAJOR, Opts.MAX_MAJOR + 1): | |||
| 148 | first_ploop = False | 154 | first_ploop = False |
| 149 | 155 | ||
| 150 | # remove duplicate entries: | 156 | # remove duplicate entries: |
| 157 | print("[+] Deduplicating detections... ", end='') | ||
| 151 | known_files = [] | 158 | known_files = [] |
| 152 | for version, rules in copy(whitelists.items()): | 159 | for version, rules in copy(whitelists.items()): |
| 153 | used_rules = 0 | 160 | used_rules = 0 |
| @@ -160,7 +167,9 @@ for version, rules in copy(whitelists.items()): | |||
| 160 | used_rules += 1 | 167 | used_rules += 1 |
| 161 | if used_rules == 0: | 168 | if used_rules == 0: |
| 162 | del whitelists[version] | 169 | del whitelists[version] |
| 170 | print("\x1b[1;32mDONE\x1b[0m") | ||
| 163 | 171 | ||
| 172 | print("[+] Generating final whitelist... ", end='') | ||
| 164 | # build final rule | 173 | # build final rule |
| 165 | prefix = 8 * ' ' | 174 | prefix = 8 * ' ' |
| 166 | conditions = [] | 175 | conditions = [] |
| @@ -174,6 +183,7 @@ for index, (version, rules) in enumerate(whitelists.items()): | |||
| 174 | else: | 183 | else: |
| 175 | cond_str += '%shash.sha1(0, filesize) == "%s" or // %s\n' % (prefix, digest, filename) | 184 | cond_str += '%shash.sha1(0, filesize) == "%s" or // %s\n' % (prefix, digest, filename) |
| 176 | conditions.append(cond_str) | 185 | conditions.append(cond_str) |
| 186 | print("\x1b[1;32mDONE\x1b[0m") | ||
| 177 | 187 | ||
| 178 | final_rule = """ | 188 | final_rule = """ |
| 179 | import "hash" | 189 | import "hash" |
| @@ -191,4 +201,4 @@ private rule %(name)s | |||
| 191 | 'gendate': datetime.now().isoformat(), | 201 | 'gendate': datetime.now().isoformat(), |
| 192 | 'conditions': '\n'.join(conditions) | 202 | 'conditions': '\n'.join(conditions) |
| 193 | } | 203 | } |
| 194 | print final_rule | 204 | print(final_rule) |
