OFTW3

Estimated read time: 18 minutes

My first “objective for the win” conference. I’d seen this advertised in the CyberSecurity discord, for which I am now president, and decided this would be a great opportunity to learn more about Apply device security.

I’d never looked into Apple security, neither do I own any Apple devices. So this was a first, I thought why not? I love security so I might as well explore and find out which niche I want to fall into.

Day Zer0

This day would be a workshop day in which we cover the essentials of Mac Malware analysis with the legend, Patrick Wardle. But prioer, I first had do take on some preparation, Objective See are focused on apple devices, so of course it’s an i-device event. Do you see the issue yet?

Well I don’t own any Apple devices. So what did I do? Well, I remembered something I had done in the past to ease my mum’s transition from Mac to Linux (yes she now runs Linux as her daily-driver, all be it, she doesn’t quite find enjoyment in ricing her system and writing cool utility bash scripts on a daily basis). Anyways back to the main point, I decided I would… run a hackintosh VM. Well easier said than done (because who reads the documentation until they fail countless times?).

So there’s a cool project on github called OSX KVM, it’s a simple install just run the: fetch-macOS-v2.py script. Now came the issue, I repeated the download process thrice because of this and each time took a good 2 hours. Do you know why? Because who reads documentation until they have failed for a good chunk of their time.

Anyway, tangent out of the way, let’s get back to the day. Patrick’s workshop day was heavily inspired by his book in terms of content and order (though I have to agree it’s best to cover malware from it’s initial access to its payload).

An Intro to Mac Malware Analysis - Patrick Wardle

Initial access

So we started off with a look at mac malware, its growth and infection vectors. From phishing links to 0day exploits we looked at all means of gaining initial access.

Persistence

From there we moved onto persistence, how does malware remain in a way such that even the good old fashioned classic of turning it “off and on again” doesn’t work. It was during this section we looked at tradition login items, system agents, daemons and cronjobs. This is where my ear perked up because boy oh boy do I have experience with daemons and cron jobs, finally my script scheduling experience comes to use!

But, Mac does things differently, it stores these daemons in different directories, not the usual /etc/systemd (if you use systemd - some say it’s bloatware). So we covered login items, launch items, cron jobs, login and logout hooks, kernel extensions (another parallel, after all Mac OS is UNIX based), browser plugins and many more.

Payloads

Then came payloads: browser script injectors, cryptominers, remote shells, remote execution, file exfiltrators and file encryptors (ransomware).

This was followed by a lab that went through the content as well as the “knock knock” tool curated by Patrick himself. This tool identifies and highlights all persistent applications/programs.

File types

Next was an introduction to different MacOS specific file types as well as scripts. In case you haven’t read my CTF write ups, we can use the file tool, similarly to Linux to identify files based of file headers.

MacOS also has its own version of disk image files: .dmg which you can then mount to your filesystem and explore.

Lastly comes another MacOS quirk, these being packages. Packages bundle all files and dependencies required by an application such as apple scripts (high level scripting language) or plist files (you’ll meet these a lot). This was followed by another lab to re-enforce the knowledge.

You may notice a pattern in teaching used here: the use of supplementary labs to follow up every topic of learning. I found this great in consolidating my knowledge (though the labs were a little rushed). Nevertheless, as Patrick had mentioned, we could always follow up on the labs in our own time.

We then delved deeper into the Mach-O binary file and linked dependency libraries; a perfect segway into Static Binary Analysis.

A few flags to watch out for included:

  • file hashes
  • Embedded ASCII strings
  • Code Signing (one of Mac’s easily circumventable security features)
  • Packed binaries
  • Encrypted binaries

This was accompanied by a whistle stop tour of low level programming by explaining the register convention, assembly and objective-c. Patrick’s disassembler of choice was Hopper though Chris would disagree (I agree binary ninja is better!).

This was followed by a cool static analysis lab where instead of using these proprietary tools, let’s use what the NSA developed: Ghidra!

It was around this point that we had successfully socially engineered Patrick to go off a tangent and tell us stories about his past, including his time at the NSA. He told us everything (I’m just joking, NSA don’t come after me).

Anyways for the stories that he did tell us, I’ll leave it as an exercise for the reader - to attend one of his events, listen in and ask questions.

Amazing! I’ve always wanted to pull off the “I leave this as an exercise for the reader”. It sure is great when the author (or my lecturer) is explaining an extremely complex topic and throws that into the mix, only for you to spend countless hours trying to figure it out (at least provide the solution).

