Matasano
December 2nd, 2007, 17:40
Believe it or not, we don’t just talk about OS X security, we actively search for new vulnerabilities in it. I have found a number of vulnerabilities, both local and remote in OSX and OSX Server over the years. This post is the start of a series of posts that explain some of the tricks that we use when assessing applications on Mac OS X.
For the most part, these tips apply to both GUI and command line apps. This isn’t rocket science, but is a good primer for people looking to dive into OSX vulnerability analysis. I am going to use Safari as an example, since it is somewhat topical. It isn’t the best example since enough of it is opensource that you can gain a lot more insight via debug builds.
http://www.matasano.com/log/wp-content/uploads/2007/04/CrashReporterDialog.png
If you click on Report… you will see information on CrashType. This will be your first potential clue into what might have caused the crash. Especially if you see a BAD_ACCESS along with an KERN_INVALID_ACCESS that you control. In this case, it is not obvious that I control this value, although it does look like it is an ASCII value:
http://www.matasano.com/log/wp-content/uploads/2007/04/CrashReporterCrashType.jpg
Another bad sign is if you see EXC_BAD_INSTRUCTION. Under x86 it is less likely you will see this with a straight up vanilla stack overflow, but there are other forms of memory corruption that can elicit this error.
And scrolling down, you will see register state. There is more information that is useful, including which thread you crashed, as well as which function caused the exception.
http://www.matasano.com/log/wp-content/uploads/2007/04/CrashReporterRegisters.jpg
One neat OS X feature is the ability to change this behavior via the defaults command. By settings the CrashReporter DialogType to “developer”, you will now have the option to attach to the process via GDB, by clicking a button.
In a Terminal window, execute:
Now lets look at that same crash:
http://www.matasano.com/log/wp-content/uploads/2007/04/CrashReporterWAttach-Redacted.jpg
Note: This won’t work on basic command line UNIX applications.
If you aren’t using the GUI, you can also monitor files in ~/Library/Logs/CrashReporter or /Library/Logs/CrashReporter. Files will be named .crash.log if CrashReporter can figure out the name of the application that crashed. Otherwise you will see names like ???.crash.log or Exited process.crash.log. Finally, if you are fuzzing the kernel, you can find information on kernel panics in /Library/Logs/panic.log.
http://www.matasano.com/log/wp-content/uploads/2007/04/MallocHelpNew1.png
Before I go further, if you are interested in understanding more about exploiting Apple’s malloc() implementation, you must read FelineMenace’s paper on the subject (They also discuss the MallocDebug facilities).
The variables I set are:
MallocLogFile The default behavior for the debugging modes for malloc output to stderr. For GUI apps, setting MallocLogFile makes it much easier to monitor the output. You simply set the environment variable to the name of the file you want output written to.
ThisOldVuln Moment #1: There was a vulnerability associated with this environment variable where a user with an account on the system could overwrite arbitrary files and become root.
MallocGuardEdges Helps identify potential buffer overflows by putting guard pages on either side of large blocks. It won’t detect all issues, but it can help.
MallocScribble Useful for detecting when an application is writing to an region of memory that has already been freed or memory that was never initialized. Both of these conditions can be exploitable security issues.
MallocBadFreeAbort While a simple double free or freeing non malloc()d regions of memory are generally not considered exploitable conditions under OS X, there are more complicated double free() situations that can be exploitable. Besides, in 1996 everyone I knew said that heap overflows were unexploitable.
MallocCheckHeapStart,MallocCheckHeapEach,MallocCheckHeapAbort,MallocCheckHeapSleep
These three variables control when to start checking for heap corruption, how often to check, and what to do when heap corruption is identified. I would generally recommend Abort while fuzzing. When you want to debug, switch to sleep so that you can attach at the point that corruption was identified.
Here is my Info.plist file for Safari:
http://www.matasano.com/log/wp-content/uploads/2007/04/SafariPlist.png
As you noticed from the above, somethings caused Safari to crash. Figuring out what caused the crash isn’t always easy, especially with complex applications like Safari. In this case, we get another potential clue via the malloc:
http://www.matasano.com/log/wp-content/uploads/2007/04/debugoutput1.png
Minor Note: The output was edited down.
Less Minor Note: 1.5G is a large number to get passed to vm_allocate (assuming the output here is correct).
This will be a living document (even though I hate that term). I know smarter people read this blog and would love feedback. Future topics will include file system access, deeper dive on debugging facilities and automation.
http://www.matasano.com/log/813/analyzing-mac-os-x-applications-101-crashreporter-and-malloc/
For the most part, these tips apply to both GUI and command line apps. This isn’t rocket science, but is a good primer for people looking to dive into OSX vulnerability analysis. I am going to use Safari as an example, since it is somewhat topical. It isn’t the best example since enough of it is opensource that you can gain a lot more insight via debug builds.
CrashReporter is probably the most useful utility for identifying that an application crashed, and getting some basic insight into what caused the exception. You have probably seen elements of CrashReporter when an application crashes on you. While it can be customized on a per application basis, most applications use the default. Here is an example of a CrashReporter dialog:
http://www.matasano.com/log/wp-content/uploads/2007/04/CrashReporterDialog.png
If you click on Report… you will see information on CrashType. This will be your first potential clue into what might have caused the crash. Especially if you see a BAD_ACCESS along with an KERN_INVALID_ACCESS that you control. In this case, it is not obvious that I control this value, although it does look like it is an ASCII value:
http://www.matasano.com/log/wp-content/uploads/2007/04/CrashReporterCrashType.jpg
Another bad sign is if you see EXC_BAD_INSTRUCTION. Under x86 it is less likely you will see this with a straight up vanilla stack overflow, but there are other forms of memory corruption that can elicit this error.
And scrolling down, you will see register state. There is more information that is useful, including which thread you crashed, as well as which function caused the exception.
http://www.matasano.com/log/wp-content/uploads/2007/04/CrashReporterRegisters.jpg
One neat OS X feature is the ability to change this behavior via the defaults command. By settings the CrashReporter DialogType to “developer”, you will now have the option to attach to the process via GDB, by clicking a button.
In a Terminal window, execute:
defaults write com.apple.CrashReporter DialogType developer
Now lets look at that same crash:
http://www.matasano.com/log/wp-content/uploads/2007/04/CrashReporterWAttach-Redacted.jpg
Note: This won’t work on basic command line UNIX applications.
If you aren’t using the GUI, you can also monitor files in ~/Library/Logs/CrashReporter or /Library/Logs/CrashReporter. Files will be named .crash.log if CrashReporter can figure out the name of the application that crashed. Otherwise you will see names like ???.crash.log or Exited process.crash.log. Finally, if you are fuzzing the kernel, you can find information on kernel panics in /Library/Logs/panic.log.
The OS X malloc implementation contains a lot of useful features for understanding when (and how) memory corruption is occuring. These features are controlled via environment variables. These variables are both outlined inside of the malloc man page and via setting the environment variable “MallocHelp” and executing a command:
Malloc Debugging
http://www.matasano.com/log/wp-content/uploads/2007/04/MallocHelpNew1.png
Before I go further, if you are interested in understanding more about exploiting Apple’s malloc() implementation, you must read FelineMenace’s paper on the subject (They also discuss the MallocDebug facilities).
The variables I set are:
MallocLogFile The default behavior for the debugging modes for malloc output to stderr. For GUI apps, setting MallocLogFile makes it much easier to monitor the output. You simply set the environment variable to the name of the file you want output written to.
ThisOldVuln Moment #1: There was a vulnerability associated with this environment variable where a user with an account on the system could overwrite arbitrary files and become root.
MallocGuardEdges Helps identify potential buffer overflows by putting guard pages on either side of large blocks. It won’t detect all issues, but it can help.
MallocScribble Useful for detecting when an application is writing to an region of memory that has already been freed or memory that was never initialized. Both of these conditions can be exploitable security issues.
MallocBadFreeAbort While a simple double free or freeing non malloc()d regions of memory are generally not considered exploitable conditions under OS X, there are more complicated double free() situations that can be exploitable. Besides, in 1996 everyone I knew said that heap overflows were unexploitable.
MallocCheckHeapStart,MallocCheckHeapEach,MallocCheckHeapAbort,MallocCheckHeapSleep
These three variables control when to start checking for heap corruption, how often to check, and what to do when heap corruption is identified. I would generally recommend Abort while fuzzing. When you want to debug, switch to sleep so that you can attach at the point that corruption was identified.
Here is my Info.plist file for Safari:
http://www.matasano.com/log/wp-content/uploads/2007/04/SafariPlist.png
As you noticed from the above, somethings caused Safari to crash. Figuring out what caused the crash isn’t always easy, especially with complex applications like Safari. In this case, we get another potential clue via the malloc:
http://www.matasano.com/log/wp-content/uploads/2007/04/debugoutput1.png
Minor Note: The output was edited down.
Less Minor Note: 1.5G is a large number to get passed to vm_allocate (assuming the output here is correct).
This will be a living document (even though I hate that term). I know smarter people read this blog and would love feedback. Future topics will include file system access, deeper dive on debugging facilities and automation.
http://www.matasano.com/log/813/analyzing-mac-os-x-applications-101-crashreporter-and-malloc/