0:00:03.970,0:00:16.730
35C3 preroll music
0:00:16.730,0:00:22.010
Herald-Angel: All right, let's start with[br]our next talk in the security track of the
0:00:22.010,0:00:27.239
chaos communication congress. The talk is[br]called jailbreaking iOS from past to
0:00:27.239,0:00:34.954
present. Done by tihmstar. He spoke at the[br]32nd C3 already and researched on several
0:00:34.954,0:00:40.470
jailbreaks like the Phoenix or the[br]jelbrekTime for the Apple Watch and he's
0:00:40.470,0:00:44.800
gonna talk about the history of[br]jailbreaks. He's going to familiarize you
0:00:44.800,0:00:52.020
with the terminology of jailbreaking and[br]about exploit mitigations and how you can
0:00:52.020,0:00:55.910
circumvent these mitigations. Please[br]welcome him with a huge round of applause.
0:00:55.910,0:01:02.620
Applause
0:01:02.620,0:01:08.800
tihmstar: Thank you very much. So hello[br]room, I'm tihmstar, and as already said I
0:01:08.800,0:01:13.910
want to talk about jailbreaking iOS from[br]past to present and the topics I'm going
0:01:13.910,0:01:19.800
to cover "what is jailbreaking?". I will[br]give an overview in general. I'm going to
0:01:19.800,0:01:25.600
introduce you to how jailbreak started,[br]how they got into the phone at first and
0:01:25.600,0:01:30.950
how all of these progressed. I'll[br]introduce you to the terminology which is
0:01:30.950,0:01:37.460
"tethered", "untethered", "semi-tethered",[br]"semi-untethered" jailbreaks. Stuff you
0:01:37.460,0:01:41.400
probably heard but some of you don't know[br]what that means. I'm gonna talk a bit
0:01:41.400,0:01:46.250
about hardware mitigations which were[br]introduced by Apple which is KPP, KTRR and
0:01:46.250,0:01:52.799
a little bit about PAC. I'm going to talk[br]about the general goals of... About the
0:01:52.799,0:01:57.790
technical goals of jailbreaking and the[br]kernel patches and what you want to do
0:01:57.790,0:02:02.698
with those and brief overview how[br]jailbreaking could look like in the future.
0:02:02.698,0:02:10.769
So who am I? I'm tihmstar. I got[br]my first iPod touch with iOS 5.1 and since
0:02:10.769,0:02:15.740
then I pretty much played with jailbreaks[br]and then I got really interested into that
0:02:15.740,0:02:19.440
and started doing my own research. I[br]eventually started doing my own
0:02:19.440,0:02:23.510
jailbreaks. I kinda started with[br]downgrading – so I've been here two years
0:02:23.510,0:02:28.840
ago with my presentation "iOS Downgrading:[br]From past to present". I kept hacking
0:02:28.840,0:02:33.530
since then. So back then I kind of talked[br]about the projects I made and related to
0:02:33.530,0:02:38.610
downgrading which was tsschecker,[br]futurerestore, img4tool, you probably have
0:02:38.610,0:02:42.520
heard of that. And since then I was[br]working on several jailbreaking tools
0:02:42.520,0:02:49.690
ranging from iOS 8.4.1 to 10.3.3, among[br]those 32bit jailbreaks, untethered
0:02:49.690,0:02:54.510
jailbreaks, remote jailbreaks like[br]jailbreak.me and the jailbreak for the
0:02:54.510,0:03:02.200
Apple Watch. So, what is this jailbreaking[br]I am talking about? Basically, the goal is
0:03:02.200,0:03:08.620
to get control over a device you own. You[br]want to escape the sandbox which the apps
0:03:08.620,0:03:14.440
are put in. You want to elevate the[br]privileges to root and eventually to
0:03:14.440,0:03:20.030
kernel, you want to disable code signing[br]because all applications on iOS are code-
0:03:20.030,0:03:24.090
signed and you cannot run unsigned[br]binaries. You pretty much want to disable
0:03:24.090,0:03:29.959
that to run unsigned binaries. And the[br]most popular about people on jailbreak is
0:03:29.959,0:03:35.620
to install tweaks! And also a lot of[br]people install a jailbreak or jailbreak
0:03:35.620,0:03:39.241
their devices for doing security analysis.[br]For example if you want to pentest your
0:03:39.241,0:03:44.980
application and see how an attack goes[br]foot – you want to debug that stuff and
0:03:44.980,0:03:51.120
you want to have a jailbroken phone for[br]that. So what are these tweaks? Tweaks are
0:03:51.120,0:03:55.830
usually modifications of built-in[br]userspace programs, for example one of the
0:03:55.830,0:03:59.739
programs is springboard. Springboard is[br]what you see if you turn on your phone.
0:03:59.739,0:04:04.790
This is where all the icons are at. And[br]usually you can install tweaks to, I don't
0:04:04.790,0:04:10.680
know, modify the look, the behavior or add[br]functionality, just this customization,
0:04:10.680,0:04:17.880
this is how it started with jailbreaking.[br]What is usually bundled when you install a
0:04:17.880,0:04:23.720
jailbreak is Cydia. So you install dpkg[br]and apt which is the Debian package
0:04:23.720,0:04:31.630
manager and you also get Cydia which is a[br]user-friendly graphical user interface for
0:04:31.630,0:04:38.280
the decentralized or centralized package[br]installer system. I'm saying centralized
0:04:38.280,0:04:42.250
because it is pretty much all in one spot,[br]you just open the app and you can get all
0:04:42.250,0:04:47.250
your tweaks and it's also decentralized[br]because you can just add up your own repo,
0:04:47.250,0:04:54.200
you can make your own repo, you can add[br]other repos and you're not kinda tied to
0:04:54.200,0:04:58.460
one spot where you get the tweaks from, [br]like from the App Store you can only download
0:04:58.460,0:05:02.266
from the App Store. But with Cydia you can[br]pretty much download from everywhere.
0:05:02.266,0:05:09.210
You're probably familiar with Debian and[br]it's pretty much the same. So this talk is
0:05:09.210,0:05:15.610
pretty much structured around this tweet:[br]the "Ages of jailbreaking". So as you can
0:05:15.610,0:05:20.490
see we get the Golden Age, the BootRom,[br]the Industrial Age and The Post-
0:05:20.490,0:05:25.160
Apocalyptic age. And I kind of agree with[br]that. So this is why I decided to
0:05:25.160,0:05:29.530
structure my talk around that and walk you[br]through the different ages of
0:05:29.530,0:05:35.350
jailbreaking. So starting with the first[br]iPhone OS jailbreak – then it was actually
0:05:35.350,0:05:42.490
called iPhone OS not iOS – it was not the[br]BootROM yet. So the first was a buffer
0:05:42.490,0:05:49.560
overflow and the iPhone's libTitt library.[br]And this is an image parsing library.
0:05:49.560,0:05:54.930
It was exploited through Safari and used as[br]an entry point to get code execution.
0:05:54.930,0:06:00.900
It was the first time that non-Apple software[br]was run on an iPhone and people installed
0:06:00.900,0:06:06.850
applications like Installer or AppTapp[br]which were stores similar to Cydia back
0:06:06.850,0:06:11.590
then and those were used to install apps[br]or games because for the first iPhone OS
0:06:11.590,0:06:16.650
there was no way to install applications[br]anyhow, as the App Store got introduced
0:06:16.650,0:06:24.490
with iOS 2. So then, going to the Golden[br]Age, the attention kind of shifted to the
0:06:24.490,0:06:29.949
BootROM; people started looking at the[br]boot process and they found this device
0:06:29.949,0:06:39.120
firmware upgrade mode which is a part of[br]ROM. So the most famous BootROM exploit
0:06:39.120,0:06:45.120
was limera1n by geohot. It was a bug in[br]hardware and it was unpatchable with
0:06:45.120,0:06:52.650
software. So this bug was used to[br]jailbreak devices up to the iPhone 4.
0:06:52.650,0:06:56.669
There were also several other jailbreaks –[br]we didn't rely on that one – but this one,
0:06:56.669,0:07:00.375
once discovered, you can use it over and[br]over again and there's no way to patch
0:07:00.375,0:07:06.690
that. So this was later patched in a new[br]hardware revision which is the iPhone 4s.
0:07:06.690,0:07:09.830
So with that BootROM bug –
0:07:09.830,0:07:15.930
This is how kind of tethered jailbreaks[br]became a thing. So limera1n exploits a bug
0:07:15.930,0:07:24.340
in DFU mode which allows you to load[br]unsigned software through USB. However
0:07:24.340,0:07:29.729
when you reboot the device a computer was[br]required to re-exploit and again load your
0:07:29.729,0:07:36.380
unsigned code. And then load the[br]bootloaders, load the patched kernel and
0:07:36.380,0:07:40.350
thus the jailbreak was kind of tethered to[br]the computer because whenever you shut
0:07:40.350,0:07:46.160
down you need to be back at a computer to[br]boot your phone up. So historically a
0:07:46.160,0:07:51.520
tethered jailbroken phone does not boot[br]without a computer at all. And the reason
0:07:51.520,0:07:57.990
for that is because the jailbreaks would[br]modify the kernel and the bootloaders on
0:07:57.990,0:08:04.120
the file system for performance reasons,[br]so when you do the actual tether boot you
0:08:04.120,0:08:09.229
would need to upload a very tiny payload[br]via USB which then in turn would load
0:08:09.229,0:08:14.380
everything else from the file system[br]itself. But this results in a broken chain
0:08:14.380,0:08:18.780
of trust. When the normal boot process[br]runs and the bootloader checks the
0:08:18.780,0:08:23.340
signature of the first-stage bootloader[br]that would be invalid so the bootloader
0:08:23.340,0:08:29.340
would refuse to boot that and it would end[br]up in DFU mode so basically a phone won't
0:08:29.340,0:08:36.349
boot. Sometime around then, the idea for[br]semi-tethered jailbreak came up and the
0:08:36.349,0:08:40.479
idea behind that is very simple: just[br]don't break the chain of trust for
0:08:40.479,0:08:47.149
tethered jailbreaks. So, what you would do[br]differently is you do not modify the
0:08:47.149,0:08:52.220
kernel on the file system, don't touch the[br]bootloaders at all and then when you
0:08:52.220,0:08:56.230
would boot tethered, you would need to[br]upload all the bootloaders like the first
0:08:56.230,0:09:00.790
stage bootloader, then the second stage[br]bootloader which is iBoot and then the
0:09:00.790,0:09:05.550
kernel via USB to boot into jailbroken[br]mode. However when you reboot you could
0:09:05.550,0:09:10.550
boot all those components from the file[br]system so you could actually boot your
0:09:10.550,0:09:17.149
phone into non-jailbroken mode. If you[br]don't install any tweaks or modifications
0:09:17.149,0:09:22.020
which modify critical system components[br]because if you tamper with, for example,
0:09:22.020,0:09:25.210
the signature of the mount binary the[br]system obviously cannot boot
0:09:25.210,0:09:28.810
in non-jailbroken mode.
0:09:28.810,0:09:35.910
So, this is kind of the Golden age. [br]So let's continue with the Industrial age.
0:09:35.910,0:09:43.829
So with the release of the[br]iPhone 4s and iOS 5, Apple fixed the
0:09:43.829,0:09:49.689
BootROM bug and essentially killed[br]limera1n. They also introduced APTickets
0:09:49.689,0:09:55.660
and nonces to bootloaders, which I'm just[br]mentioning because it's kind of a
0:09:55.660,0:10:00.980
throwback for downgrading: before that you[br]can have a phone if you update to the
0:10:00.980,0:10:05.529
latest firmware and before you save your[br]SHSH blobs you could just downgrade and
0:10:05.529,0:10:09.279
then jailbreak again which wasn't a big[br]deal but with that they also added
0:10:09.279,0:10:13.809
downgrade protection so jailbreaking[br]became harder. If you wanted to know more
0:10:13.809,0:10:20.009
about how the boot process works, what[br]SHSH blobs are, what APTickets are, you
0:10:20.009,0:10:24.040
should check out my talk from two years[br]ago, I go in-depth on how all of that
0:10:24.040,0:10:30.470
works. So, I'm skipping that for this[br]talk. So the binaries the phone boots are
0:10:30.470,0:10:35.829
encrypted so the bootloaders are encrypted[br]and until recently the kernel used to be
0:10:35.829,0:10:41.749
encrypted as well. And the key encryption[br]key is fused into the devices and it is
0:10:41.749,0:10:46.329
impossible to get through hardware[br]attacks. At least there's no public case
0:10:46.329,0:10:53.100
where somebody actually got that recovered[br]at keys so it's probably impossible,
0:10:53.100,0:11:01.059
nobody has done it yet. So old boot files[br]are decrypted at boot by the previous
0:11:01.059,0:11:09.610
bootloader. And before the iPhone 4s you[br]could actually just talk to the hardware
0:11:09.610,0:11:15.079
iOS engine as soon as you got kernel-level[br]code execution. But with the iPhone 4s
0:11:15.079,0:11:19.471
they introduced a feature where before the[br]kernel would boot they would shut off the
0:11:19.471,0:11:25.870
iOS engine by hardware, so there is no way[br]to decrypt bootloader files anymore so
0:11:25.870,0:11:33.019
easily unless you got code execution in[br]the bootloader itself. So decrypting
0:11:33.019,0:11:38.720
bootloaders is a struggle from now on. So[br]I think kind of because of that the
0:11:38.720,0:11:44.810
attention shifted to userland and from now[br]the jailbreaks kind of had to be
0:11:44.810,0:11:50.569
untethered. So untethered here means that[br]if you jailbreak your device, you turn it
0:11:50.569,0:11:55.820
off, you boot it again, then the device is[br]still jailbroken, and this is usually
0:11:55.820,0:12:01.089
achieved through re-exploitation at some[br]point in the boot process. So you can't
0:12:01.089,0:12:05.529
just patch the kernel on file system[br]because that would invalidate signatures,
0:12:05.529,0:12:09.939
so instead you would, I don't know, add[br]some configuration files to some demons
0:12:09.939,0:12:16.079
which would trigger bugs and then exploit.[br]So jailbreaks then chained many bugs
0:12:16.079,0:12:21.249
together, sometimes six or more bugs to [br]get initial code execution, kernel code
0:12:21.249,0:12:28.078
execution and persistence. This somewhat[br]changed when Apple introduced free
0:12:28.078,0:12:33.759
developer accounts around the time they[br]released iOS 9. So these developer
0:12:33.759,0:12:38.949
accounts allow everybody who has an Apple[br]ID to get a valid signing certificate for
0:12:38.949,0:12:44.970
seven days for free. So you can actually[br]create an XCode project and run your app
0:12:44.970,0:12:49.939
on your physical device. Before that that[br]was not possible, so the only way to run
0:12:49.939,0:12:56.400
your own code on your device was to buy a[br]paid developer account which is 100$ per
0:12:56.400,0:13:03.149
year if you a buy personal developer[br]account. But now you can just get that for
0:13:03.149,0:13:07.670
free. And after seven days the certificate[br]expires, but you can just, for free,
0:13:07.670,0:13:12.040
request another one and keep doing that.[br]Which is totally enough if you develop
0:13:12.040,0:13:18.540
apps. So this kind of led to semi-[br]untethered jailbreaks because initial code
0:13:18.540,0:13:21.737
execution was not an issue anymore.[br]Anybody could just get that free
0:13:21.737,0:13:28.564
certificate, sign apps and run some kind[br]of code that was sandboxed. So jailbreak
0:13:28.564,0:13:36.350
focus shifted to more powerful kernel bugs[br]which were reachable from sandbox. So we
0:13:36.350,0:13:40.809
had jailbreaks using just one single bug[br]or maybe just two bugs and the jailbreaks
0:13:40.809,0:13:46.629
then were distributed as an IPA, which is[br]an installable app people would download,
0:13:46.629,0:13:53.489
sign themselves, put on the phone and just[br]run the app. So semi-untethered means
0:13:53.489,0:13:59.639
you can reboot into non-jailbroken mode,[br]however you can get to jailbroken mode
0:13:59.639,0:14:06.370
easily by just pressing an app. And over[br]the years Apple stepped up its game
0:14:06.370,0:14:13.829
constantly. So with iOS 5 they introduced[br]ASLR address space layer randomisation,
0:14:13.829,0:14:21.310
with iOS 6 they added kernel ASLR, with[br]the introduction of the iPhone 5, as they
0:14:21.310,0:14:27.949
added 64bit CPUs, which isn't really a[br]security mitigation, it just changed a bit
0:14:27.949,0:14:37.629
how you would exploit. So the real deal[br]started to come with iOS 9, where they
0:14:37.629,0:14:42.689
first introduced Kernel Patch Protection,[br]an attempt to make the kernel immutable
0:14:42.689,0:14:50.109
and not patchable. And they stepped up that [br]with the iPhone 7 where they introduced
0:14:50.109,0:14:57.551
Kernel Text Readonly Region, also known as[br]KTRR. So with iOS 11 they removed 32bit
0:14:57.551,0:15:03.459
libraries, which I think has very little[br]to no impact on exploitation; it's mainly
0:15:03.459,0:15:09.699
in the list because up to that point Cydia[br]was compiled as a 32bit binary and that
0:15:09.699,0:15:17.720
stopped working, that's why that had to be[br]recompiled for 64bit, which took someone
0:15:17.720,0:15:26.040
to do until you could get a working Cydia[br]on 64bits iOS 11. So with the iPhone Xs
0:15:26.040,0:15:30.989
which came out just recently they[br]introduced Pointer Authentication Codes,
0:15:30.989,0:15:35.386
and I'm gonna go more in detail into these[br]hardware mitigations in the next few
0:15:35.386,0:15:42.079
slides. So let's start with Kernel Patch[br]Protection. So when people say KPP, they
0:15:42.079,0:15:47.519
usually refer to what Apple calls[br]watchtower. So watchtower, as the name
0:15:47.519,0:15:53.769
suggests, watches over the kernel and[br]panics when modifications are detected,
0:15:53.769,0:15:58.859
and it prevents the kernel from being[br]patched. At least that's the idea of it.
0:15:58.859,0:16:03.069
It doesn't really prevent it because it's[br]broken but when they engineered it, it
0:16:03.069,0:16:08.689
should prevent you from patching the[br]kernel. So how does it work? Watchtower is
0:16:08.689,0:16:13.301
a piece of software which runs in EL3[br]which is the ARM exception level 3.
0:16:13.301,0:16:18.709
So exception levels are kind of privilege[br]separations while 3 is the highest and 0
0:16:18.709,0:16:24.519
is the lowest. And you can kind of trigger[br]an exception to call handler code in
0:16:24.519,0:16:31.459
higher levels. So the idea of watchtowers[br]that recurring events which is FPU usage
0:16:31.459,0:16:35.720
trigger Watchtower inspection of the[br]kernel, and you cannot really turn it off
0:16:35.720,0:16:41.819
because you do need the FPU. So if you[br]picture how it looks like, we have the
0:16:41.819,0:16:46.919
Watchtower to the left (which totally[br]looks like a lighthouse) and the
0:16:46.919,0:16:51.149
applications at the right. So in the[br]middle, in EL1, we have the kernel and
0:16:51.149,0:17:00.720
recent studies revealed that this is[br]exactly how the XNU kernel looks like. So
0:17:00.720,0:17:06.060
how can we be worse? An event occurs from[br]time to time which is from using userland
0:17:06.060,0:17:11.110
application, for example JavaScript makes[br]heavy use of floating points, and the
0:17:11.110,0:17:15.929
event would then go to the kernel and the[br]kernel would then trigger Watchtower as it
0:17:15.929,0:17:24.049
tries to enable the FPU. Watchtower would[br]scan the kernel and then if everything is
0:17:24.049,0:17:28.710
fine it would transition execution back[br]into the kernel which then in turn would
0:17:28.710,0:17:36.009
transition back into userspace which can[br]then use the FPU. However with a modified
0:17:36.009,0:17:41.974
kernel, when Watchtower scans the kernel[br]and detects modification, it would just
0:17:41.974,0:17:48.940
panic. So the idea is that the kernel is[br]forced to call Watchtower because the FPU
0:17:48.940,0:17:54.130
is blocked otherwise. But the problem at[br]the same time is that the kernel is in
0:17:54.130,0:18:00.480
control before it calls watchtower. And[br]this thing was fully defeated by qwerty in
0:18:00.480,0:18:09.720
yalu102. So how qwerty's KPP bypass works:[br]The idea is: you copy the kernel in memory
0:18:09.720,0:18:15.860
and you mody the copied kernel. Then you[br]would modify the page tables to use the
0:18:15.860,0:18:23.981
patched kernel. And whenever the FPU[br]triggers a Watchtower inspection, before
0:18:23.981,0:18:29.539
actually calling Watchtower you would[br]switch back to the unmodified kernel and
0:18:29.539,0:18:34.059
then let it run, let it check the[br]unmodified kernel when that returns you
0:18:34.059,0:18:39.909
would go back to the modified kernel. So[br]this one it looks like: we copy the kernel
0:18:39.909,0:18:47.130
in memory, we patch the modified copy, we[br]switch the page tables to actually use the
0:18:47.130,0:18:53.669
modified copy and when we have the FPU[br]event it would just switch the page tables
0:18:53.669,0:19:00.190
back, forward the call to Watchtower, make[br]then watch tower scan the unmodified
0:19:00.190,0:19:08.490
kernel and after the scan we would just[br]return to the patched kernel. So the
0:19:08.490,0:19:13.820
problem here is: Time of check – Time of[br]Use, the classical TOCTOU. And this works
0:19:13.820,0:19:20.370
on the iPhone 5s, the iPhone 6 and the[br]iPhone 6s and it's not really patchable.
0:19:20.370,0:19:27.130
However, with the iPhone 7, Apple[br]introduced KTRR, which kind of proves that
0:19:27.130,0:19:34.700
and they really managed to do an[br]unpatchable kernel. So how does KTRR work?
0:19:34.700,0:19:40.584
So Kernel Text Readonly Region, I'm going[br]to present as described by Siguza in his
0:19:40.584,0:19:49.061
blog, adds an extra memory controller[br]which is the AMCC which traps all writes to
0:19:49.061,0:19:56.750
the read-only region. And there's extra CPU[br]registers which mark and executable range
0:19:56.750,0:20:02.524
which are the KTRR registers and they[br]obviously mark a subsection of the
0:20:02.524,0:20:08.720
read-only region, so you have hardware[br]enforcement at boot time for read-only
0:20:08.720,0:20:15.352
memory region and hardware enforcement at[br]boot-time for an executable memory region.
0:20:15.682,0:20:21.350
So this the CPU. This is the memory at the[br]bottom. You would set the read-only region
0:20:21.350,0:20:26.320
at boot and since that's enforced by the[br]hardware memory controller everything
0:20:26.320,0:20:32.470
inside that region is not writable and[br]everything outside that region is
0:20:32.470,0:20:40.850
writable. And the CPU got KTRR registers[br]which mark begin and end. So the
0:20:40.850,0:20:46.809
executable region is a subsection of the[br]read-only region. Everything outside there
0:20:46.809,0:20:52.246
cannot be executed by the CPU. Everything[br]inside the read-only region cannot be
0:20:52.246,0:20:58.679
modified. And this has not been truly[br]bypassed yet. There's been a bypass but
0:20:58.679,0:21:04.409
that actually targeted how that thing gets[br]set up. But that's fakes and now it's
0:21:04.409,0:21:11.000
probably setting up everything and so far[br]it hasn't been bypassed. So jailbreaks are
0:21:11.000,0:21:15.710
still around. So what are they doing?[br]Well, they just walk around kernel patches
0:21:15.710,0:21:22.600
and this is when KPP jailbreaks evolved. [br]Which means, they just don't patch
0:21:22.600,0:21:28.330
the kernel. But before we dive into that,[br]let's take a look what previous jailbreaks
0:21:28.330,0:21:35.029
actually did patch in the kernel. So the[br]general goals are to disable code signing
0:21:35.029,0:21:41.460
to disable the sandbox to make the root[br]file system writable to somehow make
0:21:41.460,0:21:46.951
tweaks work which involves making mobile[br]substrate or libsubstitute work which is
0:21:46.951,0:21:53.650
the library for hooking. And I was about[br]to make a list of kernel patches which you
0:21:53.650,0:22:00.220
could simply apply, however, the[br]techniques and patches vary across
0:22:00.220,0:22:03.750
individual jailbreaks so much that I[br]couldn't even come up with the list of
0:22:03.750,0:22:09.568
kernel patches among the different[br]jailbreaks I worked on. So there's no
0:22:09.568,0:22:13.429
general set of patches, some prefer to do[br]it that way, some prefer to do it that
0:22:13.429,0:22:18.970
way. So instead of doing a kind of full[br]list, I'll just show you what the Helix
0:22:18.970,0:22:24.340
jailbreak does patch. So the Helix[br]jailbreak first patches the
0:22:24.340,0:22:30.411
i_can_has_debugger, which is a boot arc.[br]It's a variable in the kernel and if you
0:22:30.411,0:22:36.299
set that to true that would relax the[br]sandbox. So to relax the sandbox or to
0:22:36.299,0:22:42.049
disable code signing usually involves[br]multiple steps. Also since iOS 7 you need
0:22:42.049,0:22:48.450
to patch mount because there's actual[br]hardcoded that the root filesystem cannot
0:22:48.450,0:22:54.539
be mounted as read-write. Since iOS 10.3,[br]there is also hardcoded that you cannot
0:22:54.539,0:22:59.492
mount the root filesystem without the[br]nosuid flag, so you probably want to patch
0:22:59.492,0:23:04.538
that out as well. And then if you patch[br]both these you can remount the root
0:23:04.538,0:23:09.279
filesystem as read-and-write, however you[br]cannot actually write to the files on the
0:23:09.279,0:23:14.419
root filesystem unless you patch Light-[br]Weight Volume Manager which you also only
0:23:14.419,0:23:21.220
need to do in iOS 9 up to iOS 10.3. Later[br]when they switched to APFS you don't
0:23:21.220,0:23:27.779
actually need that anymore. Also there's a[br]variable called proc_enforce. You set that
0:23:27.779,0:23:34.149
to 0 to disable code signing which is one[br]of the things you need to do to disable
0:23:34.149,0:23:43.090
code signing. Another flag is[br]cs_enforcement_disable, set that to 1 to
0:23:43.090,0:23:50.550
disable code signing. So amfi, which is[br]Apple mobile file integrity is a kext which
0:23:50.550,0:23:59.519
handles the code signing checks. In that [br]kext it imports the mem-copy function.
0:23:59.519,0:24:05.399
So there's a stub and one of the patches[br]is to patch that stub to always return 0
0:24:05.399,0:24:10.496
by some simple gadget. So what this does[br]is, whenever it compares something in a
0:24:10.496,0:24:16.370
code, it would just always compare… say[br]that the compare succeeds and is equal.
0:24:16.370,0:24:21.982
I'm not entirely sure what it does,[br]so this patch dates back to Yalu
0:24:21.982,0:24:24.010
but like just supplying that patch helps
0:24:24.010,0:24:29.820
killing code signing, so that's why it's[br]in there. Another thing h3lix does is, it
0:24:29.820,0:24:36.009
adds the get-task-allow entitlement to[br]every process and this is for allowing
0:24:36.009,0:24:41.190
read/ write/executable mappings and this[br]is what you want for a mobile substrate
0:24:41.190,0:24:46.450
tweaks. So initially this entitlement [br]is used for debugging because
0:24:46.450,0:24:52.700
there you also need to be able to modify[br]code at runtime for setting breakpoints
0:24:52.700,0:24:59.580
while we use it for getting tweaks to[br]work. Since iOS 10.3 there's... h3lix also
0:24:59.580,0:25:07.110
patches label_update_execve patch...[br]label_update_execve function. So the idea
0:25:07.110,0:25:11.879
of that patch was to fix the "process-exec[br]denied while updating label" error message
0:25:11.879,0:25:17.389
in Cydia and several other processes. Well[br]that seems to completely nuke the sandbox
0:25:17.389,0:25:22.890
and also break sandbox containers so this[br]is also the reason why if you're
0:25:22.890,0:25:28.090
jailbreaking with h3lix apps would save[br]their data in the global directory instead
0:25:28.090,0:25:33.350
of their sandbox containers. And you also[br]kill a bunch of checks in
0:25:33.350,0:25:40.650
map_ops_policy... mac_policy_ops to relax[br]the sandbox. So if you want to check out
0:25:40.650,0:25:45.429
how that works yourself, unfortunately[br]h3lix itself is not open-source and I've
0:25:45.429,0:25:50.409
no plans of open-sourcing that. But[br]there's two very very closely related
0:25:50.409,0:25:55.960
projects which are open-source which is[br]doubleH3lix – this is pretty much exactly
0:25:55.960,0:26:03.980
the same but for 64 bit devices which[br]does include the KPP bypass, so it also
0:26:03.980,0:26:11.409
patches the kernel – and jelbrekTime,[br]which is the watchOS jailbreak. But h3lix
0:26:11.409,0:26:17.850
is for iOS 10 and the watchOS jailbreak is[br]kind of the iOS 11 equivalent but it
0:26:17.850,0:26:21.950
shares like most of the code. So most of[br]the patch code is the same if you want to
0:26:21.950,0:26:29.000
check that out. Check these out. So,[br]KPPless jailbreaks. So the idea is, don't
0:26:29.000,0:26:35.230
patch the kernel code but instead patch[br]the data. So for an example we go for
0:26:35.230,0:26:39.370
remounting root file system. We know we[br]have hardcoded checks which forbid us to
0:26:39.370,0:26:44.540
mount the root file system read/write. But[br]what we can do is in the kernel there's
0:26:44.540,0:26:49.110
this structure representing the root file[br]system and we can patch that structure
0:26:49.110,0:26:54.020
removing the flag saying that this[br]structure represents the root file system.
0:26:54.020,0:27:00.210
And we simply remove that and then we can[br]call remount on the root file system and
0:27:00.210,0:27:05.851
then we put back in the flag. So we kind[br]of bypass the hardcoded check. For
0:27:05.851,0:27:12.620
disabling code signing and disabling[br]sandbox there are several approaches.
0:27:12.620,0:27:17.169
In the kernel there's a trust cache so[br]usually amfi handles the code signing.
0:27:17.169,0:27:21.280
The demon in userspace handles the code[br]signing requests. But the demon itself
0:27:21.280,0:27:25.270
also needs to be code-signed. So you have[br]the chicken and egg problem. That's why in
0:27:25.270,0:27:31.392
the kernel there is a list of hashes of[br]binaries which are allowed to execute. And
0:27:31.392,0:27:35.409
this thing is actually writable because[br]when you mount the developer disk image it
0:27:35.409,0:27:40.919
actually adds some debugging things to it[br]so you can simply inject your own hash
0:27:40.919,0:27:46.779
into the trust cache making the binary[br]trusted. Another approach taken by
0:27:46.779,0:27:51.830
jailbreakd and the latest electro[br]jailbreak is to have a process, in this
0:27:51.830,0:27:58.070
case jailbreakd, which would patch the[br]processes on creation, so when you spawn a
0:27:58.070,0:28:03.889
process that thing would immediately stop[br]the process, go into the kernel, look up
0:28:03.889,0:28:10.620
the structure and remove the flags[br]saying "kill this process when the cold
0:28:10.620,0:28:15.809
signature becomes involved" and it will[br]invalid. And it would also add the
0:28:15.809,0:28:20.808
get-task-low entitlements. And then after [br]it's done that it would resume the process
0:28:20.808,0:28:25.850
and then the process won't get killed any [br]more because it's kind of already trusted.
0:28:25.850,0:28:33.450
And the third approach taken or demoed by[br]bazad was to take over amfid and userspace
0:28:33.450,0:28:41.210
completely. So if you can get a Mac port[br]to launchd or to amfid you can impersonate
0:28:41.210,0:28:47.340
that and whenever the kernel asks and[br]feels that it's trusted you would reply
0:28:47.340,0:28:51.190
"Okay yeah that's trusted that's fine[br]you can run it" so that way you don't need
0:28:51.190,0:28:59.510
to go for the kernel at all. So future[br]jailbreaks. Kernel patches are not really
0:28:59.510,0:29:04.879
possible anymore and they're not even[br]required. Because we can still patch the
0:29:04.879,0:29:13.080
kernel data or not go for the kernel at[br]all. But we're still not done yet, we
0:29:13.080,0:29:21.639
still didn't go for Post-Apocalyptic[br]or short PAC. Well actually
0:29:21.639,0:29:25.039
PAC stands for pointer authentication[br]codes but you get the joke.
0:29:25.039,0:29:30.590
So pointer authentication codes were[br]introduced with the iPhone Xs and if we
0:29:30.590,0:29:36.532
quote Qualcomm "This is a stronger version[br]off stack protection". And pointer
0:29:36.532,0:29:41.809
authentication codes are similar to[br]message authentication codes but for
0:29:41.809,0:29:47.490
pointers, if you are familiar with that.[br]And the idea of that is to protect data in
0:29:47.490,0:29:55.389
memory in relation to context with a[br]secret key. So the data in memory could be
0:29:55.389,0:30:00.869
the return value and the context could be[br]the stack pointer or data in memory could
0:30:00.869,0:30:07.749
be a function pointer and the context[br]could be a vtable. So if we take a look
0:30:07.749,0:30:14.649
how PAC is implemented. So at the left you[br]can see function entry and like function
0:30:14.649,0:30:19.740
prologue and function epilogue without PAC[br]and with PAC the only thing that would be
0:30:19.740,0:30:27.139
changed is when you enter a function[br]before actually doing anything inside it,
0:30:27.139,0:30:31.980
you would normally store the return value[br]on the stack but when doing that you would
0:30:31.980,0:30:39.299
first authenticate the pointer with the[br]context and then kinda create the
0:30:39.299,0:30:44.358
signature and store it inside the pointer[br]and then put it on the stack. And then
0:30:44.358,0:30:49.549
when you leave the function you would just[br]take back the pointer, again calculate the
0:30:49.549,0:30:56.429
signature and see if these both signatures[br]matches and if they do then just return
0:30:56.429,0:31:03.977
and if the signature's invalid you would[br]just throw a hardware fault. So this is
0:31:03.977,0:31:10.649
how it looks like for 64-bit pointers. You[br]don't really use all of the available bits.
0:31:10.649,0:31:16.820
So usually you use 48 bits for[br]virtual memory which is more than enough.
0:31:16.820,0:31:22.200
If you use memory tagging[br]you have seven bits left for putting in
0:31:22.200,0:31:28.989
the signature or if you do not use memory[br]tagging you can use up to 15 bits for the
0:31:28.989,0:31:39.852
pointer authentication code. So the basic[br]idea of PAC is to kill ROP like code reuse
0:31:39.852,0:31:46.402
attacks. You cannot simply smash the stack[br]and create a ROP chain because every
0:31:46.402,0:31:53.899
return would have an instruction verifying[br]the signature of the return value and that
0:31:53.899,0:32:00.580
means you would need to sign everything,[br]every single of these pointers and since
0:32:00.580,0:32:07.103
you don't know the key you can't do that[br]in advance. So you cannot modify a return
0:32:07.103,0:32:12.049
value and you cannot swap two signed[br]values on the stack unless the stack
0:32:12.049,0:32:22.677
pointer is the same for both. Can we[br]bypass it? Maybe. I don't know. But we can
0:32:22.690,0:32:29.484
take a look at how that thing is[br]implemented. So if we take a look at the
0:32:29.484,0:32:35.792
ARM slides you can see that PAC is[br]basically derived from a pointer and a
0:32:35.792,0:32:41.659
64-bit context value and the key and we[br]put all of that in the algorithm P. And
0:32:41.659,0:32:48.230
that gives us the PAC which we store in[br]the unused bits. So the algorithm P can
0:32:48.230,0:32:56.450
either be QARMA or it can be something[br]completely custom. And the instructions,
0:32:56.450,0:33:03.419
the ARM instructions, kind of hide the[br]implementation details. So if you would go
0:33:03.419,0:33:11.350
for attacking PAC, there's two ways of[br]attack strategies. We can either try and
0:33:11.350,0:33:16.140
go straight for the cryptographic[br]primitive like take a look what cipher it
0:33:16.140,0:33:22.419
is or how that cipher is implemented.[br]Maybe it's weak or we can go and attack
0:33:22.419,0:33:29.029
the implementation. So if we go and attack[br]the implementation we could look for
0:33:29.029,0:33:35.379
signing primitives, which could be like[br]small gadgets we could jump to somehow,
0:33:35.379,0:33:42.499
somehow execute to sign a value which[br]could be either an arbitrary context
0:33:42.499,0:33:50.369
signing gadget or maybe a fixed context[br]signing gadget. We could also look for
0:33:50.369,0:33:56.640
unauthenticated code, for example I[br]imagine the code which sets up PAC itself
0:33:56.640,0:34:03.529
is probably not protected by PAC because[br]you can't sign the pointer if the key is
0:34:03.529,0:34:08.900
not set up yet. Maybe that code is still[br]accessible. We could look for something
0:34:08.900,0:34:17.720
like that. We could also try to replace[br]pointers which share the same context.
0:34:17.720,0:34:23.710
It's probably not feasible for return[br]values on the stack, but maybe it's
0:34:23.710,0:34:30.089
feasible for swapping pointers in the[br]vtable. Or maybe you come up with your own
0:34:30.089,0:34:37.049
clever idea how to bypass that. These are[br]just like some ideas. So I want to make a
0:34:37.049,0:34:44.639
point here, that in my opinion it doesn't[br]make much sense to try to attack the
0:34:44.639,0:34:51.550
underlying cryptography on PAC, so I think[br]that if we go for attacking PAC it makes
0:34:51.550,0:34:56.329
much more sense to look for implementation[br]attacks and not attacking the cryptography
0:34:56.329,0:35:04.290
and the next few slides are just there to[br]explain why I think that. So if we take a
0:35:04.290,0:35:10.309
look at QARMA which was proposed by ARM as[br]being one of the possible ways of
0:35:10.309,0:35:16.750
implementing PAC. PAC, uhm, QARMA is a[br]tweakable block cipher, so it takes an
0:35:16.750,0:35:22.859
input, a tweak and gives you an output.[br]Which kind of fits perfectly for what we
0:35:22.859,0:35:30.390
want. And then I started looking at QARMA[br]and came up with ideas on how are you
0:35:30.390,0:35:35.780
could maybe attack that cipher. At some[br]point I realized that practical crypto
0:35:35.780,0:35:42.550
attacks on QARMA if there will be any in[br]the future will probably that's what I
0:35:42.550,0:35:51.140
think completely irrelevant to the PAC[br]security. So why's that? If we define –
0:35:51.140,0:35:55.349
So just so you know, the next few slides[br]I'm going to bore you with some math but
0:35:55.349,0:36:03.510
it's not too complex. So if we define PAC[br]as a function which takes a 128 bit input
0:36:03.510,0:36:11.540
and a 120-bit key and maps it to 15 bits[br]output. Or we can more realistically
0:36:11.540,0:36:18.190
define it as a function which takes 96[br]bits input with a 128-bit key because we
0:36:18.190,0:36:24.080
have a 48-bit pointer because the other[br]ones we can't use because that's where we
0:36:24.080,0:36:29.770
store the signature and we're most likely[br]using the stack pointer as a context so
0:36:29.770,0:36:38.970
that one will also only use 48-bit [br]pointers, 48 bits. Then we have PAC as a
0:36:38.970,0:36:44.297
construct so then we define the attacker[br]with following capabilities. The attacker
0:36:44.297,0:36:50.650
is allowed to observe some pointer and[br]signature pairs and I assume that you can
0:36:50.650,0:36:54.579
get that through some info leaks, for[br]example you have some bug in the code
0:36:54.579,0:37:01.220
which lets you dump a portion of the stack[br]with a bunch of signed pointers.
0:37:01.220,0:37:06.829
This is why you can observe some, not all,[br]but you can see some and I would also
0:37:06.829,0:37:13.240
allow to have the attacker be able to[br]slightly modify the context and what I
0:37:13.240,0:37:19.619
mean by that is I imagine a scenario where[br]the attacker could maybe shift the stack,
0:37:19.619,0:37:25.277
maybe through more nested function calls[br]before executing the leak which will give
0:37:25.277,0:37:31.821
you actually two signatures for the same[br]pointer but with a different context.
0:37:31.821,0:37:39.240
Maybe that's somewhat helpful. But still[br]we realize that the attacker, the
0:37:39.240,0:37:45.990
cryptographic attacker, is super weak so[br]the only other cryptographic problem there
0:37:45.990,0:37:52.570
could be is collisions. And for those of[br]you who seen my last talk they probably
0:37:52.570,0:38:02.280
know I love collisions. So we have 48-bit[br]pointer, 48-bit context and 128-bit key.
0:38:02.280,0:38:08.559
We sum that up and we divide that by the[br]15-bit of output we get from PAC which
0:38:08.559,0:38:17.069
gives us 2 to the power of 209 possible[br]collisions because we map so many bits to
0:38:17.069,0:38:24.670
so little bits. But even if we reduce the[br]pointers because practically probably less
0:38:24.670,0:38:33.059
than 34 bit of a pointer are really used,[br]we still get 2 to the power 181
0:38:33.059,0:38:38.340
collisions, which is a lot of collisions[br]but the bad thing here is random
0:38:38.340,0:38:45.323
collisions are not very useful to us[br]unless we can predict them somehow. So
0:38:45.323,0:38:50.700
let's take a look how a cryptographically[br]secure MAC is defined. So a MAC is defined
0:38:50.700,0:38:55.250
as following: Let p be a MAC with the[br]following components and those are
0:38:55.250,0:39:00.791
basically Gen(), Mac() and Vrfy(). So[br]Gen() just somehow generates a key, it's
0:39:00.791,0:39:06.010
only here for the sake of mathematical[br]completeness. Just assume we generate the
0:39:06.010,0:39:14.385
key by randomly choosing n bits or however[br]how much bits the key needs. And Mac() is
0:39:14.385,0:39:22.020
just a function where you put in an n-bit[br]message called m and it gives us a
0:39:22.020,0:39:25.569
signature t. And I'm going to say[br]signature but in reality I mean a message
0:39:25.569,0:39:30.940
authentication code. And the third[br]function is Vrfy() and you give it a
0:39:30.940,0:39:34.880
message and a signature and that just[br]returns true if that signature is valid
0:39:34.880,0:39:41.670
for the message or false if it's not. And[br]when cryptographers prove that something
0:39:41.670,0:39:46.700
is secure they like to play games. So I'm[br]gonna to show you my favorite game, which
0:39:46.700,0:39:52.230
is Mac-forge game. So the game is pretty[br]simple you have to the left the game
0:39:52.230,0:39:58.652
master which is playing Mac-forge and[br]to the right the attacker. So the game
0:39:58.652,0:40:04.369
starts when the Mac-forge game master[br]informs the attacker how much bits are we
0:40:04.369,0:40:08.609
playing. So this is the first 1 to the[br]power of n, basically means hey we're
0:40:08.609,0:40:13.934
having MAC-forge with, I don't know,[br]64-bit messages so the attacker knows the
0:40:13.934,0:40:22.130
size. Then the game master just generates[br]the key and then the attacker can choose to
0:40:22.130,0:40:30.500
q messages of n-bit length and send them[br]over to the game master and the game
0:40:30.500,0:40:36.210
master will generate signatures and send[br]them back. So then the attacker can
0:40:36.210,0:40:42.390
observe all the messages he generated and[br]all the matching signatures. So what the
0:40:42.390,0:40:47.059
attacker needs to do then is to choose[br]another message which he did not send over
0:40:47.059,0:40:56.119
yet and somehow come up with a valid[br]signature and if he can manage to do that
0:40:56.119,0:41:02.619
he sends it over and if that's actually a[br]valid signature for the message then he
0:41:02.619,0:41:09.490
wins the game, otherwise he looses the[br]game. So we say a Mac is secure if the
0:41:09.490,0:41:15.996
probability that an attacker can somehow[br]win this is negligible. So I'm gonna spare
0:41:15.996,0:41:20.059
you the mathematical definition of what[br]negligible means but like just guessing or
0:41:20.059,0:41:27.670
trying means that it's still secure if[br]that's the best tech. So as you can see is
0:41:27.670,0:41:36.650
a MAC which is secure needs to withstand[br]this. But for our PAC attacker we do not
0:41:36.650,0:41:43.105
even have this oracle. So our attacker for[br]PAC is even weaker than that. So why do we
0:41:43.105,0:41:49.230
not have this oracle? Well simple if we[br]allow the attacker to sign arbitrary
0:41:49.230,0:41:55.819
messages the attacker wouldn't even need[br]to try to somehow get the key or forged
0:41:55.819,0:42:00.900
message because then he could just send[br]over all the messages. All the pointers he
0:42:00.900,0:42:05.390
wants to sign get back signed pointers and[br]you wouldn't need to bother about breaking
0:42:05.390,0:42:11.109
the crypto at all. So basically the point[br]I'm trying to make here is that the PAC
0:42:11.109,0:42:18.609
attacker is weaker than a MAC attacker. So[br]every secure MAC we know is also a secure
0:42:18.609,0:42:28.750
PAC, but even then an insecure MAC might[br]still be sufficiently secure for PAC so
0:42:28.750,0:42:33.900
secure MACs have been around for a while[br]and thus in my opinion, I think if
0:42:33.900,0:42:41.250
somebody, who knows what he's doing,[br]designs a PAC algorithm today it will
0:42:41.250,0:42:49.069
likely be secure. So instead of going for[br]the crypto I think we should rather go for
0:42:49.069,0:42:53.579
implementation attacks instead because[br]those will be around forever. And by that
0:42:53.579,0:43:00.170
I mean well you can either see how the[br]crypto itself is implemented, what I mean
0:43:00.170,0:43:07.224
especially by that is you could see how[br]the PAC is used in the actual code. Maybe
0:43:07.224,0:43:12.155
you can find signing oracles, maybe you[br]can find unauthenticated code. I think
0:43:12.155,0:43:20.260
this is where we need to go if wanna[br]bypass PAC somehow. So just to recap where
0:43:20.260,0:43:29.987
we're coming from. Future iPhone hacks[br]probably gonna not try to bypass KTRR. I
0:43:29.987,0:43:35.420
think they will not try to patch Kernel[br]code because we can achieve pretty much
0:43:35.420,0:43:41.240
all the things we want to achieve for end[br]user jailbreak without having to patch the
0:43:41.240,0:43:49.110
kernel so far. And I think people are[br]going to struggle a bit. At least a bit
0:43:49.110,0:43:56.885
when exploiting with PAC because that kind[br]will either make some bugs unexploitable
0:43:56.885,0:44:04.550
or really really hard to exploit. Also[br]maybe we're gonna avoid the Kernel at all
0:44:04.550,0:44:10.140
as it has demoed that userland-only[br]jailbreaks are possible. Maybe we're going
0:44:10.140,0:44:15.680
to recalculate what the low hanging fruits[br]are. Maybe just go back to iBoot or look
0:44:15.680,0:44:22.490
for what other thing is interesting. So,[br]that was about it, thank you very much for
0:44:22.490,0:44:34.259
your attention.[br]Applause
0:44:34.259,0:44:38.730
Herald-Engel: Thank you, sir. If you would[br]like to ask a question please line up
0:44:38.730,0:44:48.809
on the microphones in the room. We do not[br]have a question from the Internet.
0:44:48.809,0:44:53.369
One question over there, yes please.[br]Question: Hi. I would like to be
0:44:53.369,0:44:58.109
interested what your comment is on the[br]statement from Zarek that basically
0:44:58.109,0:45:01.960
jailbreaking is not a thing anymore[br]because you're breaking so much security
0:45:01.960,0:45:07.520
features that makes the phone basically[br]more insecure than the former reasons of
0:45:07.520,0:45:15.579
doing a jailbreaking allow for.[br]tihmstar: Well, jailbreaking -- I don't
0:45:15.579,0:45:21.540
think jailbreaking itself nowadays makes a[br]phone really insecure. So of course if you
0:45:21.540,0:45:25.855
patched a kernel and disable all of the[br]security features that will be less
0:45:25.855,0:45:31.020
secure. But if you take a look what we[br]have here with the unpatchable kernel I
0:45:31.020,0:45:35.700
think the main downside of being[br]jailbroken is the fact that you cannot go
0:45:35.700,0:45:42.419
to the latest software version because you[br]want the box to be in there to have the
0:45:42.419,0:45:51.270
jailbreak. So I don't really think if you[br]have like a KTRR device the jailbreak
0:45:51.270,0:45:56.079
itself makes it less secure. Just the fact[br]that you are not on the latest firmware is
0:45:56.079,0:46:01.000
the insecure part of it.[br]Herald: Alright, thank you.
0:46:01.000,0:46:05.759
Microphone number two, your question.[br]Mic #2: Hi good talk. Could you go back to
0:46:05.759,0:46:13.589
the capabilities of the adversary please?[br]Yeah. So you said you can do basically two
0:46:13.589,0:46:17.690
things right. This one, yes. Yeah you can[br]observe some pointers and some signature
0:46:17.690,0:46:23.960
pairs. But why is this not an oracle?[br]tihmstar: Because you cannot choose...
0:46:23.960,0:46:26.420
Mic #2: Your message yourself.[br]tihmstar: ...your message yourself.
0:46:26.420,0:46:31.080
Mic #2: And you have also an oracle that[br]says if the signature is valid. For a
0:46:31.080,0:46:33.829
chosen message.[br]tihmstar: Well yeah but this is if you
0:46:33.829,0:46:39.490
take a look at the game and this game for[br]a secure MAC the attacker can choose up to
0:46:39.490,0:46:44.890
q messages sending over... like he can do[br]whatever he wants with that messages and
0:46:44.890,0:46:51.900
get a signature while the package hacker[br]can see a few very limited amount of
0:46:51.900,0:46:59.243
messages and their matching signature and[br]he has little to no influence on these
0:46:59.243,0:47:04.800
messages.[br]Mic #2: Okay. So it's a bit weaker.
0:47:04.800,0:47:08.240
tihmstar: So yeah that's the point. Just[br]that it's weaker.
0:47:08.240,0:47:10.600
Mic #2: Thanks.[br]Herald-Engel: Do we have a question from
0:47:10.600,0:47:23.599
the internet? No. OK. Yes please. All[br]right then I don't see anyone else being
0:47:23.599,0:47:31.214
lined up and... please give a lot of[br]applause for tihmstar for his awesome
0:47:31.214,0:47:35.955
talk![br]Applause
0:47:35.955,0:47:46.137
postroll music
0:47:46.137,0:47:58.000
subtitles created by c3subtitles.de[br]in the year 2020. Join, and help us!