FlockFlock - file access policy enforcement by Jonathan Zdziarski This project is currently UNDER DEVELOPMENT and ALPHA VERSION. USE AT YOUR OWN RISK! NOTE: I have applied for a kext signing certificate from Apple. Without one, FlockFlock only works with SIP's kext checking turned off on the host machine, therefore FlockFlock should be used only for testing until Apple provides a cert. WHY FLOCKFLOCK EXISTS One of the worst parts about being compromised is not knowing you're compromised, and having your data stolen by spyware, or hijacked by ransomware, only to find out about it too late. Most security researchers aren't even 100% positive that their system hasn't been compromised. Between spyware, ransomware, trojanized or misbehaving applications, nation state hacking, and other threats, simply relying on file permissions and a secure execution environment no longer cuts it. FlockFlock fills the need for a solution that can keep your personal data protected from potentially malicious software that has rooted your system, or to monitor applications that you have to have installed, but don't necessarily trust. WHAT IS FLOCKFLOCK? In Simple Terms: FlockFlock is a utility to help protect your personal files in macOS, to be able to tell if your system has been compromised, to ensure your applications are respecting your privacy, and to defend your personal data against ransomware, spyware, infection, and other threats by preventing unauthorized processes (even by super user processes) from being able to open, read, or destroy your personal files without your explicit permission. In short, FlockFlock is like the popular "Little Snitch" program, but for file access instead of network connections. It integrates with the operating system on a low level, and has capabilities higher than root. For Developers: FlockFlock is a programmable macOS kernel extension that enforces file access and modification policies using macOS's kernel-level MAC (mandatory access control) framework. The MAC framework began in TrustedBSD and was later adopted into the Darwin kernel; it's used by Apple to perform a number of tasks related to sandboxing on macOS and iOS. It lets FlockFlock intercept every file open/write/delete/rename call on the system and analyze it against a set of rules programmed into the kernel at boot time. Even if an attacker gets root on your system, the kernel module continues to enforce the user's rules, and even attempts to persist FlockFlock from being unloaded, deleted, or its helper daemon killed. FlockFlock comes in three pieces: the kernel extension, which contains a live copy of all active rules (so that a rooted device should not be able to disable it), a helper daemon that programs it at boot time and prompts the user for new access entitlements, and a user space client, which provides basic status via a status bar menu, and a way to disable FlockFlock from the GUI for upgrades. Per-user rules are stored, and can be edited (with the proper access entitlements) by the user. FlockFlock is also open source, because there is such a lack of good driver and kernel code for Mac. I think you'll find FlockFlock to be very useful in developing your own kernel-mode drivers. FlockFlock is an IOKit based driver, and the source code should help you understand complex concepts such as mach messages, user-space client communication, driver contruction, memory and locking, and much more. Enjoy the knowledge! WHY THE STUPID NAME? It's a play on words with the old unix "flock" style advisory locking combined with a hat tip to Patrick Wardle, author of BlockBlock, which is a different type of system integrity protection tool you should also be using. NOTE: FlockFlock's locking is much more advanced than the flocks of olde, it's just a play on words, and does not rely on (or use) flocks. FEATURES - Real-time, kernel-level protection against unauthorized access to files - Defend against ransomware, spyware, trojanized applications, or other malicious programs that might attempt to steal, encrypt, or destroy your personal files - Monitor applications to ensure they aren’t misbehaving, and are respecting your personal privacy in accessing your data files. - A user-friendly interface to add new rules and receive notifications of unauthorized access attempts. - Persistence; protects itself against root processes from unloading the kernel extension, tampering with core files, or manipulating the user's rules. * This feature has been disabled in alpha versions for testing INSTALLATION NOTE: Until Apple provides me with a kext signing certificate, you will have to disable SIP's kext checks in order to use FlockFlock, but can leave the rest of SIP on. This slightly compromises the security of macOS, so I only recommend using FlockFlock for testing until Apple cuts a kext signing cert for me. Reboot your computer into "Recovery Mode" by rebooting and holding in Command-R after the chime, until it boots to the recovery partition. Start a Terminal (Utilities->Terminal) and type: csrutil enable --without kext; reboot After your system reboots, double click the FlockFlock.pkg file and follow the installation process. A reboot will be required after installation. FIRST RUN When the system comes back up, FlockFlock should be active on your system, and you should start being prompted to grant file access permissions to various programs you might run. When first running your favorite applications for the first time, you'll be prompted to allow or deny access to specific files or folders. This allows you to set up initial access rules. FlockFlock will remember your choices so it won't bother you again, unless you check the box "Forget after Restart". At first, you may get a lot of requests, one after the other; take a look at the directory path dropdown and choose the best paths to allow each application. For example, if an application is trying to access a file inside of its cache folder, you'll probably want to give it permanent access to its entire cache folder, rather than just that one file, so you're not nagged again by requests for files in that folder. RULES EDITING For manual rules editing, edit the .flockflockrc file in your home directory. You will need to reboot in order for the changes to take effect, since they are programmed directly into the kernel. NOTE: You'll need to temporarily disable FlockFlock to save your rules file. REMOVAL Disable FlockFlock from the status bar, and then run the uninstall.sh script provided, then reboot. PERSISTENCE FlockFlock's kernel module prevents deletion or overwriting of core files. Any attempt to unload the kernel extension, except through recovery mode, will cause a kernel panic and subsequent reboot. Its data files and core files are protected from modification, and its processes are protected from being killed. The goal of FlockFlock's persistence routines are to provide a protected execution environment for FlockFlock to the point where one would need to gain kernel-level code execution to disable it, and malware that can gain kernel privileges would need to attack FlockFlock. At that point, you've got bigger problems... but it certainly does up the ante for malware. The user interface has a convenient menu option to disable FlockFlock so that it can be removed or upgraded without booting into recovery mode. This requires user interaction, providing a reasonable compromise between security and usability. NOTE: Persistence is disabled for alpha versions, except for specific builds labeled "persistence"; however, these builds will still allow the kernel module to be unloaded in the event of a problem. It will, however notify the user. DISABLING PERSISTENCE To disable persistence, allowing for upgrades or removal, simply select "Disable FlockFlock" from the FlockFlock status bar menu. This is the preferred way to disable it, and allows for easy upgrades. As always is the case with alpha/beta software, things can go wrong, so I've left the ability to unload the kernel module open in all alpha persistence builds, so you won't have to go into recovery mode (usually) to remove or change the software is something goes wrong. If you find things are bogging down or experiencing other problems, and you can't get to the FlockFlock menu to disable it, you can do the following: sudo kextunload /Library/Extensions/FlockFlock.kext launchctl unload /Library/LaunchAgents/com.zdziarski.FlockFlockUserAgent.plist sudo launchctl unload /Library/LaunchDaemons/com.zdziarski.FlockFlockDaemon.plist sudo kextunload /Library/Extensions/FlockFlock.kext You'll unload the kext twice, once to disengage the operational hooks, and a second time to disengage persistence after you've shut down the daemon and agent. The first will give you an error that it can't unload the kext, because of the agents, however it will have stopped the operational part of the code. If all else fails, use recovery mode to delete the kext from /Library/Extensions/FlockFlock.kext. I don't expect even an alpha should ever come to that, though. COMPATIBILITY Tested With: El Capitan Sierra Beta 3, 4, 5 NOTE: THIS SOFTWARE IS ALPHA SOFTWARE AND MAY HAVE BUGS KNOWN BUGS - Please send me bug reports FUTURE PLANS - Implement a rules editing tool in user-space and give it exclusive editing capabilities (to avoid having to boot into recovery mode) - Implement activity logging - Richer popup screen to support more configurations - A simple mode for novice users FAQ - What does this protect? The default ruleset protects files in /Users only, although this can be changed. If FlockFlock tried to block on every file acccess in the system, everything would come to a screeching halt. - Does this impact performance? When an application attempts to access a protected file, FlockFlock performs a policy lookup. The lookup is generally fast, and should not impact performance except possibly on extremely busy systems that are opening a lot of files in the background. - Where performance is impacted is the quarantine during a user prompt. If FlockFlock decides the user must approve the file access, then the program is blocked on the file access until the user responds. This, obviously, is the behavior you want, but if you let the prompt sit there forever, you'll end up getting a backlog of prompts to answer, which can become a bottleneck for you. It could possibly also make some programs malfunction, such as those that are waiting for a file to open and let a network connection time out due to being blocked. ACKNOWLEDGMENTS Thanks to Patrick Wardle for providing some initial code to peruse on the MAC framework and his blog posts on pid task tracking. CHANGELOG 0.0.1 Initial alpha release 0.0.2 Temporarily disable persistence mechanisms for alpha testing Break lock if driver disconnects Truncated /Application apps to their .app container Resolved issued with duplicate queries Reduced the sleep time between waiting for policy lock Re-checked policy list before sending blocked queries 0.0.3 Added radio buttons for choosing "Once", "Until Restart", and "Forever" 0.0.4 Fixed issues with OSDictionary, replaced with custom structure 0.0.5 Implemented KAuth to replace vnode_check_exec hooks Added process hierarchy (e.g. "/bin/sh via Xcode") Improvements to locking and memory allocation Significant code cleanup Added keychain files to default ruleset, as many apps use it Other various improvements Hopefully added (some) stability for Sierra 0.0.6 Added MAC hooking to detect and associate posix spawned procs Cleanup temporary tables in memory Added "Until Quit" option, made the default Added application icon to user prompt 0.0.7 Fixed a crash in the user agent when adding "Any Files" Stability improvements for Sierra 0.0.8 Fixed a bug that led to a kernel panic 0.0.9 Manicured display names for the user Improvements to finding the application path icon Fixed a bug that caused a crash in the user agent Incorporated master userspace/kernel security protocol Fixed a bug causing ~/Library/LaunchAgents to not get creaetd 0.0.10 Don't blow up the agent on unicode filenames Rolled agent into an app with status bar icon for enable/disable 0.0.11 Fixed packaging issues and macOS relocation, etc Made small change to help hide agent from dock better Nicer icon for the status bar 0.0.12 Treat /Library/Application Support/FlockFlock/.flockflockrc as a a system-wide configuration file, append to ~/.flockflockrc Support $HOME in rules for current home directory Deny driver connection attempts by root (userland only) Don't start filter until initial programming is complete 0.0.13 Fixed a bug causing certain background tasks to not be tracked 0.0.14 Cleanup from 0.0.13 and ppid full path tracking 0.0.15 Various tweaks 0.0.16 Completely reworked process tracking and it's awesome 0.0.17 Further improvements to process tracking 0.0.18 Added persistence hook for mpo_vnode_check_rename In addition to read access, added write access protection for all protected files; apps can work with files they've created, but cannot modify protected files without user consent Code cleanup and commenting Removed significant logging overhead 0.0.19 Added FlockFlockDaemon, moved load-time and policy code into it Tweaks to persistence 0.0.20 More improvements to persistence and stability Fixed some locking issues in persistence mode 0.0.21 Put kauth loop into a separate thread to get path before check_oper 0.0.22 Improved spawn tracking, trimmed display name of .app packages Turned off heavy debug logging for performance 0.0.23 Fixed issues with freezing due to not recognizing daemon as friendly 0.0.24 Added missing persistence hook mpo_vnode_check_rename_to 0.0.25 Changed "allow!" rule to "watch" to indicate a watched folder Added support for separation of operations (read, write create) Added file operations (rwc) to .flockflockrc NOTE: UI still grants either all or none to make it easy for user 0.0.26 Modified open hook to eval persistence and write rules for O_TRUNC Removed persistence for user .flockflockrc files, which are instead protected with a user prompt 0.0.27 Moved housekeeping to separate timed thread to improve performance 0.0.28* Reworked display name and icon presentation and attribution Decided not to consolidate all sub-binaries in an .app folder if the executable matches CFBundleExecutable, it's attributed to the .app, otherwise, it's considered a standalone binary this may lead to more noise, but also better malware identification and granularity in rules composition 0.0.29 Minor hacks for posix_spawn detection Added codesign verify to daemon; if binary is correctly signed, will use the .app package's icon; otherwise will use the generic executable icon (unless it's the CFBundleExecutable, then we'll use the icon regardless). The codesign status is also displayed to the user in the dialog