36c3 preroll
Herald: To everybody here, please be
welcome to this fantastic kid here. I
learned a lot from him, even though he's
only since two years playing around with
iOS. I mentioned as well the first
untethering case that I had with my phone
was something about iOS 5.1 and with every
update, you had to do the whole shebang
again. Of course, that's what I remember.
So please give a warm welcome here too
littlelailo. Do I spell this correctly?
Offscreen: Yeah.
Herald: Yes, littlelailo is really a very
fascinating geek. He actually hacks any
kind of OS device, to my opinion. Any kind
of. Yeah. So throw it to him and it comes
back in pieces. He's as sharp as a knife.
Please give him a warm, well, welcoming
applause. We're gonna untether iOS. Yay!
applause
littlelailo: Okay, so yeah, I'm
littlelailo, as already introduced. I'm
interested in I.T. security in general.
And I started to look into iOS about two
years ago and then I met three awesome
guys: @s1guza, @stek29 and @iBSparkes. And
we basically started to chat a lot and in
the end also released the "jailbreak me"
for iOS 10 on https://totally-
not.spyware.lol/. For everybody who isn't
familiar with the jailbreak scene, it's
like rooting on Android. So it basically
is a tool that gives the user the
capability to tweak the device, and that's
mostly done by basically installing a
jailbreak in this case. You just go to a
website on the slide there
[https://totally-not.spyware.lol/] and it
will install a package manager on your
phone and then the end user can install
tweaks. So just a little dynamic libraries
and they get injected into all the other
system processes and then they can
obviously modify their memory. And that,
for example, allows customization of the
home screen or something like that. And
basically with the release, we also formed
the team @Jakeblair420 was created with a
Twitter account. There are also a few
demos there if you want to check it out
after the talk. And I basically had this
pipe dream that in my life. I really want
to achieve an untethered jailbreak using
only some sort of plist or other save file
corruption. So basically there are
different kinds of jailbreaks. In modern
jailbreak the most common kind are semi-
untethered, which means that the users has
to connect their device to a PC when they
first install a jailbreak and then they
sideload an app onto the device or it just
installs itself there. And then on each
reboot, the user has to go into the app
and press a button to jailbreak the phone.
And basically, after they reboot, they
lose the jailbreak and have to go through
this process again. And with an untethered
jailbreak, the jailbreak gains persistent
installation and then they will
automatically jailbreak the device on each
boot. So the device automatically boots
jailbroke. The untether can be divided
into four stages. The first stage is when the
config file or database stage. I would go
over how we gain execution of the boot.
Then the config parser bug that gives us
the right opey primitive. And then I will
talk about the main bug, the ASLR bypass,
which allows us to get into ROP. Then
stage two is basically a kernel exploit
and completely written in ROP and there I
will go over the two main kernel bugs: the
kASLR leak and then the racy double free
we used to get the kernel read/write, and
I will also talk about the kASLR weakness
and RootDomain user client memory leak
which aided us in exploitation. And after
we get kernel read/write, we can remove a
few restrictions from Apple. Mainly we can
bypass code signing and that gives us the
ability to load an unsigned dynamic
library into our process. So now in stage
3, we are basically C, we are dynamic
library and there we are stashing the
kernel task port to host special port 4.
So iOS has this concept of ports and task
ports. And basically, if you have a send
right to a task port of a process, you can
read and write its memory. They're most
used for inter process communication. And
where modern jailbreaks used to stash the
kernel task port into a special port 4 so
that other user mode applications can then
retrieve it and with that retrieved and
with send right they can just read and
write process memory. And after that I
just fix up everything and then spawn
stage four and that's basically running in
a separate process. That has a few
advantages I will go into later. It's
basically performing the whole post
exploitation process, including launching
substrate - the framework that's used for
tweek injection and then performing
ldrestart to restart or launch demons on
the system and inject the tweaks into
them. In stage 1, we first need to get
execution after boot, and when iOS boots
launchd is the first process that's
running on the system and it then loads a
dynamic library with a list of executables
- that are LaunchDaemons - and there are a
few flags associated with them. If the
"run and load" flag is set, launchd will
then spawn all of those LaunchDaemons
afterwards. And we basically just take one
of those launch demons, namely Racoon. So
what is Racoon? Basically Racoon is part
of the ipsec package. And it's a VPN
client used to interact with an IPSec VPN
server. And the problem is though, that
IPsec-Tools project has been abandoned
since 2014. So they officially here state
on their website that the development of
the project has been abandoned and that
IPsec-Tools has security issues. You
should not use it. Apple still decided it
was a good idea to ship it after 2014 and
they now maintain their own fork on
https://opensource.apple.com . And yeah,
basically the only thing that's important
for the talk is that raccoon has a
configuration parser. So on startup it
will just look for a file on disk and
start to parse that. And that's written in
yacc so completely written in C. So memory
corruption might become a problem. And it
actually is a problem as we can see if the
config parser bug and for that when we
have to go back a bit. Basically in 2011
Pod2g released Corona for iOS 5, which was
also an untethered. He used a bug in
Racoon in the configuration parser and
Pod2g found this one on an old bug tracker
and basically the IPsec website had this
bug tracker there. There users could just
report problems with their programs and
one user in 2009 I think reported a bug
that if he would use the specific config
Racoon would just segfault, but nobody
looked at this for two years. So in 2011
Pod2g realized that this was actually
exploitable and then used in a jailbreak.
And after that, obviously Apple got aware
of it. And then they also said that they
fixed it. And it's got a CV, assigned
CVS-2012-2737. And yeah, they say that
this was improved through improved bounds
checking. So let's look at the patch.
That's the function before the patch and
that's the function after the patch. And
if this was too fast for you, here's the
diff. So basically there is no difference.
The bug is still there and Apple didn't
patch it. What really happened here was
that basically this is obviously a
configuration parser. So there are
different statements that nearly do the
same thing. There are these nbns4
statements to parse an IP address and
there are wins4 statement followed by an
IP address and both of them have to parse
the IP address. So the function for
parsing that was just copy pasted from
another one. And yeah, basically Apple
fixed the bug in the other function. Which
I don't get because basically the engineer
there had to look at PoC Pod2g provided
then they had to realize okay, the bug is
in there, fix it, then they had to
recompile and never tested against the
original PoC because otherwise Racoon
would have crashed again. Yeah, it's
basically an off by one which allows you
to overwrite the index of an array and
Pod2g gave a talk about this and we can
basically reuse his strategy from back in
2011 to get a write primitive.
Again, the one function here at the top.
You can see the yacc syntax so an addrwins
list has to consist of either an addrwins
statement or addrwins statement followed
by a comma, followed by an addrwins list.
So that's a recursion. There can be
multiple addrwins statements in a row. And
then below that, an addrwins statement is
defined as containing an address string.
And that's just a regex to match an IP
version 4 address. And if the parcel finds
that it would run the code between those
two brackets. So they get the pointer to a
global struct and then they check if this
nbns4_index is bigger than MAXWINS and if
so, they return an error. The problem here
is that this is off by 1. It shouldn't be
checking if it's greater than so, but it
should be a check for greater or equal
than MAXWINS. And after that, they use
thisinet_pton function to basically parse
the address, which is in this variable
into the nbns4 array at the nbns4 index
and then post-increment the index. And
that will also be coming in handy when
exploiting this bug. So yeah. How is
exploitation done? Basically there are
here the globals, there is this Lcconfig
pointer in the globals pointing to a heap
structure and that the parser also uses.
And then there is this dns4 array followed
by the dns_area_index and then the nbns4
array followed by the nbns_4_array_index
so we can just use mode_cfg statement
followed by this wins4 statement with the
IP address to parse the IP address in the
first array element and we can repeat this
process four times to then move the index
out of bounds. So now it's pointing to
itself and the cool thing is about that is
that therefore there would be a good idea
to use integers for those area indexes
instead of unsigned integers so we can
just point them... you just use negative
numbers to bypass the bounds check. So
we'll overwrite it with -1 to point it to
an dns_array_index and then we use another
wins statement to override the
dns_array_index with a negative number.
And the cool thing about this is that
because of the post-incrementation, it
will move it back to zero so we can repeat
this process as often times as we want,
and we will use a negative number to
basically point it to the Lcconfig
pointer. And then we can use two dns4
statements to override the Lcconfig
pointer and point it anywhere in memory.
And after that we can use a timer
statement with a counter. Then the
parsible just tried to write it to the
Lcconfig structure so it will de-reference
our pointer and write it there and the
interval statement will basically write to
an uint32, which is followed by the uint
where the counter statement is written so
we can turn this into a 64 bit write
anywhere primitive and write anywhere in
process memory and that gives us an
ability to basically exploit the ASLR
bypass. So this is the main bug of the
whole untethered and allows us to
basically have this primitive. And it's
also the reason why I decided to give this
talk this year and not last year, because
there the bug was pretty fresh and only
patched in iOS 12 and it gives to an
attacker the ability to exploit zero click
more easily because they just need the
write anywhere primitive. And that's why I
held back on it. Siguza found it after
looking into Apple's patches of the Corona
ASLR bypass and basically from Pod2g's
presentation, we as a team learned that
ASLR is always bypassed when a writable
region is larger than the maximum slide,
because then there's always a writable
address in process memory and you can use
this to brute force the slide and Siguza
found out that there was what was also the
same problem with the cache in iOS 11 and
a few versions of iOS 10 actually. So
what's the cache? Basically, the cache is
a pre compiled blob containing the dynamic
link libraries from Apple. So on each
released, you just move all of those into
one big file to optimize load times of
apps and keep memory pressure low. So it's
a pretty big file. And for that on boot
the kernel needs to calculate a slide and
slide it in memory. But they only slide it
once on boot because it's used in every
process. And so Apple defines an area of
memory for the cache with a base address
and the size and that's hardcoded on iOS
11. The cache got so big that a maximum
slide is now smaller than its data
segment. So the conditioning is satisfied
and ASLR can be bypassed, basically. And
the weird thing about this is that
actually the same thing also happened in
iOS 7. Back then, the size was defined as
500 megabytes and the cache got bigger
than 500 megabytes. But before that, it
was also in a few versions possible to
have the same condition that the data
segment again was bigger than the maximum
slide. And Apple was actually also aware
of this because Acer talked about it
in one of his talks, but they just
increased the maximum slide to 1 gigabyte
and didn't edit any asserts. And now in
iOS 11, it again got so big that the same
thing happened. And we believe that they
didn't even really notice that up until
iOS 12 where the cache was now bigger than
1 gigabyte so the kernel just couldn't fit
it in the memory region and paniced. And
because of that they just thought well,
then we will increase it to 4 gigabyte
while developing so we might see this
reoccurring in I don't know, iOS 15 or
something like that. Exploitation is also
pretty simple. We can just brute force the
slide now and there are a lot of function
pointers in the data segment. So we
decided to go with __platform_mem_move
because we can reach it via strlcpy from
the conflict parser. And the basic
strategy behind this is we write a slid
rop chain into an address we can always
write to for a specific slide abc and then
we overwrite the __platform_mem_move
pointer at its unslid address plus the
slide we just chose with a gadget that
would pivot to our slid rop chain and then
we call strlcpy. And now there are
basically two possibilities. Either we
guessed the right slide and then we jump
to our gadget and pivot the stack or we
guessed the wrong slide. But obviously
nothing happened because we can just write
there so we can go back to step one and
try again. And then with that we can just
brute force the slide till we get the
right one. The catch with this, however,
is that the write what were is pretty slow
and it also needs a lot of storage. So for
a 64 bit write I need about 120 bytes in
the config file. And because there are so
many possible slide values, the chain I
have currently is around... it's only to
rop gadgets, but the config file is
already 12 megabytes, I think. And because
of that, it takes around 10 seconds to run
if it's a really bad slide. So the rop
chain has to be as short as possible. And
the other problem is that if we have a bad
slide, we will basically smash the whole
data segment and we can't really recover
from that. So we had crashes in malloc and
stuff like that while developing,
basically. There are some solutions to
that, we can have a really short rop chain
in stage one and we can achieve this by
basically just opening the big cache file
to get a file descriptor to it and then we
can map it at a static address and then
get many gadgets there because the file is
obviously code signed by Apple so we can
just jump there after mapping it. But the
problem with that is that nothing is set
up. So malloc and other functions aren't
working. But as I said earlier, the
current cache has a smashed data segment
so we don't really lose anything. And
after having the cache at a static address
we can use the open and mmap functions
from that cache to basically map stage two
into the process memory and stage two is
just a really big rop stack. So, yeah. And
then we are basically in ROP, but we can
only use raw syscalls and not much more
because everything else will either use a
function that uses malloc or will use
malloc on it's own. And the other problem
is that basically errno is also broken. So
every syscall which fails will crush the
binary. So the first thing I do is
basically map a few pages so that errno
works again because we have a few syscalls
that might fail. And then the other big
problem is that we now need to implement
the whole kernel exploit in rop. So I
start to write a framework around this
awesome gadget which is present in all the
cache versions I looked at. Basically at the
top you can see that all the high
registers are moved into x0 through x7. So
all the registers used for the calling
convention are and then we branch with
link to register based on x27. So also
high register. And after that we load all
the register values back from the stack so
we can just chain those gadgets together
to call any functions. You basically rop
into the lower half and then chain another
one of those afterwards and then they can
load all the values, call the function and
then load all the values from the stack
again. And that's how the whole rop chain
works. So yeah, I also used another gadget
to basically add two registers together
and another one which stores x0 so that I
can store the return value on the stack
and later reuse it. And for loops I use a
gadget which just returns if x0 is zero.
So it's basically just a read instruction
then and otherwise it will tail call a
function using function pointer from the
data segment. And because I can control
the whole data segment, I can just put a
function pointer there that that will then
jump to an epilog and misasligning the stack
with that. And then I can call longjmp
with two different register values and
because of that pivot the stack to another
location. And when we basically didn't
jump outside of the loop, I just mmap the
part of stage 2 which has the loop in it
back over old stack again. And then I can
just reuse to stack every time. And then
pivot up using longjup. The problem wih
this, however, is obviously that it's
pretty slow because I use mmap as a
syscall. But this can be solved by just
unrolling your loops like for 10
iterations and then mmapping the file so
that I get more loop iterations basically
per second, which is important for the
race. So now we will go over the kernel
bug so the kASLR leak is CVS-2018-4413 by
panicall. It was fixed in iOS 12.1 and
it's luckily reachable from the Racoon
sandbox because Apple is sandboxing most
userland processes and the Racoon sandbox
is really tight. We didn't have that much,
many bugs that would work in Racoon, but
luckily this one does because Racoon has
access to the sysctl functions and this
one is in the sysctl_progargsx function.
The progargsx function basically allocates
a page using kmem_alloc. But it doesn't
zero it so it might contain old heap data
and then they copy the process arguments
to the front of the page. And now if you
supply a wrong size from user space and
there are a few other conditions that have
to be met for some weird reason it copies
from the end of the page into user space
which I don't get why does this even get
by code review. But here's a graphical
illustration: there is basically this page
is full of uninitialized data and then
they put the process arguments in the
front and copy out uniinitialized heap
data from the back into user land and we
can obviously just spray specific heap
objects with kernel pointers in them and
then free them again and use this
primitive to maybe leak them. And if we
find a kernel pointer in there, we can
just calculate this kernel slide. So yeah.
And then we come to the racy double free.
As I said, the main problem of the
untether is the racoon sandbox, so many of
the kernel bugs that would work in iOS 11
from an app, didn't work from racoon. But
luckily on Halloween Sparky told me about
Lightspeed bug from Synacktiv, which is
reachable from the sandbox. It's a double
free in kalloc.16. The kernel allocator's
based on zones and with different sizes.
So there's, for example, kalloc.16 and
then all objects in that zone have a size
of 16 or less bytes and they are obviously
also other zones for bigger objects. And
basically there is a structure in there
that then gets doubled. And there is the
syscall that's handling async file events.
So a user mode application can just call
it and tell the kernel, hey, please write
a buffer to a file and then move on with
execution and it uses a kernel thread to
perform those. And for that, that
basically allocates a structure to contain
some metadata like where the buffer is and
to which file it should write, and the
kernel thread obviously has to free the
structure after it's done because it just
gets into the query for
the kernel thread, that then wakes up and
maybe sees it has a new job, then performs
the operation and then it has to free it,
otherwise it will leak. But the problem
here is that if an error occurred while
setting the structure up, the second field
in the structure will be zero. And then
the structure also isn't included into the
jobs list. So the kernel thread will never
wake up and look at it. So the syscall has
to free it because otherwise it will leak.
And the problem here is that we can
basically reallocate the structure before
the syscall checks. So what happens here
is that the syscall allocates the
structure, fills it up, and then it gets
added to the list and then the kernel
thread is so fast that it runs while the
syscall isn't finished yet and basically
gets the gets the job done and frees it.
And then we can spray heap objects pretty
fast to overlay with that structure. And
then the syscall finishes and checks the
field and sees that it's zero because we
just replaced it with an object that has
zero at that location so it frees it again
leading to a double free. And yeah, we can
obviously exploit it. So for exploitation
I just spam the syscall on one thread
which is pretty hard to do in ROP, but I
just call threadCreate. We've appointed
two long jump and then pivot the stack to
the application and then in the other
thread I spray Mach messages with
MACH_PORT_NULL in it. And the thing with
Mach messages is they can be used to do
inter-process communication and you can
also transfer port rights from one process
to another. So in this case we just send
an empty port, but you could also place
something else there and that will create
a structure and kalloc.16 containing zero
at that location. And and then if the Mach
message gets freed, we can replace it with
something and basically point it to
somewhere in kernel where fake port
structure lives. And when we receive the
Mach message again, it will basically
think that this is a real port and treat
it as such. And with that we can create a
fake kernel task port. But for that we
obviously need to replace it and we need
to heap spray. And most commonly iOS
surface is used for that as a kernel
extension, but because of our sandbox we
are so limited that we don't have iOS
surface access. So the question is how we
actually spray and the
rootDomainUserClient comes to rescue with
a memory leak. So actually this function
secureSleepSystemOptions is reachable from
the raccoon sandbox and Apple has a way of
basically passing data to the kernel via
XML. So a userland application can just
pass the XML to the kernel and then they
will use this OSUnserializeXML function to
turn the XML back into C++ objects which
the kernel can then use. And if this
sounds dangerous to you, it actually is.
There were a few bugs in that. But in this
case we basically this just makes sure
with the OSDynamicCast that the data the
user mode application supplied isn't
always dictionaries so that it can use it
afterwards. And the problem here is that
we can basically just OSDataObject or an
always OSArray. So this OSDynamicCast
will fail and serialized options will
become null. But the original point of
return from OS under the XML will get lost
and so we will leak that memory and we
can just use this for spraying. So then
about those two primitives, I will use to
basically exploitation. The case law
weakness, Darrell Justice CCL buffers and
they are located in the kernel data region
and because of that they are stacked with
the same slide as the kernel text region.
And this means that as long as we know the
kernel slide we already do, that from the
case of largely and we can control the
contents of a CCL buffer and we can get
data to a known address and we can easily
do that with racoon because it runs US
route. And so we can just switch all of
this of CCL buffer, for example, place the
same point structure there will be later.
Also, place a fake trust constructively,
but I will get into that. So yeah, now we
can use that primitive to basically spray
tan or state objects pointing to the CCL
buffer. And then we just received the
message again and check if the polls are
now. And if that's the case, we best place
the structure. And then for the non SMP
version we can even get the case load by
traversing a few pointers. But that's not
needed for SMP Version because there we
already got it with the case logic but
young, Non CCL IP devices, we also don't
need a CCL buffers because we can just
place the fake port structure and use the
land and then we get the kernel slide this
way. And with the kernel slide and this
fake port, we can create a fake user
client and from there we can create a
called primitive and then we can use this
to override that pierce's trusses pointer
and pointed to a buffer with two hashes
and four stage 3 and stage 4. So basically
Apple has two ways of doing code signing.
Either it has a used land daemon that
verifies third party applications or a
test, so-called trust cache, which is a
list of hashes from all of their system
applications. And as soon as the process
spawned or dynamic link library is loaded
and they will basically first verify if
the hash of that file is inside of the
trust cache. And if so, they will just
trust a binary blindly because it comes
from Apple, basically. And now when we
override this trust cache point and
pointed to our buffer, we can basically
place the hash of stage 3 and 4 there. And
then the system will think those are apple
binaries and we can just load them. So.
Yeah. And for that we need to use a geter
open. We can't use the real deal open
because that uses malock. So we just
open stage 3 to get a file descriptor.
Then we attached a signature which now
succeeds as the caches and trust cache and
then we can map it as read executed and
jump there. And then we are after two
months of writing options. We are finally
in C and we can write code more easily.
And the problem there is that we still
don't have a working cache. So we are
still limited to the basic functionality
and because of the ghetto dlopen link is
obviously not working. So we just rely on
raw as somebody follows syscalls. And I
also pass some function pointers which I
already use for stage 2. So for example,
open and a map to stage 3. And from there
we remove the con task and session into
our special port 4 so that other user mode
applications can use it. And then we can
basically escape the sandbox by removing
the sandbox label in the process
structure, so that we can launch a new
binary, because otherwise the raccoons and
bugs doesn't allow it. But in the kernel,
those process structures basically have
this label, which tells the kernel of
which sandbox to use. And as you're doing
it, you can just tell it to not use any
samples. And and then we can launch stage
3, 4 and with that, get a working
cashback. And that's the big advantage
from like having a separate file. We now
have the full cache functions working and
can do work more easily. And then I it's
just called two opposing spawn and then a
raw exit. This to exit the daemon without
crashing because of launch. You would see
that one of the launch demons crashed and
the specifics flag inside it would try to
restart it. And then our option would run
again. We obviously want to prevent that.
So we use the exits as call to exit it.
And then we are in stage 4. And from my
side, that was just basically to block or
signal. So we don't get killed by launchd.
Because when launchd the launch and
exits, it will send the kill to all this
child process. And I need to catch that.
Otherwise Stage 4 would get killed. And
then I just called the Post Exploitation
Framework, which was written by Sparky.
And basically that does the following. It
first elevates the process to root with
current credentials, then it performs a
remount of the root file system because on
stock IOS, a file system was mounted as
read only and we obviously need to
mount it as read/write to modify some files
on there and then set non it sets the
nonce so that the user might be able to
downgrade to an older version if they are
flops. Verifies that the bootstrap was in
place from the installation. And then
checked substrates or the framework that's
used for them to perform tweak injection
and it's plugging into trust us and starts
them so that they can start to inject into
newly spawn processes. Then it's Ponce or
the launch demons associate with the
jailbreak and unloads or own demons so
that we don't respawned by extended
run. They kernel exploit again and then
performs an LUV start to basically restart
all of the launch teams off the system so
that subset can inject 3 STEM. And with
that the system is faulty, jail broken and
we can perform a few cleanup steps. But
yeah, basically the end user has
jailebroken system. Then as a little
side note while we are testing all the
demons, we got killed by jetsam a lot. So
basically jetsam is the kernel
extension from Apple. That is therefore
memory management. And they basically want
to make sure the user mode application
doesn't use too much memory because they
don't have that much on iPhone. And on all
the iPhones, actually. So there is this
list and jetsam, it jetsam seems easier to
use than process uses more than read and
should use. It would just kill it. So we
changed the values in the plist under
LaunchDaemons to actually allow the
LaunchDaemons to use more memory. But
the weird thing about this is that this
actually got us accepted by jetsam and we
had normal crashes while Apple actually
tried to mitigate that beforehand. So
because jailbreak is always modify those
configuration files on the LaunchDaemons,
they start to move all of them into a
dynamic library to guard them under code
signing. So the jailbreak just couldn't
change them anymore. But when you tried to
figure out the Launchdemon at the Launch
Demons, we dumped the dylib and ahm
there was also plist embedded for
Jetsam, but Apple was still using those
files on disk. So I really want to look
further into this because it seems like
Apple isn't always ignoring those
configurations files on disk. And then
thanks to the whole team. Siguza, Sparkey,
and Stek for bouncing ideas back and
forth and writing the many part of the
jailbreak. Then for Pod2g, Synacktiv for
the kernel bugs. And basically also a big
thanks to Saurik for substrate and the
whole jailbreaking framework and for
Swaggo, parrorgeek and Samg_is_a_Ninja
for testing a few things and keeping
motivated. And for Jonathan Levin for his
books basically because he bought a few
awesome books about IOS and that got me
into it two years ago. And yeah. And in
the future, I think exploiting kernel
vulnerability with other cache functions
and owning ROP really is a pain and that
probably won't do it again. Because he's
spent most of that. But yeah, the other
big problem now is that with a 12 so the
new iPhones pack. So point authentication
kills most of these types of exploits
because the problem there is that you
would now need an ASLA bypass and the pack
bypass to get into return oriented
programing. And it's pretty unlikely to
basically have both. And because Pegg
bypasses are really rare and yet I only
know about this one is a LA bypass. So you
would have to get pretty lucky. Also un-
tethering gets progressively harder. Apple
just fixed another good idea ahead in iOS
13.1. Basically the idea was to use printf
with the format string format modify
'%n' to get a Turing complete
machine because printf, this modifier
is basic Turing complete and then you
start to develop a pack bypass basically
and get them to ROP. But now we're in IS
13.1. I think Apple actually removed the
'%n' modifier, so you can no
longer do this. And yeah. So this idea is
also gone. And yeah. In the end, I was
able to complete my pipe dream, so I guess
I will need a new one. So watch out, Apple
and that spice. Are there any questions?
Applause
Herald: Thank you, littlelailo for is
fantastic work. I suppose we're going to
hear more from you in the future.
Littlelailo: Maybe.
Herald: Are there questions here in
this audience. No one who wants to hire
this guy now right away. No one. No one.
Can you describe to me what change
actually do times in these, you know, all
the ASICs? Oh, yeah. Oh, yes. versions.
Littlelailo: Well what they change to
make.
Herald: Yeah. What. Plus, you know, I told
you like I started the tethering challenge
actually at 5.1.
Littlelailo: Well, they added a lot new
mitigations and also obviously pitched a
few bugs like for example, those ASLR
bypasses that posterity used in Corona
got patched. And this one also now got
patched by accident. But yeah, I mean like
some bugs are still there. For example,
the Bug in racoon and the conflict pass.
The bug is still an all day. But yeah, I
don't really care about it. And the kernel
bugs got patched by Apple. But for
example, this synthetic one, they also
also patched wrong by accident. And now it
always leaked the strike. But I think they
also fixed that now.
Herald: Your team, you you're mentioning
your team. You're working not on
your own, of course.
Littlelailo: No.
Herald: And how would you restructured?
How are the roles divided? How was...
Littlelailo: Well, we are just like four
people. So and we have this group chat and
then we are just hanging out there and
bouncing ideas back and forth and maybe
working on some stuff.
Herald: A close contact with the Apple
developers.
Littlelailo: No, not at all.
Herald: More.
Littlelailo: I mean, I reported one bug to
their bounty once or like actually says to
them that their bounty and that one got
fixed and it was all fine. But yeah, for
now, I don't report bugs at the moment.
Herald: If you have time, you've time left
now actually, you're looking for a new
project doesn't it?
Littlelailo: Yeah. Yeah. And I might
report some of those bugs in the meantime
but I mean with the presentation they know
about them though so they might fix them.
Herald: They will be listening now and at
least probably I hope.
Littlelailo: Yes.
Herald: Is there anyone who has really,
you where sitting on a question here. None
of you? It's already noon. You know, noon
passed, so could be that none of you. You
can ask them something, maybe someone
asked them something, maybe they can help
you out with certain challenges that are
there.
Littlelailo: Well, I don't really have a
question either. Laughter I have my own
research project now. Well, like, I do
stuff at the moment and look at other
things. For example, to the bootrom
exploit came out now. And so I started
developing on the chick team with them.
And that's what I currently do, basically.
Herald: You're great, man. Littlelailo,
thank you. Giving him a warm applause!
Applause
36c3 Postroll music
Subtitles created by c3subtitles.de
in the year 2020. Join, and help us!