1 00:00:03,020 --> 00:00:12,840 So our next speaker is Jonathan Bar-Orr on how getting a free phone got me to report critical vulnerabilities affecting millions of Android devices. 2 00:00:12,840 --> 00:00:14,120 I am so glad you did that. 3 00:00:14,120 --> 00:00:15,060 Thank you. 4 00:00:15,200 --> 00:00:23,920 Jonathan Bar-Orr, or J-B-O, is the Microsoft Defender Research Architect for cross-platform... blah, blah, blah. 5 00:00:23,920 --> 00:00:25,760 I rented these lips this morning. 6 00:00:25,760 --> 00:00:26,920 They're not working. 7 00:00:27,460 --> 00:00:34,380 Research Architect for cross-platform, focusing on macOS, Linux, Android, and iOS research. 8 00:00:34,420 --> 00:00:42,960 Jonathan has rich offensive security research on various platforms and architectures, as well as a combination of defensive skills and threat research. 9 00:00:42,960 --> 00:00:45,720 So without any further ado, Jonathan, take it over. 10 00:00:57,060 --> 00:00:59,640 You need to pick up a microphone in order to... 11 00:00:59,640 --> 00:01:00,820 Yeah, I know. 12 00:01:00,820 --> 00:01:01,100 Hold on. 13 00:01:01,100 --> 00:01:02,080 Turn it on. 14 00:01:03,080 --> 00:01:03,820 Hold on. 15 00:01:03,820 --> 00:01:05,700 Do I pick that with R or L? 16 00:01:11,680 --> 00:01:12,960 Leave it to R. 17 00:01:14,320 --> 00:01:15,960 Just the left click. 18 00:01:18,720 --> 00:01:19,560 Jesus. 19 00:01:19,560 --> 00:01:20,400 All right. 20 00:01:20,720 --> 00:01:22,680 Can anyone hear me at all? 21 00:01:23,960 --> 00:01:24,560 I can. 22 00:01:24,560 --> 00:01:26,000 Yes, we hear you just fine. 23 00:01:26,740 --> 00:01:29,000 So I do have the mic right now? 24 00:01:30,380 --> 00:01:31,680 I think so. 25 00:01:31,840 --> 00:01:32,440 All right. 26 00:01:32,440 --> 00:01:32,920 Awesome. 27 00:01:32,920 --> 00:01:33,740 Let me check real quick. 28 00:01:36,620 --> 00:01:38,640 Doesn't look like I have the mic, but let me... 29 00:01:39,100 --> 00:01:39,820 Okay. 30 00:01:40,320 --> 00:01:43,220 I turned megaphone on for you, so it should work. 31 00:01:43,220 --> 00:01:43,740 All right. 32 00:01:43,740 --> 00:01:44,120 Awesome. 33 00:01:44,120 --> 00:01:45,340 Thank you so much. 34 00:01:45,340 --> 00:01:47,520 So let's go on the next slide, please. 35 00:01:49,340 --> 00:01:50,720 Who am I? 36 00:01:50,840 --> 00:01:54,360 My name is Jonathan Boror, or JBO for short. 37 00:01:54,480 --> 00:01:57,260 That's my Twitter handle if you ever want to contact. 38 00:01:57,720 --> 00:02:02,400 As I was introduced, I'm the Microsoft Defender for Cross-Platform Research Architect. 39 00:02:02,400 --> 00:02:12,500 That's basically a very long name, but it basically means that I look at everything that does not run Windows, and that's my responsibility. 40 00:02:12,500 --> 00:02:23,960 I do Windows once in a while, though, especially when it comes to, you know, the things that intertwine between Windows and other operating systems like WSL and WSA. 41 00:02:24,020 --> 00:02:28,680 And I released some cool blog posts this year on all of these platforms. 42 00:02:28,740 --> 00:02:31,000 The Chrome OS one will be released soon. 43 00:02:31,380 --> 00:02:32,440 Next slide, please. 44 00:02:35,460 --> 00:02:38,180 Well, how did this get started? 45 00:02:38,180 --> 00:02:46,520 I relocated to the US back in 2017, and I'm an Android user, so I relocated with the same old Android phone that I had back home. 46 00:02:47,080 --> 00:02:56,000 And my carrier, who shall not be named, decommissioned 3G and transitioned into 5G, right, with all the cool stuff that it brings. 47 00:02:56,160 --> 00:03:02,420 And because my phone didn't support 5G, it basically became useless. 48 00:03:02,420 --> 00:03:06,000 So they decided to send me a free phone as compensation. 49 00:03:06,000 --> 00:03:12,400 And, you know, my brain started pounding, and I'm like, should I really trust them? 50 00:03:12,500 --> 00:03:20,860 And I decided not to trust their phone blindly and actually see what's inside and buy myself a new phone and play with the old one. 51 00:03:20,920 --> 00:03:22,860 Next slide, please. 52 00:03:25,940 --> 00:03:29,400 So when exploring a brand new phone, you can do a bunch of stuff. 53 00:03:29,400 --> 00:03:34,420 But first thing first, you know, the easiest things, I decided to look at apps. 54 00:03:34,420 --> 00:03:38,860 And I discovered that there are tons of system apps there. 55 00:03:38,920 --> 00:03:50,480 And one of them seemed to be bundled with something called DTE Ignite, which is an advertisement framework that might install new apps on your phone silently based on your browsing habits. 56 00:03:50,480 --> 00:03:54,760 It sounds terrible, but I'm actually not here to talk about that. 57 00:03:54,760 --> 00:03:57,220 I'm here to talk about something else that I discovered. 58 00:03:57,220 --> 00:04:01,360 So I discovered tons of stuff, but one thing in particular caught my eye. 59 00:04:02,000 --> 00:04:06,380 And that was something called a device health app. 60 00:04:06,380 --> 00:04:09,340 And it's a system app and had tons of permissions. 61 00:04:09,340 --> 00:04:11,100 And that's our focus for today. 62 00:04:11,100 --> 00:04:11,920 Next slide, please. 63 00:04:14,080 --> 00:04:17,720 Just some background, if you're really unfamiliar with Android. 64 00:04:17,720 --> 00:04:20,380 Android apps are conceptually archives. 65 00:04:20,380 --> 00:04:23,420 They're not really archives, but you can think of them as archives. 66 00:04:23,420 --> 00:04:25,220 And they contain various files. 67 00:04:25,220 --> 00:04:29,520 And those files are resources, code, metadata, digital signatures. 68 00:04:29,520 --> 00:04:33,160 They're all separated by design and are basically different files. 69 00:04:33,760 --> 00:04:43,700 And one of the most important sections there is called a manifest, which contains metadata about the app, the app name, version, activities in it, as well as permissions. 70 00:04:43,980 --> 00:04:48,700 And the first thing in any Android app analysis is to examine the permissions that it has. 71 00:04:48,700 --> 00:04:57,000 It's saved under androidmanifest.xml as a binary data, but any basic Android analysis tool translates that XML to a human-readable text. 72 00:04:57,140 --> 00:04:58,700 So just some background. 73 00:04:58,700 --> 00:04:59,500 Next slide, please. 74 00:05:02,280 --> 00:05:04,280 And this is a list. 75 00:05:04,280 --> 00:05:12,080 I don't know how much you can see with the OutSpace VR thingy, but this is a pretty big list of what the app is capable of doing. 76 00:05:12,080 --> 00:05:24,440 And basically, it can access the internet, access Wi-Fi state, read phone state, read external storage, get package size, use the camera, use the fingerprints, record audio, read phone numbers. 77 00:05:24,440 --> 00:05:30,980 And it can do a bunch of stuff that is really overwhelming what it can do. 78 00:05:31,540 --> 00:05:33,100 And the list goes on and on. 79 00:05:33,100 --> 00:05:35,280 This is just a partial screenshot. 80 00:05:44,080 --> 00:05:54,080 So when you look at the activities, they're also in the manifest.xml file, the thing that shows the metadata of the package. 81 00:05:54,440 --> 00:05:59,940 You can see that there is the main activity called com.mceMainActivity. 82 00:05:59,940 --> 00:06:04,040 And then there are a bunch of other stuff there, like the actions and so on. 83 00:06:04,040 --> 00:06:13,620 And the thing that caught my eye is the last two readable lines, the one that says browsable, and then it has the Android scheme mceDigital. 84 00:06:13,620 --> 00:06:17,640 So this is basically like the main activity, and it's browsable. 85 00:06:17,640 --> 00:06:18,900 Next slide, please. 86 00:06:20,580 --> 00:06:26,180 So browsable activities, the app registers a new schema called mceDigital, right? 87 00:06:26,180 --> 00:06:30,700 And basically, when the schema is browsed to, this is an Android feature, right? 88 00:06:30,700 --> 00:06:32,600 The main activity starts. 89 00:06:32,600 --> 00:06:40,460 And this is, for example, how when you open like a Zoom link, you know, Android knows to start Zoom with the right parameters. 90 00:06:40,500 --> 00:06:44,680 It's basically a way for an app to say, hey, I want to register that schema. 91 00:06:44,680 --> 00:06:48,880 And whenever that schema is accessed, please, please wake me up. 92 00:06:49,440 --> 00:06:54,140 And this is the first obvious foothold for a logical remote code execution. 93 00:06:54,140 --> 00:06:57,300 Mentally, that's how I imagine it in my mind. 94 00:06:57,300 --> 00:07:06,120 And sometimes an attacker can pass malicious data with a schema that will be parsed by the activity, like a buggy schema, URL, get parameters, info. 95 00:07:06,680 --> 00:07:12,740 And the next analysis goal for me is, well, what does the app do once it launches through the schema? 96 00:07:12,740 --> 00:07:18,640 And can I give it any meaningful input, right, from the URL that's being accessed? 97 00:07:18,640 --> 00:07:20,300 Next slide, please. 98 00:07:22,200 --> 00:07:27,700 Something about web views, if you've completely been living under a rock in the Android world. 99 00:07:27,700 --> 00:07:34,000 In Android, web views are basically components that can parse and present web content, including JavaScript capabilities. 100 00:07:34,000 --> 00:07:36,880 So they're like almost mini browsers, if you will. 101 00:07:37,460 --> 00:07:43,080 They're useful for app developers, especially for engines that use them extensively cross-platform, right? 102 00:07:43,080 --> 00:07:49,440 So if you want to write an app and make it available in Android and iOS, you can use that. 103 00:07:49,440 --> 00:07:51,500 And web view is a component. 104 00:07:51,500 --> 00:07:53,120 Well, React will do that. 105 00:07:53,120 --> 00:07:57,620 But web view is a component that will be used extensively, actually, to run that app. 106 00:07:57,620 --> 00:07:59,380 And a lot of apps rely on web views. 107 00:07:59,380 --> 00:08:02,400 That's not very, very new. 108 00:08:02,520 --> 00:08:15,120 And, you know, a security question is that granting web view capabilities to do certain things, because a lot of apps are, you know, relying on web views, granting the web view capabilities to do certain things is quite problematic. 109 00:08:15,120 --> 00:08:19,940 Think of unlimited file access from something that behaves like a browser, right? 110 00:08:20,100 --> 00:08:25,380 And plausible scenarios that attacker could actually inject malicious coding to the web view. 111 00:08:25,380 --> 00:08:28,420 And the question is, how does Android solve this problem? 112 00:08:28,420 --> 00:08:29,560 Next slide, please. 113 00:08:30,980 --> 00:08:35,120 And this is achieved by something called an Android base bridge. 114 00:08:35,140 --> 00:08:40,480 An app, it's a web view, and it can declare a JavaScript interface and attach it to the web view. 115 00:08:40,540 --> 00:08:49,020 And from that point on, the web view can actually invoke methods in the app by that interface and get responses back. 116 00:08:49,200 --> 00:08:55,980 The data that can be sent is limited to primitive data types in the Java virtual machine. 117 00:08:56,120 --> 00:08:58,900 And this is what's called an Android.js bridge. 118 00:08:58,900 --> 00:09:00,280 Next slide, please. 119 00:09:00,740 --> 00:09:04,500 This is a toy example of Android.js bridge. 120 00:09:04,500 --> 00:09:13,240 In the first part, you can see Java code that will run in the Java app on the Android device. 121 00:09:13,920 --> 00:09:16,800 You can see that I declare a class called JS interface. 122 00:09:16,800 --> 00:09:19,940 I have to declare something called JavaScript interface. 123 00:09:19,940 --> 00:09:21,920 That's an annotation to a method. 124 00:09:22,200 --> 00:09:24,440 And then the method actually just adds two numbers. 125 00:09:24,440 --> 00:09:26,040 So nothing scary here. 126 00:09:26,380 --> 00:09:30,100 And you can see that I had to do two other things. 127 00:09:30,260 --> 00:09:34,360 Given a web view, I had to basically enable JavaScript. 128 00:09:34,440 --> 00:09:40,700 Then I basically add JavaScript interface with that sense of that class that I just said. 129 00:09:40,700 --> 00:09:42,320 And expose it under name. 130 00:09:42,320 --> 00:09:45,460 In this case, I expose it under some name. 131 00:09:45,560 --> 00:09:48,240 And then the web view can run JavaScript. 132 00:09:48,240 --> 00:09:51,080 That's the lower part of the page here. 133 00:09:51,360 --> 00:09:55,360 And it will basically invoke window.someName.addNumbers. 134 00:09:55,360 --> 00:09:56,860 Just invoke it like that. 135 00:09:56,860 --> 00:10:02,580 And the parameters and everything will be sent from the web view to the Android app. 136 00:10:02,580 --> 00:10:04,440 And then basically invoked. 137 00:10:04,440 --> 00:10:06,100 And I can also get the result. 138 00:10:06,100 --> 00:10:10,280 So this is how you add two numbers with an Android.js bridge. 139 00:10:10,280 --> 00:10:11,460 Next slide, please. 140 00:10:12,320 --> 00:10:15,780 So , only methods. 141 00:10:15,780 --> 00:10:20,280 This is something, just a little more background on Android.js bridges. 142 00:10:20,280 --> 00:10:23,980 Only methods that are annotated with a JavaScript interface annotation. 143 00:10:23,980 --> 00:10:26,660 You've seen that one slide, two slides ago. 144 00:10:26,660 --> 00:10:31,360 Can be invoked starting API level four, which is ages ago. 145 00:10:31,360 --> 00:10:40,120 Otherwise, you get this funny vulnerability where you say, where the web view can do windows.withName.getClassForName, whatever. 146 00:10:40,120 --> 00:10:44,480 You can basically get the runtime.exec method. 147 00:10:44,580 --> 00:10:47,740 This happened in 2004 or something. 148 00:10:47,740 --> 00:10:49,300 So very, very old. 149 00:10:50,620 --> 00:10:57,500 And you can't do that anymore after Android API level four. 150 00:10:58,260 --> 00:11:05,840 And therefore, what I'm trying to say is that an analysis of a JS interface should examine the methods that are annotated with a JavaScript interface. 151 00:11:05,880 --> 00:11:10,100 So this is kind of like a background on why I'm doing what I'm doing. 152 00:11:10,120 --> 00:11:11,800 Next slide, please. 153 00:11:12,900 --> 00:11:17,600 If we're going back to my app analysis, we have the health app, right? 154 00:11:17,700 --> 00:11:20,160 And the health app basically is browsable. 155 00:11:20,160 --> 00:11:25,520 And one thing that I discovered is that it also has a web view called JarvisWebView. 156 00:11:25,520 --> 00:11:27,280 That's how they expose it to the... 157 00:11:29,220 --> 00:11:30,420 Actually, not expose it. 158 00:11:30,420 --> 00:11:32,800 This is how they declare it in the classes there. 159 00:11:32,820 --> 00:11:37,740 And the web view has an attached JavaScript interface called JarvisJSInterface. 160 00:11:37,740 --> 00:11:39,620 That's just the name that they expose. 161 00:11:40,120 --> 00:11:50,900 And the interfaces can be accessed from within the web page via the JavaScript bridges and invoke accessible methods. 162 00:11:52,100 --> 00:11:56,860 And one remark is that they're notorious for trust issues, right? 163 00:11:56,860 --> 00:12:01,300 In many cases, the app can blindly trust the web view's input, right? 164 00:12:01,300 --> 00:12:03,140 And next slide, please. 165 00:12:03,520 --> 00:12:08,980 This is kind of like a code blurb of the annotated methods that I found. 166 00:12:09,560 --> 00:12:12,240 Three out of four of the annotated methods. 167 00:12:12,240 --> 00:12:15,420 And I'll explain why I added the third one as well. 168 00:12:15,460 --> 00:12:16,880 The first one is called init. 169 00:12:16,880 --> 00:12:18,220 It gets a string. 170 00:12:18,220 --> 00:12:25,260 And it basically saves something that I, you know, while reverting, just called a callback name. 171 00:12:25,260 --> 00:12:26,760 The second one is called request. 172 00:12:26,760 --> 00:12:27,860 It gets a string. 173 00:12:27,860 --> 00:12:31,180 And it calls super.request with that string. 174 00:12:31,460 --> 00:12:34,580 The third one is called sendResponse. 175 00:12:34,580 --> 00:12:38,960 And it's not annotated, so you can't really access it from the web view. 176 00:12:38,980 --> 00:12:43,240 And the fourth one is called window.close, which is not very interesting. 177 00:12:43,240 --> 00:12:46,040 And I'm just not going to talk about that at all. 178 00:12:46,040 --> 00:12:47,120 Slide, please. 179 00:12:48,520 --> 00:12:58,780 From a software design perspective, the JarvisJS interface that we saw in the app, it works as an asynchronous server to the JavaScript client. 180 00:12:58,780 --> 00:13:04,020 It gets requests in the three methods that I've just shown you. 181 00:13:04,240 --> 00:13:08,120 And returns callbacks by injecting JavaScript back to the web view. 182 00:13:08,660 --> 00:13:11,800 This kind of explains the stuff that we saw earlier. 183 00:13:13,200 --> 00:13:15,700 Init basically gets a string and saves it. 184 00:13:15,700 --> 00:13:20,720 That string is going to be used later as a callback function, JavaScript function, to the client. 185 00:13:21,020 --> 00:13:22,500 CloseWindow is not very interesting. 186 00:13:22,500 --> 00:13:26,320 And request serves requests from the JavaScript client. 187 00:13:26,540 --> 00:13:30,760 And this also explains the response methods that we saw earlier. 188 00:13:30,760 --> 00:13:31,800 The response methods... 189 00:13:31,800 --> 00:13:33,900 Would you actually mind going back one slide? 190 00:13:33,900 --> 00:13:35,000 Is that possible? 191 00:13:35,580 --> 00:13:36,720 Awesome, thank you. 192 00:13:36,720 --> 00:13:45,280 The sendResponse method that we saw is going to be invoked later by the app when it's ready to send a response. 193 00:13:45,580 --> 00:13:48,580 And if you can see the code there, I know it's a bit difficult. 194 00:13:48,580 --> 00:13:56,380 But basically, it's going to build a URL that starts with JavaScript colon and add some JavaScript code there. 195 00:13:56,380 --> 00:13:59,280 That also includes the callback name, by the way. 196 00:13:59,340 --> 00:14:02,700 And basically, inject it with loadUrl. 197 00:14:02,700 --> 00:14:05,680 That's the last line in the third method here. 198 00:14:06,400 --> 00:14:09,020 Next slide, and then next slide again. 199 00:14:11,820 --> 00:14:13,840 The request method is... 200 00:14:14,740 --> 00:14:20,000 Well, the request method actually invokes the superclass.request. 201 00:14:20,080 --> 00:14:25,320 And the superclass for that JavaJS interface is just called serviceTransport. 202 00:14:25,460 --> 00:14:29,600 And after some unimportant tasks, I examined what it does. 203 00:14:29,600 --> 00:14:32,680 And it will treat the input string as a JSON object. 204 00:14:32,680 --> 00:14:34,620 And it extracts some members from it. 205 00:14:35,120 --> 00:14:36,720 Those are the four members. 206 00:14:36,720 --> 00:14:40,720 First of all, there is context, which I think of as a request ID. 207 00:14:40,720 --> 00:14:50,540 Basically, in an asynchronous model, when you have a client in a server, the client needs to supply, or in some way, there needs to be tracing of some request ID. 208 00:14:50,540 --> 00:14:52,320 So that's the context, basically. 209 00:14:52,640 --> 00:14:54,280 Service is a service name. 210 00:14:54,280 --> 00:14:55,680 More on that later. 211 00:14:55,680 --> 00:14:57,080 Command is an integer. 212 00:14:57,080 --> 00:14:58,860 Effectively, it's a command number. 213 00:14:58,860 --> 00:15:03,340 And data is effectively the arguments that are sent with that command. 214 00:15:03,340 --> 00:15:04,300 Next slide, please. 215 00:15:06,420 --> 00:15:23,480 And, you know, when you start to take a look at the services that are implemented, again, let me remind everyone, if I have malicious code that runs in the web view, I can basically invoke the JavaJS interface methods. 216 00:15:23,480 --> 00:15:25,180 One of them is called request. 217 00:15:25,300 --> 00:15:28,940 And with request, I can actually invoke services. 218 00:15:28,940 --> 00:15:30,280 And what does that mean? 219 00:15:30,500 --> 00:15:32,580 So I started reverse engineering that thing. 220 00:15:32,580 --> 00:15:36,820 And there are many services that get registered in a global table. 221 00:15:36,820 --> 00:15:40,140 I won't bore you with the gory details too much. 222 00:15:40,140 --> 00:15:43,300 But basically, there is a global table that is saved. 223 00:15:43,300 --> 00:15:51,020 And each service declares its exposed methods, maps them to command members, along with the argument names and types it expects. 224 00:15:51,160 --> 00:15:57,240 And the entire request is being translated on the flight with JavaScript reflection. 225 00:15:57,360 --> 00:16:05,540 And each request can also invoke the send response methods that we saw earlier to actually return a response to the client. 226 00:16:05,820 --> 00:16:07,140 Next slide, please. 227 00:16:07,880 --> 00:16:16,660 Some of the invocable services that I saw, this is a very partial list of interesting services that are accessible from the web view. 228 00:16:16,660 --> 00:16:18,020 One of them is audio. 229 00:16:18,020 --> 00:16:22,780 You can control audio on the phone, including peripheral volumes and stuff like that. 230 00:16:22,780 --> 00:16:25,980 Camera, you can take silent camera pictures. 231 00:16:26,260 --> 00:16:30,440 Connectivity, you can basically control Wi-Fi, Bluetooth, NFC, and whatnot. 232 00:16:30,440 --> 00:16:33,040 Device controls many aspects of the device. 233 00:16:33,040 --> 00:16:35,940 I also found the command injection there, more on that later. 234 00:16:36,160 --> 00:16:39,740 Location, you can access GPS and whatnot. 235 00:16:39,740 --> 00:16:48,020 Package manager, you can control packages, you can install new apps, which, by the way, because you're a system app, you can do that silently. 236 00:16:48,020 --> 00:16:50,100 So, not great. 237 00:16:50,760 --> 00:16:57,880 So, basically, my understanding is that Hiku controls the JavaScript, controls the device. 238 00:16:57,880 --> 00:17:02,680 If you're able to get malicious JavaScript code, the web view, you basically win. 239 00:17:02,680 --> 00:17:06,560 Because it can do a lot of those stuff and many, many more. 240 00:17:06,560 --> 00:17:07,820 Next slide, please. 241 00:17:08,660 --> 00:17:11,640 This is an example of the camera service. 242 00:17:11,900 --> 00:17:14,440 This is actually how the code looks like. 243 00:17:14,500 --> 00:17:16,780 After some predefining by me. 244 00:17:16,880 --> 00:17:18,000 You have basically... 245 00:17:18,720 --> 00:17:22,800 all services must implement something called set service methods map. 246 00:17:22,800 --> 00:17:28,800 That's what I referred to earlier as kind of registering their own methods. 247 00:17:28,800 --> 00:17:31,340 And you can see that there are two methods exposed here. 248 00:17:31,340 --> 00:17:32,740 One of them is get camera list. 249 00:17:32,740 --> 00:17:35,360 And the other one is capture still image no preview. 250 00:17:35,360 --> 00:17:40,500 And get camera list basically gets no arguments. 251 00:17:40,500 --> 00:17:46,160 And capture still image no preview gets one argument, which is called camera ID. 252 00:17:46,160 --> 00:17:47,260 And it's a string. 253 00:17:47,860 --> 00:17:55,220 And there is another class called IPC, which maps the method names to the actual numbers. 254 00:17:55,220 --> 00:17:57,900 So, method number zero is get camera list. 255 00:17:57,900 --> 00:18:00,840 Method number one is capture still image no preview. 256 00:18:00,840 --> 00:18:03,040 That's just an example of how a service looks like. 257 00:18:03,040 --> 00:18:06,900 And then the service can implement those methods however it sees fit. 258 00:18:06,900 --> 00:18:08,440 Next slide, please. 259 00:18:10,020 --> 00:18:14,440 Well, one of the services in device specifically gets... 260 00:18:14,440 --> 00:18:16,300 this is just a command injection that I found. 261 00:18:16,300 --> 00:18:17,900 I mentioned that two slides ago. 262 00:18:17,900 --> 00:18:23,720 One of the services that gets an activity name and tries to stop it by running the following command. 263 00:18:23,720 --> 00:18:29,060 am force-stop, open quotes, activity name, close quotes. 264 00:18:29,060 --> 00:18:33,440 And guess what happens when the activity name has quotation marks. 265 00:18:33,440 --> 00:18:39,860 So, surprise, surprise, if the activity name has quotation marks, you can basically run arbitrary commands, right? 266 00:18:39,860 --> 00:18:41,780 So, this is kind of a command injection. 267 00:18:41,780 --> 00:18:47,640 Just in case I wanted to take control of the device even further, this would basically allow me to... 268 00:18:47,640 --> 00:18:57,600 if I'm able to run malicious code in the web view, to inject arbitrary code to run as the device health app, which is a system app again. 269 00:18:58,140 --> 00:19:01,480 So, this is just one thing, one minor thing that I found. 270 00:19:01,500 --> 00:19:02,760 Slide, please. 271 00:19:04,060 --> 00:19:08,060 At this point, I was pretty convinced that, you know, this is big. 272 00:19:08,120 --> 00:19:14,520 And I assume that a JavaScript injection is possible somehow to the web view. 273 00:19:14,520 --> 00:19:18,900 And if we assume that, we can control the phone with all the services. 274 00:19:18,900 --> 00:19:30,600 And we can abuse the command injection or simply do other fun stuff, like taking camera snapshots, turning on the microphone, you know, all the fun stuff that you see in the movies. 275 00:19:31,040 --> 00:19:34,380 So, you know, you have to do this kind of mental exercise. 276 00:19:34,380 --> 00:19:38,220 And, you know, I was like, this is too good not to inject into. 277 00:19:38,220 --> 00:19:39,280 There must be a way. 278 00:19:39,280 --> 00:19:51,200 So, even before I was convinced I'm going to inject into the web view, I basically implemented my own exploit, which is kind of like a post-exploit, if you think about it, because you still have to inject into the web view. 279 00:19:51,520 --> 00:19:52,640 And this is what I did. 280 00:19:52,640 --> 00:19:53,760 Next slide, please. 281 00:19:55,140 --> 00:19:57,920 This is kind of like a post-exploit code. 282 00:19:57,920 --> 00:20:05,200 You basically implement just the thing that the web view is supposed to implement, right? 283 00:20:05,200 --> 00:20:09,040 So, basically, create some map. 284 00:20:09,060 --> 00:20:11,720 I created a C2 just for us to have fun. 285 00:20:11,720 --> 00:20:13,880 And you can invoke that with Ajax. 286 00:20:13,960 --> 00:20:15,500 And you can set the callback. 287 00:20:15,500 --> 00:20:23,000 If you can see in the last part, it says window.response callback equals whatever. 288 00:20:23,000 --> 00:20:28,230 And then you can actually call the bridge and initiate that with whatnot. 289 00:20:28,880 --> 00:20:29,950 Next slide, please. 290 00:20:31,120 --> 00:20:36,160 And this is kind of like a generic code for the send request part. 291 00:20:36,160 --> 00:20:43,090 This actually sends a request to the web view, to the JS bridge, sorry. 292 00:20:43,090 --> 00:20:45,510 And this makes everything very simple. 293 00:20:45,510 --> 00:20:53,630 Because now, if you look at the right part, you will see that it says, basically, this is how you run stuff from the web view, if you could inject into it. 294 00:20:53,630 --> 00:20:56,010 You basically do exploit equals new exploit. 295 00:20:56,010 --> 00:21:01,130 And then exploit.getCameraList, exploit.storage, do whatever, and so on. 296 00:21:01,130 --> 00:21:04,210 So, you can just invoke those methods freely. 297 00:21:04,210 --> 00:21:06,630 As I said, you can basically control the phone. 298 00:21:06,710 --> 00:21:07,850 So, I prepared that. 299 00:21:07,850 --> 00:21:13,050 And, you know, I basically patched the app just to see that it works and it works well. 300 00:21:13,730 --> 00:21:15,550 Next slide, please. 301 00:21:16,710 --> 00:21:20,190 Kind of like a mid-talk summary, because we've been through a lot. 302 00:21:20,230 --> 00:21:21,590 Have a system app. 303 00:21:21,590 --> 00:21:24,630 That system app is pre-installed on the phone. 304 00:21:24,750 --> 00:21:30,590 And it has a remotely invocable main activity through a browsable activity, right? 305 00:21:30,590 --> 00:21:32,910 If you... the MC digital thing. 306 00:21:32,910 --> 00:21:35,470 The activity loads a web view, right? 307 00:21:35,470 --> 00:21:39,390 That if... and I put a strong emphasis on if. 308 00:21:39,390 --> 00:21:42,830 If injected into can essentially take over the phone. 309 00:21:43,090 --> 00:21:47,690 And we can build an exploit code that does just that. 310 00:21:47,690 --> 00:21:50,510 But can we really inject into web view? 311 00:21:50,510 --> 00:21:52,750 That's the question that I had in mind. 312 00:21:52,750 --> 00:21:58,810 And that's the 1 million vulnerable Android apps... devices question. 313 00:21:58,810 --> 00:21:59,810 Next slide, please. 314 00:22:01,630 --> 00:22:05,570 Well, the first attempt to inject was that... 315 00:22:07,510 --> 00:22:11,930 I discovered that the page that is being loaded to the web view is loaded... 316 00:22:12,510 --> 00:22:15,750 is actually embedded in the app itself as an asset. 317 00:22:16,010 --> 00:22:20,890 So a web view can, you know, just like a normal browser, can just load stuff from HTTP. 318 00:22:20,890 --> 00:22:24,950 Or it can load stuff from like file, comma, slash, slash, right? 319 00:22:24,950 --> 00:22:26,210 Like an asset. 320 00:22:26,230 --> 00:22:28,570 And this is what happens in this case. 321 00:22:28,590 --> 00:22:34,630 And the JavaScript code that runs on the web is quite obfuscated and was extremely long. 322 00:22:34,730 --> 00:22:37,770 Like 100k lines long. 323 00:22:37,910 --> 00:22:43,950 And, you know, at this point, by the way, I did forget to mention, like, it became too big for me. 324 00:22:43,950 --> 00:22:47,670 And I'm like, okay, let's involve our Android team, because why not? 325 00:22:47,690 --> 00:22:52,130 And I basically involved our Android V team in Defender. 326 00:22:52,130 --> 00:22:55,190 And we reversed engineered parts of it. 327 00:22:55,190 --> 00:22:59,630 But we couldn't find meaningful ways to affect the behavior from the browsable intent. 328 00:22:59,850 --> 00:23:01,990 So that was kind of a bummer. 329 00:23:02,210 --> 00:23:08,490 And the second hope that I had was to basically have, like, kind of like a person in the middle story. 330 00:23:08,490 --> 00:23:18,630 If the app is opened and the web view opens a plain text page, I can basically inject as just because I'm like a person in the middle between the phone and the internet. 331 00:23:18,690 --> 00:23:21,870 And we did find several scenarios when that happens. 332 00:23:21,870 --> 00:23:24,350 And this is kind of like a success, right? 333 00:23:24,350 --> 00:23:32,630 Because basically what you have to do right now is, in my opinion, you know, it's not trivial, but it's not impossible. 334 00:23:32,630 --> 00:23:34,130 Next slide, please. 335 00:23:35,950 --> 00:23:39,830 So the scenario for remote code execution in this case. 336 00:23:39,950 --> 00:23:41,690 Be a person in the middle, right? 337 00:23:41,690 --> 00:23:43,630 You can achieve that in numerous ways. 338 00:23:43,630 --> 00:23:47,690 Like I can open, you know, a Starbucks Wi-Fi on my phone or something. 339 00:23:47,690 --> 00:23:52,650 I can, you know, control your router or do other stuff. 340 00:23:53,090 --> 00:23:59,290 Send a link to the target or inject it into a normal plain text web view that the target just browses into. 341 00:23:59,290 --> 00:24:03,210 And trigger the browsable activity, the MC digital thing. 342 00:24:03,210 --> 00:24:13,250 Because the MC digital browser activity actually kicks in and it's registered by that device health app, which is a system app that was, by the way, hidden from the UI. 343 00:24:13,410 --> 00:24:14,990 The app kicks in. 344 00:24:14,990 --> 00:24:23,190 The app loads the web view, which runs complicated logic and ends up viewing more contents in plain text, right? 345 00:24:23,190 --> 00:24:26,510 Load stuff from external HTTP over plain text. 346 00:24:26,510 --> 00:24:30,870 And then I inject malicious JavaScript code into the plain text code. 347 00:24:30,870 --> 00:24:34,850 And, you know, I run my exploit and I basically take over the phone. 348 00:24:34,850 --> 00:24:36,690 So that's pretty good. 349 00:24:37,530 --> 00:24:39,290 Next slide, please. 350 00:24:40,030 --> 00:24:45,190 It sounds like our kind of fun RCE on Android is over. 351 00:24:45,190 --> 00:25:00,290 But, you know, one thing that got me a bit worried or a bit, you know, intrigued was the fact that during the reverse engineering, we saw that, like, you know, I got my phone from my carrier. 352 00:25:00,290 --> 00:25:06,770 In all of the class names and whatnot, when reverse engineering that app, we didn't see that, like, carrier name at all. 353 00:25:07,490 --> 00:25:12,190 And we suspected that there is an entire framework, which was not carrier specific, right? 354 00:25:12,190 --> 00:25:15,770 You did see that MCA digital thing and so on. 355 00:25:17,090 --> 00:25:27,370 And basically tried to assess, you know, we already had an RCE and I was going to basically disclose it responsibly. 356 00:25:27,530 --> 00:25:33,910 But when assessing the number of affected devices, we decided to hunt for similar apps that might be using the same framework. 357 00:25:33,910 --> 00:25:39,330 And, you know, there is no shame to say we actually just used VirusTotal. 358 00:25:39,470 --> 00:25:45,410 And surprisingly, we discovered numerous telcos that use the same framework, right? 359 00:25:45,410 --> 00:25:47,010 So imagine all the big telcos. 360 00:25:47,010 --> 00:25:49,730 I will not mention anyone because I don't want to be sued. 361 00:25:49,770 --> 00:25:54,430 But imagine, you know, all the big telcos in America and whatnot. 362 00:25:54,710 --> 00:25:59,330 I mean, this was embedded in five of them and big ones. 363 00:26:00,670 --> 00:26:05,390 There seemed to be some customization per telco. 364 00:26:05,390 --> 00:26:10,250 So one telco might have certain features and a different telco might have other features. 365 00:26:10,270 --> 00:26:14,770 Obviously, besides the app name and logos that are used and stuff like that. 366 00:26:14,770 --> 00:26:19,150 And not all apps were susceptible to like the person in the middle attack, right? 367 00:26:19,150 --> 00:26:25,470 Some of them actually did not load external code from plain text. 368 00:26:25,470 --> 00:26:28,610 So the remote code execution part didn't work. 369 00:26:28,610 --> 00:26:43,750 And one thing that I also discovered is that besides those five telcos, there are certain apps that use that framework that might be installed by phone repair shops or for trading purposes. 370 00:26:43,750 --> 00:26:51,250 So if it wasn't clear, the device health app is supposed to basically make sure that the camera is working, that the microphone is working. 371 00:26:51,250 --> 00:26:54,050 This is why it needed all of those permissions. 372 00:26:54,050 --> 00:26:59,590 And basically, some of those telcos pre-installed it in the firmware, right? 373 00:26:59,590 --> 00:27:01,930 That's what I've got initially. 374 00:27:01,930 --> 00:27:07,610 But we also discovered that there is a specific app that can be installed by repair shops. 375 00:27:07,610 --> 00:27:14,990 And sometimes they forget to uninstall the app after you get your phone back from fixed and whatnot. 376 00:27:14,990 --> 00:27:18,350 So this is another issue that we saw. 377 00:27:18,990 --> 00:27:29,430 Users are always, in this case, either because the app is baked into the firmware or because you got your phone fixed and someone installed an app unbeknownst to you. 378 00:27:29,510 --> 00:27:36,630 And users were always, to the best of my knowledge, unsuspecting that this thing even existed. 379 00:27:37,070 --> 00:27:38,510 Next slide, please. 380 00:27:39,990 --> 00:27:48,190 So we decided to dig deeper and see if we could exploit the apps that were not susceptible to the person-in-the-middle JavaScript injection. 381 00:27:48,890 --> 00:27:52,430 And eventually, we found a local JavaScript injection. 382 00:27:53,090 --> 00:27:57,090 And this is like... I won't actually wait for responses. 383 00:27:57,090 --> 00:28:01,390 But the question is, can you spot the injection opportunity with the next slide? 384 00:28:03,410 --> 00:28:05,210 So this is kind of like... 385 00:28:05,930 --> 00:28:09,470 Well, this code is taken from multiple methods. 386 00:28:09,470 --> 00:28:18,890 But basically, the injection part actually resides in the last part, in the third part. 387 00:28:19,210 --> 00:28:28,310 But basically, what's going to happen here is that you get some parameter called flow input that I will mention what it does briefly in a sec. 388 00:28:28,310 --> 00:28:33,970 But basically, this flow input is going to be sent to the WebView's init function. 389 00:28:34,070 --> 00:28:37,890 The init function is going to basically see if it's empty. 390 00:28:37,890 --> 00:28:42,710 And if it's not empty, it's going to save it in other member name. 391 00:28:42,710 --> 00:28:54,690 And later, that member name, if it's not empty, is going to be basically loaded into the WebView with load URL again, just like the JavaScript injection that we saw earlier. 392 00:28:54,950 --> 00:28:56,150 Next slide, please. 393 00:28:58,270 --> 00:29:00,590 This is kind of like what I mentioned. 394 00:29:00,590 --> 00:29:03,470 There is a member called mflow SDK input. 395 00:29:03,470 --> 00:29:05,850 By the way, I have no idea what it's supposed to do. 396 00:29:05,850 --> 00:29:07,850 I never saw it actually being used. 397 00:29:07,850 --> 00:29:09,650 But the member exists. 398 00:29:09,870 --> 00:29:15,610 And the member is a JSON object stringified and perfectly injected into the WebView, as we saw. 399 00:29:15,610 --> 00:29:28,750 The interesting part, and this is where the injection kicks in, there is no string sanitization on the string itself, which means that we could inject it to control that member, right? 400 00:29:28,750 --> 00:29:34,260 If I can control that member, I can actually inject JavaScript into the WebView locally. 401 00:29:35,290 --> 00:29:43,390 And the member is initialized very indirectly, like there are four or five different classes there, by the intent that creates the app. 402 00:29:43,390 --> 00:29:51,990 Interestingly, from a Google Firebase parcel, it doesn't really matter that much, but just because it's funny to me. 403 00:29:52,330 --> 00:29:54,090 Next slide, please. 404 00:29:54,390 --> 00:29:56,790 I did have one pesky limitation. 405 00:29:56,790 --> 00:30:18,250 That the entire payload, because we're talking about the JSON object, and it's going to be, you know, eventually turned into a string, and then injected into the WebView with a JavaScript injection, the entire payload can contain new lines, because JSON stuff, 406 00:30:18,250 --> 00:30:23,150 but you can easily overcome that with eval, a2b, and then base64 encoded payload. 407 00:30:23,150 --> 00:30:36,230 So, if you have a payload, you can just turn it into base64, and then add some code to, you know, unwrap and undo what you wanted, like the entire base64 thingy. 408 00:30:36,410 --> 00:30:41,170 And basically, this is kind of like how you run JavaScript code in one line, right? 409 00:30:41,170 --> 00:30:43,370 Which is not a big thing, but still. 410 00:30:43,930 --> 00:30:45,490 Next slide, please. 411 00:30:46,670 --> 00:30:51,330 Oh, this has a nice PowerPoint animation. 412 00:30:51,330 --> 00:30:52,490 Kudos to me. 413 00:30:52,890 --> 00:30:55,470 In the left side, you can see the app itself. 414 00:30:55,470 --> 00:30:57,710 In the middle part, you can see the WebView. 415 00:30:57,710 --> 00:31:00,950 And in the right part, there is an attacker, right? 416 00:31:00,950 --> 00:31:06,270 And basically, what's going to happen, and can you click one time, please? 417 00:31:07,310 --> 00:31:10,690 You basically, I prepared like the second stage JS loader. 418 00:31:10,690 --> 00:31:17,330 That's the first, like, part where, you know, the entire payload where I assumed that I could inject. 419 00:31:17,330 --> 00:31:18,770 So, I have that code. 420 00:31:18,770 --> 00:31:20,370 And then, next, click, please. 421 00:31:21,310 --> 00:31:27,490 I wrap it with eval a2b and base64, but just to make it a one-liner. 422 00:31:27,510 --> 00:31:28,930 Next, please. 423 00:31:29,630 --> 00:31:33,150 I wrap it into some member that is called dynamic. 424 00:31:33,150 --> 00:31:35,930 This is how Google Firebase works in this case. 425 00:31:35,930 --> 00:31:37,350 Next one, please. 426 00:31:37,690 --> 00:31:40,090 I wrap it into something called a parcel. 427 00:31:40,090 --> 00:31:46,410 How objects are basically being serialized in Android. 428 00:31:46,690 --> 00:31:47,870 Next, please. 429 00:31:48,890 --> 00:31:54,930 This thing is turned into bytes, because this is how you, like, intents can just contain bytes. 430 00:31:54,930 --> 00:31:55,930 Next one, please. 431 00:31:56,830 --> 00:32:00,670 Then, I wrap it into an intent. 432 00:32:00,670 --> 00:32:07,710 An intent, basically, I didn't mention it, but that's the way that you, that's a very popular IPC in Android. 433 00:32:08,170 --> 00:32:12,790 And basically, it's the thing that fires apps and activities and whatnot. 434 00:32:13,250 --> 00:32:14,770 Next, click, please. 435 00:32:15,030 --> 00:32:16,970 So, the intent gets into the app. 436 00:32:16,970 --> 00:32:17,870 Next, click. 437 00:32:18,890 --> 00:32:29,910 And then, the app unwraps it, takes the bytes, unwraps it, takes the parcel, unwraps it, and so on. 438 00:32:29,910 --> 00:32:31,430 It does all of those things. 439 00:32:31,430 --> 00:32:35,250 And eventually, it will basically run the second stage JS loader. 440 00:32:35,250 --> 00:32:37,790 It will load the JavaScript into the web view. 441 00:32:37,790 --> 00:32:39,270 Next one, please. 442 00:32:39,810 --> 00:32:41,970 The web view loads the JavaScript. 443 00:32:41,970 --> 00:32:46,290 The web view actually loads additional JavaScript from my C2. 444 00:32:46,490 --> 00:32:48,030 Next one, please. 445 00:32:49,290 --> 00:32:52,170 It invokes client requests, right? 446 00:32:52,170 --> 00:32:53,550 And next one, please. 447 00:32:54,170 --> 00:32:56,070 It provides responses. 448 00:32:56,090 --> 00:33:06,050 Also, by the way, if you want to take pictures of, you know, cameras or turn on the microphone and whatnot, this all works well. 449 00:33:06,350 --> 00:33:21,830 And I mentioned here local injection, because if it wasn't clear, to fire that intent with the very specific bytes inside, you have to run and get the app inside to the system app that, you know, the device health app. 450 00:33:21,870 --> 00:33:26,470 But this is still considered an elevation of privilege for obvious reasons. 451 00:33:26,470 --> 00:33:30,430 Like, your initial app doesn't have to have any permissions. 452 00:33:30,430 --> 00:33:34,730 If you can inject and do all of those things, you can basically take over the phone. 453 00:33:34,970 --> 00:33:36,410 Next slide, please. 454 00:33:38,090 --> 00:33:40,190 This is my exploit code. 455 00:33:41,510 --> 00:33:48,270 I won't dive too much into it, but you can see in the first part that I basically take the JavaScript payload. 456 00:33:48,530 --> 00:34:03,270 I basically add some code to embed that payload into the web view itself by just inserting a new script element and loading the source from my C2. 457 00:34:03,690 --> 00:34:17,070 And basically, I had to append an extra quote, and then I just put A's there for fun. 458 00:34:17,070 --> 00:34:21,850 And the idea behind that is that, you know, this is how the JavaScript injection works, right? 459 00:34:21,850 --> 00:34:26,970 Like, it takes my input and treats it as a string with quotation marks. 460 00:34:26,970 --> 00:34:31,350 So, if I finish a quotation, I can actually inject more JavaScript stuff there. 461 00:34:31,590 --> 00:34:40,890 And then basically, the second part was to encode everything into a single statement that's just, you know, basic C4 encoding. 462 00:34:40,890 --> 00:34:42,210 Next slide, please. 463 00:34:45,960 --> 00:34:50,140 And this basically is kind of... 464 00:34:50,140 --> 00:34:52,460 Oh, and in the previous slide... 465 00:34:52,460 --> 00:34:53,960 Sorry, can you go one slide back? 466 00:34:53,960 --> 00:34:55,020 I apologize. 467 00:34:55,020 --> 00:35:00,580 The thing that has the red rectangle is basically where the other injection kicks in. 468 00:35:00,580 --> 00:35:04,840 You basically have to put, like, a single quote, right? 469 00:35:04,940 --> 00:35:10,640 This is where the JavaScript injection actually kicks in. 470 00:35:12,360 --> 00:35:15,280 Flow input member that we discussed. 471 00:35:15,280 --> 00:35:16,960 Sorry, now next slide. 472 00:35:18,400 --> 00:35:21,300 This basically continues building the entire thing. 473 00:35:21,300 --> 00:35:23,780 I build something called a dynamic link data. 474 00:35:25,080 --> 00:35:35,400 And basically, in that dynamic link data, the only thing that actually was meaningful is building it eventually as a parcel. 475 00:35:35,400 --> 00:35:37,980 And then the parcel, I have to embed into... 476 00:35:37,980 --> 00:35:39,320 Like, I have to marshal it. 477 00:35:39,320 --> 00:35:40,460 It turns into bytes. 478 00:35:40,460 --> 00:35:44,380 And then those bytes are basically embedded in the app itself. 479 00:35:44,380 --> 00:35:46,020 In the intent itself. 480 00:35:46,020 --> 00:35:47,060 I apologize. 481 00:35:47,380 --> 00:35:51,140 As the com.google.firebase.dynamic.links.dynamic.link.data. 482 00:35:51,140 --> 00:35:54,980 That's the last part of this right here. 483 00:35:55,700 --> 00:35:57,380 Next slide, please. 484 00:35:58,060 --> 00:36:01,480 This is a recording of the local injection. 485 00:36:01,480 --> 00:36:03,140 I hope it plays well. 486 00:36:03,140 --> 00:36:04,820 Can you please try to play it? 487 00:36:06,140 --> 00:36:07,940 See how that works. 488 00:36:10,180 --> 00:36:11,100 Hey, okay. 489 00:36:11,100 --> 00:36:13,930 So, on the left side, you can see the two... 490 00:36:14,820 --> 00:36:18,400 We actually had two servers for C2 for other reasons. 491 00:36:18,440 --> 00:36:22,480 And then on the right side, you can see the checkup app. 492 00:36:22,480 --> 00:36:28,220 And this is our PC app that injects into the system app. 493 00:36:28,220 --> 00:36:30,760 The system app, by the way, doesn't have to be turned on. 494 00:36:30,760 --> 00:36:32,060 I just turned it off. 495 00:36:32,060 --> 00:36:32,540 That's fine. 496 00:36:32,540 --> 00:36:33,660 It doesn't really matter. 497 00:36:33,660 --> 00:36:36,120 Because we can always start an intent. 498 00:36:36,280 --> 00:36:38,280 This will basically start an intent. 499 00:36:38,360 --> 00:36:42,240 And on the left side, you can see that it actually starts getting data, right? 500 00:36:42,260 --> 00:36:45,520 So, this is basically how our exploit works. 501 00:36:46,580 --> 00:36:48,680 This is our recording. 502 00:36:48,980 --> 00:36:50,120 Next slide, please. 503 00:36:52,760 --> 00:36:53,500 Okay. 504 00:36:53,500 --> 00:36:55,000 Responsible disclosure. 505 00:36:56,120 --> 00:37:05,280 We disclosed everything to the company that maintains the framework itself, like the entire SDK, as well as all the telcos that were involved. 506 00:37:05,280 --> 00:37:06,760 There are five in total. 507 00:37:06,920 --> 00:37:09,220 I can't give an exact number. 508 00:37:09,220 --> 00:37:16,920 But we're talking about millions of Android devices with vulnerable system apps affected by bugs ranging from full RCE to local EOP. 509 00:37:18,180 --> 00:37:20,820 And it took a lot of months, actually. 510 00:37:20,820 --> 00:37:22,340 This is quite problematic. 511 00:37:22,340 --> 00:37:27,820 You can't really even remove system apps from your Android phone. 512 00:37:27,820 --> 00:37:32,500 At least my grandma kind of users can't do that. 513 00:37:32,520 --> 00:37:40,240 And we basically released details in coordination with everyone involved to make sure that no end user is put in danger. 514 00:37:40,660 --> 00:37:48,320 Because releasing new firmware and basically making sure that everyone updates and so on is very painful to those telcos. 515 00:37:48,320 --> 00:37:57,500 And we also constantly work together with Google to actually improve Google Play Protect and spot similar bugs automatically. 516 00:37:58,540 --> 00:38:00,320 This is kind of interesting. 517 00:38:00,960 --> 00:38:07,320 Those apps, those device health apps or that SDK, actually, was in Google Play. 518 00:38:07,320 --> 00:38:11,040 And it still is, by the way, in the Google Play Store. 519 00:38:11,740 --> 00:38:19,660 And Google Play has basically something called Google Play Protect, which scans your apps against evil and also vulnerabilities. 520 00:38:20,040 --> 00:38:27,540 But they simply didn't have good handling of that vulnerability class, like vulnerabilities that involve JS interfaces. 521 00:38:28,200 --> 00:38:31,820 So we are working with Google on that. 522 00:38:32,240 --> 00:38:34,040 Next slide, please. 523 00:38:35,360 --> 00:38:36,400 Resolution. 524 00:38:36,400 --> 00:38:45,300 So disclosure happened around September 2021, but it took more than six months until user risk became sufficiently low for public disclosure. 525 00:38:46,220 --> 00:38:49,500 And this is just my take on the thing. 526 00:38:49,500 --> 00:38:53,080 One of the main problems is that those were system apps, right? 527 00:38:53,260 --> 00:38:57,300 I don't want to use the term bloatware, but I already used it. 528 00:38:57,300 --> 00:38:59,080 So let's call it bloatware. 529 00:39:00,080 --> 00:39:03,480 System apps are baked into the device firmware image. 530 00:39:03,480 --> 00:39:05,040 You can't turn them off. 531 00:39:05,040 --> 00:39:07,320 And there are many unsuspecting users. 532 00:39:07,320 --> 00:39:19,940 Like, I bet if some of you are Android users, I'm willing to bet that you don't know at least 30% of the system apps that are installed on your phone at any given time. 533 00:39:21,360 --> 00:39:35,640 And basically, me working as Microsoft for Defender, we also have Microsoft Defender on Android, and we support something called vulnerability management, which does indicate the existence of vulnerable apps. 534 00:39:35,640 --> 00:39:45,220 So if you have a vulnerable app on your phone, and specifically that set of vulnerabilities, we'd be able to at least tell you. 535 00:39:45,240 --> 00:39:50,820 So, you know, you can't uninstall the system app, but that's a good start, I think. 536 00:39:51,660 --> 00:39:53,320 Next slide, please. 537 00:39:54,440 --> 00:39:57,420 A quick note for Android developers. 538 00:39:58,240 --> 00:40:03,760 Overpowered web views with JS interfaces are the source of many interesting security bugs. 539 00:40:03,960 --> 00:40:08,960 And apps, as I mentioned before, sometimes just blindly trust input from the web views, right? 540 00:40:08,960 --> 00:40:17,500 You have a web view and you have your app, and the app simply trusts it without thinking whether it could be injected into or not. 541 00:40:17,680 --> 00:40:19,320 And that's one thing. 542 00:40:19,320 --> 00:40:23,360 So whenever you develop an app, you know, be mindful of those things. 543 00:40:23,360 --> 00:40:29,320 If you implement an asynchronous client-server module by JavaScript injection, then please don't do that. 544 00:40:29,320 --> 00:40:37,680 It's really bad practice, and there are good APIs that are included in AndroidX Web Message Listener specifically. 545 00:40:37,680 --> 00:40:42,780 Google pointed that out, and we actually look at that code. 546 00:40:42,960 --> 00:40:53,020 And the entire serialization is, in my opinion, pretty flawless there, unlike injecting JavaScript and not sanitizing your strings. 547 00:40:53,720 --> 00:40:58,060 So use your own API and don't develop something from scratch. 548 00:40:58,500 --> 00:41:06,800 And again, and this is like a recurring theme in cybersecurity, if you're forced to inject JavaScript, sanitize your inputs. 549 00:41:06,800 --> 00:41:08,560 That should be obvious. 550 00:41:08,760 --> 00:41:10,720 Next slide, please. 551 00:41:10,940 --> 00:41:12,580 These are kind of conclusions. 552 00:41:12,640 --> 00:41:17,460 System apps, in my opinion, do not get enough attention from the security industry. 553 00:41:17,980 --> 00:41:21,720 They're especially bad because they can't be easily removed. 554 00:41:21,740 --> 00:41:26,020 End users never suspect they have all these apps to begin with. 555 00:41:26,260 --> 00:41:30,080 Bloatware, that's what some of us call them. 556 00:41:30,080 --> 00:41:36,320 I did mention other suspicious-looking bloatware that were also installed on that phone. 557 00:41:38,280 --> 00:41:41,460 But no, I didn't pay too much attention to them. 558 00:41:41,460 --> 00:41:44,460 I just really need to find the time, to be honest. 559 00:41:44,460 --> 00:41:48,300 But I bet there are other things in that phone as well. 560 00:41:48,360 --> 00:42:00,660 And there are special thanks here to the Android V team that worked with me, which is Shengxin Zhang, Michael Peck, Joe Mancer, and Apoorva Kumar, and the entire Microsoft 365 Defender research team. 561 00:42:00,660 --> 00:42:02,560 And with that, I'm done. 562 00:42:02,560 --> 00:42:08,960 If you have any questions, please do ask them now, or you can just reach out over Twitter or something. 563 00:42:08,960 --> 00:42:10,380 My DMs are open. 564 00:42:10,420 --> 00:42:11,920 Thank you so much for attending. 565 00:42:14,100 --> 00:42:15,860 I have a question. 566 00:42:16,340 --> 00:42:17,380 Yes. 567 00:42:18,780 --> 00:42:49,820 So, like, this is like, the device, the device, I think, is it like one of those system apps that come with Android, or is it one of those carrier system apps, like the synonym for running apps that you get when you get from that specific carrier? 568 00:42:50,540 --> 00:42:57,520 So, it's actually, well, it's not done by Google or by... 569 00:42:58,280 --> 00:43:01,220 Yeah, it's more of the latter than the former. 570 00:43:01,220 --> 00:43:11,140 Although you could actually, as I said, you can actually install that from Google Play, or if you ever get your phone fixed or traded in or something, it might be installed there already. 571 00:43:11,140 --> 00:43:21,420 So, it can be either someone installing that, or it could be baked into your firmware just by the carrier itself. 572 00:43:21,740 --> 00:43:23,400 I hope that answers the question. 573 00:43:23,560 --> 00:43:24,560 Okay, yes. 574 00:43:25,320 --> 00:43:27,100 What's the carrier thing? 575 00:43:27,280 --> 00:43:29,780 Yeah, that's why I mentioned those telcos. 576 00:43:29,780 --> 00:43:32,760 It's done, well, not by the telcos. 577 00:43:32,760 --> 00:43:37,840 They're actually just using that other company that developed the SDK with customization. 578 00:43:37,840 --> 00:43:42,660 But basically, the telcos are kind of responsible for that in this case. 579 00:43:43,740 --> 00:43:44,520 Okay. 580 00:43:47,100 --> 00:43:47,820 Some... 581 00:43:50,600 --> 00:43:51,920 Go ahead. 582 00:43:57,060 --> 00:44:06,040 I'm just trying to think about those kinds of exploits between those that... 583 00:44:06,940 --> 00:44:12,880 You know how you need root to have to remove the system apps and stuff? 584 00:44:12,880 --> 00:44:21,360 I was thinking, how actually... 585 00:44:25,120 --> 00:44:29,860 I mean, if you run as root, yes, you can uninstall those system apps. 586 00:44:29,860 --> 00:44:35,670 I mean, is it just... 587 00:44:36,510 --> 00:44:43,130 Does the exploit doesn't really have any practical use for other things? 588 00:44:43,170 --> 00:44:47,970 Other things, you know, or just, you know, thread actor stuff? 589 00:44:48,490 --> 00:44:56,770 I mean, generally, those kind of exploits could mostly be used, in my opinion, for bad stuff. 590 00:44:56,770 --> 00:45:05,130 Could be like an NSO kind of level exploit where someone remotely can just hack your phone. 591 00:45:05,670 --> 00:45:17,970 Also, because it's a system app, in most cases, it can actually install apps silently, which a normal app, if you try to install an app, it would actually pop up and at least ask the user for permission. 592 00:45:18,150 --> 00:45:20,770 But as far as I remember, not for system apps. 593 00:45:22,550 --> 00:45:26,490 And I mean, it's hard for me to say. 594 00:45:26,490 --> 00:45:33,630 Exploits are usually used for, you know, either bad guys or for educational purposes. 595 00:45:33,630 --> 00:45:34,670 In this case, we actually... 596 00:45:35,350 --> 00:45:36,430 Yeah, go ahead. 597 00:45:37,350 --> 00:45:48,010 Yeah, because I know like, yeah, you know, because not those exploits are used for an exploit chain. 598 00:45:49,090 --> 00:45:53,850 Oh, oh, you mean, yeah, you mean like for jailbreaking and stuff like that? 599 00:45:53,850 --> 00:45:54,670 Yeah, that's what I'm saying. 600 00:45:54,670 --> 00:46:03,470 The difference between, you know, the exploits, is it more of an exploit can also be used for that? 601 00:46:03,470 --> 00:46:08,530 Or is it mostly just for the really, really bad stuff? 602 00:46:09,070 --> 00:46:12,790 Well, to be honest, I think mostly not for that. 603 00:46:12,790 --> 00:46:20,390 I mean, for jailbreak, you'll have to run as root normally, or flash a new bootloader or whatnot. 604 00:46:20,450 --> 00:46:23,130 This is not this kind of exploit. 605 00:46:23,130 --> 00:46:31,510 This exploit, I mean, it is beneficial in some cases to run as a system app, but it's not running as root. 606 00:46:32,530 --> 00:46:34,510 Oh, okay. 607 00:46:34,510 --> 00:46:38,270 Yeah, so it's not really useful for that kind of stuff. 608 00:46:38,270 --> 00:46:38,830 More so just... 609 00:46:39,890 --> 00:46:42,130 Oh, it's mostly for bad guys. 610 00:46:42,190 --> 00:46:43,810 Yeah, that's what I was asking. 611 00:46:44,910 --> 00:46:46,130 Thank you. 612 00:46:47,210 --> 00:46:48,910 Any more questions? 613 00:46:50,230 --> 00:46:57,930 I wanted to ask, like, oftentimes I've heard horror stories of people revealing vulnerabilities with big companies and getting some negative responses. 614 00:46:58,640 --> 00:47:07,350 Did you get any kind of negative response from big telco companies when you kind of revealed to them that there's this kind of vulnerability on their product? 615 00:47:07,570 --> 00:47:08,660 Good question. 616 00:47:08,950 --> 00:47:16,750 This is kind of like a political question, so it's hard for me to answer, but I would say that the responses were mixed. 617 00:47:16,750 --> 00:47:25,050 I think that the telco industry is not as mature as other companies, and they might not see you exploiting their stuff with a... 618 00:47:27,370 --> 00:47:34,270 They don't see it as a nice gesture, even though we really worked hard to do responsible disclosure. 619 00:47:34,270 --> 00:47:34,770 We also... 620 00:47:34,770 --> 00:47:44,370 I didn't mention that, but after that company, the company that develops everything, patched everything, we actually tested to make sure that they did everything properly. 621 00:47:44,370 --> 00:47:45,750 We did code reviews and whatnot. 622 00:47:45,750 --> 00:47:47,950 So it's not just about the exploitation. 623 00:47:47,950 --> 00:47:54,210 It's also about how to get that fixed, and they were pretty collaborative, to be honest. 624 00:47:54,310 --> 00:47:56,410 The telcos, it's mixed. 625 00:47:56,410 --> 00:48:05,490 Some of them were really open and really receptive to basically that kind of disclosure. 626 00:48:05,550 --> 00:48:09,510 Others were not as much and had to be convinced. 627 00:48:10,170 --> 00:48:14,490 In this case, I would say I'm lucky that I'm running... 628 00:48:15,210 --> 00:48:19,250 I'm basically part of a big company that can... 629 00:48:20,190 --> 00:48:24,390 Someone important from my company can talk to someone important from that telco. 630 00:48:24,390 --> 00:48:28,870 But if you're an individual researcher, I don't know. 631 00:48:28,870 --> 00:48:31,210 I think it would have been much more difficult. 632 00:48:32,310 --> 00:48:34,910 I would probably say that. 633 00:48:37,710 --> 00:48:42,130 Large men in fancy suits would come for your house. 634 00:48:42,910 --> 00:48:43,770 Yeah, yeah. 635 00:48:43,770 --> 00:48:45,370 Hopefully not. 636 00:48:46,230 --> 00:48:47,950 Hopefully not. 637 00:48:48,570 --> 00:48:49,770 Yeah. 638 00:48:50,910 --> 00:48:54,090 I have a guard cat in my home, so... 639 00:48:55,690 --> 00:48:56,630 Awesome. 640 00:48:56,630 --> 00:48:58,550 Yes, perfect. 641 00:48:59,410 --> 00:49:00,410 Yes, perfect. 642 00:49:00,410 --> 00:49:06,310 Make sure you protect both the front and back door. 643 00:49:06,510 --> 00:49:07,150 Yeah, yeah. 644 00:49:07,150 --> 00:49:08,930 Well, I need another cat. 645 00:49:09,110 --> 00:49:10,610 More questions. 646 00:49:13,770 --> 00:49:14,430 Awesome. 647 00:49:14,430 --> 00:49:19,410 Well, if there are any follow-up questions or you want to get more technical data or whatnot, just reach out to me. 648 00:49:19,410 --> 00:49:24,430 I do also macOS, Linux, Chrome OS, iOS, those sort of things. 649 00:49:24,430 --> 00:49:26,790 And I'm interested in everything that runs code. 650 00:49:26,790 --> 00:49:28,070 So thank you so much. 651 00:49:28,070 --> 00:49:29,490 And I'll see you guys around. 652 00:49:41,850 --> 00:49:43,310 Thank you, Jonathan. 653 00:49:43,630 --> 00:49:47,350 Give our speaker a warm round of applause. 654 00:49:47,850 --> 00:49:50,970 We've got roughly 10 minutes to our next speaker. 655 00:49:50,970 --> 00:49:53,190 So good time to take a bio break. 656 00:49:53,190 --> 00:49:56,930 And choose with the people that are here and network. 657 00:49:57,490 --> 00:49:59,090 And then look around for Easter eggs. 658 00:49:59,090 --> 00:50:00,710 And we'll see you back in about 10 minutes.