System programming is one of the more interesting topics to me because it seems like it’s the hackers domain. When I first got into programming I always wanted to see if I could make the computer do something that nobody else anticipated it could do. I think it was probably just from watching too many hacker movies. Even the Matrix (the first one, not those other two contorted kill joys) had this affect on me that somehow I could beat the system because as Morpheus put it,
I’ve seen an agent punch through a concrete wall. Men have emptied entire clips at them and hit nothing but air, yet their strength and their speed are still based in a world that is built on rules. Because of that, they will never be as strong or as fast as you can be.
Man! I loved that movie the first time I watched it. A world without rules? Or more specifically a world where you set the rules by your most awesome hacker powers. Sweet!
But alas, as I’ve proceeded and matured (I hope) in my programming abilities, this whole area has become much less glamorous as I realize that hacking is really about finding vulnerabilities in other people’s code. That’s really not that exciting to me, but system level programming remains interesting and a good place to start is to look into who the users are on my system. Time to use Identity Services. And in this intro I’ve written a very basic password cracking system.
I’m about to yell in red, so you might want to cover your ears.
YOU CAN MESS UP YOUR USER ACCOUNT ON YOUR SYSTEM IF YOU ARE NOT CAREFUL WITH HOW YOU USE IDENTITY SERVICES. DO NOT BLAME ME IF YOU DO SO. CREATE A DEMO USER NOW BEFORE YOU PROCEED AND USE IT FOR YOUR TESTS. YOU HAVE BEEN WARNED!
Yelling is over. You can uncover your ears now.
You can download the demo application here: Identity Services Demo Application
Simple Password Cracking
If you need information about a user in your code, you can get most of what you need through the user account information provided through identity services. And while you won’t be able to retrieve passwords since they are stored as hashes, you can check passwords against a list of dictionary words. This type of attack is known as a brute force dictionary attack. It is considered brute force as it will just keep running through a loop checking the hash against every word in the dictionary. It’s one for one so there’s no efficiency. It will only quit should it find a hash that matches. This could take a very very long time.
Keep in mind that this method will only work on simple dictionary based password. Once a password has alpha and numeric characters, the likelihood of a simple dictionary attack actually finding the password in any reasonable amount of time diminishes rapidly.
If you want to test this out, I recommend that instead of changing your own password, you create a new test user in your System Preferences | Accounts control panel. Give it one of these passwords that are in our dictionary:
A Potential Bug?
I’ve never filed a bug with Apple before, but I realized that when I was trying to use the wrapper class called CBIdentity to retrieve the user’s email address with -[CBIdentity emailAddress], it kept on returning me their Posix Name (Unix username) instead of the email address. I verified this with the API call CSIdentityGetEmailAddress() which does properly return the email address.
I’m not absolutely sure that it’s a bug, but since it works properly with the API call, it seemed logical that it would be. Plus, in this demo application from Apple, they use the CSIdentityGetEmailAddress().
Note: In order to get the sample code from Apple to work, you will need to make a change to two lines in the IdentityController.m file. Anyplace where you see kCSLocalIdentityAuthority you need to change it to [[CBIdentityAuthority localIdentityAuthority] CSIdentityAuthority]. You will also need to add the Collaboration.framework framework to your project and add #import <Collaboration/Collaboration.h> to the IdentityController.h file.
The IdentitySample project provides a lot more code for demonstrating Identity Services, so take a close look at it to see some more usages examples.
Update: Apple wrote me back and said that it was indeed a bug, but it’s a duplicate.
Password Cracking Dictionaries
I’m not going to take you too much farther into doing password cracking as the only legitimate uses for it that I can think of are either detecting weak passwords, or sanctioned corporate hacking where security experts are hired to attempt to find vulnerabilities.
I will say, however, that if you want to pursue creating a password cracking utility that uses a brute force method for any of these legitimate uses, you will, obviously, need a much larger dictionary than the little array I’ve put into the project. There are free dictionary files out there you should be able to find on Google without much trouble. You can simply load one of those up and you’ll be on your way to a little more sophisticated password cracker, or shall we call it, weak password detector?
For a comprehensive guide to the Identity Services API, first take a look at Apple’s Identity Services Programming Guide. Then, refer to the Core Services Identity Reference which will give you everything you need to load user information, save user information, and create new users. While most of the types you will find in Core Services are CF references, you can convert them toll-free to their NS counterparts with simple typecasting.