0:00:00.000,0:00:18.450
36C3 preroll music
0:00:18.450,0:00:25.160
Herald Angel: On my left, I have Omer[br]Gull, and Omer Gull is gonna tell us - A
0:00:25.160,0:00:33.092
SELECT code_execution FROM * USING SQLite.[br]Omer, Omer Gull, that's your talk, your stage, have fun!
0:00:33.092,0:00:42.190
Omer Gull: Thank you. Thank you. Hello,[br]everyone. Welcome to my talk, SELECT code
0:00:42.190,0:00:49.110
execution from just about anything using[br]SQLite, where we will gain code execution
0:00:49.110,0:00:54.440
using malicious SQLite databases. So my[br]name is Omer Gull. I'm a vulnerability
0:00:54.440,0:00:59.559
researcher from Tel Aviv. I've been[br]working in Check Point Research for the
0:00:59.559,0:01:05.960
past three years, and I've recently moved[br]on to a new startup called Hunters.AI.
0:01:05.960,0:01:11.409
Our agenda for today: So we'll start with a[br]little motivation and the backstory for
0:01:11.409,0:01:18.139
this research. Then we'll have a brief[br]SQLite introduction, and we'll examine the
0:01:18.139,0:01:22.759
attack surface given to a malicious[br]database. Then we will discuss some
0:01:22.759,0:01:29.359
previous work done in the field of SQLite[br]exploitation and think about exploiting
0:01:29.359,0:01:36.229
memory corruption bugs, using nothing but[br]pure SQL. We'll then demonstrate our own
0:01:36.229,0:01:41.450
innovative technique, called "Query[br]Oriented Programing", or QOP, and take it
0:01:41.450,0:01:47.929
for a spin in a couple of demos. We'll[br]wrap things up with some future work
0:01:47.929,0:01:54.200
possibilities and some conclusion. So the[br]motivation for this research is quite
0:01:54.200,0:02:00.649
obvious. SQLite is one of the most[br]deployed pieces of software out there.
0:02:00.649,0:02:08.005
Whether it's PHP 5, PHP 7, Android, iOS,[br]Mac OS, it is now built into Windows 10.
0:02:08.005,0:02:14.380
It's in Firefox and Chrome. This list[br]could continue forever. Yet querying an
0:02:14.380,0:02:20.310
SQLite database is considered safe.[br]Hopefully, by the end of this talk, you
0:02:20.310,0:02:27.290
will realize why this is not necessarily[br]the case. So, it all began with password
0:02:27.290,0:02:32.020
stealers, which is pretty strange, and[br]there are many, many password stealers in
0:02:32.020,0:02:37.680
the wild, but the story is usually the[br]same. First of all, a computer gets
0:02:37.680,0:02:43.170
infected. Then some malware collects the[br]storage credentials, as they are
0:02:43.170,0:02:48.510
maintained by various clients. Now, some[br]of these clients actually store your
0:02:48.510,0:02:55.090
secrets within SQLite databases. So the[br]malware just ships these SQLite databases
0:02:55.090,0:03:01.760
to its C2 server, where the secrets are[br]extracted and stored within a collective
0:03:01.760,0:03:07.740
database with the rest of the loot. So,[br]one day, my colleague and I, Omri, we were
0:03:07.740,0:03:13.210
looking at the leaked sources of a very[br]well known password stealers. Then we
0:03:13.210,0:03:17.930
thought to ourself: "These guys are just[br]harvesting a bunch of our databases and
0:03:17.930,0:03:24.700
parse them in their own backend. Can we[br]actually leverage the load and query of an
0:03:24.700,0:03:30.360
untrusted database to our advantage?" And[br]if we could, this could have much bigger
0:03:30.360,0:03:37.300
implications, just because SQLite is used[br]in countless scenarios. And so began the
0:03:37.300,0:03:46.320
longest CTF challenge of my life so far.[br]So, SQLite. Unlike most SQL databases,
0:03:46.320,0:03:52.740
SQLite does not have that client server[br]architecture. Instead, it simply reads and
0:03:52.740,0:03:58.630
write files directly to the file system.[br]So, you have one complete database, with
0:03:58.630,0:04:03.340
multiple tables, and indices, and[br]triggers, and views, and everything is
0:04:03.340,0:04:09.660
contained within the single file. So let's[br]examine the attack surface given to a
0:04:09.660,0:04:15.240
potentially malicious SQLite database. So[br]again, this is a snippet of code, of a
0:04:15.240,0:04:21.400
very well known password stealer, and we[br]have two main points of interest here:
0:04:21.400,0:04:26.430
First of all, we have sqlite3_open, where[br]our potentially malicious database is
0:04:26.430,0:04:32.179
loaded, and some parsing is going on. And,[br]obviously, we have the query itself,
0:04:32.179,0:04:36.950
right? The SELECT statement. Now, do note[br]that we have no control over that
0:04:36.950,0:04:41.020
statement, right. It is hardcoded within[br]our target. It tries to extract the
0:04:41.020,0:04:47.160
secrets out of our database. Yet we do[br]control the content, so we might have some
0:04:47.160,0:04:52.319
effect on what's going on there, right.[br]So, starting with the first point, the
0:04:52.319,0:04:58.099
sqlite3_open. This is just a bunch of[br]setup and configuration code. Then we move
0:04:58.099,0:05:03.110
on to really straightforward header[br]parsing, and the header itself is not that
0:05:03.110,0:05:10.420
long, just 100 bytes. And thirdly, it was[br]already fuzzed to death by AFL. So it's
0:05:10.420,0:05:17.229
probably not a very promising path to[br]pursue. But the SEL- the sqlite3_query
0:05:17.229,0:05:22.449
might be a bit more interesting, because[br]using SQLite author's words, "The SELECT
0:05:22.449,0:05:29.160
statement is the most complicated command[br]in the SQL language". Now, you might be
0:05:29.160,0:05:36.310
aware that behind the scenes, SQLite is a[br]virtual machine. So every query must first
0:05:36.310,0:05:42.259
be compiled to some proprietary bytecode.[br]And this is also known as the preparation
0:05:42.259,0:05:48.140
step. So sqlite3_prepare would walk and[br]expand the query. So, for example, every
0:05:48.140,0:05:56.079
time you select an asterisk, it simply[br]rewrite this asterisk as all column names.
0:05:56.079,0:06:02.059
So, sqlite3LocateTable will actually[br]verified that all the relevant objects
0:06:02.059,0:06:07.289
that you are querying actually exist, and[br]will locate them in memory. Where does it
0:06:07.289,0:06:13.589
locate them? So, every SQLite database has[br]a table called sqlite_master, and this is
0:06:13.589,0:06:20.139
actually the schema that is defining the[br]database. And this is its structure. So,
0:06:20.139,0:06:25.569
for every object in the database, you have[br]an entry, so its type, like whether it's a
0:06:25.569,0:06:32.120
table or view, and its name, and at the[br]very bottom you can see something called
0:06:32.120,0:06:40.569
SQL. And SQL is actually the DDL that is[br]describing the object. And DDL stands for
0:06:40.569,0:06:46.509
data definition language, and you can sort[br]of look at it like header files in C. So,
0:06:46.509,0:06:51.759
they are used to define the structures,[br]and names, and types of the objects within
0:06:51.759,0:06:57.750
the database. Furthermore, they appear in[br]plaintext within the file. So, let me show
0:06:57.750,0:07:02.949
you an example. Here I opened the SQLite[br]interpreter, I create a table, and I
0:07:02.949,0:07:08.360
insert some values into it. Then I quit[br]the interpreter, and now I hex dump the
0:07:08.360,0:07:15.169
file that was created. And you can see,[br]highlighted in yellow, the DDL statement
0:07:15.169,0:07:20.044
that is part of the master schema. And at[br]the very bottom, you can also see the
0:07:20.044,0:07:25.900
values. So, let's go back to query[br]preparation. We have sqlite3LocateTable
0:07:25.900,0:07:31.110
that attempts to find the structure that[br]is describing the table that we are
0:07:31.110,0:07:36.639
interested in querying. So it goes on and[br]reads the schema available in
0:07:36.639,0:07:41.119
sqlite_master that we just described. And[br]if it's the first time that it is doing
0:07:41.119,0:07:47.639
so, it has some callback function for[br]every of these DDL statements. The
0:07:47.639,0:07:53.169
callback function would actually validate[br]the DDL, and then it will go on and build
0:07:53.169,0:07:58.189
the internal structures of the object in[br]question. So then we thought about the
0:07:58.189,0:08:06.219
concept of DDL patching. What if I simply[br]replace the SQL query within the DDL? So
0:08:06.219,0:08:10.599
it turns out that there is a slight[br]problem with it. And this is the callback
0:08:10.599,0:08:16.469
function that I mentioned earlier, and as[br]you can tell, the DDL is first verified to
0:08:16.469,0:08:23.210
begin with "CREATE ". And only if it does[br]then we continue with the preparation. So,
0:08:23.210,0:08:28.969
this is definitely a constraint, right?[br]Our DDL must begin with "CREATE ". Yet it
0:08:28.969,0:08:35.030
does leave some room for flexibility,[br]because judging by SQLite documentation,
0:08:35.030,0:08:40.740
many things can be created. We can create[br]indexes, and tables, and triggers, and
0:08:40.740,0:08:46.560
views, and something we still don't quite[br]understand, called virtual tables. So,
0:08:46.560,0:08:53.280
then we thought about "CREATE VIEW",[br]because view is simply a pre-packaged
0:08:53.280,0:08:59.760
SELECT statement, and views are queried[br]very similarly to tables. So, selecting a
0:08:59.760,0:09:04.836
column out of a table is semantically[br]equivalent to selecting a column out of a
0:09:04.836,0:09:10.712
view. Then when we thought about the[br]concept of query hijacking. We are going
0:09:10.712,0:09:16.700
to patch sqlite_master DDL with views[br]instead of tables. Now our patched views
0:09:16.700,0:09:22.680
can actually have any SELECT subquery that[br]we wish. And now with this subquery I can
0:09:22.680,0:09:26.640
suddenly interact with the SQLite[br]interpreter. And this is a huge step
0:09:26.640,0:09:31.790
forward! We just turned an uncontrollable[br]query to something that we have some
0:09:31.790,0:09:38.110
control over. So let me show you query[br]hijacking by example. So let's say that
0:09:38.110,0:09:43.710
some original database had a single table,[br]and this is the DDL that is defining it.
0:09:43.710,0:09:49.130
So it's called "dummy" and it has two[br]columns. So, obviously any target software
0:09:49.130,0:09:53.390
would try to query it in the following[br]way: It would just try to select these
0:09:53.390,0:09:58.314
columns out of the table, right. Yet the[br]following view can actually hijack this
0:09:58.314,0:10:03.280
query. I create a view, it has just the[br]same name, and just the same amount of
0:10:03.280,0:10:08.220
columns, and each column is named just the[br]same way, and you can see that now every
0:10:08.220,0:10:13.800
column can have any sub query that I wish,[br]highlighted in blue at the bottom. So
0:10:13.800,0:10:18.570
again, let me show you a practical example[br]of it. Here, I created a view called
0:10:18.570,0:10:23.900
"dummy" with cola and colb, and the first[br]column is utilizing the sqlite_version()
0:10:23.900,0:10:28.340
function, and that's a built in function[br]that simply returns the SQLite version,
0:10:28.340,0:10:35.420
obviously. The second column is utilizing[br]SQLite's own implementation of printf.
0:10:35.420,0:10:40.030
That's right, they have all these really[br]surprising features and capabilities. So,
0:10:40.030,0:10:46.150
let's see that from the supposedly - from[br]the target side. So, anyone trying to
0:10:46.150,0:10:51.890
select out of these column, is suddenly[br]executing our functions. So, at the left
0:10:51.890,0:10:57.180
you can see the SQLite version, and on the[br]right you can see the printf that was
0:10:57.180,0:11:02.120
executed on the target side. So again,[br]this is a huge step forward. We just
0:11:02.120,0:11:08.760
gained some control over that query,[br]right. And the question is, what can we do
0:11:08.760,0:11:15.440
with this control? Does SQLite have any[br]system commands? Can maybe - maybe we can
0:11:15.440,0:11:23.360
read and write to some other files on the[br]file system. So, this was a good point to
0:11:23.360,0:11:28.380
stop and look at some previous work done[br]in the field, because obviously, we are
0:11:28.380,0:11:34.533
not the first to notice SQLite's huge[br]potential, in terms of exploitation. A
0:11:34.533,0:11:39.171
reasonable place to start is SQLite[br]injection, because this is sort of a
0:11:39.171,0:11:45.540
similar scenario, right? Someone malicious[br]has some control on an SQL query. So,
0:11:45.540,0:11:51.550
there are a couple of known tricks in SQL[br]injection with SQLite. The first one has
0:11:51.550,0:11:56.450
something to do with attaching another[br]database, and then creating a table, and
0:11:56.450,0:12:01.390
inserting some strings into it. And[br]because, as I mentioned earlier, every -
0:12:01.390,0:12:06.920
every database is just a file, so this is[br]somewhat of an arbitrary file, right, on
0:12:06.920,0:12:11.490
the file system. Yet we do have this[br]constraint, if you remember, that we can't
0:12:11.490,0:12:17.730
ATTACH, because our DDL must begin with[br]"CREATE". Another cool trick is abusing
0:12:17.730,0:12:23.740
the load extension function. And here you[br]can see how you can potentially load a
0:12:23.740,0:12:28.160
remote DLL. In this case, the[br]meterpreter.dll, but obviously this very
0:12:28.160,0:12:35.104
dangerous function is disabled by default.[br]So again, no go. What about memory
0:12:35.104,0:12:42.290
corruption in SQLite, because SQLite is[br]really complex and it's all written in C.
0:12:42.290,0:12:48.200
So in his amazing blog post "Finding Bugs[br]in SQLite, the easy way", Michal Zalewski,
0:12:48.200,0:12:54.870
the author of AFL, described how he found[br]22 bugs in just under 30 minutes of
0:12:54.870,0:13:01.790
fuzzing. And actually, since then, since[br]that was version 3.8.10, that was in 2015,
0:13:01.790,0:13:06.840
SQLite actually started using AFL as an[br]integral part of the remarkable test
0:13:06.840,0:13:11.690
suite. Yet these memory corruption bugs[br]all proved to be really difficult to
0:13:11.690,0:13:16.610
exploit without some convenient[br]environment. Yet, the security research
0:13:16.610,0:13:25.300
community soon found the perfect target,[br]and it was called WebSQL. So, WebSQL is
0:13:25.300,0:13:30.240
essentially an API for storing data in[br]databases, and it is queried from
0:13:30.240,0:13:36.240
JavaScript and it has an SQLite backend.[br]Also, it is available in Chrome and
0:13:36.240,0:13:41.990
Safari. So here you can see a very simple[br]example of how to interact with WebSQL
0:13:41.990,0:13:51.100
from JavaScript. But in other words, what[br]I'm hearing here is that we have some
0:13:51.100,0:13:56.240
untrusted input to SQLite and it is[br]reachable from any website on the Internet
0:13:56.240,0:14:02.350
in two of the world's most popular[br]browsers. And suddenly these bugs, these
0:14:02.350,0:14:07.040
memory corruptions can now be leveraged[br]with the knowledge and - with the
0:14:07.040,0:14:10.762
knowledge and comfort of JavaScript[br]exploitation, right. The JavaScript
0:14:10.762,0:14:16.200
interpreter exploitation that we got, we[br]got pretty good over the years. So there
0:14:16.200,0:14:20.420
have been really several really impressive[br]research that were published regarding
0:14:20.420,0:14:28.610
WebSQL from really low hanging fruits like[br]CVE-2015-7036, that was an untrusted
0:14:28.610,0:14:35.190
pointer dereference in the fts3_tokenizer(),[br]to some more complex exploit as presented
0:14:35.190,0:14:40.840
in Blackhat 2017 by the awesome Chaitin[br]team, that found a type confusion in the
0:14:40.840,0:14:46.480
FTS optimizer, to the very recent Magellan[br]bugs found and exploited by Tencent, that
0:14:46.480,0:14:52.350
found an integer overflow in the FTS[br]segment reader. And if you are paying even
0:14:52.350,0:14:58.080
a tiny bit of attention by now, you must[br]see an interesting pattern arises. All
0:14:58.080,0:15:04.760
these vulnerable functions start with FTS.[br]So what is FTS? I have never heard of it.
0:15:04.760,0:15:11.580
And actually googling it just left me more[br]confused. After some time, I came to the
0:15:11.580,0:15:17.560
realization that FTS stands for "full text[br]search", and it is something called a
0:15:17.560,0:15:22.840
virtual table module and it allows for[br]some really cool textual search on a set
0:15:22.840,0:15:28.260
of documents. Or like the SQLite authors[br]described it, It's "like Google for your
0:15:28.260,0:15:33.700
SQlite databases". So virtual tables allow[br]for some pretty cool functionality in
0:15:33.700,0:15:39.410
SQLite, whether it's this free text search[br]or a virtual table module called RTREE,
0:15:39.410,0:15:44.750
that does some really clever geographical[br]indexing, or a virtual table called CSV,
0:15:44.750,0:15:50.060
that lets you treat your database as a CSV[br]file. And these virtual tables are
0:15:50.060,0:15:55.970
actually queried just like regular tables.[br]Yet behind the scenes, some dark magic
0:15:55.970,0:16:02.350
happens. And after every query, there is[br]some callback function that is invoked and
0:16:02.350,0:16:07.370
it works on something called shadow[br]tables. Now, shadow tables would be best
0:16:07.370,0:16:13.800
explained by example. So let's say that I[br]create a virtual table using that FTS
0:16:13.800,0:16:19.910
virtual table module and I insert a string[br]into it. Now, obviously, to allow for some
0:16:19.910,0:16:23.980
efficient search, I need to have some[br]metadata, right? I need to have some
0:16:23.980,0:16:28.650
offsets or indexes or tokens or stuff like[br]that. So - and obviously they're all text,
0:16:28.650,0:16:35.310
right? So that one virtual table is[br]actually, it's raw text, and metadata is
0:16:35.310,0:16:40.620
stored among three shadow tables. So the[br]raw text would go to vt_content and the
0:16:40.620,0:16:46.050
metadata would go to vt_segments and[br]vt_segdir. And in time, these shadow
0:16:46.050,0:16:51.740
tables actually have interfaces passing[br]information between them, right. Because
0:16:51.740,0:16:55.680
the metadata is storing all these[br]pointers, so you need to pass them between
0:16:55.680,0:17:01.500
each other. And these interfaces proved to[br]be really, really trusting in their
0:17:01.500,0:17:09.589
nature. And it makes them a really fertile[br]ground for bug hunting. So let me show you
0:17:09.589,0:17:15.819
a bug that I found in the RTREE virtual[br]table module. So, RTREE virtual table
0:17:15.819,0:17:20.589
module is available now in MacOS and iOS,[br]and it's really cool because now it's also
0:17:20.589,0:17:24.890
built into Windows 10. And as I've[br]mentioned, it does some really clever
0:17:24.890,0:17:31.400
geographical indexing. Now, the DDL is[br]supposed to be the following. Any RTREE
0:17:31.400,0:17:37.020
virtual table is supposed to begin with[br]"id", that needs to be an integer. Then
0:17:37.020,0:17:41.970
you have some X and Y coordinates. So[br]obviously every RTREE interface would
0:17:41.970,0:17:48.250
expect "id" to be an integer. But if I[br]create a virtual table and I insert into
0:17:48.250,0:17:53.970
"id" something that is definitely not an[br]integer, then I use one of these RTREE
0:17:53.970,0:17:59.560
interfaces, rtreenode at the very bottom,[br]you see that we got this crash, this out-
0:17:59.560,0:18:08.590
of-bounds read on the heap. And this[br]example is a crash in Windows 10. So
0:18:08.590,0:18:15.040
that's pretty good. We have established[br]that virtual table has bugs. And now,
0:18:15.040,0:18:21.260
using query hijacking technique, we can[br]suddenly trigger these bugs on our target,
0:18:21.260,0:18:26.435
which is a C2 of the password stealer, and[br]will cause it to segfault. And this is
0:18:26.435,0:18:32.120
nice, but actually gaining flow control[br]over our target requires us to have some
0:18:32.120,0:18:37.480
form of scripting, right? We want to[br]bypass ASLR and do all these crazy things.
0:18:37.480,0:18:42.390
Yet we don't have JavaScript, we don't[br]have JavaScript arrays and variables and,
0:18:42.390,0:18:48.320
like, logic statements, like if and and[br]loops and stuff like that. However, we do
0:18:48.320,0:18:54.580
vaguely recall hearing somewhere that SQL[br]is turing complete. So we decided to put
0:18:54.580,0:19:00.780
it to the test from exploitation[br]perspective, and we started creating our
0:19:00.780,0:19:06.580
own primitive wish list for exploitation.[br]So if it would create a full exploit
0:19:06.580,0:19:11.080
exploiting memory corruption bugs with[br]nothing but SQL, what capabilities do we
0:19:11.080,0:19:16.160
want? So, obviously, to bypass ASLR and[br]these kind of things, we want to leak some
0:19:16.160,0:19:21.040
memory. We need to have an info leak. And[br]if you've done any pwning in your past,
0:19:21.040,0:19:27.190
you must be familiar with really common[br]tasks like unpacking 64-bit pointers and
0:19:27.190,0:19:31.190
doing some pointer arithmetics, right?[br]Because we had an info leak, we converted
0:19:31.190,0:19:35.700
- we read this pointer, and it's a little[br]endian and so we need to flip it, and now
0:19:35.700,0:19:40.030
we want to calculate, let's say where's[br]the base of libsqlite so we can find some
0:19:40.030,0:19:45.650
more functions maybe. So we need some[br]pointer arithmetics. Obviously, after
0:19:45.650,0:19:50.720
reading pointers and manipulating them, we[br]want to pack them again and write them
0:19:50.720,0:19:57.710
somewhere. Obviously, writing a single[br]pointer is never enough. We want to create
0:19:57.710,0:20:03.140
fake objects in memory, like more complex[br]objects than this one pointer. And
0:20:03.140,0:20:08.090
finally, we would like to heap spray[br]because this might be really useful. So,
0:20:08.090,0:20:13.230
the question remains, can all this[br]exploitation be done with nothing but SQL?
0:20:13.230,0:20:19.020
So, the answer is "yes, it is". And I[br]proudly present to you Query Oriented
0:20:19.020,0:20:25.860
Programing, or QOP. And to demonstrate[br]QOP, we are going to exploit the unfixed
0:20:25.860,0:20:37.360
CVE-2015-7036. And you might ask yourself[br]"What? How come a four year old bug is
0:20:37.360,0:20:44.390
still unfixed?" And this is a great point[br]to our argument. This CVE was only ever
0:20:44.390,0:20:50.450
considered dangerous in the context of[br]untrusted WebSQL. So it was mitigated
0:20:50.450,0:20:55.210
accordingly, right. It is blacklisted[br]unless SQLite is compiled with is certain
0:20:55.210,0:20:59.910
flag. So, obviously browsers are not[br]compiled with this flag anymore. But let
0:20:59.910,0:21:04.740
me show you who is compiled with this[br]flag. So, we have PHP 5 and PHP 7, in
0:21:04.740,0:21:09.340
charge on most of the Internet, and iOS[br]and MacOS and probably so many other
0:21:09.340,0:21:15.260
targets that we just didn't have the time[br]to go over. So, let's explain this
0:21:15.260,0:21:20.780
vulnerability a little bit. I've mentioned[br]that it's in the FTS tokenizer. So, a
0:21:20.780,0:21:26.830
tokenizer is just a set of rules to[br]extract terms from documents or queries.
0:21:26.830,0:21:32.679
And the default tokanizer, that is named[br]"simple", just split the strings by
0:21:32.679,0:21:38.820
whitespaces. However, if you like, you can[br]register your own custom tokenizer. You
0:21:38.820,0:21:43.890
can just pass a C function and you[br]actually register this custom tokenizer
0:21:43.890,0:21:50.020
with the function fts3_tokenizer() in an[br]SQL query. This is a bit where it's all
0:21:50.020,0:21:55.930
repeated slowly. You pass a row pointer[br]to a C function in an SQL query. This is
0:21:55.930,0:22:01.390
absolutely insane. To be honest, after[br]studying this for quite a while, I still
0:22:01.390,0:22:06.021
don't understand how to use this feature[br]outside of my exploit.
0:22:06.021,0:22:15.654
audience laughing[br]clapping
0:22:15.654,0:22:17.640
So fts3_tokenizer()
0:22:17.640,0:22:22.800
is actually an overloaded function, and if[br]you call it with one argument that is the
0:22:22.800,0:22:28.230
name of a tokenizer, you get back the[br]address of that tokenizer, and to make it
0:22:28.230,0:22:34.760
a bit more human readable, or somewhat[br]human, we'll use the hex decoder. And you
0:22:34.760,0:22:40.210
can now see that we actually got an info[br]leak to libsqlite3. Now, because it's
0:22:40.210,0:22:43.390
little endian, so it's the other way[br]around, so we need to reverse it, but this
0:22:43.390,0:22:48.230
is already pretty cool. If you call[br]fts3_tokenizer() with two arguments, the
0:22:48.230,0:22:53.162
first one being a name of a tokenizer, and[br]the second one, again, is a row pointer,
0:22:53.162,0:22:58.426
this is absolutely insane, you rewrite the[br]address of that tokenizer. So now,
0:22:58.426,0:23:05.300
whenever someone will try to use a virtual[br]table, so it will instantiate our default
0:23:05.300,0:23:10.870
tokenizer, right. It will crash and burn.[br]And this is pretty amazing. Let's have a
0:23:10.870,0:23:17.110
short recap. So, we've established that[br]SQLite is a wonderful one-shot for many
0:23:17.110,0:23:21.540
targets, right? It's absolutely[br]everywhere. And it is a complex machine
0:23:21.540,0:23:26.720
that is written in C. Now, with query[br]hijacking, we can start triggering these
0:23:26.720,0:23:32.640
bugs, and we aim to write a full exploit,[br]implementing all necessary primitives
0:23:32.640,0:23:40.140
using SQL queries. Our exploitation game[br]plan is as follows: We will leak some
0:23:40.140,0:23:45.990
pointers, and then we'll calculate some[br]function addresses. We'll then create a
0:23:45.990,0:23:51.650
fake tokenizer object with some pointer to[br]system(). We will override the default
0:23:51.650,0:23:57.770
tokenizer and trigger our malicious[br]tokenizer. Then something will happen, and
0:23:57.770,0:24:02.690
obviously by the end of the process we[br]should be able to profit somehow, right?
0:24:02.690,0:24:08.620
So, starting with memory leak, an info[br]leak to libsqlite. So, you already know
0:24:08.620,0:24:13.299
how to do it, right? We've seen[br]fts3_tokenizer(), but we still have a tiny
0:24:13.299,0:24:19.290
problem of the little-endian pointer. So[br]we need to flip it. Now, surely we can use
0:24:19.290,0:24:24.600
the SUBSTR function and read this pointer[br]two characters at a time in a reverse
0:24:24.600,0:24:30.180
fashion, and then simply concatenate[br]everything throughout the pointer. So, we
0:24:30.180,0:24:35.420
get a SELECT query that looks the[br]following, but now we have our pointer.
0:24:35.420,0:24:39.810
This is great. What about an info leak to[br]the heap? We want to know where the heap
0:24:39.810,0:24:44.590
is located. So, to do that trick, I'm[br]going to do something pretty similar to
0:24:44.590,0:24:49.480
the RTREE bug that we've found. So, again,[br]I'm going to confuse some shadow table
0:24:49.480,0:24:57.740
interface. So, we created a virtual table[br]and inserted some values into it. And now
0:24:57.740,0:25:02.190
we're about to confuse the match[br]interface. So, the match interface does
0:25:02.190,0:25:06.960
many things, but behind the scenes, it[br]just finds - it serves the pointer in
0:25:06.960,0:25:11.020
memory to where the text is located,[br]right. It's this metadata, cool things
0:25:11.020,0:25:16.030
that virtual table has. So we're going to[br]confuse it, and instead of passing it to
0:25:16.030,0:25:21.191
another virtual table interface, we'll[br]simply pass it to the hex decoder, so we
0:25:21.191,0:25:25.670
will decode this raw pointer. And you can[br]see that, again in little-endian, but now
0:25:25.670,0:25:32.799
we have a link to the heap. We can cross[br]that off the list. And before we go on to
0:25:32.799,0:25:39.320
unpacking this pointer, we have a very[br]basic problem. How do we even save these
0:25:39.320,0:25:44.620
things? Because unlike browser WebSQL, we[br]don't have JavaScript variables or arrays
0:25:44.620,0:25:49.690
to use and then abuse them later, but we[br]need to create some complex logic, right?
0:25:49.690,0:25:54.910
We need to calculate the function address[br]and create things in memory, but how can
0:25:54.910,0:25:58.780
we do it? Obviously, with SQLite, when you[br]want to save some values, you need to have
0:25:58.780,0:26:05.220
insert statements, but we can only create[br]tables and views and index and triggers.
0:26:05.220,0:26:10.520
Then we thought about chaining this view[br]together to use them sort of like a
0:26:10.520,0:26:16.370
pseudo-variable. So again, let me show you[br]an example. Here, I create a view, it's
0:26:16.370,0:26:20.929
called "little-endian leak", right? And[br]again, I abuse the fts3_tokenizer()
0:26:20.929,0:26:25.530
function. Now I create another view on top[br]of it, and this one is called "leak", and
0:26:25.530,0:26:30.240
it's flipping it using the SUBSTR trick[br]that you know from before. But notice how
0:26:30.240,0:26:34.360
I referred to the first view, I referred[br]to "little-endian leak". So again, I do it
0:26:34.360,0:26:39.781
throughout the pointer, and eventually[br]what I have is a pseudo-variable that's
0:26:39.781,0:26:46.710
called "leak". And when I select from it,[br]I get the expected result. So now we can
0:26:46.710,0:26:51.059
really move forward. Now we can start[br]building some more complex things based on
0:26:51.059,0:26:57.190
this logic. And now we can go to unpacking[br]the pointers. So, we want to calculate a
0:26:57.190,0:27:02.610
base of an image, for example, or maybe[br]find the beginning of the heap. So first
0:27:02.610,0:27:09.160
of all, we want to convert our pointers to[br]integers. So, again, we're going to start
0:27:09.160,0:27:14.740
and read these pointers one character at a[br]time and in reverse fashion using SUBSTR.
0:27:14.740,0:27:20.690
And to get the value of this hex[br]character, we're going to use INSTR, that
0:27:20.690,0:27:26.110
is just like strchar, and using the[br]following string we'll get the value of
0:27:26.110,0:27:31.450
the hex character. Now, because it is one-[br]based, you have on the right the minus
0:27:31.450,0:27:39.970
one. Then I need to have some shifting,[br]like, dark magic, and then I go and just
0:27:39.970,0:27:44.860
concatenate everything throughout the[br]pointer. So the result is this monster
0:27:44.860,0:27:50.179
query. But eventually, when all of this is[br]done, I get an integer that is the
0:27:50.179,0:27:56.880
unpacked version of our initial leak. So I[br]successfully unpacked this pointer and we
0:27:56.880,0:28:02.169
now have integers at hand, so we can cross[br]that off the list as well. We know how to
0:28:02.169,0:28:08.140
convert pointers to integers. Now, pointer[br]arithmetics, right, because we want to
0:28:08.140,0:28:13.190
have the addresses of some functions in[br]memory and actually, with integer, this is
0:28:13.190,0:28:19.059
super simple. All we need to do is use[br]some more sub-queries. So, on the left you
0:28:19.059,0:28:22.490
can see that I'm referring to the, now,[br]pseudo-variables that we have, the
0:28:22.490,0:28:28.760
unpacked leak, and on the right I can[br]either have, like, subtract a silly
0:28:28.760,0:28:32.570
constant like I did here, or I can[br]actually use another pseudo-variable to
0:28:32.570,0:28:39.870
make it a bit more dynamic, can make some[br]a bit more reliable. So, eventually, what
0:28:39.870,0:28:47.490
I'm ending up with is the libsqlite base[br]in an integer form. So, we've read some
0:28:47.490,0:28:53.990
pointers and we manipulated them. Now it's[br]a good time to write them back. And
0:28:53.990,0:29:00.510
obviously we're all used to "char" being[br]the exact opposite of "hex". And you can
0:29:00.510,0:29:05.700
see that it works fairly well on most of[br]the values, but bigger integers were
0:29:05.700,0:29:10.980
actually translated to their two-byte[br]code-points. So this was a huge obstacle
0:29:10.980,0:29:20.180
for us. So, after bashing our head against[br]the documentation for quite a while, we
0:29:20.180,0:29:25.370
suddenly had the strangest epiphany. We[br]realized that our exploit is actually a
0:29:25.370,0:29:30.650
database. And if I want any conversion to[br]take place, I can simply create, ahead of
0:29:30.650,0:29:37.780
time, this key-value map and simply query[br]it to translate whatever value I want to
0:29:37.780,0:29:43.530
another value with sub-queries. So this is[br]the python function that I've used and you
0:29:43.530,0:29:48.490
can see that there's a very simple for[br]loop going from 0 to FF and just inserting
0:29:48.490,0:29:54.520
values to a table called "hex_map" with[br]its key-map value. And now our conversions
0:29:54.520,0:30:00.610
are using sub-queries. So again, let me[br]show you by example. You can see that I'm
0:30:00.610,0:30:06.810
selecting "val" from hex map, this key-[br]value map, where "int" is equal to, and
0:30:06.810,0:30:11.371
then I go and then doing some more like[br]shifting and modulo dark magic, but
0:30:11.371,0:30:18.230
eventually, what I'm ending up with is a[br]packed version of our libsqlite base. Now
0:30:18.230,0:30:22.450
it's, we have a packed little-endian[br]pointer, so we can cross that off the list
0:30:22.450,0:30:30.001
as well. As I've mentioned, writing a[br]single pointer is definitely useful, but
0:30:30.001,0:30:35.280
it's not enough. We want to be faking[br]complete objects, right? All the cool kids
0:30:35.280,0:30:40.130
are doing it and it's a pretty powerful[br]primitive. And if you actually recall, we
0:30:40.130,0:30:45.970
have to do it because fts3_tokenizer()[br]requires us to assign a tokenizer module.
0:30:45.970,0:30:50.510
Now, what is a tokenizer module? How does[br]it look? So, this is the beginning of its
0:30:50.510,0:30:54.740
structure and there is an "iVersion",[br]that's an integer at the beginning, we
0:30:54.740,0:31:00.360
don't really care about it, but following[br]it are three function pointers. We have
0:31:00.360,0:31:04.840
"xCreate", which is the constructor of the[br]tokenizer, and "xDestroy", which is the
0:31:04.840,0:31:10.530
destructor. We need to have both of them[br]valid so we don't crash during our
0:31:10.530,0:31:14.340
exploitation. The third function pointer[br]is really interesting, because this is
0:31:14.340,0:31:18.360
what actually tokenizes the string. So we[br]have a function pointer that we are
0:31:18.360,0:31:23.550
passing a controllable string into. This[br]would be a perfect place to put our system
0:31:23.550,0:31:33.000
gadget, right. So by now, I've used a fair[br]share of my SQL knowledge, right. But I do
0:31:33.000,0:31:37.919
have one more trick up my sleeve and[br]that's JOIN queries, right? Because I
0:31:37.919,0:31:43.730
learned about it at a time in the past. So[br]we're now going to create a fake tokenizer
0:31:43.730,0:31:48.169
view and we're going to concatenate a[br]bunch of "A"'s and then, using a JOIN
0:31:48.169,0:31:53.320
query, we'll concatenate it with a pointer[br]to simple_create and a pointer to
0:31:53.320,0:31:58.039
simple_destroy and then a bunch of "B"'s.[br]Now let's verify it from a low-level
0:31:58.039,0:32:02.860
debugger and you can actually see that at[br]some place in memory, we have a bunch of
0:32:02.860,0:32:06.990
"A"'s followed by a pointer to[br]simple_create, followed by a pointer to
0:32:06.990,0:32:14.280
simple_destroy, and a bunch of "B"'s. So,[br]we're almost done. But we need one more
0:32:14.280,0:32:20.200
primitive for this exploit. And this is[br]because we already have our malicious
0:32:20.200,0:32:24.700
tokenizer, and we know where the heap is[br]located, but we are not quite sure where
0:32:24.700,0:32:31.140
our tokenizer is. So this is a great time[br]for some heap spraying, right. And ideally
0:32:31.140,0:32:36.660
this would be some repetitive form of our[br]fake object primitive. So we've thought
0:32:36.660,0:32:45.360
about repeat, but sadly SQLite did not[br]implement it like mySQL. So, like anyone
0:32:45.360,0:32:51.480
else, we went to Stack Overflow, and we[br]found this really elegant solution. So
0:32:51.480,0:32:59.030
we're going to use the zeroblob function[br]that simply returns a blob of N zeros. And
0:32:59.030,0:33:03.630
then we will replace each of that zeros[br]with our fake tokenizer. And we're going
0:33:03.630,0:33:07.640
to do it ten thousand times, as you can[br]see above. Again, let's verifiy it with a
0:33:07.640,0:33:12.620
debugger. So, you see a bunch of "A"'s and[br]it's kind of hard to see, because these
0:33:12.620,0:33:17.049
are really bad colors, but we also got[br]perfect consistency, because these
0:33:17.049,0:33:24.820
structures repeat themselves every 20 hex[br]bytes. So we created a pretty good heap
0:33:24.820,0:33:30.631
spraying capabilities and we are done with[br]our exploitation primitive wish list, so
0:33:30.631,0:33:37.710
we can go back to our initial target.[br]Again, this is the code snippet of a very
0:33:37.710,0:33:43.200
well known password stealer. And at the[br]bottom, you can see that it's trying to
0:33:43.200,0:33:49.090
SELECT to extract the secrets by selecting[br]a column called "BodyRich" from a table
0:33:49.090,0:33:55.330
called "Notes". So, we're going to prepare[br]a little surprise for him, right? We're
0:33:55.330,0:33:59.049
going to create a view that is called[br]"Notes". And it has three sub-queries in a
0:33:59.049,0:34:04.289
column called "BodyRich". And each of[br]these sub-queries is actually a QOP chain
0:34:04.289,0:34:09.020
on its own. So if you remember my[br]exploitation game plan, we're going to
0:34:09.020,0:34:14.500
start with heap spray, and then we will[br]override the default tokenizer, and then
0:34:14.500,0:34:19.179
we will trigger our malicious tokenizer.[br]And you might ask yourself, what is
0:34:19.179,0:34:25.160
heap_spray? Obviously, heap_spray is a QOP[br]chain that utilizes our heap spraying
0:34:25.160,0:34:33.109
capabilities, right. We are spraying ten[br]thousand instances of our fake tokenizer,
0:34:33.109,0:34:37.690
that is a JOIN query of a bunch of "A"'s[br]and then some pointers like
0:34:37.690,0:34:43.720
p64_simple_create. And the party goes on,[br]because p64_ simple_create is actually
0:34:43.720,0:34:52.399
derived from u64_simple_create, right,[br]with our pointer-packing capabilities. And
0:34:52.399,0:34:56.790
this is just turtles all the way down,[br]because you have u64_simple_create, that
0:34:56.790,0:35:04.440
is derived from libsqlite_base plus some[br]constant. And this goes back to the
0:35:04.440,0:35:09.620
unpacked leak version, right, minus some[br]constant. So again, we're using our
0:35:09.620,0:35:16.410
pointer arithmetics capabilities. We can[br]continue with u64_leak being derived from
0:35:16.410,0:35:23.470
the almost initial leak. And we'll wrap up[br]by showing how the leak is actually
0:35:23.470,0:35:29.410
derived from the initial vulnerability[br]using fts3_tokenizer. And this was just
0:35:29.410,0:35:35.040
one out of three QOP chains that we used[br]in this exploit. And by now, every time
0:35:35.040,0:35:40.490
that I described this exploit, this is how[br]I must look. And to be honest, this is how
0:35:40.490,0:35:44.660
I feel. But luckily for you guys, you[br]don't have to look and feel like me
0:35:44.660,0:35:50.340
because we created QOP.py, and it is[br]available on Checkpoint Research GitHub.
0:35:50.340,0:35:56.650
And suddenly these crazy long chains can[br]now be created with four easy lines of
0:35:56.650,0:36:01.290
python. And it feels like pwntools if you're[br]familiar with it, so you can go ahead and
0:36:01.290,0:36:08.640
play with it and not look crazy on stage.[br]So, we'll go to our first demo. We'll own
0:36:08.640,0:36:15.740
a password stealer backend running the[br]latest PHP 7. So obviously that's a model
0:36:15.740,0:36:20.480
that we created with the leaked sources[br]and you can see all the infected victims,
0:36:20.480,0:36:30.340
right. Cool. Now we'll try to go to our[br]webshell, to p.php. Obviously it still
0:36:30.340,0:36:35.770
does not exist, we get a 404. Moving to[br]the attacker's computer. So, we see that
0:36:35.770,0:36:42.060
we have two scripts here. First, we're[br]going to use QOP.py, that will generate a
0:36:42.060,0:36:47.700
malicious database. Let's see, the[br]database was created. Now we're going to
0:36:47.700,0:36:52.609
emulate an infection. We're going to send[br]our malicious database to the C2 server as
0:36:52.609,0:36:56.950
if we were infected by a password stealer.[br]And because this process takes a bit of
0:36:56.950,0:37:01.490
time, we can look at all the cool DDL[br]statements, right. So you see that we
0:37:01.490,0:37:06.619
started with some bin leak and heap leak[br]and then we unpacked them. And at the very
0:37:06.619,0:37:10.800
bottom, you can see that our end gadget is[br]echoing the simplest webshell to p.php,
0:37:10.800,0:37:19.310
right. And this is the same page that we[br]just tried to reach. So hopefully, yeah -
0:37:19.310,0:37:27.140
great, it's done. Now we go back to the[br]password stealer backend. We go to p.php
0:37:27.140,0:37:35.210
and we got 200. Now, let's execute some[br]code on it. whoami. www-data. And
0:37:35.210,0:37:44.220
obviously we need to go for /etc/password.[br]Yay.
0:37:44.220,0:37:55.410
applause[br]So, what just happened is that we've shown
0:37:55.410,0:38:02.109
that, given just the query to our[br]malicious a database, we can execute code
0:38:02.109,0:38:07.920
on the querying process. Now, given the[br]fact that SQLite is so popular, this
0:38:07.920,0:38:13.320
really opens up the door to a wide range[br]of attacks. Let's explore another use case
0:38:13.320,0:38:21.060
that is completely different. And our next[br]target is going to be iOS persistency. So,
0:38:21.060,0:38:28.090
iOS uses SQLite extensively, and[br]persistency is really hard to achieve,
0:38:28.090,0:38:34.570
because all executable files must be[br]signed. Yet, SQLite databases are not
0:38:34.570,0:38:40.440
signed, right, they're data-only. There is[br]no need to sign them. And iOS and MacOS
0:38:40.440,0:38:44.320
are both compiled with[br]ENABLE_FTS3_TOKENIZER. That's the
0:38:44.320,0:38:50.770
dangerous compile-time flag. So, my plan[br]is to regain code execution after reboot
0:38:50.770,0:38:56.599
by replacing an arbitrary SQLite DB. And[br]to do this, I'm going to target that
0:38:56.599,0:39:02.810
contacts database, and its name is[br]"AddressBook.sqlite". So these are two
0:39:02.810,0:39:09.080
tables in the original database. They have[br]no significant meaning, right. Just for
0:39:09.080,0:39:15.050
example. And I'm going to create malicious[br]contacts DB, and I'm going to start with
0:39:15.050,0:39:19.900
two malicious DDL statements that you're[br]already familiar by now. First of all,
0:39:19.900,0:39:25.770
we'll override the default organizer[br]"simple" to a bunch of "A"'s. Then, our
0:39:25.770,0:39:30.911
second DDL statement would actually[br]instantiate this malicious trigger, so it
0:39:30.911,0:39:34.599
will actually crash the program, right,[br]because every time you create a virtual
0:39:34.599,0:39:40.000
table module, someone is trying to go to[br]the constructor of the tokenizer. So then
0:39:40.000,0:39:45.290
it will crash. Now, what I'm doing next is[br]I'm going to go over each and every of the
0:39:45.290,0:39:51.100
original table and rewrite them using our[br]query hijacking technique, right. So,
0:39:51.100,0:39:56.359
instead of the columns that it expected,[br]we are going to redirect the execution to
0:39:56.359,0:40:00.160
the override statement and the crash[br]statement. So, we did it for one table, we
0:40:00.160,0:40:07.710
also do it for the others. Now we reboot[br]and voila, we get the following CVE and
0:40:07.710,0:40:12.200
secure boots was bypassed. And if you pay[br]close attention, this is really cool,
0:40:12.200,0:40:19.420
because we see that the crash happened at[br]0x414141...49. And this is exactly what we
0:40:19.420,0:40:24.470
expected to happen, right, because this is[br]where our constructor should be, at an
0:40:24.470,0:40:30.930
offset of eight after the first integer of[br]the version. But actually, there is more.
0:40:30.930,0:40:35.710
We get a bonus here. Because the contacts[br]DB is actually used by many, many
0:40:35.710,0:40:41.020
different processes. So Contacts and[br]Facetime and Springboard and WhatsApp and
0:40:41.020,0:40:47.040
Telegram and XPCProxy and so many others.[br]And a lot of these processes are way more
0:40:47.040,0:40:51.300
privileged than others. And we've[br]established that we can now execute code
0:40:51.300,0:40:56.560
on the process that queries our malicious[br]database. So we also got a privilege
0:40:56.560,0:41:01.260
escalation in this process, right. And[br]this is really cool. And there's nothing
0:41:01.260,0:41:06.000
special about the contacts database.[br]Actually, any shared database can be used.
0:41:06.000,0:41:11.820
All we need is something to be writeable[br]by a weak user and then being queried by a
0:41:11.820,0:41:16.970
stronger user, right. And obviously all[br]these techniques and bugs were reported to
0:41:16.970,0:41:20.790
Apple and they're all fixed. And these are[br]the CVEs if you want to go and read about
0:41:20.790,0:41:27.030
it later. Now, to wrap things up, if[br]you'll take anything away from this talk,
0:41:27.030,0:41:33.723
I don't want it to be the crazy SQL[br]gymnastics or a bunch of CVE numbers. I
0:41:33.723,0:41:38.770
want it to be the following. Querying it[br]database might not be safe, whether if
0:41:38.770,0:41:44.660
it's across reboots or between users or[br]processes, querying a database might not
0:41:44.660,0:41:50.810
be safe with query hijacking. And now,[br]with query hijacking and query oriented
0:41:50.810,0:41:55.330
programing, these memory corruptions that[br]we can trigger can actually be reliably
0:41:55.330,0:42:00.170
exploited with nothing but SQL. We don't[br]need JavaScript anymore. We don't need
0:42:00.170,0:42:05.880
WebSQL. And we truly think that this is[br]just the tip of the iceberg. So far,
0:42:05.880,0:42:11.570
SQLite, super popular, yet it was only[br]assessed from the very narrow lands of
0:42:11.570,0:42:18.220
WebSQL, and as much as browser pwning is[br]exciting, SQLite has so much more
0:42:18.220,0:42:24.590
potential. So we do have some thoughts[br]about possible future work with this.
0:42:24.590,0:42:29.530
Obviously, something really cool to do[br]would be expanding our primitives to some
0:42:29.530,0:42:35.608
stronger primitives, right. We want to[br]gain things like absolute read and write.
0:42:35.608,0:42:43.510
And my sketchy POC exploit was pretty[br]silly because it had many constants in it,
0:42:43.510,0:42:49.080
like you've seen, but actually if you used[br]the internal function of SQLite, like, if
0:42:49.080,0:42:53.590
during the exploitation you use functions[br]like sqlite3_version(), you ask the
0:42:53.590,0:42:57.560
interpreter, what version are you, what[br]compile options where you compiled with,
0:42:57.560,0:43:03.530
you can dynamically build these QOP chains[br]as you go and actually target the specific
0:43:03.530,0:43:08.280
target environment that you are[br]exploiting. Like, actually utilizing the
0:43:08.280,0:43:12.090
fact that our exploit is a database, we[br]can create this really cool exploit
0:43:12.090,0:43:17.100
polyglot, and we think that these[br]techniques can be used to privilege
0:43:17.100,0:43:23.200
escalate so many situations, because the[br]developers never had it in mind that now,
0:43:23.200,0:43:28.240
we can take any database that is writeable[br]by a weak user and queried by a strong
0:43:28.240,0:43:36.020
user, and suddenly we can try to privilege[br]our escalation. Another cool thing to do
0:43:36.020,0:43:40.330
would be to note that many of the[br]primitives that I've shown you are not
0:43:40.330,0:43:44.710
exclusive to SQLite, right?[br]The pointer packing and unpacking and
0:43:44.710,0:43:49.740
heap spraying, and all these things are[br]not exclusive to SQLite. So it would be
0:43:49.740,0:43:53.580
really interesting to take these[br]primitives and see if we can go ahead and
0:43:53.580,0:44:00.070
exploit other memory corruption bugs in[br]different database engines.
0:44:00.070,0:44:02.421
Thank you very much.
0:44:02.421,0:44:09.430
Applause
0:44:09.430,0:44:13.543
Herald Angel: Omer Gull, thank you very[br]much. That gives us a lot of time for
0:44:13.543,0:44:18.412
questions. So we do have three microphones[br]here in the hall: Number one, Number two and
0:44:18.412,0:44:23.680
Number three, if you have questions,[br]please line up. Do we have some questions
0:44:23.680,0:44:31.140
from the net already? No. All right. Then[br]we're gonna start with microphone number
0:44:31.140,0:44:34.140
two.[br]Microphone two: Yeah. So the question is
0:44:34.140,0:44:42.520
regarding the hijacking of the CREATE [br]something. So you mentioned that at the
0:44:42.520,0:44:48.590
beginning of the research was assuming[br]that CREATE was the first order of
0:44:48.590,0:44:54.720
checking and then a space following the[br]CREATE word and then it could create all
0:44:54.720,0:44:59.880
of other things. Now, my question is, if[br]that was changed following your report,
0:44:59.880,0:45:06.910
because this seems like a way to expose[br]larger attack surface then. Well, most of
0:45:06.910,0:45:10.800
the other bugs. So I just wonder if they[br]changed. And I mean, what basically what
0:45:10.800,0:45:14.190
was the mitigation if and if that was all[br]of it?
0:45:14.190,0:45:18.280
Omer Gull: Yeah. So the escalate people,[br]we're really more concerned with specific
0:45:18.280,0:45:23.359
bugs and not exploitation techniques. And[br]this is really sad because we all know
0:45:23.359,0:45:27.270
that you can kill bugs, but exploitation[br]techniques is what sticks. So no, they
0:45:27.270,0:45:34.390
didn't change this verification. And[br]actually this validation of create space
0:45:34.390,0:45:38.740
was actually added not so long ago. Before[br]that, you can have any DDL statement
0:45:38.740,0:45:42.550
that you want. So the situation is not[br]really good over there.
0:45:42.550,0:45:46.331
Microphone two: Good for them and good[br]luck in the future. And that was the
0:45:46.331,0:45:49.061
question.[br]Herald Angel: All right. We head over to
0:45:49.061,0:45:52.250
microphone one, please.[br]Microphone one: Did you, maybe by
0:45:52.250,0:45:56.339
accident, attack a server which was used[br]for password stealing stealing?
0:45:56.339,0:46:00.223
Omer Gull: No, obviously, I would never do[br]that. I would never attack anyone. This is
0:46:00.223,0:46:04.170
just in our lab on POC. Right.[br]Microphone one: Thank you.
0:46:04.170,0:46:08.130
Omer Gull: Your passwords are safe with[br]the Stealers.
0:46:08.130,0:46:09.820
laughter
0:46:09.820,0:46:12.140
Herald Angel: Right. Nobody is queueing [br]anymore. Do we have questions from the
0:46:12.140,0:46:16.130
net? Nothing over there. Well, here we go.[br]Omer Gull: Thank you.
0:46:16.130,0:46:18.383
Herald Angel: Omer Gull, thank you very much.
0:46:18.383,0:46:20.786
applause
0:46:20.786,0:46:24.982
36c3 outro music
0:46:24.982,0:46:47.000
subtitles created by c3subtitles.de[br]in the year 2019. Join, and help us!