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!