EPFL's CTF team

CSAW CTF 2018: whyOS


Forensics, 300 points.

Have fun digging through that one. No device needed.

Note: the flag is not in flag{} format

We are given a huge console.log log file (185087 lines), as well as the package for an iPhone app.


Quickly searching for flag or so in the log file doesn’t wield immediate results, so we’ll return to it later.

Digging into the package, we see various interesting files:

Opening the binary in Hopper (or another disassembler), we see that it uses standard Objective-C methods. This confirms we are looking at an iOS app, or something similar. There’s a promising method called setFlag, which decompiles to something like this, using Hopper:

void -[CSAWRootListController setflag](void * self, void * _cmd) {
    sp = sp - 0x30;
    r0 = *self;
    r0 = [r0 alloc];
    r0 = [r0 initWithContentsOfFile:@"/var/mobile/Library/Preferences/com.yourcompany.whyos.plist"];
    var_10 = r0;
    if ([var_10 objectForKey:@"flag", @"flag"] != 0x0) {
            var_2C = [var_10 objectForKey:@"flag", r1];
    else {
            var_2C = @"";
    NSLog(@"%@", var_2C);

It seems that var_2C, which is what the flag was “set” to, will be printed just before this function exits. Importantly, the string is printed alone, without any knwon prefix or suffix that we could search for in the log file.

Returning to the log file, and searching for “whyos”, we get a hint:

default 19:10:40.537634 -0400   Preferences Injecting /Library/TweakInject/Activator.dylib into com.apple.Preferences
default 19:10:53.647765 -0400   amfid   We got called! /Library/PreferenceBundles/whyOSsettings.bundle/whyOSsettings with {
    RespectUppTrustAndAuthorization = 1;
    UniversalFileOffset = 81920;
    ValidateSignatureOnly = 1;
} (info: (null))
default 19:10:53.651675 -0400   amfid   MacOS error: -67062
default 19:10:53.656042 -0400   amfid   MacOS error: -67062
default 19:10:53.659202 -0400   amfid   We got called! AFTER ACTUAL /Library/PreferenceBundles/whyOSsettings.bundle/whyOSsettings with {
    RespectUppTrustAndAuthorization = 1;
    UniversalFileOffset = 81920;
    ValidateSignatureOnly = 1;
} (info: (null))
default 19:10:53.659578 -0400   amfid   ours: {
    CdHash = <610dc945 cd145933 7f552fe5 528afdc7 4bdd0559>;

Hm… injecting libraries into Preferences? This tells us two things:

  1. This is supposed to run on a jailbroken iPhone (which the many logs from Cydia confirm)
  2. The app is not an app, but a sort of extension that gets added to the built-in Preferences app. One big consequence is that when calling NSLog, the corresponding log line will not get a prefix identifying the binary (whyOSsettings), but the Preferences app.

And so we go back to the search, this time looking for log lines for the Preferences app that are fairly short. Even though we don’t know the format of the flag, we know that it is logged on its own, not too long, and unlikely to contain spaces.

 +Preferences +[^ ]{5,50}$

This regular expression wields only 8 matches… we got the flag!

default 19:12:18.884704 -0400   Preferences ca3412b55940568c5b10a616fa7b855e

Later updates

After solving this task, the following hints were added to the task description:

HINT: the flag is literally a hex string. Put the hex string in the flag submission box

Update (09/15 11:45 AM EST) - Point of the challenge has been raised to 300 Update Sun 9:09 AM: its a hex string guys

This makes the task quite a bit easier, since it should only be a matter of writing a regular expression to parse hex strings of a few lengths.