[Script Info] Title: [Events] Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text Dialogue: 0,0:00:00.00,0:00:19.52,Default,,0000,0000,0000,,{\i1}36c3 preroll{\i0} Dialogue: 0,0:00:19.52,0:00:25.99,Default,,0000,0000,0000,,Herald: To everybody here, please be\Nwelcome to this fantastic kid here. I Dialogue: 0,0:00:25.99,0:00:31.25,Default,,0000,0000,0000,,learned a lot from him, even though he's\Nonly since two years playing around with Dialogue: 0,0:00:31.25,0:00:37.38,Default,,0000,0000,0000,,iOS. I mentioned as well the first\Nuntethering case that I had with my phone Dialogue: 0,0:00:37.38,0:00:44.01,Default,,0000,0000,0000,,was something about iOS 5.1 and with every\Nupdate, you had to do the whole shebang Dialogue: 0,0:00:44.01,0:00:50.91,Default,,0000,0000,0000,,again. Of course, that's what I remember.\NSo please give a warm welcome here too Dialogue: 0,0:00:50.91,0:00:54.47,Default,,0000,0000,0000,,littlelailo. Do I spell this correctly?\NOffscreen: Yeah. Dialogue: 0,0:00:54.47,0:01:03.25,Default,,0000,0000,0000,,Herald: Yes, littlelailo is really a very\Nfascinating geek. He actually hacks any Dialogue: 0,0:01:03.25,0:01:08.61,Default,,0000,0000,0000,,kind of OS device, to my opinion. Any kind\Nof. Yeah. So throw it to him and it comes Dialogue: 0,0:01:08.61,0:01:14.39,Default,,0000,0000,0000,,back in pieces. He's as sharp as a knife.\NPlease give him a warm, well, welcoming Dialogue: 0,0:01:14.39,0:01:17.85,Default,,0000,0000,0000,,applause. We're gonna untether iOS. Yay! Dialogue: 0,0:01:17.85,0:01:23.76,Default,,0000,0000,0000,,{\i1}applause{\i0} Dialogue: 0,0:01:23.76,0:01:28.47,Default,,0000,0000,0000,,littlelailo: Okay, so yeah, I'm\Nlittlelailo, as already introduced. I'm Dialogue: 0,0:01:28.47,0:01:34.12,Default,,0000,0000,0000,,interested in I.T. security in general.\NAnd I started to look into iOS about two Dialogue: 0,0:01:34.12,0:01:40.67,Default,,0000,0000,0000,,years ago and then I met three awesome\Nguys: @s1guza, @stek29 and @iBSparkes. And Dialogue: 0,0:01:40.67,0:01:46.79,Default,,0000,0000,0000,,we basically started to chat a lot and in\Nthe end also released the "jailbreak me" Dialogue: 0,0:01:46.79,0:01:50.95,Default,,0000,0000,0000,,for iOS 10 on https://totally-\Nnot.spyware.lol/. For everybody who isn't Dialogue: 0,0:01:50.95,0:01:55.43,Default,,0000,0000,0000,,familiar with the jailbreak scene, it's\Nlike rooting on Android. So it basically Dialogue: 0,0:01:55.43,0:02:02.42,Default,,0000,0000,0000,,is a tool that gives the user the\Ncapability to tweak the device, and that's Dialogue: 0,0:02:02.42,0:02:06.17,Default,,0000,0000,0000,,mostly done by basically installing a\Njailbreak in this case. You just go to a Dialogue: 0,0:02:06.17,0:02:07.92,Default,,0000,0000,0000,,website on the slide there\N[https://totally-not.spyware.lol/] and it Dialogue: 0,0:02:07.92,0:02:12.49,Default,,0000,0000,0000,,will install a package manager on your\Nphone and then the end user can install Dialogue: 0,0:02:12.49,0:02:17.98,Default,,0000,0000,0000,,tweaks. So just a little dynamic libraries\Nand they get injected into all the other Dialogue: 0,0:02:17.98,0:02:21.50,Default,,0000,0000,0000,,system processes and then they can\Nobviously modify their memory. And that, Dialogue: 0,0:02:21.50,0:02:25.62,Default,,0000,0000,0000,,for example, allows customization of the\Nhome screen or something like that. And Dialogue: 0,0:02:25.62,0:02:31.77,Default,,0000,0000,0000,,basically with the release, we also formed\Nthe team @Jakeblair420 was created with a Dialogue: 0,0:02:31.77,0:02:35.07,Default,,0000,0000,0000,,Twitter account. There are also a few\Ndemos there if you want to check it out Dialogue: 0,0:02:35.07,0:02:39.70,Default,,0000,0000,0000,,after the talk. And I basically had this\Npipe dream that in my life. I really want Dialogue: 0,0:02:39.70,0:02:44.74,Default,,0000,0000,0000,,to achieve an untethered jailbreak using\Nonly some sort of plist or other save file Dialogue: 0,0:02:44.74,0:02:49.89,Default,,0000,0000,0000,,corruption. So basically there are\Ndifferent kinds of jailbreaks. In modern Dialogue: 0,0:02:49.89,0:02:54.48,Default,,0000,0000,0000,,jailbreak the most common kind are semi-\Nuntethered, which means that the users has Dialogue: 0,0:02:54.48,0:02:59.58,Default,,0000,0000,0000,,to connect their device to a PC when they\Nfirst install a jailbreak and then they Dialogue: 0,0:02:59.58,0:03:04.25,Default,,0000,0000,0000,,sideload an app onto the device or it just\Ninstalls itself there. And then on each Dialogue: 0,0:03:04.25,0:03:09.16,Default,,0000,0000,0000,,reboot, the user has to go into the app\Nand press a button to jailbreak the phone. Dialogue: 0,0:03:09.16,0:03:14.37,Default,,0000,0000,0000,,And basically, after they reboot, they\Nlose the jailbreak and have to go through Dialogue: 0,0:03:14.37,0:03:19.51,Default,,0000,0000,0000,,this process again. And with an untethered\Njailbreak, the jailbreak gains persistent Dialogue: 0,0:03:19.51,0:03:24.25,Default,,0000,0000,0000,,installation and then they will\Nautomatically jailbreak the device on each Dialogue: 0,0:03:24.25,0:03:31.90,Default,,0000,0000,0000,,boot. So the device automatically boots\Njailbroke. The untether can be divided Dialogue: 0,0:03:31.90,0:03:37.39,Default,,0000,0000,0000,,into four stages. The first stage is when the\Nconfig file or database stage. I would go Dialogue: 0,0:03:37.39,0:03:42.15,Default,,0000,0000,0000,,over how we gain execution of the boot.\NThen the config parser bug that gives us Dialogue: 0,0:03:42.15,0:03:47.97,Default,,0000,0000,0000,,the right opey primitive. And then I will\Ntalk about the main bug, the ASLR bypass, Dialogue: 0,0:03:47.97,0:03:53.09,Default,,0000,0000,0000,,which allows us to get into ROP. Then\Nstage two is basically a kernel exploit Dialogue: 0,0:03:53.09,0:03:58.36,Default,,0000,0000,0000,,and completely written in ROP and there I\Nwill go over the two main kernel bugs: the Dialogue: 0,0:03:58.36,0:04:03.57,Default,,0000,0000,0000,,kASLR leak and then the racy double free\Nwe used to get the kernel read/write, and Dialogue: 0,0:04:03.57,0:04:09.69,Default,,0000,0000,0000,,I will also talk about the kASLR weakness\Nand RootDomain user client memory leak Dialogue: 0,0:04:09.69,0:04:14.44,Default,,0000,0000,0000,,which aided us in exploitation. And after\Nwe get kernel read/write, we can remove a Dialogue: 0,0:04:14.44,0:04:19.81,Default,,0000,0000,0000,,few restrictions from Apple. Mainly we can\Nbypass code signing and that gives us the Dialogue: 0,0:04:19.81,0:04:24.38,Default,,0000,0000,0000,,ability to load an unsigned dynamic\Nlibrary into our process. So now in stage Dialogue: 0,0:04:24.38,0:04:30.21,Default,,0000,0000,0000,,3, we are basically C, we are dynamic\Nlibrary and there we are stashing the Dialogue: 0,0:04:30.21,0:04:36.83,Default,,0000,0000,0000,,kernel task port to host special port 4.\NSo iOS has this concept of ports and task Dialogue: 0,0:04:36.83,0:04:41.77,Default,,0000,0000,0000,,ports. And basically, if you have a send\Nright to a task port of a process, you can Dialogue: 0,0:04:41.77,0:04:48.22,Default,,0000,0000,0000,,read and write its memory. They're most\Nused for inter process communication. And Dialogue: 0,0:04:48.22,0:04:53.41,Default,,0000,0000,0000,,where modern jailbreaks used to stash the\Nkernel task port into a special port 4 so Dialogue: 0,0:04:53.41,0:04:57.83,Default,,0000,0000,0000,,that other user mode applications can then\Nretrieve it and with that retrieved and Dialogue: 0,0:04:57.83,0:05:01.81,Default,,0000,0000,0000,,with send right they can just read and\Nwrite process memory. And after that I Dialogue: 0,0:05:01.81,0:05:07.74,Default,,0000,0000,0000,,just fix up everything and then spawn\Nstage four and that's basically running in Dialogue: 0,0:05:07.74,0:05:12.60,Default,,0000,0000,0000,,a separate process. That has a few\Nadvantages I will go into later. It's Dialogue: 0,0:05:12.60,0:05:15.70,Default,,0000,0000,0000,,basically performing the whole post\Nexploitation process, including launching Dialogue: 0,0:05:15.70,0:05:19.69,Default,,0000,0000,0000,,substrate - the framework that's used for\Ntweek injection and then performing Dialogue: 0,0:05:19.69,0:05:24.10,Default,,0000,0000,0000,,ldrestart to restart or launch demons on\Nthe system and inject the tweaks into Dialogue: 0,0:05:24.10,0:05:30.93,Default,,0000,0000,0000,,them. In stage 1, we first need to get\Nexecution after boot, and when iOS boots Dialogue: 0,0:05:30.93,0:05:35.83,Default,,0000,0000,0000,,launchd is the first process that's\Nrunning on the system and it then loads a Dialogue: 0,0:05:35.83,0:05:41.87,Default,,0000,0000,0000,,dynamic library with a list of executables\N- that are LaunchDaemons - and there are a Dialogue: 0,0:05:41.87,0:05:47.22,Default,,0000,0000,0000,,few flags associated with them. If the\N"run and load" flag is set, launchd will Dialogue: 0,0:05:47.22,0:05:52.76,Default,,0000,0000,0000,,then spawn all of those LaunchDaemons\Nafterwards. And we basically just take one Dialogue: 0,0:05:52.76,0:05:58.59,Default,,0000,0000,0000,,of those launch demons, namely Racoon. So\Nwhat is Racoon? Basically Racoon is part Dialogue: 0,0:05:58.59,0:06:07.03,Default,,0000,0000,0000,,of the ipsec package. And it's a VPN\Nclient used to interact with an IPSec VPN Dialogue: 0,0:06:07.03,0:06:13.92,Default,,0000,0000,0000,,server. And the problem is though, that\NIPsec-Tools project has been abandoned Dialogue: 0,0:06:13.92,0:06:18.65,Default,,0000,0000,0000,,since 2014. So they officially here state\Non their website that the development of Dialogue: 0,0:06:18.65,0:06:22.79,Default,,0000,0000,0000,,the project has been abandoned and that\NIPsec-Tools has security issues. You Dialogue: 0,0:06:22.79,0:06:29.06,Default,,0000,0000,0000,,should not use it. Apple still decided it\Nwas a good idea to ship it after 2014 and Dialogue: 0,0:06:29.06,0:06:34.68,Default,,0000,0000,0000,,they now maintain their own fork on\Nhttps://opensource.apple.com . And yeah, Dialogue: 0,0:06:34.68,0:06:39.10,Default,,0000,0000,0000,,basically the only thing that's important\Nfor the talk is that raccoon has a Dialogue: 0,0:06:39.10,0:06:43.56,Default,,0000,0000,0000,,configuration parser. So on startup it\Nwill just look for a file on disk and Dialogue: 0,0:06:43.56,0:06:49.08,Default,,0000,0000,0000,,start to parse that. And that's written in\Nyacc so completely written in C. So memory Dialogue: 0,0:06:49.08,0:06:53.79,Default,,0000,0000,0000,,corruption might become a problem. And it\Nactually is a problem as we can see if the Dialogue: 0,0:06:53.79,0:07:00.41,Default,,0000,0000,0000,,config parser bug and for that when we\Nhave to go back a bit. Basically in 2011 Dialogue: 0,0:07:00.41,0:07:08.62,Default,,0000,0000,0000,,Pod2g released Corona for iOS 5, which was\Nalso an untethered. He used a bug in Dialogue: 0,0:07:08.62,0:07:15.70,Default,,0000,0000,0000,,Racoon in the configuration parser and\NPod2g found this one on an old bug tracker Dialogue: 0,0:07:15.70,0:07:20.79,Default,,0000,0000,0000,,and basically the IPsec website had this\Nbug tracker there. There users could just Dialogue: 0,0:07:20.79,0:07:27.46,Default,,0000,0000,0000,,report problems with their programs and\None user in 2009 I think reported a bug Dialogue: 0,0:07:27.46,0:07:31.51,Default,,0000,0000,0000,,that if he would use the specific config\NRacoon would just segfault, but nobody Dialogue: 0,0:07:31.51,0:07:36.93,Default,,0000,0000,0000,,looked at this for two years. So in 2011\NPod2g realized that this was actually Dialogue: 0,0:07:36.93,0:07:40.54,Default,,0000,0000,0000,,exploitable and then used in a jailbreak.\NAnd after that, obviously Apple got aware Dialogue: 0,0:07:40.54,0:07:45.61,Default,,0000,0000,0000,,of it. And then they also said that they\Nfixed it. And it's got a CV, assigned Dialogue: 0,0:07:45.61,0:07:53.91,Default,,0000,0000,0000,,CVS-2012-2737. And yeah, they say that\Nthis was improved through improved bounds Dialogue: 0,0:07:53.91,0:07:58.87,Default,,0000,0000,0000,,checking. So let's look at the patch.\NThat's the function before the patch and Dialogue: 0,0:07:58.87,0:08:03.25,Default,,0000,0000,0000,,that's the function after the patch. And\Nif this was too fast for you, here's the Dialogue: 0,0:08:03.25,0:08:07.56,Default,,0000,0000,0000,,diff. So basically there is no difference.\NThe bug is still there and Apple didn't Dialogue: 0,0:08:07.56,0:08:13.03,Default,,0000,0000,0000,,patch it. What really happened here was\Nthat basically this is obviously a Dialogue: 0,0:08:13.03,0:08:17.53,Default,,0000,0000,0000,,configuration parser. So there are\Ndifferent statements that nearly do the Dialogue: 0,0:08:17.53,0:08:22.61,Default,,0000,0000,0000,,same thing. There are these nbns4\Nstatements to parse an IP address and Dialogue: 0,0:08:22.61,0:08:27.18,Default,,0000,0000,0000,,there are wins4 statement followed by an\NIP address and both of them have to parse Dialogue: 0,0:08:27.18,0:08:33.94,Default,,0000,0000,0000,,the IP address. So the function for\Nparsing that was just copy pasted from Dialogue: 0,0:08:33.94,0:08:41.13,Default,,0000,0000,0000,,another one. And yeah, basically Apple\Nfixed the bug in the other function. Which Dialogue: 0,0:08:41.13,0:08:47.52,Default,,0000,0000,0000,,I don't get because basically the engineer\Nthere had to look at PoC Pod2g provided Dialogue: 0,0:08:47.52,0:08:51.25,Default,,0000,0000,0000,,then they had to realize okay, the bug is\Nin there, fix it, then they had to Dialogue: 0,0:08:51.25,0:08:55.05,Default,,0000,0000,0000,,recompile and never tested against the\Noriginal PoC because otherwise Racoon Dialogue: 0,0:08:55.05,0:08:59.62,Default,,0000,0000,0000,,would have crashed again. Yeah, it's\Nbasically an off by one which allows you Dialogue: 0,0:08:59.62,0:09:05.64,Default,,0000,0000,0000,,to overwrite the index of an array and\NPod2g gave a talk about this and we can Dialogue: 0,0:09:05.64,0:09:11.39,Default,,0000,0000,0000,,basically reuse his strategy from back in\N2011 to get a write primitive. Dialogue: 0,0:09:11.39,0:09:16.73,Default,,0000,0000,0000,,Again, the one function here at the top.\NYou can see the yacc syntax so an addrwins Dialogue: 0,0:09:16.73,0:09:21.24,Default,,0000,0000,0000,,list has to consist of either an addrwins\Nstatement or addrwins statement followed Dialogue: 0,0:09:21.24,0:09:25.60,Default,,0000,0000,0000,,by a comma, followed by an addrwins list.\NSo that's a recursion. There can be Dialogue: 0,0:09:25.60,0:09:31.02,Default,,0000,0000,0000,,multiple addrwins statements in a row. And\Nthen below that, an addrwins statement is Dialogue: 0,0:09:31.02,0:09:35.39,Default,,0000,0000,0000,,defined as containing an address string.\NAnd that's just a regex to match an IP Dialogue: 0,0:09:35.39,0:09:38.95,Default,,0000,0000,0000,,version 4 address. And if the parcel finds\Nthat it would run the code between those Dialogue: 0,0:09:38.95,0:09:44.48,Default,,0000,0000,0000,,two brackets. So they get the pointer to a\Nglobal struct and then they check if this Dialogue: 0,0:09:44.48,0:09:50.50,Default,,0000,0000,0000,,nbns4_index is bigger than MAXWINS and if\Nso, they return an error. The problem here Dialogue: 0,0:09:50.50,0:09:54.62,Default,,0000,0000,0000,,is that this is off by 1. It shouldn't be\Nchecking if it's greater than so, but it Dialogue: 0,0:09:54.62,0:09:58.44,Default,,0000,0000,0000,,should be a check for greater or equal\Nthan MAXWINS. And after that, they use Dialogue: 0,0:09:58.44,0:10:03.09,Default,,0000,0000,0000,,thisinet_pton function to basically parse\Nthe address, which is in this variable Dialogue: 0,0:10:03.09,0:10:10.13,Default,,0000,0000,0000,,into the nbns4 array at the nbns4 index\Nand then post-increment the index. And Dialogue: 0,0:10:10.13,0:10:13.99,Default,,0000,0000,0000,,that will also be coming in handy when\Nexploiting this bug. So yeah. How is Dialogue: 0,0:10:13.99,0:10:18.74,Default,,0000,0000,0000,,exploitation done? Basically there are\Nhere the globals, there is this Lcconfig Dialogue: 0,0:10:18.74,0:10:23.61,Default,,0000,0000,0000,,pointer in the globals pointing to a heap\Nstructure and that the parser also uses. Dialogue: 0,0:10:23.61,0:10:29.67,Default,,0000,0000,0000,,And then there is this dns4 array followed\Nby the dns_area_index and then the nbns4 Dialogue: 0,0:10:29.67,0:10:35.34,Default,,0000,0000,0000,,array followed by the nbns_4_array_index\Nso we can just use mode_cfg statement Dialogue: 0,0:10:35.34,0:10:39.27,Default,,0000,0000,0000,,followed by this wins4 statement with the\NIP address to parse the IP address in the Dialogue: 0,0:10:39.27,0:10:44.63,Default,,0000,0000,0000,,first array element and we can repeat this\Nprocess four times to then move the index Dialogue: 0,0:10:44.63,0:10:49.68,Default,,0000,0000,0000,,out of bounds. So now it's pointing to\Nitself and the cool thing is about that is Dialogue: 0,0:10:49.68,0:10:53.91,Default,,0000,0000,0000,,that therefore there would be a good idea\Nto use integers for those area indexes Dialogue: 0,0:10:53.91,0:10:59.11,Default,,0000,0000,0000,,instead of unsigned integers so we can\Njust point them... you just use negative Dialogue: 0,0:10:59.11,0:11:04.26,Default,,0000,0000,0000,,numbers to bypass the bounds check. So\Nwe'll overwrite it with -1 to point it to Dialogue: 0,0:11:04.26,0:11:09.11,Default,,0000,0000,0000,,an dns_array_index and then we use another\Nwins statement to override the Dialogue: 0,0:11:09.11,0:11:13.13,Default,,0000,0000,0000,,dns_array_index with a negative number.\NAnd the cool thing about this is that Dialogue: 0,0:11:13.13,0:11:16.40,Default,,0000,0000,0000,,because of the post-incrementation, it\Nwill move it back to zero so we can repeat Dialogue: 0,0:11:16.40,0:11:20.76,Default,,0000,0000,0000,,this process as often times as we want,\Nand we will use a negative number to Dialogue: 0,0:11:20.76,0:11:24.74,Default,,0000,0000,0000,,basically point it to the Lcconfig\Npointer. And then we can use two dns4 Dialogue: 0,0:11:24.74,0:11:28.94,Default,,0000,0000,0000,,statements to override the Lcconfig\Npointer and point it anywhere in memory. Dialogue: 0,0:11:28.94,0:11:34.66,Default,,0000,0000,0000,,And after that we can use a timer\Nstatement with a counter. Then the Dialogue: 0,0:11:34.66,0:11:39.51,Default,,0000,0000,0000,,parsible just tried to write it to the\NLcconfig structure so it will de-reference Dialogue: 0,0:11:39.51,0:11:44.20,Default,,0000,0000,0000,,our pointer and write it there and the\Ninterval statement will basically write to Dialogue: 0,0:11:44.20,0:11:49.74,Default,,0000,0000,0000,,an uint32, which is followed by the uint\Nwhere the counter statement is written so Dialogue: 0,0:11:49.74,0:11:53.50,Default,,0000,0000,0000,,we can turn this into a 64 bit write\Nanywhere primitive and write anywhere in Dialogue: 0,0:11:53.50,0:11:59.56,Default,,0000,0000,0000,,process memory and that gives us an\Nability to basically exploit the ASLR Dialogue: 0,0:11:59.56,0:12:05.03,Default,,0000,0000,0000,,bypass. So this is the main bug of the\Nwhole untethered and allows us to Dialogue: 0,0:12:05.03,0:12:10.35,Default,,0000,0000,0000,,basically have this primitive. And it's\Nalso the reason why I decided to give this Dialogue: 0,0:12:10.35,0:12:14.53,Default,,0000,0000,0000,,talk this year and not last year, because\Nthere the bug was pretty fresh and only Dialogue: 0,0:12:14.53,0:12:20.55,Default,,0000,0000,0000,,patched in iOS 12 and it gives to an\Nattacker the ability to exploit zero click Dialogue: 0,0:12:20.55,0:12:23.68,Default,,0000,0000,0000,,more easily because they just need the\Nwrite anywhere primitive. And that's why I Dialogue: 0,0:12:23.68,0:12:29.74,Default,,0000,0000,0000,,held back on it. Siguza found it after\Nlooking into Apple's patches of the Corona Dialogue: 0,0:12:29.74,0:12:35.41,Default,,0000,0000,0000,,ASLR bypass and basically from Pod2g's\Npresentation, we as a team learned that Dialogue: 0,0:12:35.41,0:12:40.16,Default,,0000,0000,0000,,ASLR is always bypassed when a writable\Nregion is larger than the maximum slide, Dialogue: 0,0:12:40.16,0:12:45.10,Default,,0000,0000,0000,,because then there's always a writable\Naddress in process memory and you can use Dialogue: 0,0:12:45.10,0:12:51.23,Default,,0000,0000,0000,,this to brute force the slide and Siguza\Nfound out that there was what was also the Dialogue: 0,0:12:51.23,0:12:56.68,Default,,0000,0000,0000,,same problem with the cache in iOS 11 and\Na few versions of iOS 10 actually. So Dialogue: 0,0:12:56.68,0:13:02.20,Default,,0000,0000,0000,,what's the cache? Basically, the cache is\Na pre compiled blob containing the dynamic Dialogue: 0,0:13:02.20,0:13:07.55,Default,,0000,0000,0000,,link libraries from Apple. So on each\Nreleased, you just move all of those into Dialogue: 0,0:13:07.55,0:13:13.43,Default,,0000,0000,0000,,one big file to optimize load times of\Napps and keep memory pressure low. So it's Dialogue: 0,0:13:13.43,0:13:19.23,Default,,0000,0000,0000,,a pretty big file. And for that on boot\Nthe kernel needs to calculate a slide and Dialogue: 0,0:13:19.23,0:13:23.94,Default,,0000,0000,0000,,slide it in memory. But they only slide it\Nonce on boot because it's used in every Dialogue: 0,0:13:23.94,0:13:30.07,Default,,0000,0000,0000,,process. And so Apple defines an area of\Nmemory for the cache with a base address Dialogue: 0,0:13:30.07,0:13:35.89,Default,,0000,0000,0000,,and the size and that's hardcoded on iOS\N11. The cache got so big that a maximum Dialogue: 0,0:13:35.89,0:13:42.63,Default,,0000,0000,0000,,slide is now smaller than its data\Nsegment. So the conditioning is satisfied Dialogue: 0,0:13:42.63,0:13:47.91,Default,,0000,0000,0000,,and ASLR can be bypassed, basically. And\Nthe weird thing about this is that Dialogue: 0,0:13:47.91,0:13:54.04,Default,,0000,0000,0000,,actually the same thing also happened in\NiOS 7. Back then, the size was defined as Dialogue: 0,0:13:54.04,0:13:58.22,Default,,0000,0000,0000,,500 megabytes and the cache got bigger\Nthan 500 megabytes. But before that, it Dialogue: 0,0:13:58.22,0:14:02.65,Default,,0000,0000,0000,,was also in a few versions possible to\Nhave the same condition that the data Dialogue: 0,0:14:02.65,0:14:06.91,Default,,0000,0000,0000,,segment again was bigger than the maximum\Nslide. And Apple was actually also aware Dialogue: 0,0:14:06.91,0:14:11.15,Default,,0000,0000,0000,,of this because Acer talked about it\Nin one of his talks, but they just Dialogue: 0,0:14:11.15,0:14:15.95,Default,,0000,0000,0000,,increased the maximum slide to 1 gigabyte\Nand didn't edit any asserts. And now in Dialogue: 0,0:14:15.95,0:14:22.24,Default,,0000,0000,0000,,iOS 11, it again got so big that the same\Nthing happened. And we believe that they Dialogue: 0,0:14:22.24,0:14:27.38,Default,,0000,0000,0000,,didn't even really notice that up until\NiOS 12 where the cache was now bigger than Dialogue: 0,0:14:27.38,0:14:31.15,Default,,0000,0000,0000,,1 gigabyte so the kernel just couldn't fit\Nit in the memory region and paniced. And Dialogue: 0,0:14:31.15,0:14:35.25,Default,,0000,0000,0000,,because of that they just thought well,\Nthen we will increase it to 4 gigabyte Dialogue: 0,0:14:35.25,0:14:41.14,Default,,0000,0000,0000,,while developing so we might see this\Nreoccurring in I don't know, iOS 15 or Dialogue: 0,0:14:41.14,0:14:47.30,Default,,0000,0000,0000,,something like that. Exploitation is also\Npretty simple. We can just brute force the Dialogue: 0,0:14:47.30,0:14:52.21,Default,,0000,0000,0000,,slide now and there are a lot of function\Npointers in the data segment. So we Dialogue: 0,0:14:52.21,0:14:58.55,Default,,0000,0000,0000,,decided to go with __platform_mem_move\Nbecause we can reach it via strlcpy from Dialogue: 0,0:14:58.55,0:15:02.73,Default,,0000,0000,0000,,the conflict parser. And the basic\Nstrategy behind this is we write a slid Dialogue: 0,0:15:02.73,0:15:08.64,Default,,0000,0000,0000,,rop chain into an address we can always\Nwrite to for a specific slide abc and then Dialogue: 0,0:15:08.64,0:15:13.22,Default,,0000,0000,0000,,we overwrite the __platform_mem_move\Npointer at its unslid address plus the Dialogue: 0,0:15:13.22,0:15:19.59,Default,,0000,0000,0000,,slide we just chose with a gadget that\Nwould pivot to our slid rop chain and then Dialogue: 0,0:15:19.59,0:15:25.55,Default,,0000,0000,0000,,we call strlcpy. And now there are\Nbasically two possibilities. Either we Dialogue: 0,0:15:25.55,0:15:30.22,Default,,0000,0000,0000,,guessed the right slide and then we jump\Nto our gadget and pivot the stack or we Dialogue: 0,0:15:30.22,0:15:33.50,Default,,0000,0000,0000,,guessed the wrong slide. But obviously\Nnothing happened because we can just write Dialogue: 0,0:15:33.50,0:15:38.54,Default,,0000,0000,0000,,there so we can go back to step one and\Ntry again. And then with that we can just Dialogue: 0,0:15:38.54,0:15:41.65,Default,,0000,0000,0000,,brute force the slide till we get the\Nright one. The catch with this, however, Dialogue: 0,0:15:41.65,0:15:45.59,Default,,0000,0000,0000,,is that the write what were is pretty slow\Nand it also needs a lot of storage. So for Dialogue: 0,0:15:45.59,0:15:53.46,Default,,0000,0000,0000,,a 64 bit write I need about 120 bytes in\Nthe config file. And because there are so Dialogue: 0,0:15:53.46,0:16:01.72,Default,,0000,0000,0000,,many possible slide values, the chain I\Nhave currently is around... it's only to Dialogue: 0,0:16:01.72,0:16:07.01,Default,,0000,0000,0000,,rop gadgets, but the config file is\Nalready 12 megabytes, I think. And because Dialogue: 0,0:16:07.01,0:16:11.49,Default,,0000,0000,0000,,of that, it takes around 10 seconds to run\Nif it's a really bad slide. So the rop Dialogue: 0,0:16:11.49,0:16:16.05,Default,,0000,0000,0000,,chain has to be as short as possible. And\Nthe other problem is that if we have a bad Dialogue: 0,0:16:16.05,0:16:19.57,Default,,0000,0000,0000,,slide, we will basically smash the whole\Ndata segment and we can't really recover Dialogue: 0,0:16:19.57,0:16:23.52,Default,,0000,0000,0000,,from that. So we had crashes in malloc and\Nstuff like that while developing, Dialogue: 0,0:16:23.52,0:16:27.65,Default,,0000,0000,0000,,basically. There are some solutions to\Nthat, we can have a really short rop chain Dialogue: 0,0:16:27.65,0:16:34.10,Default,,0000,0000,0000,,in stage one and we can achieve this by\Nbasically just opening the big cache file Dialogue: 0,0:16:34.10,0:16:39.44,Default,,0000,0000,0000,,to get a file descriptor to it and then we\Ncan map it at a static address and then Dialogue: 0,0:16:39.44,0:16:43.30,Default,,0000,0000,0000,,get many gadgets there because the file is\Nobviously code signed by Apple so we can Dialogue: 0,0:16:43.30,0:16:47.90,Default,,0000,0000,0000,,just jump there after mapping it. But the\Nproblem with that is that nothing is set Dialogue: 0,0:16:47.90,0:16:53.11,Default,,0000,0000,0000,,up. So malloc and other functions aren't\Nworking. But as I said earlier, the Dialogue: 0,0:16:53.11,0:16:57.83,Default,,0000,0000,0000,,current cache has a smashed data segment\Nso we don't really lose anything. And Dialogue: 0,0:16:57.83,0:17:01.53,Default,,0000,0000,0000,,after having the cache at a static address\Nwe can use the open and mmap functions Dialogue: 0,0:17:01.53,0:17:05.57,Default,,0000,0000,0000,,from that cache to basically map stage two\Ninto the process memory and stage two is Dialogue: 0,0:17:05.57,0:17:16.48,Default,,0000,0000,0000,,just a really big rop stack. So, yeah. And\Nthen we are basically in ROP, but we can Dialogue: 0,0:17:16.48,0:17:21.20,Default,,0000,0000,0000,,only use raw syscalls and not much more\Nbecause everything else will either use a Dialogue: 0,0:17:21.20,0:17:26.45,Default,,0000,0000,0000,,function that uses malloc or will use\Nmalloc on it's own. And the other problem Dialogue: 0,0:17:26.45,0:17:30.36,Default,,0000,0000,0000,,is that basically errno is also broken. So\Nevery syscall which fails will crush the Dialogue: 0,0:17:30.36,0:17:35.11,Default,,0000,0000,0000,,binary. So the first thing I do is\Nbasically map a few pages so that errno Dialogue: 0,0:17:35.11,0:17:40.61,Default,,0000,0000,0000,,works again because we have a few syscalls\Nthat might fail. And then the other big Dialogue: 0,0:17:40.61,0:17:45.15,Default,,0000,0000,0000,,problem is that we now need to implement\Nthe whole kernel exploit in rop. So I Dialogue: 0,0:17:45.15,0:17:50.48,Default,,0000,0000,0000,,start to write a framework around this\Nawesome gadget which is present in all the Dialogue: 0,0:17:50.48,0:17:54.06,Default,,0000,0000,0000,,cache versions I looked at. Basically at the\Ntop you can see that all the high Dialogue: 0,0:17:54.06,0:18:00.56,Default,,0000,0000,0000,,registers are moved into x0 through x7. So\Nall the registers used for the calling Dialogue: 0,0:18:00.56,0:18:07.61,Default,,0000,0000,0000,,convention are and then we branch with\Nlink to register based on x27. So also Dialogue: 0,0:18:07.61,0:18:11.95,Default,,0000,0000,0000,,high register. And after that we load all\Nthe register values back from the stack so Dialogue: 0,0:18:11.95,0:18:16.75,Default,,0000,0000,0000,,we can just chain those gadgets together\Nto call any functions. You basically rop Dialogue: 0,0:18:16.75,0:18:22.31,Default,,0000,0000,0000,,into the lower half and then chain another\None of those afterwards and then they can Dialogue: 0,0:18:22.31,0:18:26.89,Default,,0000,0000,0000,,load all the values, call the function and\Nthen load all the values from the stack Dialogue: 0,0:18:26.89,0:18:32.40,Default,,0000,0000,0000,,again. And that's how the whole rop chain\Nworks. So yeah, I also used another gadget Dialogue: 0,0:18:32.40,0:18:37.48,Default,,0000,0000,0000,,to basically add two registers together\Nand another one which stores x0 so that I Dialogue: 0,0:18:37.48,0:18:42.80,Default,,0000,0000,0000,,can store the return value on the stack\Nand later reuse it. And for loops I use a Dialogue: 0,0:18:42.80,0:18:46.95,Default,,0000,0000,0000,,gadget which just returns if x0 is zero.\NSo it's basically just a read instruction Dialogue: 0,0:18:46.95,0:18:51.30,Default,,0000,0000,0000,,then and otherwise it will tail call a\Nfunction using function pointer from the Dialogue: 0,0:18:51.30,0:18:54.89,Default,,0000,0000,0000,,data segment. And because I can control\Nthe whole data segment, I can just put a Dialogue: 0,0:18:54.89,0:19:00.23,Default,,0000,0000,0000,,function pointer there that that will then\Njump to an epilog and misasligning the stack Dialogue: 0,0:19:00.23,0:19:05.12,Default,,0000,0000,0000,,with that. And then I can call longjmp\Nwith two different register values and Dialogue: 0,0:19:05.12,0:19:10.40,Default,,0000,0000,0000,,because of that pivot the stack to another\Nlocation. And when we basically didn't Dialogue: 0,0:19:10.40,0:19:16.40,Default,,0000,0000,0000,,jump outside of the loop, I just mmap the\Npart of stage 2 which has the loop in it Dialogue: 0,0:19:16.40,0:19:23.05,Default,,0000,0000,0000,,back over old stack again. And then I can\Njust reuse to stack every time. And then Dialogue: 0,0:19:23.05,0:19:27.53,Default,,0000,0000,0000,,pivot up using longjup. The problem wih\Nthis, however, is obviously that it's Dialogue: 0,0:19:27.53,0:19:33.59,Default,,0000,0000,0000,,pretty slow because I use mmap as a\Nsyscall. But this can be solved by just Dialogue: 0,0:19:33.59,0:19:38.98,Default,,0000,0000,0000,,unrolling your loops like for 10\Niterations and then mmapping the file so Dialogue: 0,0:19:38.98,0:19:43.39,Default,,0000,0000,0000,,that I get more loop iterations basically\Nper second, which is important for the Dialogue: 0,0:19:43.39,0:19:52.31,Default,,0000,0000,0000,,race. So now we will go over the kernel\Nbug so the kASLR leak is CVS-2018-4413 by Dialogue: 0,0:19:52.31,0:19:58.13,Default,,0000,0000,0000,,panicall. It was fixed in iOS 12.1 and\Nit's luckily reachable from the Racoon Dialogue: 0,0:19:58.13,0:20:03.29,Default,,0000,0000,0000,,sandbox because Apple is sandboxing most\Nuserland processes and the Racoon sandbox Dialogue: 0,0:20:03.29,0:20:08.39,Default,,0000,0000,0000,,is really tight. We didn't have that much,\Nmany bugs that would work in Racoon, but Dialogue: 0,0:20:08.39,0:20:14.51,Default,,0000,0000,0000,,luckily this one does because Racoon has\Naccess to the sysctl functions and this Dialogue: 0,0:20:14.51,0:20:20.24,Default,,0000,0000,0000,,one is in the sysctl_progargsx function.\NThe progargsx function basically allocates Dialogue: 0,0:20:20.24,0:20:25.50,Default,,0000,0000,0000,,a page using kmem_alloc. But it doesn't\Nzero it so it might contain old heap data Dialogue: 0,0:20:25.50,0:20:30.89,Default,,0000,0000,0000,,and then they copy the process arguments\Nto the front of the page. And now if you Dialogue: 0,0:20:30.89,0:20:35.14,Default,,0000,0000,0000,,supply a wrong size from user space and\Nthere are a few other conditions that have Dialogue: 0,0:20:35.14,0:20:40.06,Default,,0000,0000,0000,,to be met for some weird reason it copies\Nfrom the end of the page into user space Dialogue: 0,0:20:40.06,0:20:44.56,Default,,0000,0000,0000,,which I don't get why does this even get\Nby code review. But here's a graphical Dialogue: 0,0:20:44.56,0:20:49.91,Default,,0000,0000,0000,,illustration: there is basically this page\Nis full of uninitialized data and then Dialogue: 0,0:20:49.91,0:20:53.24,Default,,0000,0000,0000,,they put the process arguments in the\Nfront and copy out uniinitialized heap Dialogue: 0,0:20:53.24,0:20:58.91,Default,,0000,0000,0000,,data from the back into user land and we\Ncan obviously just spray specific heap Dialogue: 0,0:20:58.91,0:21:04.43,Default,,0000,0000,0000,,objects with kernel pointers in them and\Nthen free them again and use this Dialogue: 0,0:21:04.43,0:21:08.19,Default,,0000,0000,0000,,primitive to maybe leak them. And if we\Nfind a kernel pointer in there, we can Dialogue: 0,0:21:08.19,0:21:15.38,Default,,0000,0000,0000,,just calculate this kernel slide. So yeah.\NAnd then we come to the racy double free. Dialogue: 0,0:21:15.38,0:21:19.68,Default,,0000,0000,0000,,As I said, the main problem of the\Nuntether is the racoon sandbox, so many of Dialogue: 0,0:21:19.68,0:21:24.72,Default,,0000,0000,0000,,the kernel bugs that would work in iOS 11\Nfrom an app, didn't work from racoon. But Dialogue: 0,0:21:24.72,0:21:30.08,Default,,0000,0000,0000,,luckily on Halloween Sparky told me about\NLightspeed bug from Synacktiv, which is Dialogue: 0,0:21:30.08,0:21:35.96,Default,,0000,0000,0000,,reachable from the sandbox. It's a double\Nfree in kalloc.16. The kernel allocator's Dialogue: 0,0:21:35.96,0:21:42.88,Default,,0000,0000,0000,,based on zones and with different sizes.\NSo there's, for example, kalloc.16 and Dialogue: 0,0:21:42.88,0:21:47.27,Default,,0000,0000,0000,,then all objects in that zone have a size\Nof 16 or less bytes and they are obviously Dialogue: 0,0:21:47.27,0:21:55.46,Default,,0000,0000,0000,,also other zones for bigger objects. And\Nbasically there is a structure in there Dialogue: 0,0:21:55.46,0:22:00.69,Default,,0000,0000,0000,,that then gets doubled. And there is the\Nsyscall that's handling async file events. Dialogue: 0,0:22:00.69,0:22:04.37,Default,,0000,0000,0000,,So a user mode application can just call\Nit and tell the kernel, hey, please write Dialogue: 0,0:22:04.37,0:22:09.72,Default,,0000,0000,0000,,a buffer to a file and then move on with\Nexecution and it uses a kernel thread to Dialogue: 0,0:22:09.72,0:22:13.64,Default,,0000,0000,0000,,perform those. And for that, that\Nbasically allocates a structure to contain Dialogue: 0,0:22:13.64,0:22:18.33,Default,,0000,0000,0000,,some metadata like where the buffer is and\Nto which file it should write, and the Dialogue: 0,0:22:18.33,0:22:23.59,Default,,0000,0000,0000,,kernel thread obviously has to free the\Nstructure after it's done because it just Dialogue: 0,0:22:23.59,0:22:27.85,Default,,0000,0000,0000,,gets into the query for\Nthe kernel thread, that then wakes up and Dialogue: 0,0:22:27.85,0:22:33.00,Default,,0000,0000,0000,,maybe sees it has a new job, then performs\Nthe operation and then it has to free it, Dialogue: 0,0:22:33.00,0:22:36.45,Default,,0000,0000,0000,,otherwise it will leak. But the problem\Nhere is that if an error occurred while Dialogue: 0,0:22:36.45,0:22:41.42,Default,,0000,0000,0000,,setting the structure up, the second field\Nin the structure will be zero. And then Dialogue: 0,0:22:41.42,0:22:46.44,Default,,0000,0000,0000,,the structure also isn't included into the\Njobs list. So the kernel thread will never Dialogue: 0,0:22:46.44,0:22:51.46,Default,,0000,0000,0000,,wake up and look at it. So the syscall has\Nto free it because otherwise it will leak. Dialogue: 0,0:22:51.46,0:22:55.10,Default,,0000,0000,0000,,And the problem here is that we can\Nbasically reallocate the structure before Dialogue: 0,0:22:55.10,0:22:58.93,Default,,0000,0000,0000,,the syscall checks. So what happens here\Nis that the syscall allocates the Dialogue: 0,0:22:58.93,0:23:04.40,Default,,0000,0000,0000,,structure, fills it up, and then it gets\Nadded to the list and then the kernel Dialogue: 0,0:23:04.40,0:23:09.100,Default,,0000,0000,0000,,thread is so fast that it runs while the\Nsyscall isn't finished yet and basically Dialogue: 0,0:23:09.100,0:23:17.78,Default,,0000,0000,0000,,gets the gets the job done and frees it.\NAnd then we can spray heap objects pretty Dialogue: 0,0:23:17.78,0:23:22.98,Default,,0000,0000,0000,,fast to overlay with that structure. And\Nthen the syscall finishes and checks the Dialogue: 0,0:23:22.98,0:23:27.62,Default,,0000,0000,0000,,field and sees that it's zero because we\Njust replaced it with an object that has Dialogue: 0,0:23:27.62,0:23:32.75,Default,,0000,0000,0000,,zero at that location so it frees it again\Nleading to a double free. And yeah, we can Dialogue: 0,0:23:32.75,0:23:38.91,Default,,0000,0000,0000,,obviously exploit it. So for exploitation\NI just spam the syscall on one thread Dialogue: 0,0:23:38.91,0:23:42.87,Default,,0000,0000,0000,,which is pretty hard to do in ROP, but I\Njust call threadCreate. We've appointed Dialogue: 0,0:23:42.87,0:23:46.97,Default,,0000,0000,0000,,two long jump and then pivot the stack to\Nthe application and then in the other Dialogue: 0,0:23:46.97,0:23:52.93,Default,,0000,0000,0000,,thread I spray Mach messages with\NMACH_PORT_NULL in it. And the thing with Dialogue: 0,0:23:52.93,0:23:58.59,Default,,0000,0000,0000,,Mach messages is they can be used to do\Ninter-process communication and you can Dialogue: 0,0:23:58.59,0:24:03.35,Default,,0000,0000,0000,,also transfer port rights from one process\Nto another. So in this case we just send Dialogue: 0,0:24:03.35,0:24:07.71,Default,,0000,0000,0000,,an empty port, but you could also place\Nsomething else there and that will create Dialogue: 0,0:24:07.71,0:24:14.29,Default,,0000,0000,0000,,a structure and kalloc.16 containing zero\Nat that location. And and then if the Mach Dialogue: 0,0:24:14.29,0:24:18.69,Default,,0000,0000,0000,,message gets freed, we can replace it with\Nsomething and basically point it to Dialogue: 0,0:24:18.69,0:24:22.86,Default,,0000,0000,0000,,somewhere in kernel where fake port\Nstructure lives. And when we receive the Dialogue: 0,0:24:22.86,0:24:26.81,Default,,0000,0000,0000,,Mach message again, it will basically\Nthink that this is a real port and treat Dialogue: 0,0:24:26.81,0:24:32.60,Default,,0000,0000,0000,,it as such. And with that we can create a\Nfake kernel task port. But for that we Dialogue: 0,0:24:32.60,0:24:38.41,Default,,0000,0000,0000,,obviously need to replace it and we need\Nto heap spray. And most commonly iOS Dialogue: 0,0:24:38.41,0:24:43.52,Default,,0000,0000,0000,,surface is used for that as a kernel\Nextension, but because of our sandbox we Dialogue: 0,0:24:43.52,0:24:48.42,Default,,0000,0000,0000,,are so limited that we don't have iOS\Nsurface access. So the question is how we Dialogue: 0,0:24:48.42,0:24:54.31,Default,,0000,0000,0000,,actually spray and the\NrootDomainUserClient comes to rescue with Dialogue: 0,0:24:54.31,0:25:01.18,Default,,0000,0000,0000,,a memory leak. So actually this function\NsecureSleepSystemOptions is reachable from Dialogue: 0,0:25:01.18,0:25:07.02,Default,,0000,0000,0000,,the raccoon sandbox and Apple has a way of\Nbasically passing data to the kernel via Dialogue: 0,0:25:07.02,0:25:12.85,Default,,0000,0000,0000,,XML. So a userland application can just\Npass the XML to the kernel and then they Dialogue: 0,0:25:12.85,0:25:18.04,Default,,0000,0000,0000,,will use this OSUnserializeXML function to\Nturn the XML back into C++ objects which Dialogue: 0,0:25:18.04,0:25:21.79,Default,,0000,0000,0000,,the kernel can then use. And if this\Nsounds dangerous to you, it actually is. Dialogue: 0,0:25:21.79,0:25:27.55,Default,,0000,0000,0000,,There were a few bugs in that. But in this\Ncase we basically this just makes sure Dialogue: 0,0:25:27.55,0:25:33.31,Default,,0000,0000,0000,,with the OSDynamicCast that the data the\Nuser mode application supplied isn't Dialogue: 0,0:25:33.31,0:25:38.50,Default,,0000,0000,0000,,always dictionaries so that it can use it\Nafterwards. And the problem here is that Dialogue: 0,0:25:38.50,0:25:44.13,Default,,0000,0000,0000,,we can basically just OSDataObject or an\Nalways OSArray. So this OSDynamicCast Dialogue: 0,0:25:44.13,0:25:48.90,Default,,0000,0000,0000,,will fail and serialized options will\Nbecome null. But the original point of Dialogue: 0,0:25:48.90,0:25:55.57,Default,,0000,0000,0000,,return from OS under the XML will get lost\Nand so we will leak that memory and we Dialogue: 0,0:25:55.57,0:26:02.01,Default,,0000,0000,0000,,can just use this for spraying. So then\Nabout those two primitives, I will use to Dialogue: 0,0:26:02.01,0:26:06.86,Default,,0000,0000,0000,,basically exploitation. The case law\Nweakness, Darrell Justice CCL buffers and Dialogue: 0,0:26:06.86,0:26:10.98,Default,,0000,0000,0000,,they are located in the kernel data region\Nand because of that they are stacked with Dialogue: 0,0:26:10.98,0:26:17.08,Default,,0000,0000,0000,,the same slide as the kernel text region.\NAnd this means that as long as we know the Dialogue: 0,0:26:17.08,0:26:21.16,Default,,0000,0000,0000,,kernel slide we already do, that from the\Ncase of largely and we can control the Dialogue: 0,0:26:21.16,0:26:27.66,Default,,0000,0000,0000,,contents of a CCL buffer and we can get\Ndata to a known address and we can easily Dialogue: 0,0:26:27.66,0:26:33.01,Default,,0000,0000,0000,,do that with racoon because it runs US\Nroute. And so we can just switch all of Dialogue: 0,0:26:33.01,0:26:37.32,Default,,0000,0000,0000,,this of CCL buffer, for example, place the\Nsame point structure there will be later. Dialogue: 0,0:26:37.32,0:26:44.37,Default,,0000,0000,0000,,Also, place a fake trust constructively,\Nbut I will get into that. So yeah, now we Dialogue: 0,0:26:44.37,0:26:49.87,Default,,0000,0000,0000,,can use that primitive to basically spray\Ntan or state objects pointing to the CCL Dialogue: 0,0:26:49.87,0:26:53.74,Default,,0000,0000,0000,,buffer. And then we just received the\Nmessage again and check if the polls are Dialogue: 0,0:26:53.74,0:27:00.12,Default,,0000,0000,0000,,now. And if that's the case, we best place\Nthe structure. And then for the non SMP Dialogue: 0,0:27:00.12,0:27:04.83,Default,,0000,0000,0000,,version we can even get the case load by\Ntraversing a few pointers. But that's not Dialogue: 0,0:27:04.83,0:27:10.71,Default,,0000,0000,0000,,needed for SMP Version because there we\Nalready got it with the case logic but Dialogue: 0,0:27:10.71,0:27:15.04,Default,,0000,0000,0000,,young, Non CCL IP devices, we also don't\Nneed a CCL buffers because we can just Dialogue: 0,0:27:15.04,0:27:20.11,Default,,0000,0000,0000,,place the fake port structure and use the\Nland and then we get the kernel slide this Dialogue: 0,0:27:20.11,0:27:24.09,Default,,0000,0000,0000,,way. And with the kernel slide and this\Nfake port, we can create a fake user Dialogue: 0,0:27:24.09,0:27:28.79,Default,,0000,0000,0000,,client and from there we can create a\Ncalled primitive and then we can use this Dialogue: 0,0:27:28.79,0:27:33.54,Default,,0000,0000,0000,,to override that pierce's trusses pointer\Nand pointed to a buffer with two hashes Dialogue: 0,0:27:33.54,0:27:38.18,Default,,0000,0000,0000,,and four stage 3 and stage 4. So basically\NApple has two ways of doing code signing. Dialogue: 0,0:27:38.18,0:27:42.75,Default,,0000,0000,0000,,Either it has a used land daemon that\Nverifies third party applications or a Dialogue: 0,0:27:42.75,0:27:48.11,Default,,0000,0000,0000,,test, so-called trust cache, which is a\Nlist of hashes from all of their system Dialogue: 0,0:27:48.11,0:27:54.28,Default,,0000,0000,0000,,applications. And as soon as the process\Nspawned or dynamic link library is loaded Dialogue: 0,0:27:54.28,0:27:59.31,Default,,0000,0000,0000,,and they will basically first verify if\Nthe hash of that file is inside of the Dialogue: 0,0:27:59.31,0:28:02.80,Default,,0000,0000,0000,,trust cache. And if so, they will just\Ntrust a binary blindly because it comes Dialogue: 0,0:28:02.80,0:28:07.31,Default,,0000,0000,0000,,from Apple, basically. And now when we\Noverride this trust cache point and Dialogue: 0,0:28:07.31,0:28:13.77,Default,,0000,0000,0000,,pointed to our buffer, we can basically\Nplace the hash of stage 3 and 4 there. And Dialogue: 0,0:28:13.77,0:28:20.00,Default,,0000,0000,0000,,then the system will think those are apple\Nbinaries and we can just load them. So. Dialogue: 0,0:28:20.00,0:28:24.47,Default,,0000,0000,0000,,Yeah. And for that we need to use a geter\Nopen. We can't use the real deal open Dialogue: 0,0:28:24.47,0:28:29.78,Default,,0000,0000,0000,,because that uses malock. So we just\Nopen stage 3 to get a file descriptor. Dialogue: 0,0:28:29.78,0:28:34.44,Default,,0000,0000,0000,,Then we attached a signature which now\Nsucceeds as the caches and trust cache and Dialogue: 0,0:28:34.44,0:28:39.56,Default,,0000,0000,0000,,then we can map it as read executed and\Njump there. And then we are after two Dialogue: 0,0:28:39.56,0:28:46.10,Default,,0000,0000,0000,,months of writing options. We are finally\Nin C and we can write code more easily. Dialogue: 0,0:28:46.10,0:28:51.23,Default,,0000,0000,0000,,And the problem there is that we still\Ndon't have a working cache. So we are Dialogue: 0,0:28:51.23,0:28:57.22,Default,,0000,0000,0000,,still limited to the basic functionality\Nand because of the ghetto dlopen link is Dialogue: 0,0:28:57.22,0:29:02.60,Default,,0000,0000,0000,,obviously not working. So we just rely on\Nraw as somebody follows syscalls. And I Dialogue: 0,0:29:02.60,0:29:07.91,Default,,0000,0000,0000,,also pass some function pointers which I\Nalready use for stage 2. So for example, Dialogue: 0,0:29:07.91,0:29:13.70,Default,,0000,0000,0000,,open and a map to stage 3. And from there\Nwe remove the con task and session into Dialogue: 0,0:29:13.70,0:29:20.76,Default,,0000,0000,0000,,our special port 4 so that other user mode\Napplications can use it. And then we can Dialogue: 0,0:29:20.76,0:29:24.51,Default,,0000,0000,0000,,basically escape the sandbox by removing\Nthe sandbox label in the process Dialogue: 0,0:29:24.51,0:29:30.70,Default,,0000,0000,0000,,structure, so that we can launch a new\Nbinary, because otherwise the raccoons and Dialogue: 0,0:29:30.70,0:29:35.35,Default,,0000,0000,0000,,bugs doesn't allow it. But in the kernel,\Nthose process structures basically have Dialogue: 0,0:29:35.35,0:29:39.01,Default,,0000,0000,0000,,this label, which tells the kernel of\Nwhich sandbox to use. And as you're doing Dialogue: 0,0:29:39.01,0:29:45.54,Default,,0000,0000,0000,,it, you can just tell it to not use any\Nsamples. And and then we can launch stage Dialogue: 0,0:29:45.54,0:29:49.80,Default,,0000,0000,0000,,3, 4 and with that, get a working\Ncashback. And that's the big advantage Dialogue: 0,0:29:49.80,0:29:55.36,Default,,0000,0000,0000,,from like having a separate file. We now\Nhave the full cache functions working and Dialogue: 0,0:29:55.36,0:30:01.48,Default,,0000,0000,0000,,can do work more easily. And then I it's\Njust called two opposing spawn and then a Dialogue: 0,0:30:01.48,0:30:06.45,Default,,0000,0000,0000,,raw exit. This to exit the daemon without\Ncrashing because of launch. You would see Dialogue: 0,0:30:06.45,0:30:10.61,Default,,0000,0000,0000,,that one of the launch demons crashed and\Nthe specifics flag inside it would try to Dialogue: 0,0:30:10.61,0:30:14.34,Default,,0000,0000,0000,,restart it. And then our option would run\Nagain. We obviously want to prevent that. Dialogue: 0,0:30:14.34,0:30:21.45,Default,,0000,0000,0000,,So we use the exits as call to exit it.\NAnd then we are in stage 4. And from my Dialogue: 0,0:30:21.45,0:30:25.78,Default,,0000,0000,0000,,side, that was just basically to block or\Nsignal. So we don't get killed by launchd. Dialogue: 0,0:30:25.78,0:30:31.11,Default,,0000,0000,0000,,Because when launchd the launch and\Nexits, it will send the kill to all this Dialogue: 0,0:30:31.11,0:30:35.52,Default,,0000,0000,0000,,child process. And I need to catch that.\NOtherwise Stage 4 would get killed. And Dialogue: 0,0:30:35.52,0:30:40.25,Default,,0000,0000,0000,,then I just called the Post Exploitation\NFramework, which was written by Sparky. Dialogue: 0,0:30:40.25,0:30:45.20,Default,,0000,0000,0000,,And basically that does the following. It\Nfirst elevates the process to root with Dialogue: 0,0:30:45.20,0:30:50.22,Default,,0000,0000,0000,,current credentials, then it performs a\Nremount of the root file system because on Dialogue: 0,0:30:50.22,0:30:56.25,Default,,0000,0000,0000,,stock IOS, a file system was mounted as\Nread only and we obviously need to Dialogue: 0,0:30:56.25,0:31:01.47,Default,,0000,0000,0000,,mount it as read/write to modify some files\Non there and then set non it sets the Dialogue: 0,0:31:01.47,0:31:06.59,Default,,0000,0000,0000,,nonce so that the user might be able to\Ndowngrade to an older version if they are Dialogue: 0,0:31:06.59,0:31:12.10,Default,,0000,0000,0000,,flops. Verifies that the bootstrap was in\Nplace from the installation. And then Dialogue: 0,0:31:12.10,0:31:17.45,Default,,0000,0000,0000,,checked substrates or the framework that's\Nused for them to perform tweak injection Dialogue: 0,0:31:17.45,0:31:23.60,Default,,0000,0000,0000,,and it's plugging into trust us and starts\Nthem so that they can start to inject into Dialogue: 0,0:31:23.60,0:31:27.87,Default,,0000,0000,0000,,newly spawn processes. Then it's Ponce or\Nthe launch demons associate with the Dialogue: 0,0:31:27.87,0:31:33.52,Default,,0000,0000,0000,,jailbreak and unloads or own demons so\Nthat we don't respawned by extended Dialogue: 0,0:31:33.52,0:31:38.81,Default,,0000,0000,0000,,run. They kernel exploit again and then\Nperforms an LUV start to basically restart Dialogue: 0,0:31:38.81,0:31:43.65,Default,,0000,0000,0000,,all of the launch teams off the system so\Nthat subset can inject 3 STEM. And with Dialogue: 0,0:31:43.65,0:31:49.01,Default,,0000,0000,0000,,that the system is faulty, jail broken and\Nwe can perform a few cleanup steps. But Dialogue: 0,0:31:49.01,0:31:52.75,Default,,0000,0000,0000,,yeah, basically the end user has\Njailebroken system. Then as a little Dialogue: 0,0:31:52.75,0:31:58.24,Default,,0000,0000,0000,,side note while we are testing all the\Ndemons, we got killed by jetsam a lot. So Dialogue: 0,0:31:58.24,0:32:02.77,Default,,0000,0000,0000,,basically jetsam is the kernel\Nextension from Apple. That is therefore Dialogue: 0,0:32:02.77,0:32:08.35,Default,,0000,0000,0000,,memory management. And they basically want\Nto make sure the user mode application Dialogue: 0,0:32:08.35,0:32:12.91,Default,,0000,0000,0000,,doesn't use too much memory because they\Ndon't have that much on iPhone. And on all Dialogue: 0,0:32:12.91,0:32:19.02,Default,,0000,0000,0000,,the iPhones, actually. So there is this\Nlist and jetsam, it jetsam seems easier to Dialogue: 0,0:32:19.02,0:32:24.91,Default,,0000,0000,0000,,use than process uses more than read and\Nshould use. It would just kill it. So we Dialogue: 0,0:32:24.91,0:32:29.50,Default,,0000,0000,0000,,changed the values in the plist under\NLaunchDaemons to actually allow the Dialogue: 0,0:32:29.50,0:32:33.82,Default,,0000,0000,0000,,LaunchDaemons to use more memory. But \Nthe weird thing about this is that this Dialogue: 0,0:32:33.82,0:32:39.48,Default,,0000,0000,0000,,actually got us accepted by jetsam and we\Nhad normal crashes while Apple actually Dialogue: 0,0:32:39.48,0:32:46.72,Default,,0000,0000,0000,,tried to mitigate that beforehand. So\Nbecause jailbreak is always modify those Dialogue: 0,0:32:46.72,0:32:50.36,Default,,0000,0000,0000,,configuration files on the LaunchDaemons,\Nthey start to move all of them into a Dialogue: 0,0:32:50.36,0:32:54.49,Default,,0000,0000,0000,,dynamic library to guard them under code\Nsigning. So the jailbreak just couldn't Dialogue: 0,0:32:54.49,0:32:59.33,Default,,0000,0000,0000,,change them anymore. But when you tried to\Nfigure out the Launchdemon at the Launch Dialogue: 0,0:32:59.33,0:33:06.03,Default,,0000,0000,0000,,Demons, we dumped the dylib and ahm\Nthere was also plist embedded for Dialogue: 0,0:33:06.03,0:33:12.43,Default,,0000,0000,0000,,Jetsam, but Apple was still using those\Nfiles on disk. So I really want to look Dialogue: 0,0:33:12.43,0:33:16.30,Default,,0000,0000,0000,,further into this because it seems like\NApple isn't always ignoring those Dialogue: 0,0:33:16.30,0:33:22.41,Default,,0000,0000,0000,,configurations files on disk. And then\Nthanks to the whole team. Siguza, Sparkey, Dialogue: 0,0:33:22.41,0:33:27.74,Default,,0000,0000,0000,,and Stek for bouncing ideas back and\Nforth and writing the many part of the Dialogue: 0,0:33:27.74,0:33:35.30,Default,,0000,0000,0000,,jailbreak. Then for Pod2g, Synacktiv for\Nthe kernel bugs. And basically also a big Dialogue: 0,0:33:35.30,0:33:39.52,Default,,0000,0000,0000,,thanks to Saurik for substrate and the\Nwhole jailbreaking framework and for Dialogue: 0,0:33:39.52,0:33:43.24,Default,,0000,0000,0000,,Swaggo, parrorgeek and Samg_is_a_Ninja\Nfor testing a few things and keeping Dialogue: 0,0:33:43.24,0:33:49.36,Default,,0000,0000,0000,,motivated. And for Jonathan Levin for his\Nbooks basically because he bought a few Dialogue: 0,0:33:49.36,0:33:54.72,Default,,0000,0000,0000,,awesome books about IOS and that got me\Ninto it two years ago. And yeah. And in Dialogue: 0,0:33:54.72,0:33:59.92,Default,,0000,0000,0000,,the future, I think exploiting kernel\Nvulnerability with other cache functions Dialogue: 0,0:33:59.92,0:34:05.40,Default,,0000,0000,0000,,and owning ROP really is a pain and that\Nprobably won't do it again. Because he's Dialogue: 0,0:34:05.40,0:34:12.77,Default,,0000,0000,0000,,spent most of that. But yeah, the other\Nbig problem now is that with a 12 so the Dialogue: 0,0:34:12.77,0:34:18.85,Default,,0000,0000,0000,,new iPhones pack. So point authentication\Nkills most of these types of exploits Dialogue: 0,0:34:18.85,0:34:23.42,Default,,0000,0000,0000,,because the problem there is that you\Nwould now need an ASLA bypass and the pack Dialogue: 0,0:34:23.42,0:34:30.13,Default,,0000,0000,0000,,bypass to get into return oriented\Nprograming. And it's pretty unlikely to Dialogue: 0,0:34:30.13,0:34:36.69,Default,,0000,0000,0000,,basically have both. And because Pegg\Nbypasses are really rare and yet I only Dialogue: 0,0:34:36.69,0:34:43.38,Default,,0000,0000,0000,,know about this one is a LA bypass. So you\Nwould have to get pretty lucky. Also un- Dialogue: 0,0:34:43.38,0:34:48.46,Default,,0000,0000,0000,,tethering gets progressively harder. Apple\Njust fixed another good idea ahead in iOS Dialogue: 0,0:34:48.46,0:34:55.64,Default,,0000,0000,0000,,13.1. Basically the idea was to use printf\Nwith the format string format modify Dialogue: 0,0:34:55.64,0:35:01.17,Default,,0000,0000,0000,,'%n' to get a Turing complete\Nmachine because printf, this modifier Dialogue: 0,0:35:01.17,0:35:08.17,Default,,0000,0000,0000,,is basic Turing complete and then you\Nstart to develop a pack bypass basically Dialogue: 0,0:35:08.17,0:35:14.13,Default,,0000,0000,0000,,and get them to ROP. But now we're in IS\N13.1. I think Apple actually removed the Dialogue: 0,0:35:14.13,0:35:19.83,Default,,0000,0000,0000,,'%n' modifier, so you can no\Nlonger do this. And yeah. So this idea is Dialogue: 0,0:35:19.83,0:35:24.73,Default,,0000,0000,0000,,also gone. And yeah. In the end, I was\Nable to complete my pipe dream, so I guess Dialogue: 0,0:35:24.73,0:35:31.16,Default,,0000,0000,0000,,I will need a new one. So watch out, Apple\Nand that spice. Are there any questions? Dialogue: 0,0:35:31.16,0:35:41.09,Default,,0000,0000,0000,,{\i1}Applause{\i0} Dialogue: 0,0:35:41.09,0:35:45.40,Default,,0000,0000,0000,,Herald: Thank you, littlelailo for is\Nfantastic work. I suppose we're going to Dialogue: 0,0:35:45.40,0:35:49.79,Default,,0000,0000,0000,,hear more from you in the future.\NLittlelailo: Maybe. Dialogue: 0,0:35:49.79,0:35:54.94,Default,,0000,0000,0000,,Herald: Are there questions here in\Nthis audience. No one who wants to hire Dialogue: 0,0:35:54.94,0:36:01.65,Default,,0000,0000,0000,,this guy now right away. No one. No one.\NCan you describe to me what change Dialogue: 0,0:36:01.65,0:36:09.19,Default,,0000,0000,0000,,actually do times in these, you know, all\Nthe ASICs? Oh, yeah. Oh, yes. versions. Dialogue: 0,0:36:09.19,0:36:11.50,Default,,0000,0000,0000,,Littlelailo: Well what they change to\Nmake. Dialogue: 0,0:36:11.50,0:36:17.03,Default,,0000,0000,0000,,Herald: Yeah. What. Plus, you know, I told\Nyou like I started the tethering challenge Dialogue: 0,0:36:17.03,0:36:20.36,Default,,0000,0000,0000,,actually at 5.1.\NLittlelailo: Well, they added a lot new Dialogue: 0,0:36:20.36,0:36:25.93,Default,,0000,0000,0000,,mitigations and also obviously pitched a\Nfew bugs like for example, those ASLR Dialogue: 0,0:36:25.93,0:36:31.62,Default,,0000,0000,0000,,bypasses that posterity used in Corona\Ngot patched. And this one also now got Dialogue: 0,0:36:31.62,0:36:37.66,Default,,0000,0000,0000,,patched by accident. But yeah, I mean like\Nsome bugs are still there. For example, Dialogue: 0,0:36:37.66,0:36:42.12,Default,,0000,0000,0000,,the Bug in racoon and the conflict pass.\NThe bug is still an all day. But yeah, I Dialogue: 0,0:36:42.12,0:36:47.84,Default,,0000,0000,0000,,don't really care about it. And the kernel\Nbugs got patched by Apple. But for Dialogue: 0,0:36:47.84,0:36:52.59,Default,,0000,0000,0000,,example, this synthetic one, they also\Nalso patched wrong by accident. And now it Dialogue: 0,0:36:52.59,0:36:55.80,Default,,0000,0000,0000,,always leaked the strike. But I think they\Nalso fixed that now. Dialogue: 0,0:36:55.80,0:36:59.74,Default,,0000,0000,0000,,Herald: Your team, you you're mentioning\Nyour team. You're working not on Dialogue: 0,0:36:59.74,0:37:01.74,Default,,0000,0000,0000,,your own, of course.\NLittlelailo: No. Dialogue: 0,0:37:01.74,0:37:05.82,Default,,0000,0000,0000,,Herald: And how would you restructured?\NHow are the roles divided? How was... Dialogue: 0,0:37:05.82,0:37:10.74,Default,,0000,0000,0000,,Littlelailo: Well, we are just like four\Npeople. So and we have this group chat and Dialogue: 0,0:37:10.74,0:37:14.86,Default,,0000,0000,0000,,then we are just hanging out there and\Nbouncing ideas back and forth and maybe Dialogue: 0,0:37:14.86,0:37:17.64,Default,,0000,0000,0000,,working on some stuff.\NHerald: A close contact with the Apple Dialogue: 0,0:37:17.64,0:37:22.28,Default,,0000,0000,0000,,developers.\NLittlelailo: No, not at all. Dialogue: 0,0:37:22.28,0:37:25.87,Default,,0000,0000,0000,,Herald: More.\NLittlelailo: I mean, I reported one bug to Dialogue: 0,0:37:25.87,0:37:31.89,Default,,0000,0000,0000,,their bounty once or like actually says to\Nthem that their bounty and that one got Dialogue: 0,0:37:31.89,0:37:40.77,Default,,0000,0000,0000,,fixed and it was all fine. But yeah, for\Nnow, I don't report bugs at the moment. Dialogue: 0,0:37:40.77,0:37:44.02,Default,,0000,0000,0000,,Herald: If you have time, you've time left\Nnow actually, you're looking for a new Dialogue: 0,0:37:44.02,0:37:46.56,Default,,0000,0000,0000,,project doesn't it?\NLittlelailo: Yeah. Yeah. And I might Dialogue: 0,0:37:46.56,0:37:50.29,Default,,0000,0000,0000,,report some of those bugs in the meantime\Nbut I mean with the presentation they know Dialogue: 0,0:37:50.29,0:37:54.43,Default,,0000,0000,0000,,about them though so they might fix them.\NHerald: They will be listening now and at Dialogue: 0,0:37:54.43,0:37:57.22,Default,,0000,0000,0000,,least probably I hope.\NLittlelailo: Yes. Dialogue: 0,0:37:57.22,0:38:02.46,Default,,0000,0000,0000,,Herald: Is there anyone who has really,\Nyou where sitting on a question here. None Dialogue: 0,0:38:02.46,0:38:10.36,Default,,0000,0000,0000,,of you? It's already noon. You know, noon\Npassed, so could be that none of you. You Dialogue: 0,0:38:10.36,0:38:15.26,Default,,0000,0000,0000,,can ask them something, maybe someone\Nasked them something, maybe they can help Dialogue: 0,0:38:15.26,0:38:18.49,Default,,0000,0000,0000,,you out with certain challenges that are\Nthere. Dialogue: 0,0:38:18.49,0:38:23.66,Default,,0000,0000,0000,,Littlelailo: Well, I don't really have a\Nquestion either. {\i1}Laughter{\i0} I have my own Dialogue: 0,0:38:23.66,0:38:29.76,Default,,0000,0000,0000,,research project now. Well, like, I do\Nstuff at the moment and look at other Dialogue: 0,0:38:29.76,0:38:34.88,Default,,0000,0000,0000,,things. For example, to the bootrom\Nexploit came out now. And so I started Dialogue: 0,0:38:34.88,0:38:40.60,Default,,0000,0000,0000,,developing on the chick team with them.\NAnd that's what I currently do, basically. Dialogue: 0,0:38:40.60,0:38:45.45,Default,,0000,0000,0000,,Herald: You're great, man. Littlelailo,\Nthank you. Giving him a warm applause! Dialogue: 0,0:38:45.45,0:38:48.38,Default,,0000,0000,0000,,{\i1}Applause{\i0} Dialogue: 0,0:38:48.38,0:38:51.94,Default,,0000,0000,0000,,{\i1}36c3 Postroll music{\i0} Dialogue: 0,0:38:51.94,0:39:15.00,Default,,0000,0000,0000,,Subtitles created by c3subtitles.de\Nin the year 2020. Join, and help us!