Due to this tangent, Patrick had to skip the sections on the new ARM architecture that the latest Macs use. Instead, we moved on to dynamic analysis and of malware. This is where Patrick (rightfully) plugged his tools: ProcessMonitor, FileMonitor and Netiquette.

These tools are amazing when it comes to displaying process, file and network events respectfully, especially for malware detection and dynamic analysis on Mac. I never thought I’d consider using a Mac but these tools might sweeten the deal when it comes to endpoint malware detection so thank you Patrick!

Essentially, you would use these tools to look out for anomalous processes running, file deletion/writing (indication of ransomware) and strange network traffic (usually connection to C2s). We also looked at the good old classic tool: Wireshark. You can never go wrong with Wireshark when it comes to network traffic monitoring and it is definitely a must-have for nearly all user needs.

Next came debugging an exceptionally important tactic in dynamic analysis. This would be useful in: decrypting strings (considering the malware does it for you) and analysing behaviour while controlling the program. Though I was already quite familiar with debuggers, given my experience with peda gdb when doing CTF challenges, I still found this section insightful.

Unfortunately, I had to leave as I could not delay my departure any further given my coach to catch. Nevertheless, the day was extremely enjoyable and I was sure to attend the next!

Day 0ne

The second day kicked off with a series of engaging talks from leading experts in Mac and iOS security. It was an eye-opening experience to hear directly from professionals who are actively working in the field - many of whom are involved in real-world red teaming, IR (incident response), malware analysis and security architecture.

Find all the talks and slides here.

Talk 1: iPhone Backup Forensics

Speaker: Kinga Kieczkowska (@kieczkowska), Security Consultant at Rada Cyber Security
📑 Slides
🎥 Recording

The first talk provided a detailed overview of iPhone backup forensics. We started by looking at the process of creating an iPhone backup; it a hassle when compared to android (at least in my opinion considering I have an auto sync set up to my home server).

Kinga then covered the key files contained within a backup:

  • Info.plist for general information on the the device and its state (including installed apps) when the backup is taken
  • Status.plist for metadata aboout the backup (e.g. eversion, creation start date etc)
  • Manifest.plist for details on the application bundles on the device. It also contains a date, though Kinga is not sure what the date represents, I haven’t had the chance to look into it so if you do know please reach out to me.
  • Manifest.db which is an SQLite database file containing two tables. One of these tables being the files on the device (filterable by the unique hash fingerprint for the file).

Kinga then noted some files of interest in case you are doing forensics which would be the databases in which your SMS messages, Notes and Whatsapp messages are stored.

She also made us aware of the open source backup analysis tool to aid in this process: iLEAPP.

Overall, this talk was brilliant, especially for someone who was not even aware that iPhones had a backup feature. I definitely found it insightful and interesting and now I definitely know where to look when I obtain someone’s backup files (so make sure to encrypt yours!). Thank you Kinga, it was great!

Talk 2: Come Reverse Engineer Malware With Me

Speaker: Chris Lopez (@L0psec), Senior macOS Security Researcher at Kandji
📑 Slides
🎥 Recording

Subsequently was Chris Lopez’s talk and what it missed out on in the number of slides, it definitely made up in content and Chris made no secret of his strong appreciation of Binary Ninja.

This would be a reverse engineering session where we analysed the Odyssey infostealer malware sample. Specifically we analysed the dropper written in Swift, which the article linked had only mentioned in passing.

One of the biggest threats posed by this malware was due to the facts that it had been both code signed but also notorised by Apple themselves (something that Patrick had mentioned and also wrote at great lengths about in his book).

From the article, we can gather that the dropper presented a SwiftUI application that would reach out to a C2 server and retrieve an AppleScript payload using native Swift APIs before making this script downloadable and then executing it.

Looking at the sample, we can see that the symbols have been mangled during compilation. This is where Binary Ninja’s plugin (Swift Demangler) came handy.

To understand that this is a Swift UI app we can easily look at it’s dependent libraries and come to this conclusion. Chris then mentioned that since this UI app must spawn a process and there are only a few ways to do so using Swift, it will be easy to narrow down where this is done.

In this case, the malware used NSTask ObjectiveC class. One thing that I’ll definitely give to Binary Ninja, that Chris made great use of was renaming subroutines and variables. Another cool thing I picked up here was the smooth integration of the lower-level ObjectiveC language with the higher level Swift language.

We began by looking within the function that used the NSTask class to spawn the process that set the privileges and executed the payload. This function simply appended together the command as a string before running it as a process. We then reversed through the caller functions to find the subroutine responsible for connecting to the C2 server using NSURLsession and the Swift hardcoded URL that is converted into an ObjectiveC URL: hxxps://allteching[.]xyz/auto.

