2

In Objective C, how do I get a checksum for an OSX folder and its contents (which may also have several subfolders)? Preferably, I'd like to get the sha512 value.

In Bash, I can do this like so:

find /tmp/examplefolder -type f -print | xargs cat | shasum -a 512

...however, one can replace the shasum command with their own version and undo what I'm trying to do.

BACKGROUND:

I'm using the native OSX webkit widget for the GUI of my OSX application. This pulls from file:// out of a folder called MyApp.app/Resources/html. To resist some virus maliciously hacking MyApp.app, I plan to have an info.plist with a sha512 value in it (that will be encrypted of course). When the application boots, it will calculate the sha512 value of MyApp.app/Resources/html, then encrypt it in the same way as my info.plist value, and then compare the two values to see if they are identical. If not, then the application has been compromised. I'll alert the user with a dialog box and shut down the application.

Questions Answered

Q1. Won't it have to be encrypted in some way to prevent tampering with the saved value in Info.plist? – mipadi

A1. Yes, before storing in Info.plist, it will be encrypted. I said that above. I can handle the encryption step using the Crypto library.

Q2. Files in the app (resource directory) do not have write permissions. If you encrypt to where will you save the encryption key? – zaph

A2. At the time of compilation, in the compilation steps, I will have a Bash script calculate the sha512 checksum, encrypt it, and update the Info.plist.

Q3. If files in the application can't be written to, what's the point of the checksum at all? – mipadi

A3. My application won't write back to the Resources/html folder. It will store session state using the typical user settings strategy that Apple encourages for all applications. Instead, what I fear is a virus that infects the Resources/html folder, replacing it with bad stuff, and causes the application to appear to be normal but is doing something harmful in the background. This is where the checksum can help -- it can help prevent tampering after application installation.

Q4. I assumed the asker was not using code signing (for some reason), since code signing does already cover this. – mipadi

A4. If you're asking why I don't just rely on code signing -- it's because after the application is marked as trusted, the virus can get into the Resources/html folder and cause havoc. This is why I need the checksum mechanism on application boot.

Volomike
  • 23,743
  • 21
  • 113
  • 209
  • Calculating the shasum of the file will be sufficient. And this stack answer probably covers what you are trying to do: http://stackoverflow.com/questions/6228092/how-can-i-compute-a-sha-2-ideally-sha-256-or-sha-512-hash-in-ios – Cliff Ribaudo Jan 27 '16 at 16:48
  • @CliffRibaudo I need this on all the files in the folder, not just one file. Is there a routine to do this recursively? – Volomike Jan 27 '16 at 17:09
  • Is your application bundle signed (using the `codesign` tool)? – mipadi Jan 27 '16 at 19:29
  • It will eventually, yes. The problem is that a virus can still change the contents of the folder after the fact. – Volomike Jan 27 '16 at 20:02

1 Answers1

1

You could use the FileManager method:

- (NSDirectoryEnumerator<NSURL *> *)enumeratorAtURL:(NSURL *)url includingPropertiesForKeys:(NSArray<NSString *> *)keys options:(NSDirectoryEnumerationOptions)mask errorHandler:(BOOL (^)(NSURL *url, NSError *error))handler

See the Apple documentation for example code.
or

- (NSArray<NSString *> *)subpathsOfDirectoryAtPath:(NSString *)path error:(NSError *)error

to enumerator all files in the path.

Create a SHA512 instance with Common Crypto function:

CC_SHA512_Init(CC_SHA256_CTX *c)

for each file enumerated update:

CC_SHA512_Update(CC_SHA256_CTX *c, const void *data, CC_LONG len)

complete with:

CC_SHA512_Final(unsigned char *md, CC_SHA256_CTX *c)

There is no need to encrypt the SHA512 output since SHA is a one-way function.

zaph
  • 111,848
  • 21
  • 189
  • 228
  • Won't it have to be encrypted in some way to prevent tampering with the saved value in `Info.plist`? – mipadi Jan 27 '16 at 18:00
  • Files in the app (resource directory) do not have write permissions. If you encrypt to where will you save the encryption key? – zaph Jan 27 '16 at 18:02
  • If files in the application can't be written to, what's the point of the checksum at all? – mipadi Jan 27 '16 at 18:24
  • I assumed the asker was not using code signing (for some reason), since code signing does already cover this. – mipadi Jan 27 '16 at 19:29
  • I'll answer some questions in a minute in my original question. – Volomike Jan 27 '16 at 20:03
  • Encryption is necessary because all the virus has to do is infect the directory, recalculate the sha512, store it in the Info.plist, and the application would think everything was okay. By encrypting it, the virus can't figure out how to make the proper value. – Volomike Jan 27 '16 at 20:12
  • I also wonder if this is the best strategy. One strategy would be to zip the html folder, validate the unharmed zip on boot, and, if good, unzip and then load the application from that. Would that run faster or slower? I mean, I only have a handful of files here for the application -- HTML, CSS, and JS files. – Volomike Jan 27 '16 at 20:20
  • @Volomike Why do you think an attacker/virus can't figure out the encryption? If it already knows so much about your app, encryption of the hash is only one step further. The key for encryption has to be contained in the app, somehow. – Nikolai Ruhe Jan 27 '16 at 20:23
  • Do you realize how many decades it would take to figure out the encryption with the toughest encryption algo in the Crypto library, using an extremely long salt and password? Plus, the salt and password are themselves encrypted, and I've done some clever obfuscation such that the UNIX `strings` command can't be used to find it. – Volomike Jan 27 '16 at 20:43
  • An attacker will examine the app while it is running and see the key being used. Protecting from the owner is virtually impossible. – zaph Jan 27 '16 at 20:48
  • What other suggestions do you have for protecting something disturbing what's inside the .app folder? – Volomike Jan 27 '16 at 20:55
  • 1
    What you are looking for is essentially DRM and that relies on a server for the key. Even then one can debug a running app. On OSX there all many possibilities, I have added code to the Finder, the debugger can be attached to a running app, The code can be class dumped, that is how people figure out how to patch other apps such as the finder. Is all about increasing the work factor for the attacker. Identify the attacker and the value of the data, then protect to that level. Apple with iMessages uses HSMs and destroys the admin key cards. Pick your level. – zaph Jan 27 '16 at 21:02