Advertisements

Monthly Archives: August 2016

discovering how Dropbox hacks your mac

Screen Shot 2016-08-26 at 23.05.27

Update: Dropbox hack blocked by Apple in Sierra

Following my post revealing Dropbox’s Dirty Little Security Hack a few weeks ago, I thought I’d look deeper into how Dropbox was getting around Apple’s security.

After a little digging around in Apple’s vast documentation, it occurred to me to check the authorization database and see if that had been tampered with. According to the docs:

In a policy-based system, a user requests authorization—the act of granting a right or privilege—to perform a privileged operation. Authorization is performed through an agent so the user doesn’t have to trust the application with a password. The agent is the user interface— operating on behalf of the Security Server—used to obtain the user’s password or other form of identification, which also ensures consistency between applications. The Security Server—a Core Services daemon in OS X that deals with authorization and authentication—determines whether no one, everyone, or only certain users may perform a privileged operation.

The list of authorization “rights” used by the system to manage this “policy based system” is held in /var/db/auth.db database, and a backup or default copy is retained in /System/Library/Security/authorization.plist.

Looking at the default with

defaults read /System/Library/Security/authorization.plist

we can find that there is an authorization right for System Preferences’ Accessibility list, which says:

"system.preferences.accessibility" = {
class = user;
comment = "Checked when making changes to the Accessibility Preferences.";
group = admin;
shared = 0;
timeout = 0;

That file’s comments also state that “The allow-root property specifies whether a right should be allowed automatically if the requesting process is running with uid == 0. This defaults to false if not specified.”

In other words, if allow-root isn’t explicitly set, the default is that even a process with root user privileges does not have the right to perform that operation. Since that’s not specified in the default shown above, then even root couldn’t add Dropbox to the list of apps in Accessibility preferences. Is it possible then, that Dropbox had overriden this setting in the auth.db? Let’s go and check!

To see what the current policies are, you have to actually read the sql database in /var/db/auth.db. There’s various ways of doing that, but the easiest for me was to access auth.db through the command line using the security tool. Issuing the following command in Terminal will return us the currently active policy for Accessibility:

security authorization read system.preferences.accessibility

On my machine, this returned:

Screen Shot 2016-08-26 at 20.57.12

Root wasn’t allowed to override Accessibility, and authenticate was on, so it couldn’t be this way that Dropbox was hacking my mac.

Security on OS X is a complex beast, however, and there are other authorization protocols at work. One that I already knew of is tccutil. If you issue man tccutil in Terminal, you’ll see this:

tccutil(1) BSD General Commands Manual tccutil(1)

NAME
tccutil — manage the privacy database

SYNOPSIS
tccutil command service

DESCRIPTION
The tccutil command manages the privacy database, which stores decisions the user has made about
whether apps may access personal data.

One command is current supported:

reset Reset all decisions for the specified service, causing apps to prompt again the next time
they access the service.

EXAMPLES
To reset all decisions about whether apps may access the address book:

tccutil reset AddressBook

Darwin April 3, 2012 Darwin
(END)

I had heard of a hack of this utility that was related directly to adding apps to Accessibility list over a year ago when I stumbled across this stackexchange page. In short, what that hack suggests is that you modify tcc directly by inserting an entry into the sql database located here /Library/Application Support/com.apple.TCC/TCC.db.

You can read the current list with the command:

sudo sqlite3 /Library/Application\ Support/com.apple.TCC/TCC.db 'select * from access'.

To insert an app in the list, you grab it’s bundle identifier (in the case of Dropbox, that’s com.getdropbox.dropbox), and issue:

sudo sqlite3 /Library/Application\ Support/com.apple.TCC/TCC.db “REPLACE INTO access VALUES(‘kTCCServiceAccessibility’,’com.getdropbox.dropbox’,0,1,1,NULL, NULL);”

(*note the code given on the stackexchange page isn’t quite correct for the latest builds of the mac operating system, in which the access table now has 7 columns and so requires and extra “NULL” on the end as shown above).

I tested this with several of my own apps and found it worked reliably. It’ll even work while System Preferences is open, which is exactly the behaviour I saw with Dropbox.

It remained to prove, though, that this was indeed the hack that Dropbox was using, and so I started to look at what exactly Dropbox did after being given an admin password on installation or launch. Using DetectX, I was able to see that Dropbox added a new folder to my /Library folder after the password was entered:

Screen Shot 2016-08-26 at 21.36.35

Screen Shot 2016-08-26 at 21.37.09

As can be seen, instead of adding something to the PrivilegedHelperTools folder as is standard behaviour for apps on the mac that need elevated privileges for one or two specialist operations, Dropbox installs its own folder containing these interesting items:

Screen Shot 2016-08-26 at 21.40.45

Not one, but three binaries! I wonder what they do? The first thing I did on each was to run the strings command on them. I still haven’t determined what that 1.5MB DropboxHelperInstaller binary is doing (that’s pretty big for a binary for a helper app), but its jam-packed with strings relating to file compression and encryption. The string output for dbfseventsd binary didn’t reveal anything much interesting, but with the deliciously named dbaccessperm file, we finally hit gold and the exact proof I was looking for that Dropbox was using a sql attack on the tcc database to circumvent Apple’s authorization policy:

Screen Shot 2016-08-26 at 23.05.27

This is all the more telling when we look at what Dropbox themselves say when queried about why their app is in the list of Accessibility apps here. After a great deal of obfuscation, misdirection and irrelevance in which they mention everything about permissions in general and nothing about Accessibility in particular, or that they’re hacking their way into the user’s Accessibility list rather than going through the supported channel of presenting the user with a dialog box and asking for permission, comes this line:

we need to request all the permissions we need or even may need in the future.
(my emphasis)

Ostensibly, that’s in the context of Drobpox on mobile apps, but since the question isn’t related to mobile apps at all, I think interpreting anything said there as being honest is naive at best. What I do suspect, especially in light of the fact that there just doesn’t seem to be any need for Dropbox to have Accessibility permissions, is that it’s in there just in case they want that access in the future. If that’s right, it suggests that Dropbox simply want to have access to anything and everything on your mac, whether it’s needed or not.

The upshot for me was that I learned a few things about how security and authorisation work on the mac that I didn’t know before investigating what Dropbox was up to. But most of all, I learned that I don’t trust Dropbox at all. Unnecessary privileges and backdooring are what I call untrustworthy behaviour and a clear breach of user trust. With Apple’s recent stance against the FBI and their commitment to privacy in general, I feel moving over to iCloud and dropping Dropbox is a far more sensible way to go for me. For those of you who are stuck with Dropbox but don’t want to allow it access to Accessibility features, you can thwart Dropbox’s hack by following my procedure here.

🙂

Further Reading:

Dropbox hack blocked by Apple in Sierra

Revealing Dropbox’s Dirty Little Security Hack

Hackers steal over 60m Dropbox user account passwords

How keyloggers get around OSX Security

 

Advertisements

make a Sierra USB bootable installer

Screen Shot 2016-08-21 at 13.06.29
For those participating in Apple’s public beta program or developer program, here’s a script that will make a bootable flash drive installer of Sierra for you. Of course, you’ll need to have downloaded and saved the original installer before running it on your mac for this to work.

When an installer is made available to you from Apple, the first thing to do after downloading it is to quit the installer if it auto runs. Insert your blank USB thumb drive, and make sure it’s at least 8GB (16GB recommended).

Screen Shot 2016-08-21 at 13.36.22

You can either run the script immediately with the installer app still in your /Applications or /Downloads folder, or you can move the installer first to your preferred location. It doesn’t make any difference to the script since it’ll ask you for the location of both the Installer and the USB drive before doing its thing. It’ll also give you an option to cancel out if you made any mistake in specifying the location or you just change your mind. The script will ask you for an administrator password as it needs elevated privileges to run the createInstallMedia routine.

Note the script continues to run in the background until the installer has been created. It sleeps for an interval of 10 secs between checking the job status. Since it takes around ten minutes for the createInstallMedia routine to finish its work, you could comfortably increase that sleep time 30 secs or more if you desire. The script will present you a dialog when it detects all is done:

Screen Shot 2016-08-21 at 13.37.32



To use the bootable installer, just pop it into a mac, reboot holding down the ‘option’ key and choose the USB drive to kick off the installation process on a partition of your choice.

The full script is available here.

Enjoy!

how to fix a ‘file in use’ problem

script


Sometimes when you try to eject a disk, unmount a volume or empty the Trash, you get caught out by some app or process that’s using the file and won’t release it. This is usually signalled by a warning dialog telling you the said file is “in use” or is “locked”.

Part of the difficulty of dealing with this problem is that the warning message may not actually tell you which process is hanging on to the file or give you any options on what to do next to solve the problem.

Sounds like a job for a quick bit of bash scripting then!

We’ll write a one-stop script that leverages a few different command line utilities to help us out here. First, our script will call fuser to report the processes using the file. Then it’ll use ps to get those processes’ ID numbers and, after asking us to confirm what we want to do, it’ll feed those to the kill command to quit them and release the file.

The whole script is available here.

To use it, save the script as a plain text file in the root of your home folder (alternatively, save it in an /sbin folder. You can do echo $PATH on the command line to get a list of places you can save it to if you’re not sure).

Secondly, give it executable permissions with

chmod +x <script name>

When the problem strikes, jump into Terminal and type

./<script name>

Add a space, then type or drag the file from Finder onto the command line and hit ‘return’ if necessary. The script will do the rest.

In the image below, I first gave my script (named ‘releaseFile’) exec permissions. Then I called it and chose ‘a’ to quit all processes holding on to the file (in this case, only one process).



fuser



Hope that helps. Enjoy! 🙂


ejecting some, all or just specified disks

Screen Shot 2016-08-03 at 13.06.32

We posted this one liner some time ago in response to the fact that you can’t actually get the Finder to eject all volumes on multiple drives at the same time.

However, I thought it’d be good to have a slightly more useful version. In this version, you can choose individual volumes or all volumes from a list. Optionally, you could also include collections.

Screen Shot 2016-08-03 at 13.36.56
Suppose for example you wanted to eject one volume from one physical drive along with one from another and two from a third? To do that, just uncomment these two lines and supply your own volume names in the collection_1 list:

--if you want to create an item that groups some volumes together uncomment the following two lines:
# set collection_1 to {"Archive 1.5TB", "BUFFALO 500GB", "This disk", "That disk", "Another disk"} -- supply as many disks names you want to group together here
# set diskList to {"All Disks", "Disk Group 1"}
Then, when you run the script, choose ‘Disk Group 1’ to eject that collection of volumes. You could of course adapt the script to include more than one collection.

You can get the full script from my pastebin here.

Enjoy! 🙂

applescript: many buttons

Screen Shot 2016-07-21 at 18.04.41



I thought I’d share some code Shane Stanley wrote in response to a question I posed on ASUsers list a few weeks back. Both Shane and myself have modified that original answer, which wasn’t directly about how to display a dialog with more than three buttons like this.

This should work on all versions of OS X / macOS from 10.10 Yosemite onwards and produce something like the screenshot above. Obviously, you’ll want to adapt the size, message and buttons to fit your own circumstances. The parts you need to edit are near the end and begin with the commented line ‘set up the paramaters…’.

The script is helpfully peppered with notes but if you get stuck, just drop a question in the Comments below.


START
use AppleScript version "2.4" -- 10.10 or later
use framework "Foundation"
use framework "AppKit"
use framework "Carbon" -- AEInteractWithUser() is in Carbon
use scripting additions
property returnCode : missing value

on showMessage:theMessage withTitle:boldBit textFrame:textFieldSize textMaxWidth:maxWidth withButtons:buttonsList
# credit to Shane Stanley for this handler
-- make attributed string system font with monospaced digits
set fontSize to current application's NSFont's systemFontSizeForControlSize:(current application's NSRegularControlSize)
set theFont to current application's NSFont's systemFontOfSize:fontSize
set attsDict to current application's NSDictionary's dictionaryWithObject:theFont forKey:(current application's NSFontAttributeName)
set attString to current application's NSAttributedString's alloc()'s initWithString:theMessage attributes:attsDict
-- make a text field to hold the message
set theField to (current application's NSTextField's alloc()'s initWithFrame:textFieldSize)
tell theField
(its setEditable:false)
(its setBordered:false)
its setDrawsBackground:false
its (cell()'s setWraps:true)
its setPreferredMaxLayoutWidth:maxWidth
its setAttributedStringValue:attString
end tell

-- make it fit; needs to be done on the main thread
my performSelectorOnMainThread:"fitToSizeView:" withObject:theField waitUntilDone:true
-- make sure we have permission
set theError to current application's AEInteractWithUser(-1, missing value, missing value) -- -1 is kAEDefaultTimeout
if theError is not 0 then error "User interaction disallowed" number theError
-- create an alert
set theAlert to current application's NSAlert's alloc()'s init()
tell theAlert
its setMessageText:boldBit
repeat with anEntry in buttonsList
(its addButtonWithTitle:anEntry)
end repeat
its setAccessoryView:theField
end tell
-- show the alert; needs to be done on the main thread
my performSelectorOnMainThread:"showTheAlert:" withObject:theAlert waitUntilDone:true
set buttonNumber to returnCode mod 1000 + 1 -- where 1 = right-most button
set buttonName to item buttonNumber of buttonsList
return buttonName
end showMessage:withTitle:textFrame:textMaxWidth:withButtons:

on showTheAlert:theAlert
# credit to Shane Stanley for this handler
-- check we are running in foreground
if not (current application's NSThread's isMainThread()) as boolean then error "This handler must be called on the main thread." from current application
set my returnCode to theAlert's runModal()
end showTheAlert:

on fitToSizeView:aView
# credit to Shane Stanley for this handler
aView's setFrameSize:(aView's fittingSize())
end fitToSizeView:

# set up the parameters for the showMessage call:
set theMessage to "How many buttons would you like? There's no real limit except for practical and aesthetic considerations." & return & "Of course, I hope you'll never really think about using something as ugly as this!" & return & return & "Choose your heart out!"
set theTitle to "Many Buttons"

# increase or decrease the second item's numbers
# to fit larger or smaller amounts of text
# the '650' here is the text field's width
# the '80' is its height
set theTextFieldSize to {{0, 0}, {650, 80}}
set buttonsToDisplay to {"OK", "Five", "Four", "Three", "Two", "One", "Cancel"}

set theButtonReturned to its showMessage:theMessage withTitle:theTitle textFrame:theTextFieldSize textMaxWidth:(650) withButtons:buttonsToDisplay
EOF



Enjoy 🙂

applescript: get item number of list item

Screen Shot 2016-07-31 at 21.45.31

One of the annoying ‘missing features’ in AppleScript is the lack of any way to get the item number of an item in a list.

Fortunately, since Cocoa does of course include an ‘indexOfObject’ function, we can leverage Cocoa in our AppleScript to write a nice little handler (you could add this to my list and string handlers library I posted here or just add it directly in your own scripts).

First, make sure your script or library already has two lines like these to import the Foundation framework and declare an NSArray:

use framework "Foundation"

property NSArray : a reference to current application's NSArray

Then after that add the handler:

on getIndexOfItem:anItem inList:aList
set anArray to NSArray's arrayWithArray:aList
set ind to ((anArray's indexOfObject:anItem) as number) + 1 # see note below
if ind is greater than (count of aList) then
display dialog "Item '" & anItem & "' not found in list." buttons "OK" default button "OK" with icon 2 with title "Error"
return 0
else
return ind
end if
end getIndexOfItem:inList:

You can now call the code like this:

# example
set thisList to {"I", "see", "a", "red", "door", "and", "I", "want", "to", "paint", "it", "black"}
set aNum to its getIndexOfItem:"paint" inList:thisList
(* Result --> 10 *)
if aNum is not 0 then
-- do something
end if

# Note: Remember AppleScript lists are indexed from 1, unlike Cocoa arrays which start at index 0.

Enjoy! 🙂

Hack That Mac 2: Bash & Root

applescript: how to rant on Twitter

Screen Shot 2016-07-27 at 16.07.19
Well, hopefully you won’t…but if you wanted to post something longer than the 142 character limit without manually having to break it all up, this script will do it for you.

All you do is set the ‘tweetRant’ variable to whatever missive of massive importance you want to convey, and run the script. It’ll break your text into tweet-sized strings, add ellipses to them where appropriate and post them in 10-second intervals.

Of course, using this for spamming would likely not win you many friends…and besides, it’s not the only way to abuse Twitter’s 142 rule.:p

A more responsible use would be to adapt this script to create your own kind of Buffer service. You’d need to add scheduling via Calendar or a launch agent to do that, a subject we’ll tackle in an upcoming post.

Download the script from my pastebin…

Enjoy! 🙂

%d bloggers like this: