Why I Left Twitter

Because I can :-) I was going to write a longer post about this but it is pretty much irrelevant. Essentially I have been thinking about this over the past weeks given that my character might be somewhat incompatible with what I want to achieve next. Sunday I got locked out of Twitter because some random asshole made an harassment complaint because I called him “dumb fuck” and “dumb idiot”, pretty normal things around my feed. [Read More]

How to make LLDB a real debugger

These days the de facto debugger in macOS is LLDB. Apple’s old gdb fork doesn’t work anymore and the GNU gdb version is better these days but still quite meh (in the past it couldn’t deal with fat binary targets and I still think this holds true). So we are all essentially stuck with LLDB, warts and all. I also hate the lack of a gdbinit style output but Deroko started that project and I improved it with lldbinit.

Besides its horrible long command line syntax which is so unpopular that gdb-compatible commands were introduced, my biggest problem with it has been the lack of x86 hardware breakpoint support. While hardware breakpoints might not be needed to debug applications within Xcode, they are essential to any serious reverse engineer dealing with arbitrary untrusted targets such as malware, packers, obfuscators, and DRM. It has been a serious blocker for me against some targets and a source of immense frustration because it should be a basic debugger feature.

Last week I finally got fed up enough to dive into the LLDB C++ codebase and finally try to implement this feature. Instead of just posting a patch, this post is a journey into LLDB internals and how I implemented this feature. Hopefully it will help others exploring the LLDB codebase, which seems unfriendly because of the lack of really good documentation into its architecture. Maybe this could lead to further improvements and make LLDB more reverse engineer friendly.

[Read More]

Crafting an EFI Emulator and Interactive Debugger

In 2016 I reversed Apple’s EFI firmware password reset scheme using SCBO files. There was an old rumor that these files were able to unlock firmware password locked Macs (and even a sketchy video about a universal SCBO able to unlock any Mac). That post is available at Apple EFI firmware passwords and the SCBO myth.

All the interesting computing action happened at the EFI execution level. I made good reversing progress with static analysis, but dynamic analysis with a debugger would make the job much easier. I love debuggers because they allow you to quickly test ideas and cut corners while reversing a target. Reading disassembly listings for long periods is tiring. (U)EFI debuggers can be found in the market but they are usually quite expensive (a couple thousand USD).

My solution was to create an emulator and debugger based on Unicorn. At the time I was working a lot with Unicorn so it was natural to use it to solve this problem (“if all you have is a hammer, everything looks like a nail”). After I wrote the blogpost some people directed me to some emulators (TianoCore EmulatorPkg and efiperun). I never tried them to see if they contained an interactive debugger like I wanted. The pain wasn’t big since this was a couple of days project and it was quite fun to write.

[Read More]

Keygenning Carbon Copy Cloner Keychain Password

Passwords are a modern annoyance and their diversity is something you can’t avoid if you want a minimum amount of account security (don’t forget to turn on those 2FA options, avoiding SMS versions if possible). They get more annoying when you set a super smart new password with that smug feeling that it is such a great password that you will never forget about it (or something crappy you set in a rush). Usually you can’t remember it already in the next day or in the next week, since in a month it is totally wiped out from your memory.

This time my victim was Carbon Copy Cloner (CCC). When you generate a backup you can select an encrypted sparse bundle (disk image) as destination, and save its password in the application private keychain.

Disk Image
Password input

Some time ago I created some backups in a hurry and used the encrypted sparse bundle option as destination. Of course I used a super smart password and now I couldn’t remember it. Carbon Copy Cloner was still able to make the backups to that image but I couldn’t open it myself (well it is mounted during a backup but that is not fun enough to write a blogpost about!). I knew CCC had a private keychain somewhere in the system (/Library/Application Support/com.bombich.ccc/CCC-global.keychain to be precise) so my goal was to click Keychain Access show password radio button to recover the password.

The problem is that the private keychain is locked with a password and I couldn’t find any information about this password. Is it dumb enough to be hardcoded? Or is it something smarter and generated per user/machine/etc? Well the latter is the obvious answer now since this post titles gives it up.

Given that CCC has a privileged helper tool, it is a pretty good assumption that it will be responsible for managing the private keychain (because it runs with higher privileges and protects keychain access from regular users). So load up /Library/PrivilegedHelperTools/com.bombich.ccchelper into your favorite disassembler. While waiting for disassembly to complete we can try to guess what to look for.

If CCC is using macOS keychain infrastructure then we should be able to see Keychain related APIs in this binary.

$ nm /Library/PrivilegedHelperTools/com.bombich.ccchelper|grep -i keychain
                 U _SecKeychainCopySearchList
                 U _SecKeychainCreate
                 U _SecKeychainFindGenericPassword
                 U _SecKeychainFindInternetPassword
                 U _SecKeychainGetStatus
                 U _SecKeychainItemCopyAttributesAndData
                 U _SecKeychainItemCreateFromContent
                 U _SecKeychainItemDelete
                 U _SecKeychainItemFreeAttributesAndData
                 U _SecKeychainItemFreeContent
                 U _SecKeychainItemModifyAttributesAndData
                 U _SecKeychainLock
                 U _SecKeychainOpen
                 U _SecKeychainSetSearchList
                 U _SecKeychainSetSettings
                 U _SecKeychainSetUserInteractionAllowed
                 U _SecKeychainUnlock

SecKeychainUnlock appears to be a good first candidate to poke around. Apple’s API documentation has everything we need to know about this:

OSStatus SecKeychainUnlock(SecKeychainRef keychain, UInt32 passwordLength, const void *password, Boolean usePassword);

A buffer containing the password for the keychain. Pass NULL if the user password is unknown. In this case, this function displays the Unlock Keychain dialog to prompt the user for the keychain password.

A cleartext password is passed to SecKeychainUnlock to unlock the keychain. Took longer to disassemble than to find what we need to attack! IDA gives us the following cross references and we can see a very suggestive function name (strip the symbols!).

__stubs:100168D76 _SecKeychainUnlock proc near ; CODE XREF: _openAndUnlockCCCKeychain+30C
__stubs:100168D76                           ; _openAndUnlockCCCKeychain+626
__stubs:100168D76           jmp     cs:_SecKeychainUnlock_ptr
__stubs:100168D76 _SecKeychainUnlock endp

Tip: to strip symbols in Xcode the “Deployment Postprocessing” build option must be set to Yes, otherwise the binary will not be stripped.

If you poke around openAndUnlockCCCKeychain you will understand that the password is being created at the function kp. It returns a NSString object. So right now it is very easy to recover the unknown CCC keychain password. Just attach with a debugger to the privileged helper process, and breakpoint on the address after the call to kp. Print the object in rax register and voila the password is all there (a long mumbo jumbo of weird characters, impossible to bruteforce). To trigger the breakpoint just quit CCC and open it again (the helper process is still running in the background and the debugger is attached). That’s it, it really takes longer to disassemble than to recover the password. The helper process is not SIP protected so the debugger can be attached without any problems.

To test the password, copy the keychain to somewhere else, change permissions to current user and open the keychain. Insert the password, and voila it unlocks. Go to saved keychain items, click show password and our mission is complete. The password I had set was a really dumb one, and I was trying all the complex stuff I could remember of. Ah the joy of new passwords rush!

Well this wasn’t that much fun, so I got curious about the password generation algorithm. Time to poke around the kp function. The function isn’t very complicated so I will not lose much time with details. It collects the following information about the machine where it is running:

  1. IOPlatformUUID
  2. IOPlatformSerialNumber
  3. Hardware model name (via CTL_HW/HW_MODEL sysctl)
  4. Number of CPUs (via sysctl)

This gives a strong hint that the password is specific to each machine where CCC is executed (a positive thing!). With this information some transformations are done and a 64 characters password is generated. The kp function is called when the password is necessary (just from the openAndUnlockCCCKeychain function) but remains constant per machine. Given this it is very easy to build a keygen. The source for mine is available here carbon_copy_cloner_keychaingen. The code is pretty much a direct translation from the disassembled code and could be improved/optimized. I opted out to sync it with the disassembly in the comments so you could try to understand what is going on.