By reverse engineering the program, we understood that the dropper reached out to the URL above in order to obtain a payload, for which it set permissions before executing.

One thing I didn’t quite understand was as to why we added an offset of 20 to a large string’s address to get the address to read the string from. If you do know this, please let me know.

Afterwards, I asked Chris as to why he loved Binary Ninja so much (rightly so, the UI and plugins are amazing) as well as about his BJJ background - considering I have started to pick up BJJ on my transition from boxing.

Thank you Chris for discussing BJJ at lengths with me as well as your journey to malware analysis.

Talk 3: From Alert to Action: Investigating a Real Security Incident

Speaker: Shannon McCormick, Senior Incident Responder at Salesforce
📑 Slides
🎥 Recording

Shannon provided a talk on Incident response as well as a demonstration based on a true story she faced. Firstly, she outlined the responsibilities of incident response, then we looked at the MITRE ATT&CK Framework to understand the Incident repsonse investigation process.

This involved looking for IOCs in the logs, forensics and some OSINT. In her example someone had been socially engineered by DPRK threat actors via the fake job interview on Linkedin method.

This was definitely a fun talk and something I’d love to explore further considering the variety of hats you would have to pick up and thus the surplus knowledge to be gained.

Thank you Shannon for the truly insightful talk.

Talk 4: Mirror Mirror: Restoring Reflective Code Loading on macOS

Author: Patrick Wardle, Founder, Objective-See Foundation
📑 Slides
🎥 Recording

This was one of the talks I was most excited for, Patrick had hooked me in with the first day of Mac malware analysis and now I was desperate for more.

This talk would be on reflective “in-memory” code loading which is the execution of compiled code directly from memory with the payload never being written to disk (apparently if it is encrypted and written to disk then it’s still reflective?).

Running payloads from memory is not as simple as copying it from secondary storage to memory (they have different underlying architecture). Now you may ask: isn’t all code loaded to memory before being ran?

This is true and it’s done by the loader that reads the binary from the disk and maps it and any dependencies (dynamic libraries) into memory. It then applies relocations and resolves symbols before excuting initialisers to initialise the environment for the binary and trasferring control to main().

Initially malware used dyld’s (the loader’s) functionality to load binaries into memory however with dyld 3, this loader API would no longer load to memory without first writing the in-memory payload to the disk. The memory loading functionality was rarely used by genuine apps and therefore the deprecation was welcomed.

How can we get around this?

We could try using a RAM disk - allocate a section of RAM as if it were a filesystem - however these RAM disk actions still create file events as the OS treats the RAM disk as the ordinary filesystem nevertheless it still removes persistence.

We could try changing the file name in the template where the filename is written to the disk as part of the loader’s API. This ensures it is no longer added to the loader default file location, we can now patch the loader, however a file (not the payload) is still created and the event does show up.

This is where Patrick thought of an ingenious solution of simply patching the previous dyld loader version and using it’s vulnerable memory loading functionality we could essentially travel back in time to when things were all well and vulnerable.

For the final cherry on top, Patrick wanted some Objective C support and found an article called “LLVM JIT, Objective-C and Swift on macOS: knowledge dump” by Stanislav Pankevich on Objective C support in memory loaded code.

However, hardened Mac runtimes can protect against this as they enforce code signing which compares the memory binary’s signature to the one on-disk to ensure the binary in-memory is code nsigned. To get around this, one can add exception entitlements to the custom loader, which many genuine applications do indeed utilise. All you would need to do after this is submit your custom loader for notarisation, which should happen as there is nothing inherently malicious about the loader and Apple have even notarised malware in the past.

As a malicious actor, why do we want reflective code loading?

Apple doesn’t allow any process (including security tools) from reading the memory of other processes - for privacy reasons. However, this is an instance when privacy sacrifices security. This means there are no available detection protections in place for this and it remains a huge threat to Mac security. The only solution as of now would be for the monitoring and detection of payload behaviour.

Apple please provide trusted security tools with the ability to read memory completely. This will solve many issues.

Thank you Patrick for this talk, it was really interesting and now I know how I will go about commit to my master plan of a Mac port of memory-loading BonziBuddy on every Macbook across the world.

Small note: It was also interesting to see GAUSS (anther memory loaded malware variant) that has remained a mystery since 2012 as it has never been decrypted.

Talk 5: How Far Can We Push AI for Detection?

Author: Martina Tivadar, Research Assistant at iVerify
📑 Slides
🎥 Recording

This talk focused on the use of LLMs (with a comparison to previous machine learning classification models) to classify Mac malware.

