One of the most exciting things announced at this years WWDC was System Extensions. From a security perspective I think this is a really important advancedment for macOS. It means less third party code running in kernel space which should mean more security and stability. From a programmers perspective I think this is even more important. It means that the code developers previously had to write in C++ can now be written in a more modern language like Swift. Apple has been attempting to wrangle in kexts for a while now and this seems to be the final nail in the coffin. They have said macOS 10.15 will be the last release to fully support kexts without compromises and that in future releases of macOS Kernel Extensions with System Extension equivalents will not load at all. I thought it might be interesting to look at the internals of how System Extensions work.
When reverse engineering macOS binaries that are written in Objective-C, class-dump is a common tool used to extract Objective-C declarations from the runtime information stored in the Mach-O files. With Swift binaries, since there is Objective-C compatability, sometimes you can extract declarations using class-dump but not always. Swift has a rich set of type metadata itself but the documentation is not up to date. With Swift 5 bringing ABI stability I thought it would be interesting to take a look at the type of metadata availble in Swift binaries.
Recently while looking into the Apple
adid daemon, I noticed that I couldn’t attach to the process with
lldb even if SIP was completely disabled. After digging into it a little bit I came to the conclusion that
adid was calling the
ptrace API passing in
PT_DENY_ATTACH. There are numerous other posts out there (like this one) that talk about defeating
PT_DENY_ATTACH if you’re running the application yourself. In my case
adid is started as a LaunchDaemon and is already running by the time a user is logged in. I decided to take a look at how you could defeat the
ptrace call even after the application is already running.
LLDB has great Python support but it’s not always clear what functionality is there or how to use it. While there is documentation on all of the classes available to scripts, some classes and methods are better documented than others. While looking for the best way to trace through some obfuscated assembly recently I came across the
thread step-scripted command and thought it would be worth writing up a short overview of what it is and how to use it.
In the previous post we looked at different ways to inject code into tasks on macOS. The goal being to create increased awareness of the type of methods attackers writing malicious code on macOS might use. In this post I wanted to focus in on the same issue of code injection but from a defenders point of view.
I was recently reviewing the MITRE ATT&CK™ knowledge base and came across the page on process injection techniques for privilege escalation. For those that are not aware of what the MITRE ATT&CK™ knowledge base is, it’s a group of documents and definitions that cover common adversary tactics and techniques. The macOS and Linux sections for process injection were lumped together and not very detailed. In some cases it seemed like the information wasn’t even accurate for macOS. This article covers common process injection techniques that apply to macOS.
A common question that comes up when people start Swift development is what’s the difference between a
struct and a
class? The standard answer is structs are value types and classes are reference types. The Swift Programming Language book has a whole section reviewing this concept in more detail. From a reverse engineering perspective I always find it interesting to dive under the hood and see how the compiler actually handles the different concepts from high level languages. This post presents a very simple example of a struct and class in Swift and how the compiler deals with them.
With my previous post I took a look at the
SystemPolicy.framework and how it kept track of 32-bit applications that had been run. In the process of looking into that I ended up looking into the internals of
syspolicyd. Way back in macOS 10.10.5
syspolicyd was part of the security_systemkeychain source code that Apple releases with each version of macOS. Unfortunately since that time
syspolicyd was moved out of the security_systemkeychain package and closed sourced. This post details the internals of
syspolicyd as it is today in macOS 10.14.x and covers both what services it provides and what clients connect and use its functionality.
At the 2018 WWDC State of the Union event, Apple vice president of software Sebastien Marineau revealed Mojave will be “the last release to support 32-bit at all”. Since macOS 10.13.4, Apple has provided the ability to set your machine to 64-bit only mode for testing. For most users this is not a very convenient way to test. As of 10.14 the System Information application has a new “Legacy Software” section that shows you all of the 32-bit applications that have been run on the machine. This new “Legacy Software” information provides great insight for Mac Admins into what 32-bit applications their users are running so that they can work with vendors to get software updated prior to the release of macOS 10.15. From an admin perspective, it would be nice to be able to get this information in an automated way. This post covers how I went about digging into this new feature and exposing it in a way that could be queried from osquery.
Recently while reverse engineering three kernel extensions from a macOS security product, I noticed that there was a lot of duplicated code between all of the KEXTs. Common things like logging or initialization of data structures were clearly the same in each one. With an IOKit KEXT you can create parent classes in one KEXT and inherit from it in another one. In this case, these three extensions were not IOKit drivers. Although Apple doesn’t document it very well you can share code across multiple KEXTs. This post covers some examples from Apple of shared KEXTs as well as how you would do it in your own KEXT.
One technique malware uses on Windows to disguise itself is called process replacement or process hollowing. This allows malware to start a well known piece of software like
svchost.exe in a suspended state, write malicious code into the processes memory and then start the process running. Anyone looking through running processes will simply see a normal
svchost.exe process running. This has the additional benefit of allowing the malicious code to run with the same privileges as the process it is replacing. You can find a lot of examples of how to create a suspended process on Windows but there doesn’t seem to be as many good examples for other platforms. This post will look at Windows, Linux and macOS and how you can create a suspended process on all three operating systems.
Apple finally releassed the XNU source code for macOS Mojave. Oddly enough though it’s the source for 10.14.1 with the source for 10.14 still listed as coming soon. Overall the process remains almost identical to building High Sierra. The one signifigant change I noticed was when executing
xcodebuild commands, I needed to pass the
-UseModernBuildSystem=NO flag in to get things working properly.
The Nintendo Game Boy was first released in North America on April 21, 1989. It wasn’t the most powerful handheld of the time but certainly was the most popular. Over the years I’ve done some reverse engineering on Game Boy Advance and Nintendo DS handhelds but have never looked at the Game Boy. I thought it might be interesting to take a closer look into the boot ROM of the Game Boy and what it does at start up.
Inspired by a recent post on the MDSec blog, I wanted to take a deeper look at virus scanning on macOS. When I ran into issues getting McAfee kexts approved and loaded correctly it gave me a good excuse to dig deeper. In this post I will provide a brief overview of the different Kernel APIs available to virus scanning tools on macOS and specifically how McAffee’s implementation works. Finally I will cover some things that I think could be improved in the McAfee implementation.
The Go programming language does not support the concept of inheritance in the traditional object oriented sense. It does allow for type embedding which provides a powerful method for composition. When getting started with Go these patterns are not always obvious. This post provides a short example of how type embedding is used in one of the Go standard library structs.
Getting started debugging the kernel can be very intimidating the first time you do it. There are various in depth guides that have been written over the years but they frequently get out of date. This post provides a short, concise, and up to date guide on getting started as easily as possible.
MacOSX doesn’t come with the most recent Python. It’s pretty normal to install a newer version either through brew or something else like the anaconda distribution. If you do install a newer version of Python you’re likely to encounter problems when trying to access scripting in LLDB.
Recently a friend gave me a broken Phillips AJ6111 radio. It was a neat little radio that you can mount under your kitchen cupboard. Only problem was that it didn’t work. I plugged it in, heard a click of a relay and the clock in front came on but none of the buttons seemed to do anything.
Well it’s been a while since I’ve updated things. In fact looking back at the last post it’s from right around when basketball season started. Anyone who knows me knows I’m a basketball junkie. I spent a good part of the college and nba season wondering what sort of software could enhance my basketball addiction.
I wanted to post a quick update to give a big thank you to Paul Bartholomew. He grabbed a copy of the firmware and started looking things over. He took a look at the other custom app the phone runs
act_sip app runs a web server on tcp port 9999 and lets you log in and configure the phone. He noted that on the page that lets you upload a mp3 file it looked like the server was only checking for a content-type of audio/mpeg. Sure enough he was correct. I’m currently just using Tamper Data in Firefox to intercept the post and change the content type, but it works! I can now upload code to the phone.
So i failed to mention with the first post. After I found the
tftpsrv, the first thing I did was to run the
file commond on it and I got back this
At work a couple years back we got these fancy new VOIP phones. I immediately set out to figure out what else we might do with them. I unfortunately set that project aside but just recently picked it back up. I figured I would post the info I found out in case anyone else was interested. I decided to split this into multiple posts in an attempt to keep the posts a little shorter. Anyways this first post is about the firmware.
Recently, the Northeast Ohio Information Security Forum put on a malware reverse engineering challenge. The winners still haven’t been announced because they’re still reviewing all the submissions but below is the write up that I submitted:
I came across an application the other day that I was interested in taking a peek at under the hood. The first thing I did was to search through all the strings to see if there was anything interesting. Two things jumped out at me. The first was a lot of strings that looked like this:
cClass3. Alright seems like it could be something written in C++. And then I also came across this string,
qt-win-commercial-3.2.3 Alright so this information gives me a lot to start with. It is for sure C++ code and what’s more I now know what GUI toolkit it’s using. So first thing I usually do when looking at a C++ applications is to try to find the RTTI information since it makes identifying code much easier. I started by checking references to the class name strings I had found. Unfortunately I didn’t find any RTTI information. What I did find however were lots of functions that looked like this