After all this I have a problem with this solution…

Creating a private keychain that contains passwords to encrypted backups with a password that is out of my choice and constant per machine is something I don’t really like. This password is very easy to keygen or recover with a debugger. I assume we need to run the keygen in the target machine (can IOPlatformUUID and/or IOPlatformSerialNumber be known without running code?) or a debugger (for which we need admin privileges).

I understand those saved encrypted backups passwords to be at higher risk of disclosure since I don’t control the password that guards them.

Of course there are (valid) reasons for this design - easy usage and automatic backups. It is after all a software product with wide customer audience and not just experts - regular people just want stuff to work (it is already a huge step forward if they bought backup software and actively execute backups).

You can opt out for not saving the password in the keychain. But the incentives to do it are there and most users will follow them without fully understanding the risks involved. The flip side of the coin is that I could have lost my encrypted backups because I didn’t save their password in the keychain. Personally I am biased against macOS keychain, and never save any important passwords there. I view it as some sort of a single point of failure and malware is usually interested on its contents (if you use it, don’t use the login keychain for those secrets, create a new one that is only unlocked when you really need it).

I prefer to lose data than have it accessed by unknown third parties!

Have fun,

Reversing and Keygenning qwertyoruiop's Crackme

I was bored this weekend and decided to take some rust out of my reversing skills before they disappear for good. I have spent the past two years or so mostly writing C code (secure C is more like an asymptote but that is why it is a fun challenge) and barely doing any serious reverse engineering and security research. So I decided to revisit some unfinished business with qwertyoruiop’s crackme. I had a look when he originally sent it but got distracted with something else at the time and never finished it. I couldn’t find any public write-up about it so I decided to write one. It is mostly targeted to newcomers to reverse engineering and macOS. You can click the pictures to see the full size version.

[Read More]

lldbinit - Improving LLDB

Many years ago I had to use gdb for the first time and I absolutely hated it. At the time I was reversing (cof cof cof) Windows apps so SoftIce and friends were my favorite tools. Compared to these gdb was a complete trash, mostly because the naked gdb lacks a nice context display. I like to know what the hell is going around each time I step in the debugger, without having to type a bunch of commands for it. [Read More]

Measuring OS X Meltdown Patches Performance

Happy New Year and happy ten year anniversary to this blog, which I totally forgot back in October :-/. Blogging activity here has been so slow that I almost forgot how to work with Hugo. We started 2018 with heavy speculation on critical CPU bugs that were under disclosure embargo. Luckily for us, Google decided to break the embargo and release some proper information about the bugs so speculation could stop and facts could finally flow in. [Read More]

Exploiting CVE-2017-5123

This is a guest post by a young and talented Portuguese exploiter, Federico Bento. He won this year’s Pwnie for Epic Achievement exploiting TIOCSTI ioctl. Days ago he posted a video demonstrating an exploit for CVE-2017-5123 and luckly for you I managed to convince him to do a write-up about it. I hope you enjoy his work. Thanks Federico! While this one was on a rush, I want to create another blog dedicated to Portuguese hackers and researchers content. [Read More]

How to compile AFL's LLVM mode in OS X

American fuzzy lop aka AFL is one of the easiest and best fuzzers out there and should be part of your development cycle if you care at least one bit about the security of your code. Its performance in OS X is a bit of a let down because of issues at fork() system call. AFL warns you about this when compiling it: WARNING: Fuzzing on MacOS X is slow because of the unusually high overhead of fork() on this OS. [Read More]

Blog migration to Hugo

So I finally decided to bite the bullet and migrate from Wordpress to Hugo. I wanted to migrate out of Wordpress for a while but the amount of work required to keep the site structure due to SEO and migrating content always stopped me from doing it. I also wanted to keep the site comments feature and since I don’t like to use cloud services such as Disqus it created another big obstacle to this operation. [Read More]