Martina went through the entire pipeline from data collection by grabbing malware samples from the Objective-see repository, running the samples and then extracting a log of events using the Apple Endpoint Security Framework API.

We then went on to preprocessing, for classical machine learning models this would require encoding of categorical data, handling missing values, feature engineering, balancing the dataset and scaling data however, when using LLMs, all that was required was filtering the logs as they started off too large.

Martina decided the best methodology for this would be to prioritise recent activity and only keep significant data results.

There was then a brief explanation of LLMs as well as the different OpenAI models before we looked at prompt engineering.

This included 6 different prompt types:

  • Zero-shot where there is no extra instruction
  • One-shot where an extra example is provided to the model
  • Few-shot where a few examples are provided to “teach” the model the pattern
  • Chain-of-thought where instructions on how the AI should reason and think is given step by step
  • Negative where the model is told what not to do
  • Hybrid a combination of the types listed above.

Martina then did an experiment with two independent variables, those being the:

  • OpenAI model (3 variants)
  • The prompt type

The dependent variables that would be measured and reported were:

  • Accuracy
  • Precision
  • Recall
  • F1 score

The results were zero-shot prompting with no additional instructions worked best overall though the exact scores were not disclosed. It caught 100% of malware with a few false positives and in the case of malware a false positive is much better than a false negative.

Chain-of-thought and few shot prompts came next with one-shot and negative prompts doing worse. Though an interesting note was that one-shot and negative prompts had fewer false positives due to their caution but this resulted in many false negatives, which would let malware evade them.

Martina then ended the presentation off on how the use of LLMs have really condensed and simplified the machine learning pipeline making their use much more accessible.

During the happy hour mentioned below, I had asked Martina if tailor made machine learning models would perform better to which she answered that, surprisingly, performance was quite similar.

Talk 6: A Snake in the Apple Tree: Bridging Python and Objective-C for Red Team Tradecraft

Author: Luke Roberts (@rookuu), Senior Red Team Engineer at GitHub and co-founder of Phorion
📑 Slides
🎥 Recording

This was the final talk of the day but definitely a really interesting one considering red teaming is one of my aspirations.

The talk covered using the Mythic open-source C2 framework (think of it like an alternative for cobalt strike) and Medusa, an open-source implant that speaks back to the Mythic C2 written in python.

Medusa has functionality for credential theft, persistence, keylogging, screenshots and sniffing clipboards. Luke focused on implementing a clipboard snipper for macOS as the functionality only worked for Python 2.7.

Now we could use libraries that run commands however this would stick out like a sore thumb in blue teams’ logs. If pbpaste was run by Python via a shell that’s definitely something you would want to look into.

Objective-C APIs can be used instead as it’s direct communication with the OS without running a boilerplate, bloat library on top that is easily detected.

Objective-C unlike C has a very powerful runtime instead of having all functionality implemented at the compiler level. This allows for dynamic, runtime changes for example adding methods to classes which is usually prohibited. You, the developer, have direct access to the runtime while the program runs. This means the compiler does not assign function pointers or mappings, since this is decided at runtime and the compiler calls the function for runtime.

So when the compiler calls a function, since the function may change, it uses a feature called message sending. E.g. [mystring length] sends a message length to the object mystring. The message is sent to the receiver through the obj_msgSend function.

So we can use a C-based library to make Objective-C runtime calls but we want to implement a feature to make these calls in Python for the Mythic implant. Python has a great library ctypes to run C code in Python.

However, there is a lot of boiler plate code to complete simple behaviours, so Luke proposed creating an interface to abstract and hide all the boilerplate.

Luke then showcased a demo on running the code on the implant with the Mythic C2 platform.

Happy hour

I then spent the happy hour:

  • Asking Luke for career direction advice (I’m still not sure whether I want to specialise in malware analysis, red teaming or vulnerability research). Luke mentioned that I should further explore and learn which area I lean towards. For red teaming he recommended doing some bug bounties for actual practical experience instead of just hack the box as well as reading write ups for malware and vulnerability research.
  • Asking Patrick about why anti-malware tools don’t check for different variants of loaders being used that are not in line with the current released loader. For which he answered, that would be a great idea for a tool and definitely something he would do if he created a tool with that within its scope. I then asked why Apple notarised this malicious loaders - allowing them to run - for which he had as much of an idea as me.
  • I had also asked Patrick: “in terms of a bootstrapping perspective, how would the malware author ensure the payload that downloads and compiles the malicious loader is executed?”" He then responded that this would require stager/dropper to fetch and switch the loader so that we can use apples deprecated API to memory load our main payload