Apple exploits (and for that matter, any platform exploits) are a plenty. But most of them are fun, and as long as you can play around with them and understand what is going on constructively, it makes for an interesting look at the underbellies of most Operating Systems, processes and platforms.
So when my brother sent me this link to a YouTube short, I tried it out – half expecting it to not work. But then, after a couple of attempts, it actually did!
Here is a video of the “exploit” 🙂
So this is an iPhone 11 running IOS 14.6 and except for a couple of attempts, this works flawlessly! Cool right?
Except, it’s not what this actually looks like once you get into a little more detail 🙂 Let me explain
So the first things I did was reproduce the issue, then generate the sysdiagnose bundle. I then airdropped it on to my MacBook (yes work laptop, sorry, Nutanix IT) and spent the rest of the night trying to make sense of the logs
Long story short, this is what the “Error” trace looked like (I thought!)
2021-06-12 22:23:25.919946+0530 0x2a6481 Default 0x7a4077 179 7 homed: (HomeKitDaemon) [com.apple.HomeKit:Process.Monitor] Received app state change: <RBSProcessStateUpdate| proces
s:[daemon<com.apple.SpringBoard>:60] oldState:<RBSProcessState| task:running-active debug:none endowments:[
com.apple.frontboard.visibility
] rbAssertions:[
<RBSProcessAssertionInfo| type:1 reason:0 name:"Custom" domain:"(null)" expl:"injecting inherited from "UIRootWindow:0x1002317b0" to 60<UIScene:com.apple.frontboard.systemappservices::com.apple.sp
ringboard>">,
<RBSProcessAssertionInfo| type:2 reason:0 name:"Domain" domain:"com.apple.underlying:UnderlyingDarwinRoleUI" expl:"RB Underlying Assertion">,
<RBSProcessAssertionInfo| type:1 reason:0 name:"Custom" domain:"(null)" expl:"injecting inherited from "UIScene:com.apple.frontboard.systemappservices::com.apple.springboard" to 60<UIScene:com.app
le.frontboard.systemappservices::com.apple.springboard>">,
<RBSProcessAssertionInfo| type:1 reason:0 name:"Custom" domain:"(null)" expl:"creating 60<UIRootWindow:0x1002317b0> visibility">,
<RBSProcessAssertionInfo| type:1 reason:0 name:"Custom" domain:"(null)" expl:"FBSystemApp-PreventIdleSleep">,
<RBSProcessAssertionInfo| type:1 reason:0 name:"Custom" domain:"(null)" expl:"creating 60<UIRootWindow:0x105008050> visibility">,
<RBSProcessAssertionInfo| type:1 reason:10005 name:"Custom" domain:"(null)" expl:"FBSystemShell">
]> newState:<RBSProcessState| task:running-active debug:none endowments:[
com.apple.frontboard.visibility
] rbAssertions:[
<RBSProcessAssertionInfo| type:1 reason:10005 name:"Custom" domain:"(null)" expl:"FBSystemShell">,
<RBSProcessAssertionInfo| type:1 reason:0 name:"Custom" domain:"(null)" expl:"creating 60<UIRootWindow:0x105008050> visibility">,
<RBSProcessAssertionInfo| type:2 reason:0 name:"Domain" domain:"com.apple.underlying:UnderlyingDarwinRoleUI" expl:"RB Underlying Assertion">,
<RBSProcessAssertionInfo| type:1 reason:0 name:"Custom" domain:"(null)" expl:"injecting inherited from "UIRootWindow:0x1002317b0" to 60<UIScene:com.apple.frontboard.systemappservices::com.apple.sp
ringboard>">,
<RBSProcessAssertionInfo| type:1 reason:0 name:"Custom" domain:"(null)" expl:"creating 60<UIRootWindow:0x1002317b0> visibility">,
<RBSProcessAssertionInfo| type:1 reason:0 name:"Custom" domain:"(null)" expl:"FBSystemApp-PreventIdleSleep">
]> exitEvent:(null)>
2021-06-12 22:23:25.920226+0530 0x2a6474 Default 0x7a463c 60 0 SpringBoard: (UserNotificationsServer) [com.apple.UserNotifications:RemoteNotifications] [com.apple.calculator] com.
apple.calculator application state changed to BackgroundTaskSuspended
But then, taking a look at this stack a little more, this looks to be a Springboard crash. Would that really cause the Auth/FaceID bit to fail? Plus the Calculator bit doesn’t work everytime. At times, irrespective of how you orient your screen, the Scientific Calculator mode does not trigger!
This got me thinking. So I spent the good part of a quarantined rainy day to try and figure out what the heck is going on
After trying for a couple of hours and checking the logs, things got even more confusing.
This is the same assert prior to the issue being attempted
2021-06-09 18:55:29.672470+0530 0x13c64f Default 0x37697a 179 7 homed: (HomeKitDaemon) [com.apple.HomeKit:Process.Monitor] Received app state change: <RBSProcessStateUpdate| process:[daemon<com.apple.SpringBoard>:60] oldState:<RBSProcessState| task:running-active debug:none endowments:[
com.apple.frontboard.visibility
] rbAssertions:[
<RBSProcessAssertionInfo| type:1 reason:0 name:"Custom" domain:"(null)" expl:"creating 60<UIRootWindow:0x1002317b0> visibility">,
<RBSProcessAssertionInfo| type:2 reason:0 name:"Domain" domain:"com.apple.underlying:UnderlyingDarwinRoleUI" expl:"RB Underlying Assertion">,
<RBSProcessAssertionInfo| type:1 reason:0 name:"Custom" domain:"(null)" expl:"injecting inherited from "UIRootWindow:0x1002317b0" to 60<UIScene:com.apple.frontboard.systemappservices::com.apple.springboard>">,
<RBSProcessAssertionInfo| type:1 reason:0 name:"Custom" domain:"(null)" expl:"FBSystemApp-PreventIdleSleep">,
<RBSProcessAssertionInfo| type:1 reason:0 name:"Custom" domain:"(null)" expl:"creating 60<UIRootWindow:0x105008050> visibility">,
<RBSProcessAssertionInfo| type:1 reason:10005 name:"Custom" domain:"(null)" expl:"FBSystemShell">
]> newState:<RBSProcessState| task:running-active debug:none endowments:[
com.apple.frontboard.visibility
] rbAssertions:[
<RBSProcessAssertionInfo| type:1 reason:0 name:"Custom" domain:"(null)" expl:"FBSystemApp-PreventIdleSleep">,
<RBSProcessAssertionInfo| type:2 reason:0 name:"Domain" domain:"com.apple.underlying:UnderlyingDarwinRoleUI" expl:"RB Underlying Assertion">,
<RBSProcessAssertionInfo| type:1 reason:0 name:"Custom" domain:"(null)" expl:"injecting inherited from "UIScene:com.apple.frontboard.systemappservices::com.apple.springboard" to 60<UIScene:com.apple.frontboard.systemappservices::com.apple.springboard>">,
<RBSProcessAssertionInfo| type:1 reason:0 name:"Custom" domain:"(null)" expl:"creating 60<UIRootWindow:0x105008050> visibility">,
<RBSProcessAssertionInfo| type:1 reason:0 name:"Custom" domain:"(null)" expl:"creating 60<UIRootWindow:0x1002317b0> visibility">,
<RBSProcessAssertionInfo| type:1 reason:0 name:"Custom" domain:"(null)" expl:"injecting inherited from "UIRootWindow:0x1002317b0" to 60<UIScene:com.apple.frontboard.systemappservices::com.apple.springboard>">,
<RBSProcessAssertionInfo| type:1 reason:10005 name:"Custom" domain:"(null)" expl:"FBSystemShell">
]> exitEvent:(null)>
2021-06-09 18:55:29.673639+0530 0x13c64f Default 0x37697a 179 7 homed: (HomeKitDaemon) [com.apple.HomeKit:Process.Monitor] <HMDProcessInfo, Identifier: 60, Name: SpringBoard, Application Identifier: com.apple.springboard, State: foreground, Monitored: YES, Application: <__HMDApplicationInfo, Bundle Identifier: com.apple.springboard, Vendor Identifier: <[36] {length = 8, bytes = 0x3239453141414543} ... {length = 8, bytes = 0x3345394446463939}>>, Connections: (
"<HMDXPCClientConnection, Name: SpringBoard, Entitlements: com.apple.developer.homekit>"
)> back into foreground
2021-06-09 18:55:29.673824+0530 0x13c64f Default 0x37697a 179 7 homed: (HomeKitDaemon) [com.apple.HomeKit:Process.Monitor] Processing change of state for <HMDProcessInfo, Identifier: 60, Name: SpringBoard, Application Identifier: com.apple.springboard, State: foreground, Monitored: YES, Application: <__HMDApplicationInfo, Bundle Identifier: com.apple.springboard, Vendor Identifier: <[36] {length = 8, bytes = 0x3239453141414543} ... {length = 8, bytes = 0x3345394446463939}>>, Connections: (
"<HMDXPCClientConnection, Name: SpringBoard, Entitlements: com.apple.developer.homekit>"
)>
So that was obviously not the issue. Things got even more interesting when FaceID logs were co-related
2021-06-12 22:23:24.481339+0530 0x2a5e2f Default 0x0 63 0 backboardd: (AttentionAwareness) [com.apple.AttentionAwareness:AttentionAwareness] PearlAttentionSampler.m:448 : 219299.14733: Info: <AWPearlAttentionSampler: 0x10370ab90> (samplingSuppressed: false unitTestSampling: false) updateFaceState:withFaceMetadata: FACE FOUN
D at 219299.14732
2021-06-12 22:23:24.481364+0530 0x2a5e2f Default 0x0 63 0 backboardd: (AttentionAwareness) [com.apple.AttentionAwareness:AttentionAwareness] PearlAttentionSampler.m:592 : 219299.14736: Info: <AWPearlAttentionSampler: 0x10370ab90> (samplingSuppressed: false unitTestSampling: false) completing AWAttentionSamplerState transiti
on (Unknown -> Present)
2021-06-12 22:23:24.481387+0530 0x2a5e2f Default 0x0 63 0 backboardd: (AttentionAwareness) [com.apple.AttentionAwareness:AttentionAwareness] Scheduler.m:73 : 219299.14738: Info: <AWScheduler: 0x10370a2c0> (unitTestScheduler: false) attentionSampler state change (updateFaceState:withFaceMetadata: FACE FOUND at
219299.14732)
2021-06-12 22:23:24.481598+0530 0x2a5e2f Default 0x0 63 0 backboardd: (AttentionAwareness) [com.apple.AttentionAwareness:AttentionAwareness] PearlAttentionSampler.m:592 : 219299.14757: Info: <AWPearlAttentionSampler: 0x10370ab90> (samplingSuppressed: false unitTestSampling: false) completing AWAttentionSamplerState transiti
on (Present -> Unknown)
2021-06-12 22:23:24.481630+0530 0x2a5e2f Default 0x0 63 0 backboardd: (AttentionAwareness) [com.apple.AttentionAwareness:AttentionAwareness] Scheduler.m:73 : 219299.14762: Info: <AWScheduler: 0x10370a2c0> (unitTestScheduler: false) attentionSampler state change (updateFaceState:withFaceMetadata: FACE FOUND at
So from the above, my Face ID actually is found before the Calculator app is opened
So what the heck is going on here?
Here is what I was reliably able to reproduce – every time. Consistently
- I was not able to get the Calculator to toggle to Landscape mode at every attempt – the question now was, why?
- When the Calculator was toggled to Landscape mode, it worked like a charm
Looking at this a bit closer, it wasn’t so much the “timing” of the motion of opening Calculator and swiveling the screen as well
And neither was I able to consistently reproduce the Calculator in Landscape mode if I was say filming with another phone in my direct line of sight 🙂
And now that I got that out of the way, reproducing the issue was easy. Points to note
- It does not seem to matter if the Calculator was already on the “Error” screen
- It then, weirdly did not matter what keystrokes I typed 🙂
- It then became obvious I didn’t even have to type anything in the Calculator for this to work 🙂
- The *ONLY* criteria that seemed to matter was the fact that the Calculator could swivel to Landscape mode 🙂 Aha!
So what the heck is actually going on? Here is what I am pretty sure is happening
- When you pull down the notification menu from IOS, by default the phone stays locked. When you move the notification shade up, the phone either attempts a face ID or asks you for your code
- What this hides from the user, is the fact that the phone attempts to FaceID you as soon as you attempt to either access a function that needs the phone to be unlocked or attempt to change a “protected” phone function. Why this becomes easy to fall for, is the fact that unlike the home screen, the notification tray does not offer a way for the user to be aware that FaceID just attempted to authorize you while you were attempting to use the calculator
What does all this mean?
Well in simple terms, as long as you have the Calculator open in front of you, things are going as expected. But as soon as you attempt to swivel the phone to Landscape orientation, FaceID kicks in
Point to note, the Calculator will only switch to landscape mode if FaceID has actually worked 🙂 From this point on, hitting the “Error” via the function keys etc is meaningless as just a swipe up from the white bar will take you to your homescreen 🙂
Still not convinced? Move the phone away from direct line of sight and attempt changing the mode of the calculator. It will not work 🙂 Nor will it work if the person attempting the hack does not have his/her face registered on the device!
Long story short, FaceID works as expected! And there are tons of other hacks and tricks that are out there that are fun, easy to attempt, and helps you understand your device a little better each time!
Happy Weekend everyone!