-
-
Save sheagcraig/69a473f00ce434fffd5b to your computer and use it in GitHub Desktop.
#!/usr/bin/python | |
"""Identify or remove files known to be involved in Adware/Malware | |
infection. | |
Most of the code applies to building a list of malware files. Thus, | |
both extension attribute and removal handling are included. | |
Cleans files as a Casper script policy; thus, it expects four total | |
arguments, the first three of which it doesn't use, followed by | |
--remove | |
""" | |
import glob | |
import os | |
import re | |
import shutil | |
import sys | |
import syslog | |
# https://support.apple.com/en-us/ht203987 | |
known_malware = { | |
'/System/Library/Frameworks/v.framework', | |
'/System/Library/Frameworks/VSearch.framework', | |
'/Library/PrivilegedHelperTools/Jack', | |
'/Library/InputManagers/CTLoader/', | |
'/Library/Application Support/Conduit/', | |
'/Applications/SearchProtect.app', | |
'/private/etc/launchd.conf', | |
'/Applications/Genieo', | |
'/Applications/InstallMac', | |
'/Applications/Uninstall Genieo', | |
'/Applications/Uninstall IM Completer.app', | |
'/usr/lib/libgenkit.dylib', | |
'/usr/lib/libgenkitsa.dylib', | |
'/usr/lib/libimckit.dylib', | |
'/usr/lib/libimckitsa.dylib', | |
'/Library/PrivilegedHelperTools/com.genieoinnovation.macextension.client', | |
'/Library/Frameworks/GenieoExtra.framework', | |
'/Library/LaunchAgents/com.genieo.completer.update.plist', | |
'/Library/LaunchAgents/com.genieo.engine.plist', | |
'/Library/LaunchAgents/com.genieoinnovation.macextension.client.plist', | |
'/Library/LaunchAgents/com.genieoinnovation.macextension.plist', | |
'/Library/LaunchDaemons/com.genieoinnovation.macextension.client.plist', | |
'/Library/LaunchDaemons/Jack.plist' | |
'/Users/*/Library/Internet Plug-Ins/ConduitNPAPIPlugin.plugin', | |
'/Users/*/Library/Internet Plug-Ins/TroviNPAPIPlugin.plugin', | |
'/Users/*/Library/Application Support/Genieo/', | |
'/Users/*/Library/Application Support/com.genieoinnovation.Installer/', | |
'/Users/*/Conduit/', | |
'/Users/*/Trovi/', | |
'/Users/*/Library/Caches/com.Conduit.takeOverSearchAssetsMac', | |
'/Users/*/Library/Caches/com.VSearch.bulk.installer', | |
'/Users/*/Library/Caches/com.VSearch.VSinstaller', | |
'/Users/*/Library/LaunchAgents/com.genieo.completer.download.plist', | |
'/Users/*/Library/LaunchAgents/com.genieo.completer.ltvbit.plist', | |
'/Users/*/Library/LaunchAgents/com.genieo.completer.update.plist', | |
'/Users/*/Library/Preferences/com.genieo.global.settings.plist.lockfile', | |
'/Users/*/Library/Preferences/com.geneio.settings.plist.lockfile', | |
'/Users/*/Library/Preferences/com.geneio.global.settings.plist', | |
'/Users/*/Library/Saved Application State/com.genieo.RemoveGenieoMac.savedState', | |
'/Users/*/Library/Saved Application State/com.VSearch.bulk.installer.savedstate', | |
'/Users/*/Library/LaunchAgents/com.jdibackup.ZipCloud.autostart.plist'} | |
found_malware = {match for filename in known_malware for match in | |
glob.glob(filename)} | |
# Look for "ProjectX" variants. | |
# This adware seems to have a different name each time it pops up. | |
# Apple's solution is too broad. We look at the files Apple suggests, | |
# but then also search within to see if they are calling a known | |
# binary file, "agent.app/Contents/MacOS/agent". | |
projectx_files = { | |
'/Library/LaunchAgents/com.*.agent.plist', | |
'/Library/LaunchDaemons/com.*.helper.plist', | |
'/Library/LaunchDaemons/com.*.daemon.plist', | |
} | |
projectx_candidates = {match for filename in projectx_files for match in | |
glob.glob(filename)} | |
agent_regex = re.compile('.*/Library/Application Support/(.*)/Agent/agent.app/Contents/MacOS/agent') | |
for candidate in projectx_candidates: | |
with open(candidate, 'r') as candidate_file: | |
launchd_job = candidate_file.read() | |
if re.search(agent_regex, launchd_job): | |
found_malware.add(candidate) | |
# If we find a Launch[Agent|Daemon] that has ProgramArguments | |
# which runs "agent", find the unique name for this instance. | |
# We can then use it to find the Application Support folder. | |
obfuscated_name = re.search(agent_regex, launchd_job).group(1) | |
found_malware.add('/Library/Application Support/%s' % obfuscated_name) | |
# Is this an EA or a script execution (Casper scripts always have 3 | |
# args, so we can't just use the first argument. | |
if len(sys.argv) == 1: | |
# Extension attribute (First arg is always script name). | |
result = '<result>' | |
if found_malware: | |
result += 'True\n' | |
for item in enumerate(found_malware): | |
result += "%d: %s\n" % item | |
else: | |
result += 'False' | |
print('%s</result>' % result) | |
elif "--remove" in sys.argv: | |
# Removal script. | |
syslog.syslog(syslog.LOG_ALERT, "Looking for malware") | |
for item in found_malware: | |
try: | |
if os.path.isdir(item): | |
shutil.rmtree(item) | |
elif os.path.isfile(item): | |
os.remove(item) | |
syslog.syslog(syslog.LOG_ALERT, "Removed malware file: %s" % item) | |
except OSError as e: | |
syslog.syslog(syslog.LOG_ALERT, | |
"Failed to remove malware file: %s, %s" % (item, e)) |
uh, and I think you're missing from re import match
?
Oh thanks! Was going to dig out your other gists for the MacKeeper stuff. Does it install any frameworks/binaries anywhere else?
match
is not a builtin or reserved, so the match above is just a temporary variable name, not re.match
.
I found a few machines with these:
/Applications/SearchProtect/Data
/Applications/SearchProtect/SearchProtect.app
/Applications/SearchProtect/Uninstaller.app
/Applications/SearchProtect/takeOverSearchAssetsMac.app
I installed Genieo fresh this morning and they've changed some of the files in use. This is going to be a moving target :/
/Users/*/Library/Application Support/IM.Installer/
/Users/*/Library/LaunchAgents/com.Installer.completer.download.plist
/Users/*/Library/LaunchAgents/com.Installer.completer.ltvbit.plist
/Users/*/Library/LaunchAgents/com.Installer.completer.update.plist
/Users/*/Library/Preferences/com.genieo.settings.plist
/Users/*/Library/Preferences/com.IM.partner.settings.plist
/Users/*/Library/Preferences/com.installmc.global.settings.plist
/Users/*/Library/Preferences/com.installmc.settings.plist
Just installed MacKeeper and it's now /Users//Library/LaunchAgents/com.mackeeper.MacKeeper.Helper.plist
Also Spigot installs a Safari extension here: /Users//Library/Safari/Extensions/Searchme.safariextz
Hey Shea, I found that this is still missing quite a bit of adware. I modified your version with more definitions and added a section so it will delete chrome and firefox preferences files if adware is found.
Not sure how to post the code properly so here ya go.
!/usr/bin/python
"""Identify or remove files known to be involved in Adware/Malware
infection.
Most of the code applies to building a list of malware files. Thus,
both extension attribute and removal handling are included.
Cleans files as a Casper script policy; thus, it expects four total
arguments, the first three of which it doesn't use, followed by
--remove
"""
import glob
import os
import re
import shutil
import sys
import syslog
known_malware = {
#SearchMe
'/Users//Library/Safari/Extensions/Searchme.safariextz',
#ZipCloud
'/Users/*/Library/LaunchAgents/com.jdibackup.ZipCloud.autostart.plist',
#MacKeeper
'/Users/*/Library/LaunchAgents/com.zeobit.MacKeeper.Helper.plist',
'/Users/*/Library/Preferences/com.installmc.global.settings.plist',
'/Users/*/Library/Preferences/com.installmc.settings.plist',
'/Users//Library/LaunchAgents/com.mackeeper.MacKeeper.Helper.plist',
#VSearch
'/Users/*/Library/Caches/com.VSearch.bulk.installer',
'/Users/*/Library/Caches/com.VSearch.VSinstaller',
'/Users/*/Library/Saved Application State/com.VSearch.bulk.installer.savedstate',
#IM Installer
'/Users/*/Library/Application Support/IM.Installer/',
'/Users/*/Library/Preferences/com.IM.partner.settings.plist',
#Installer Completer
'/Users/*/Library/LaunchAgents/com.Installer.completer.download.plist',
'/Users/*/Library/LaunchAgents/com.Installer.completer.ltvbit.plist',
'/Users/*/Library/LaunchAgents/com.Installer.completer.update.plist',
# FkCodec
'/Users/*/Library/Application Support/Codec-M',
'/Users/*/Library/LaunchAgents/com.codecm.uploader.plist',
'/Applications/Codec-M.app',
#Yontoo
'/Users/*/Library/Application Support/Google/Chrome/YontooLayers.crx',
#ChatZum
'/Applications/ChatZumUninstaller.pkg',
'/Library/Application Support/SIMBL/Plugins/SafariOmnibar.bundle',
'/Library/Internet Plug-Ins/uid.plist',
'/Library/Internet Plug-Ins/zako.plugin',
#Spigot
'/Users/*/Library/Application Support/Spigot/',
#SaveKeep
'/Applications/Savekeep.app',
#Conduit
'/Users/*/Library/Application Support/Google/Chrome/Default/Extensions/cbmjmfcldbpelhknnfjbkobmabafpoed',
'/Library/InputManagers/CTLoader/',
'/Library/LaunchAgents/com.conduit.loader.agent.plist',
'/Library/LaunchDaemons/com.perion.searchprotectd.plist',
'/Library/Application Support/SIMBL/Plugins/CT2285220.bundle',
'/Library/Application Support/Conduit/',
'/Applications/SearchProtect.app',
'/Applications/SearchProtect/',
'/Users/*/Conduit/',
'/Users/*/Trovi/',
'/Users/*/Library/Application Support/Conduit',
'/Users/*/Library/Internet Plug-Ins/ConduitNPAPIPlugin.plugin',
'/Users/*/Library/Internet Plug-Ins/TroviNPAPIPlugin.plugin',
'/Users/*/Library/Application Support/Firefox/searchplugins/MyBrand.xml',
'/Users/*/Library/Application Support/Firefox/searchplugins/conduit.xml',
'/Users/*/Library/Application Support/Firefox/searchplugins/"Conduit Customized Web Search".xml',
'/Users/*/Library/Application Support/Firefox/takeOverNewTab.txt',
'/Users/*/Library/Application Support/Firefox/abstraction.js',
'/Users/*/Library/Caches/com.Conduit.takeOverSearchAssetsMac',
#Downlite
'/Library/Application Support/VSearch',
'/Library/LaunchAgents/com.vsearch.agent.plist',
'/Library/LaunchDaemons/com.vsearch.daemon.plist',
'/Library/LaunchDaemons/com.vsearch.helper.plist',
'/Library/LaunchDaemons/Jack.plist',
'/Library/PrivilegedHelperTools/Jack',
'/System/Library/Frameworks/VSearch.framework',
'/System/Library/Frameworks/v.framework',
#SearchProtect
'/Applications/SearchProtect/Data',
'/Applications/SearchProtect/SearchProtect.app',
'/Applications/SearchProtect/Uninstaller.app',
'/Applications/SearchProtect/takeOverSearchAssetsMac.app',
#GoPhoto
'/Users/*/Library/Application Support/Google/Chrome/External Extensions/ccfjbdjailljfihgkoccfbiljjapiijb.json',
#Genieo
'/Users/*/Library/LaunchAgents/com.genieo.completer.download.plist',
'/Users/*/Library/LaunchAgents/com.genieo.completer.update.plist',
'/Users/*/Library/LaunchAgents/com.genieo.completer.ltvbit.plist',
'/Library/LaunchAgents/com.genieoinnovation.macextension.plist',
'/Library/LaunchAgents/com.genieoinnovation.macextension.client.plist',
'/Library/LaunchAgents/com.genieo.engine.plist',
'/Library/LaunchAgents/com.genieo.completer.update.plist',
'/Library/LaunchDaemons/com.genieoinnovation.macextension.client.plist',
'/Applications/Genieo',
'/Applications/Genieo.app',
'/Applications/InstallMac',
'/Applications/InstallMac.app',
'/Applications/InstallGenieo',
'/Applications/InstallGenieo.app',
'/Applications/Reset Search',
'/Applications/Reset Search.app',
'/Applications/Uninstall Genieo',
'/Applications/Uninstall Genieo.app',
'/Applications/Uninstall IM Completer',
'/Applications/Uninstall IM Completer.app',
'/Users/*/Library/Application Support/com.genieoinnovation.Installer',
'/Users/*/Library/Application Support/Genieo',
'/Library/PrivilegedHelperTools/com.genieoinnovation.macextension.client',
'/Library/Frameworks/GenieoExtra.framework',
'/Users/*/Library/Application Support/Firefox/searchplugins/my-homepage.xml',
'/Users/*/Library/Application Support/Genieo/',
'/Users/*/Library/Application Support/com.genieoinnovation.Installer/',
'/Users/*/Library/Preferences/com.genieo.global.settings.plist.lockfile',
'/Users/*/Library/Preferences/com.geneio.settings.plist.lockfile',
'/Users/*/Library/Preferences/com.geneio.global.settings.plist',
'/Users/*/Library/Saved Application State/com.genieo.RemoveGenieoMac.savedState',
'/Users/*/Library/Preferences/com.genieo.settings.plist',
'/private/etc/launchd.conf',
'/usr/lib/libgenkit.dylib',
'/usr/lib/libgenkitsa.dylib',
'/usr/lib/libimckit.dylib',
'/usr/lib/libimckitsa.dylib',
#Vidx/MacVX
'/Applications/Vidx.app',
'/Library/Safari/Extensions/extension.safariextz',
#Best Youtube Downloader
'/Users/*/Library/LaunchAgents/com.moeppfdpoohhdcaefbfpmabjipnohiif.updater.plist',
'/Users/*/Library/Application Support/Google/Chrome/External Extensions/phpdijfdkggndfmgcfdhcimlflflnega.json',
'/Users/*/Library/LaunchAgents/Safari Security',
'/Users/*/Library/LaunchAgents/WebSocketServerApp',
'/Users/*/Library/LaunchAgents/com.webtools.update.agent.plist',
'/Users/*/Library/Application Support/webHelperApp/',
'/Users/*/Library/WebTools/',
#PremierOpinion
'/Applications/PremierOpinion',
'/Library/LaunchDaemons/PremierOpinion.plist',
}
found_malware = {match for filename in known_malware for match in
glob.glob(filename)}
settings_files = {
'/Users//Library/Application Support/Google/Chrome/Default/Preferences',
'/Users//Library/Application Support/Firefox/user.js',
'/Users/*/Library/Application Support/Firefox/prefs.js',
}
active_settings = {match for filename in settings_files for match in
glob.glob(filename)}
Look for "ProjectX" variants.
This adware seems to have a different name each time it pops up.
Apple's solution is too broad. We look at the files Apple suggests,
but then also search within to see if they are calling a known
binary file, "agent.app/Contents/MacOS/agent".
projectx_files = {
'/Library/LaunchAgents/com..agent.plist',
'/Library/LaunchDaemons/com..helper.plist',
'/Library/LaunchDaemons/com.*.daemon.plist',
}
projectx_candidates = {match for filename in projectx_files for match in
glob.glob(filename)}
agent_regex = re.compile('./Library/Application Support/(.)/Agent/agent.app/Contents/MacOS/agent')
for candidate in projectx_candidates:
with open(candidate, 'r') as candidate_file:
launchd_job = candidate_file.read()
if re.search(agent_regex, launchd_job):
found_malware.add(candidate)
# If we find a Launch[Agent|Daemon] that has ProgramArguments
# which runs "agent", find the unique name for this instance.
# We can then use it to find the Application Support folder.
obfuscated_name = re.search(agent_regex, launchd_job).group(1)
found_malware.add('/Library/Application Support/%s' % obfuscated_name)
Is this an EA or a script execution (Casper scripts always have 3
args, so we can't just use the first argument.
if len(sys.argv) == 1:
# Extension attribute (First arg is always script name).
result = ''
if found_malware:
result += 'True\n'
for item in enumerate(found_malware):
result += "%d: %s\n" % item
else:
result += 'False'
print('%s</result>' % result)
elif "--remove" in sys.argv:
# Removal script.
syslog.syslog(syslog.LOG_ALERT, "Looking for malware")
for item in found_malware:
try:
if os.path.isdir(item):
shutil.rmtree(item)
elif os.path.isfile(item):
os.remove(item)
syslog.syslog(syslog.LOG_ALERT, "Removed malware file: %s" % item)
except OSError as e:
syslog.syslog(syslog.LOG_ALERT,
"Failed to remove malware file: %s, %s" % (item, e))
syslog.syslog(syslog.LOG_ALERT, "Looking for settings files")
for item in active_settings:
try:
if os.path.isdir(item):
shutil.rmtree(item)
elif os.path.isfile(item):
os.remove(item)
syslog.syslog(syslog.LOG_ALERT, "Removed setting file file: %s" % item)
except OSError as e:
syslog.syslog(syslog.LOG_ALERT,
"Failed to remove settings file: %s, %s" % (item, e))
Just for the record I want to state that the above contributions include software not considered malware or adware, but just undesirable to admins in an enterprise environment.
They missed at least another two: