[Script Info] Title: [Events] Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text Dialogue: 0,0:00:00.00,0:00:18.45,Default,,0000,0000,0000,,{\i1}36C3 preroll music{\i0} Dialogue: 0,0:00:18.45,0:00:25.16,Default,,0000,0000,0000,,Herald Angel: On my left, I have Omer\NGull, and Omer Gull is gonna tell us - A Dialogue: 0,0:00:25.16,0:00:33.09,Default,,0000,0000,0000,,SELECT code_execution FROM * USING SQLite.\NOmer, Omer Gull, that's your talk, your stage, have fun! Dialogue: 0,0:00:33.09,0:00:42.19,Default,,0000,0000,0000,,Omer Gull: Thank you. Thank you. Hello,\Neveryone. Welcome to my talk, SELECT code Dialogue: 0,0:00:42.19,0:00:49.11,Default,,0000,0000,0000,,execution from just about anything using\NSQLite, where we will gain code execution Dialogue: 0,0:00:49.11,0:00:54.44,Default,,0000,0000,0000,,using malicious SQLite databases. So my\Nname is Omer Gull. I'm a vulnerability Dialogue: 0,0:00:54.44,0:00:59.56,Default,,0000,0000,0000,,researcher from Tel Aviv. I've been\Nworking in Check Point Research for the Dialogue: 0,0:00:59.56,0:01:05.96,Default,,0000,0000,0000,,past three years, and I've recently moved\Non to a new startup called Hunters.AI. Dialogue: 0,0:01:05.96,0:01:11.41,Default,,0000,0000,0000,,Our agenda for today: So we'll start with a\Nlittle motivation and the backstory for Dialogue: 0,0:01:11.41,0:01:18.14,Default,,0000,0000,0000,,this research. Then we'll have a brief\NSQLite introduction, and we'll examine the Dialogue: 0,0:01:18.14,0:01:22.76,Default,,0000,0000,0000,,attack surface given to a malicious\Ndatabase. Then we will discuss some Dialogue: 0,0:01:22.76,0:01:29.36,Default,,0000,0000,0000,,previous work done in the field of SQLite\Nexploitation and think about exploiting Dialogue: 0,0:01:29.36,0:01:36.23,Default,,0000,0000,0000,,memory corruption bugs, using nothing but\Npure SQL. We'll then demonstrate our own Dialogue: 0,0:01:36.23,0:01:41.45,Default,,0000,0000,0000,,innovative technique, called "Query\NOriented Programing", or QOP, and take it Dialogue: 0,0:01:41.45,0:01:47.93,Default,,0000,0000,0000,,for a spin in a couple of demos. We'll\Nwrap things up with some future work Dialogue: 0,0:01:47.93,0:01:54.20,Default,,0000,0000,0000,,possibilities and some conclusion. So the\Nmotivation for this research is quite Dialogue: 0,0:01:54.20,0:02:00.65,Default,,0000,0000,0000,,obvious. SQLite is one of the most\Ndeployed pieces of software out there. Dialogue: 0,0:02:00.65,0:02:08.00,Default,,0000,0000,0000,,Whether it's PHP 5, PHP 7, Android, iOS,\NMac OS, it is now built into Windows 10. Dialogue: 0,0:02:08.00,0:02:14.38,Default,,0000,0000,0000,,It's in Firefox and Chrome. This list\Ncould continue forever. Yet querying an Dialogue: 0,0:02:14.38,0:02:20.31,Default,,0000,0000,0000,,SQLite database is considered safe.\NHopefully, by the end of this talk, you Dialogue: 0,0:02:20.31,0:02:27.29,Default,,0000,0000,0000,,will realize why this is not necessarily\Nthe case. So, it all began with password Dialogue: 0,0:02:27.29,0:02:32.02,Default,,0000,0000,0000,,stealers, which is pretty strange, and\Nthere are many, many password stealers in Dialogue: 0,0:02:32.02,0:02:37.68,Default,,0000,0000,0000,,the wild, but the story is usually the\Nsame. First of all, a computer gets Dialogue: 0,0:02:37.68,0:02:43.17,Default,,0000,0000,0000,,infected. Then some malware collects the\Nstorage credentials, as they are Dialogue: 0,0:02:43.17,0:02:48.51,Default,,0000,0000,0000,,maintained by various clients. Now, some\Nof these clients actually store your Dialogue: 0,0:02:48.51,0:02:55.09,Default,,0000,0000,0000,,secrets within SQLite databases. So the\Nmalware just ships these SQLite databases Dialogue: 0,0:02:55.09,0:03:01.76,Default,,0000,0000,0000,,to its C2 server, where the secrets are\Nextracted and stored within a collective Dialogue: 0,0:03:01.76,0:03:07.74,Default,,0000,0000,0000,,database with the rest of the loot. So,\None day, my colleague and I, Omri, we were Dialogue: 0,0:03:07.74,0:03:13.21,Default,,0000,0000,0000,,looking at the leaked sources of a very\Nwell known password stealers. Then we Dialogue: 0,0:03:13.21,0:03:17.93,Default,,0000,0000,0000,,thought to ourself: "These guys are just\Nharvesting a bunch of our databases and Dialogue: 0,0:03:17.93,0:03:24.70,Default,,0000,0000,0000,,parse them in their own backend. Can we\Nactually leverage the load and query of an Dialogue: 0,0:03:24.70,0:03:30.36,Default,,0000,0000,0000,,untrusted database to our advantage?" And\Nif we could, this could have much bigger Dialogue: 0,0:03:30.36,0:03:37.30,Default,,0000,0000,0000,,implications, just because SQLite is used\Nin countless scenarios. And so began the Dialogue: 0,0:03:37.30,0:03:46.32,Default,,0000,0000,0000,,longest CTF challenge of my life so far.\NSo, SQLite. Unlike most SQL databases, Dialogue: 0,0:03:46.32,0:03:52.74,Default,,0000,0000,0000,,SQLite does not have that client server\Narchitecture. Instead, it simply reads and Dialogue: 0,0:03:52.74,0:03:58.63,Default,,0000,0000,0000,,write files directly to the file system.\NSo, you have one complete database, with Dialogue: 0,0:03:58.63,0:04:03.34,Default,,0000,0000,0000,,multiple tables, and indices, and\Ntriggers, and views, and everything is Dialogue: 0,0:04:03.34,0:04:09.66,Default,,0000,0000,0000,,contained within the single file. So let's\Nexamine the attack surface given to a Dialogue: 0,0:04:09.66,0:04:15.24,Default,,0000,0000,0000,,potentially malicious SQLite database. So\Nagain, this is a snippet of code, of a Dialogue: 0,0:04:15.24,0:04:21.40,Default,,0000,0000,0000,,very well known password stealer, and we\Nhave two main points of interest here: Dialogue: 0,0:04:21.40,0:04:26.43,Default,,0000,0000,0000,,First of all, we have sqlite3_open, where\Nour potentially malicious database is Dialogue: 0,0:04:26.43,0:04:32.18,Default,,0000,0000,0000,,loaded, and some parsing is going on. And,\Nobviously, we have the query itself, Dialogue: 0,0:04:32.18,0:04:36.95,Default,,0000,0000,0000,,right? The SELECT statement. Now, do note\Nthat we have no control over that Dialogue: 0,0:04:36.95,0:04:41.02,Default,,0000,0000,0000,,statement, right. It is hardcoded within\Nour target. It tries to extract the Dialogue: 0,0:04:41.02,0:04:47.16,Default,,0000,0000,0000,,secrets out of our database. Yet we do\Ncontrol the content, so we might have some Dialogue: 0,0:04:47.16,0:04:52.32,Default,,0000,0000,0000,,effect on what's going on there, right.\NSo, starting with the first point, the Dialogue: 0,0:04:52.32,0:04:58.10,Default,,0000,0000,0000,,sqlite3_open. This is just a bunch of\Nsetup and configuration code. Then we move Dialogue: 0,0:04:58.10,0:05:03.11,Default,,0000,0000,0000,,on to really straightforward header\Nparsing, and the header itself is not that Dialogue: 0,0:05:03.11,0:05:10.42,Default,,0000,0000,0000,,long, just 100 bytes. And thirdly, it was\Nalready fuzzed to death by AFL. So it's Dialogue: 0,0:05:10.42,0:05:17.23,Default,,0000,0000,0000,,probably not a very promising path to\Npursue. But the SEL- the sqlite3_query Dialogue: 0,0:05:17.23,0:05:22.45,Default,,0000,0000,0000,,might be a bit more interesting, because\Nusing SQLite author's words, "The SELECT Dialogue: 0,0:05:22.45,0:05:29.16,Default,,0000,0000,0000,,statement is the most complicated command\Nin the SQL language". Now, you might be Dialogue: 0,0:05:29.16,0:05:36.31,Default,,0000,0000,0000,,aware that behind the scenes, SQLite is a\Nvirtual machine. So every query must first Dialogue: 0,0:05:36.31,0:05:42.26,Default,,0000,0000,0000,,be compiled to some proprietary bytecode.\NAnd this is also known as the preparation Dialogue: 0,0:05:42.26,0:05:48.14,Default,,0000,0000,0000,,step. So sqlite3_prepare would walk and\Nexpand the query. So, for example, every Dialogue: 0,0:05:48.14,0:05:56.08,Default,,0000,0000,0000,,time you select an asterisk, it simply\Nrewrite this asterisk as all column names. Dialogue: 0,0:05:56.08,0:06:02.06,Default,,0000,0000,0000,,So, sqlite3LocateTable will actually\Nverified that all the relevant objects Dialogue: 0,0:06:02.06,0:06:07.29,Default,,0000,0000,0000,,that you are querying actually exist, and\Nwill locate them in memory. Where does it Dialogue: 0,0:06:07.29,0:06:13.59,Default,,0000,0000,0000,,locate them? So, every SQLite database has\Na table called sqlite_master, and this is Dialogue: 0,0:06:13.59,0:06:20.14,Default,,0000,0000,0000,,actually the schema that is defining the\Ndatabase. And this is its structure. So, Dialogue: 0,0:06:20.14,0:06:25.57,Default,,0000,0000,0000,,for every object in the database, you have\Nan entry, so its type, like whether it's a Dialogue: 0,0:06:25.57,0:06:32.12,Default,,0000,0000,0000,,table or view, and its name, and at the\Nvery bottom you can see something called Dialogue: 0,0:06:32.12,0:06:40.57,Default,,0000,0000,0000,,SQL. And SQL is actually the DDL that is\Ndescribing the object. And DDL stands for Dialogue: 0,0:06:40.57,0:06:46.51,Default,,0000,0000,0000,,data definition language, and you can sort\Nof look at it like header files in C. So, Dialogue: 0,0:06:46.51,0:06:51.76,Default,,0000,0000,0000,,they are used to define the structures,\Nand names, and types of the objects within Dialogue: 0,0:06:51.76,0:06:57.75,Default,,0000,0000,0000,,the database. Furthermore, they appear in\Nplaintext within the file. So, let me show Dialogue: 0,0:06:57.75,0:07:02.95,Default,,0000,0000,0000,,you an example. Here I opened the SQLite\Ninterpreter, I create a table, and I Dialogue: 0,0:07:02.95,0:07:08.36,Default,,0000,0000,0000,,insert some values into it. Then I quit\Nthe interpreter, and now I hex dump the Dialogue: 0,0:07:08.36,0:07:15.17,Default,,0000,0000,0000,,file that was created. And you can see,\Nhighlighted in yellow, the DDL statement Dialogue: 0,0:07:15.17,0:07:20.04,Default,,0000,0000,0000,,that is part of the master schema. And at\Nthe very bottom, you can also see the Dialogue: 0,0:07:20.04,0:07:25.90,Default,,0000,0000,0000,,values. So, let's go back to query\Npreparation. We have sqlite3LocateTable Dialogue: 0,0:07:25.90,0:07:31.11,Default,,0000,0000,0000,,that attempts to find the structure that\Nis describing the table that we are Dialogue: 0,0:07:31.11,0:07:36.64,Default,,0000,0000,0000,,interested in querying. So it goes on and\Nreads the schema available in Dialogue: 0,0:07:36.64,0:07:41.12,Default,,0000,0000,0000,,sqlite_master that we just described. And\Nif it's the first time that it is doing Dialogue: 0,0:07:41.12,0:07:47.64,Default,,0000,0000,0000,,so, it has some callback function for\Nevery of these DDL statements. The Dialogue: 0,0:07:47.64,0:07:53.17,Default,,0000,0000,0000,,callback function would actually validate\Nthe DDL, and then it will go on and build Dialogue: 0,0:07:53.17,0:07:58.19,Default,,0000,0000,0000,,the internal structures of the object in\Nquestion. So then we thought about the Dialogue: 0,0:07:58.19,0:08:06.22,Default,,0000,0000,0000,,concept of DDL patching. What if I simply\Nreplace the SQL query within the DDL? So Dialogue: 0,0:08:06.22,0:08:10.60,Default,,0000,0000,0000,,it turns out that there is a slight\Nproblem with it. And this is the callback Dialogue: 0,0:08:10.60,0:08:16.47,Default,,0000,0000,0000,,function that I mentioned earlier, and as\Nyou can tell, the DDL is first verified to Dialogue: 0,0:08:16.47,0:08:23.21,Default,,0000,0000,0000,,begin with "CREATE ". And only if it does\Nthen we continue with the preparation. So, Dialogue: 0,0:08:23.21,0:08:28.97,Default,,0000,0000,0000,,this is definitely a constraint, right?\NOur DDL must begin with "CREATE ". Yet it Dialogue: 0,0:08:28.97,0:08:35.03,Default,,0000,0000,0000,,does leave some room for flexibility,\Nbecause judging by SQLite documentation, Dialogue: 0,0:08:35.03,0:08:40.74,Default,,0000,0000,0000,,many things can be created. We can create\Nindexes, and tables, and triggers, and Dialogue: 0,0:08:40.74,0:08:46.56,Default,,0000,0000,0000,,views, and something we still don't quite\Nunderstand, called virtual tables. So, Dialogue: 0,0:08:46.56,0:08:53.28,Default,,0000,0000,0000,,then we thought about "CREATE VIEW",\Nbecause view is simply a pre-packaged Dialogue: 0,0:08:53.28,0:08:59.76,Default,,0000,0000,0000,,SELECT statement, and views are queried\Nvery similarly to tables. So, selecting a Dialogue: 0,0:08:59.76,0:09:04.84,Default,,0000,0000,0000,,column out of a table is semantically\Nequivalent to selecting a column out of a Dialogue: 0,0:09:04.84,0:09:10.71,Default,,0000,0000,0000,,view. Then when we thought about the\Nconcept of query hijacking. We are going Dialogue: 0,0:09:10.71,0:09:16.70,Default,,0000,0000,0000,,to patch sqlite_master DDL with views\Ninstead of tables. Now our patched views Dialogue: 0,0:09:16.70,0:09:22.68,Default,,0000,0000,0000,,can actually have any SELECT subquery that\Nwe wish. And now with this subquery I can Dialogue: 0,0:09:22.68,0:09:26.64,Default,,0000,0000,0000,,suddenly interact with the SQLite\Ninterpreter. And this is a huge step Dialogue: 0,0:09:26.64,0:09:31.79,Default,,0000,0000,0000,,forward! We just turned an uncontrollable\Nquery to something that we have some Dialogue: 0,0:09:31.79,0:09:38.11,Default,,0000,0000,0000,,control over. So let me show you query\Nhijacking by example. So let's say that Dialogue: 0,0:09:38.11,0:09:43.71,Default,,0000,0000,0000,,some original database had a single table,\Nand this is the DDL that is defining it. Dialogue: 0,0:09:43.71,0:09:49.13,Default,,0000,0000,0000,,So it's called "dummy" and it has two\Ncolumns. So, obviously any target software Dialogue: 0,0:09:49.13,0:09:53.39,Default,,0000,0000,0000,,would try to query it in the following\Nway: It would just try to select these Dialogue: 0,0:09:53.39,0:09:58.31,Default,,0000,0000,0000,,columns out of the table, right. Yet the\Nfollowing view can actually hijack this Dialogue: 0,0:09:58.31,0:10:03.28,Default,,0000,0000,0000,,query. I create a view, it has just the\Nsame name, and just the same amount of Dialogue: 0,0:10:03.28,0:10:08.22,Default,,0000,0000,0000,,columns, and each column is named just the\Nsame way, and you can see that now every Dialogue: 0,0:10:08.22,0:10:13.80,Default,,0000,0000,0000,,column can have any sub query that I wish,\Nhighlighted in blue at the bottom. So Dialogue: 0,0:10:13.80,0:10:18.57,Default,,0000,0000,0000,,again, let me show you a practical example\Nof it. Here, I created a view called Dialogue: 0,0:10:18.57,0:10:23.90,Default,,0000,0000,0000,,"dummy" with cola and colb, and the first\Ncolumn is utilizing the sqlite_version() Dialogue: 0,0:10:23.90,0:10:28.34,Default,,0000,0000,0000,,function, and that's a built in function\Nthat simply returns the SQLite version, Dialogue: 0,0:10:28.34,0:10:35.42,Default,,0000,0000,0000,,obviously. The second column is utilizing\NSQLite's own implementation of printf. Dialogue: 0,0:10:35.42,0:10:40.03,Default,,0000,0000,0000,,That's right, they have all these really\Nsurprising features and capabilities. So, Dialogue: 0,0:10:40.03,0:10:46.15,Default,,0000,0000,0000,,let's see that from the supposedly - from\Nthe target side. So, anyone trying to Dialogue: 0,0:10:46.15,0:10:51.89,Default,,0000,0000,0000,,select out of these column, is suddenly\Nexecuting our functions. So, at the left Dialogue: 0,0:10:51.89,0:10:57.18,Default,,0000,0000,0000,,you can see the SQLite version, and on the\Nright you can see the printf that was Dialogue: 0,0:10:57.18,0:11:02.12,Default,,0000,0000,0000,,executed on the target side. So again,\Nthis is a huge step forward. We just Dialogue: 0,0:11:02.12,0:11:08.76,Default,,0000,0000,0000,,gained some control over that query,\Nright. And the question is, what can we do Dialogue: 0,0:11:08.76,0:11:15.44,Default,,0000,0000,0000,,with this control? Does SQLite have any\Nsystem commands? Can maybe - maybe we can Dialogue: 0,0:11:15.44,0:11:23.36,Default,,0000,0000,0000,,read and write to some other files on the\Nfile system. So, this was a good point to Dialogue: 0,0:11:23.36,0:11:28.38,Default,,0000,0000,0000,,stop and look at some previous work done\Nin the field, because obviously, we are Dialogue: 0,0:11:28.38,0:11:34.53,Default,,0000,0000,0000,,not the first to notice SQLite's huge\Npotential, in terms of exploitation. A Dialogue: 0,0:11:34.53,0:11:39.17,Default,,0000,0000,0000,,reasonable place to start is SQLite\Ninjection, because this is sort of a Dialogue: 0,0:11:39.17,0:11:45.54,Default,,0000,0000,0000,,similar scenario, right? Someone malicious\Nhas some control on an SQL query. So, Dialogue: 0,0:11:45.54,0:11:51.55,Default,,0000,0000,0000,,there are a couple of known tricks in SQL\Ninjection with SQLite. The first one has Dialogue: 0,0:11:51.55,0:11:56.45,Default,,0000,0000,0000,,something to do with attaching another\Ndatabase, and then creating a table, and Dialogue: 0,0:11:56.45,0:12:01.39,Default,,0000,0000,0000,,inserting some strings into it. And\Nbecause, as I mentioned earlier, every - Dialogue: 0,0:12:01.39,0:12:06.92,Default,,0000,0000,0000,,every database is just a file, so this is\Nsomewhat of an arbitrary file, right, on Dialogue: 0,0:12:06.92,0:12:11.49,Default,,0000,0000,0000,,the file system. Yet we do have this\Nconstraint, if you remember, that we can't Dialogue: 0,0:12:11.49,0:12:17.73,Default,,0000,0000,0000,,ATTACH, because our DDL must begin with\N"CREATE". Another cool trick is abusing Dialogue: 0,0:12:17.73,0:12:23.74,Default,,0000,0000,0000,,the load extension function. And here you\Ncan see how you can potentially load a Dialogue: 0,0:12:23.74,0:12:28.16,Default,,0000,0000,0000,,remote DLL. In this case, the\Nmeterpreter.dll, but obviously this very Dialogue: 0,0:12:28.16,0:12:35.10,Default,,0000,0000,0000,,dangerous function is disabled by default.\NSo again, no go. What about memory Dialogue: 0,0:12:35.10,0:12:42.29,Default,,0000,0000,0000,,corruption in SQLite, because SQLite is\Nreally complex and it's all written in C. Dialogue: 0,0:12:42.29,0:12:48.20,Default,,0000,0000,0000,,So in his amazing blog post "Finding Bugs\Nin SQLite, the easy way", Michal Zalewski, Dialogue: 0,0:12:48.20,0:12:54.87,Default,,0000,0000,0000,,the author of AFL, described how he found\N22 bugs in just under 30 minutes of Dialogue: 0,0:12:54.87,0:13:01.79,Default,,0000,0000,0000,,fuzzing. And actually, since then, since\Nthat was version 3.8.10, that was in 2015, Dialogue: 0,0:13:01.79,0:13:06.84,Default,,0000,0000,0000,,SQLite actually started using AFL as an\Nintegral part of the remarkable test Dialogue: 0,0:13:06.84,0:13:11.69,Default,,0000,0000,0000,,suite. Yet these memory corruption bugs\Nall proved to be really difficult to Dialogue: 0,0:13:11.69,0:13:16.61,Default,,0000,0000,0000,,exploit without some convenient\Nenvironment. Yet, the security research Dialogue: 0,0:13:16.61,0:13:25.30,Default,,0000,0000,0000,,community soon found the perfect target,\Nand it was called WebSQL. So, WebSQL is Dialogue: 0,0:13:25.30,0:13:30.24,Default,,0000,0000,0000,,essentially an API for storing data in\Ndatabases, and it is queried from Dialogue: 0,0:13:30.24,0:13:36.24,Default,,0000,0000,0000,,JavaScript and it has an SQLite backend.\NAlso, it is available in Chrome and Dialogue: 0,0:13:36.24,0:13:41.99,Default,,0000,0000,0000,,Safari. So here you can see a very simple\Nexample of how to interact with WebSQL Dialogue: 0,0:13:41.99,0:13:51.10,Default,,0000,0000,0000,,from JavaScript. But in other words, what\NI'm hearing here is that we have some Dialogue: 0,0:13:51.10,0:13:56.24,Default,,0000,0000,0000,,untrusted input to SQLite and it is\Nreachable from any website on the Internet Dialogue: 0,0:13:56.24,0:14:02.35,Default,,0000,0000,0000,,in two of the world's most popular\Nbrowsers. And suddenly these bugs, these Dialogue: 0,0:14:02.35,0:14:07.04,Default,,0000,0000,0000,,memory corruptions can now be leveraged\Nwith the knowledge and - with the Dialogue: 0,0:14:07.04,0:14:10.76,Default,,0000,0000,0000,,knowledge and comfort of JavaScript\Nexploitation, right. The JavaScript Dialogue: 0,0:14:10.76,0:14:16.20,Default,,0000,0000,0000,,interpreter exploitation that we got, we\Ngot pretty good over the years. So there Dialogue: 0,0:14:16.20,0:14:20.42,Default,,0000,0000,0000,,have been really several really impressive\Nresearch that were published regarding Dialogue: 0,0:14:20.42,0:14:28.61,Default,,0000,0000,0000,,WebSQL from really low hanging fruits like\NCVE-2015-7036, that was an untrusted Dialogue: 0,0:14:28.61,0:14:35.19,Default,,0000,0000,0000,,pointer dereference in the fts3_tokenizer(),\Nto some more complex exploit as presented Dialogue: 0,0:14:35.19,0:14:40.84,Default,,0000,0000,0000,,in Blackhat 2017 by the awesome Chaitin\Nteam, that found a type confusion in the Dialogue: 0,0:14:40.84,0:14:46.48,Default,,0000,0000,0000,,FTS optimizer, to the very recent Magellan\Nbugs found and exploited by Tencent, that Dialogue: 0,0:14:46.48,0:14:52.35,Default,,0000,0000,0000,,found an integer overflow in the FTS\Nsegment reader. And if you are paying even Dialogue: 0,0:14:52.35,0:14:58.08,Default,,0000,0000,0000,,a tiny bit of attention by now, you must\Nsee an interesting pattern arises. All Dialogue: 0,0:14:58.08,0:15:04.76,Default,,0000,0000,0000,,these vulnerable functions start with FTS.\NSo what is FTS? I have never heard of it. Dialogue: 0,0:15:04.76,0:15:11.58,Default,,0000,0000,0000,,And actually googling it just left me more\Nconfused. After some time, I came to the Dialogue: 0,0:15:11.58,0:15:17.56,Default,,0000,0000,0000,,realization that FTS stands for "full text\Nsearch", and it is something called a Dialogue: 0,0:15:17.56,0:15:22.84,Default,,0000,0000,0000,,virtual table module and it allows for\Nsome really cool textual search on a set Dialogue: 0,0:15:22.84,0:15:28.26,Default,,0000,0000,0000,,of documents. Or like the SQLite authors\Ndescribed it, It's "like Google for your Dialogue: 0,0:15:28.26,0:15:33.70,Default,,0000,0000,0000,,SQlite databases". So virtual tables allow\Nfor some pretty cool functionality in Dialogue: 0,0:15:33.70,0:15:39.41,Default,,0000,0000,0000,,SQLite, whether it's this free text search\Nor a virtual table module called RTREE, Dialogue: 0,0:15:39.41,0:15:44.75,Default,,0000,0000,0000,,that does some really clever geographical\Nindexing, or a virtual table called CSV, Dialogue: 0,0:15:44.75,0:15:50.06,Default,,0000,0000,0000,,that lets you treat your database as a CSV\Nfile. And these virtual tables are Dialogue: 0,0:15:50.06,0:15:55.97,Default,,0000,0000,0000,,actually queried just like regular tables.\NYet behind the scenes, some dark magic Dialogue: 0,0:15:55.97,0:16:02.35,Default,,0000,0000,0000,,happens. And after every query, there is\Nsome callback function that is invoked and Dialogue: 0,0:16:02.35,0:16:07.37,Default,,0000,0000,0000,,it works on something called shadow\Ntables. Now, shadow tables would be best Dialogue: 0,0:16:07.37,0:16:13.80,Default,,0000,0000,0000,,explained by example. So let's say that I\Ncreate a virtual table using that FTS Dialogue: 0,0:16:13.80,0:16:19.91,Default,,0000,0000,0000,,virtual table module and I insert a string\Ninto it. Now, obviously, to allow for some Dialogue: 0,0:16:19.91,0:16:23.98,Default,,0000,0000,0000,,efficient search, I need to have some\Nmetadata, right? I need to have some Dialogue: 0,0:16:23.98,0:16:28.65,Default,,0000,0000,0000,,offsets or indexes or tokens or stuff like\Nthat. So - and obviously they're all text, Dialogue: 0,0:16:28.65,0:16:35.31,Default,,0000,0000,0000,,right? So that one virtual table is\Nactually, it's raw text, and metadata is Dialogue: 0,0:16:35.31,0:16:40.62,Default,,0000,0000,0000,,stored among three shadow tables. So the\Nraw text would go to vt_content and the Dialogue: 0,0:16:40.62,0:16:46.05,Default,,0000,0000,0000,,metadata would go to vt_segments and\Nvt_segdir. And in time, these shadow Dialogue: 0,0:16:46.05,0:16:51.74,Default,,0000,0000,0000,,tables actually have interfaces passing\Ninformation between them, right. Because Dialogue: 0,0:16:51.74,0:16:55.68,Default,,0000,0000,0000,,the metadata is storing all these\Npointers, so you need to pass them between Dialogue: 0,0:16:55.68,0:17:01.50,Default,,0000,0000,0000,,each other. And these interfaces proved to\Nbe really, really trusting in their Dialogue: 0,0:17:01.50,0:17:09.59,Default,,0000,0000,0000,,nature. And it makes them a really fertile\Nground for bug hunting. So let me show you Dialogue: 0,0:17:09.59,0:17:15.82,Default,,0000,0000,0000,,a bug that I found in the RTREE virtual\Ntable module. So, RTREE virtual table Dialogue: 0,0:17:15.82,0:17:20.59,Default,,0000,0000,0000,,module is available now in MacOS and iOS,\Nand it's really cool because now it's also Dialogue: 0,0:17:20.59,0:17:24.89,Default,,0000,0000,0000,,built into Windows 10. And as I've\Nmentioned, it does some really clever Dialogue: 0,0:17:24.89,0:17:31.40,Default,,0000,0000,0000,,geographical indexing. Now, the DDL is\Nsupposed to be the following. Any RTREE Dialogue: 0,0:17:31.40,0:17:37.02,Default,,0000,0000,0000,,virtual table is supposed to begin with\N"id", that needs to be an integer. Then Dialogue: 0,0:17:37.02,0:17:41.97,Default,,0000,0000,0000,,you have some X and Y coordinates. So\Nobviously every RTREE interface would Dialogue: 0,0:17:41.97,0:17:48.25,Default,,0000,0000,0000,,expect "id" to be an integer. But if I\Ncreate a virtual table and I insert into Dialogue: 0,0:17:48.25,0:17:53.97,Default,,0000,0000,0000,,"id" something that is definitely not an\Ninteger, then I use one of these RTREE Dialogue: 0,0:17:53.97,0:17:59.56,Default,,0000,0000,0000,,interfaces, rtreenode at the very bottom,\Nyou see that we got this crash, this out- Dialogue: 0,0:17:59.56,0:18:08.59,Default,,0000,0000,0000,,of-bounds read on the heap. And this\Nexample is a crash in Windows 10. So Dialogue: 0,0:18:08.59,0:18:15.04,Default,,0000,0000,0000,,that's pretty good. We have established\Nthat virtual table has bugs. And now, Dialogue: 0,0:18:15.04,0:18:21.26,Default,,0000,0000,0000,,using query hijacking technique, we can\Nsuddenly trigger these bugs on our target, Dialogue: 0,0:18:21.26,0:18:26.44,Default,,0000,0000,0000,,which is a C2 of the password stealer, and\Nwill cause it to segfault. And this is Dialogue: 0,0:18:26.44,0:18:32.12,Default,,0000,0000,0000,,nice, but actually gaining flow control\Nover our target requires us to have some Dialogue: 0,0:18:32.12,0:18:37.48,Default,,0000,0000,0000,,form of scripting, right? We want to\Nbypass ASLR and do all these crazy things. Dialogue: 0,0:18:37.48,0:18:42.39,Default,,0000,0000,0000,,Yet we don't have JavaScript, we don't\Nhave JavaScript arrays and variables and, Dialogue: 0,0:18:42.39,0:18:48.32,Default,,0000,0000,0000,,like, logic statements, like if and and\Nloops and stuff like that. However, we do Dialogue: 0,0:18:48.32,0:18:54.58,Default,,0000,0000,0000,,vaguely recall hearing somewhere that SQL\Nis turing complete. So we decided to put Dialogue: 0,0:18:54.58,0:19:00.78,Default,,0000,0000,0000,,it to the test from exploitation\Nperspective, and we started creating our Dialogue: 0,0:19:00.78,0:19:06.58,Default,,0000,0000,0000,,own primitive wish list for exploitation.\NSo if it would create a full exploit Dialogue: 0,0:19:06.58,0:19:11.08,Default,,0000,0000,0000,,exploiting memory corruption bugs with\Nnothing but SQL, what capabilities do we Dialogue: 0,0:19:11.08,0:19:16.16,Default,,0000,0000,0000,,want? So, obviously, to bypass ASLR and\Nthese kind of things, we want to leak some Dialogue: 0,0:19:16.16,0:19:21.04,Default,,0000,0000,0000,,memory. We need to have an info leak. And\Nif you've done any pwning in your past, Dialogue: 0,0:19:21.04,0:19:27.19,Default,,0000,0000,0000,,you must be familiar with really common\Ntasks like unpacking 64-bit pointers and Dialogue: 0,0:19:27.19,0:19:31.19,Default,,0000,0000,0000,,doing some pointer arithmetics, right?\NBecause we had an info leak, we converted Dialogue: 0,0:19:31.19,0:19:35.70,Default,,0000,0000,0000,,- we read this pointer, and it's a little\Nendian and so we need to flip it, and now Dialogue: 0,0:19:35.70,0:19:40.03,Default,,0000,0000,0000,,we want to calculate, let's say where's\Nthe base of libsqlite so we can find some Dialogue: 0,0:19:40.03,0:19:45.65,Default,,0000,0000,0000,,more functions maybe. So we need some\Npointer arithmetics. Obviously, after Dialogue: 0,0:19:45.65,0:19:50.72,Default,,0000,0000,0000,,reading pointers and manipulating them, we\Nwant to pack them again and write them Dialogue: 0,0:19:50.72,0:19:57.71,Default,,0000,0000,0000,,somewhere. Obviously, writing a single\Npointer is never enough. We want to create Dialogue: 0,0:19:57.71,0:20:03.14,Default,,0000,0000,0000,,fake objects in memory, like more complex\Nobjects than this one pointer. And Dialogue: 0,0:20:03.14,0:20:08.09,Default,,0000,0000,0000,,finally, we would like to heap spray\Nbecause this might be really useful. So, Dialogue: 0,0:20:08.09,0:20:13.23,Default,,0000,0000,0000,,the question remains, can all this\Nexploitation be done with nothing but SQL? Dialogue: 0,0:20:13.23,0:20:19.02,Default,,0000,0000,0000,,So, the answer is "yes, it is". And I\Nproudly present to you Query Oriented Dialogue: 0,0:20:19.02,0:20:25.86,Default,,0000,0000,0000,,Programing, or QOP. And to demonstrate\NQOP, we are going to exploit the unfixed Dialogue: 0,0:20:25.86,0:20:37.36,Default,,0000,0000,0000,,CVE-2015-7036. And you might ask yourself\N"What? How come a four year old bug is Dialogue: 0,0:20:37.36,0:20:44.39,Default,,0000,0000,0000,,still unfixed?" And this is a great point\Nto our argument. This CVE was only ever Dialogue: 0,0:20:44.39,0:20:50.45,Default,,0000,0000,0000,,considered dangerous in the context of\Nuntrusted WebSQL. So it was mitigated Dialogue: 0,0:20:50.45,0:20:55.21,Default,,0000,0000,0000,,accordingly, right. It is blacklisted\Nunless SQLite is compiled with is certain Dialogue: 0,0:20:55.21,0:20:59.91,Default,,0000,0000,0000,,flag. So, obviously browsers are not\Ncompiled with this flag anymore. But let Dialogue: 0,0:20:59.91,0:21:04.74,Default,,0000,0000,0000,,me show you who is compiled with this\Nflag. So, we have PHP 5 and PHP 7, in Dialogue: 0,0:21:04.74,0:21:09.34,Default,,0000,0000,0000,,charge on most of the Internet, and iOS\Nand MacOS and probably so many other Dialogue: 0,0:21:09.34,0:21:15.26,Default,,0000,0000,0000,,targets that we just didn't have the time\Nto go over. So, let's explain this Dialogue: 0,0:21:15.26,0:21:20.78,Default,,0000,0000,0000,,vulnerability a little bit. I've mentioned\Nthat it's in the FTS tokenizer. So, a Dialogue: 0,0:21:20.78,0:21:26.83,Default,,0000,0000,0000,,tokenizer is just a set of rules to\Nextract terms from documents or queries. Dialogue: 0,0:21:26.83,0:21:32.68,Default,,0000,0000,0000,,And the default tokanizer, that is named\N"simple", just split the strings by Dialogue: 0,0:21:32.68,0:21:38.82,Default,,0000,0000,0000,,whitespaces. However, if you like, you can\Nregister your own custom tokenizer. You Dialogue: 0,0:21:38.82,0:21:43.89,Default,,0000,0000,0000,,can just pass a C function and you\Nactually register this custom tokenizer Dialogue: 0,0:21:43.89,0:21:50.02,Default,,0000,0000,0000,,with the function fts3_tokenizer() in an\NSQL query. This is a bit where it's all Dialogue: 0,0:21:50.02,0:21:55.93,Default,,0000,0000,0000,,repeated slowly. You pass a row pointer\Nto a C function in an SQL query. This is Dialogue: 0,0:21:55.93,0:22:01.39,Default,,0000,0000,0000,,absolutely insane. To be honest, after\Nstudying this for quite a while, I still Dialogue: 0,0:22:01.39,0:22:06.02,Default,,0000,0000,0000,,don't understand how to use this feature\Noutside of my exploit. Dialogue: 0,0:22:06.02,0:22:15.65,Default,,0000,0000,0000,,{\i1}audience laughing{\i0}\N{\i1}clapping{\i0} Dialogue: 0,0:22:15.65,0:22:17.64,Default,,0000,0000,0000,,So fts3_tokenizer() Dialogue: 0,0:22:17.64,0:22:22.80,Default,,0000,0000,0000,,is actually an overloaded function, and if\Nyou call it with one argument that is the Dialogue: 0,0:22:22.80,0:22:28.23,Default,,0000,0000,0000,,name of a tokenizer, you get back the\Naddress of that tokenizer, and to make it Dialogue: 0,0:22:28.23,0:22:34.76,Default,,0000,0000,0000,,a bit more human readable, or somewhat\Nhuman, we'll use the hex decoder. And you Dialogue: 0,0:22:34.76,0:22:40.21,Default,,0000,0000,0000,,can now see that we actually got an info\Nleak to libsqlite3. Now, because it's Dialogue: 0,0:22:40.21,0:22:43.39,Default,,0000,0000,0000,,little endian, so it's the other way\Naround, so we need to reverse it, but this Dialogue: 0,0:22:43.39,0:22:48.23,Default,,0000,0000,0000,,is already pretty cool. If you call\Nfts3_tokenizer() with two arguments, the Dialogue: 0,0:22:48.23,0:22:53.16,Default,,0000,0000,0000,,first one being a name of a tokenizer, and\Nthe second one, again, is a row pointer, Dialogue: 0,0:22:53.16,0:22:58.43,Default,,0000,0000,0000,,this is absolutely insane, you rewrite the\Naddress of that tokenizer. So now, Dialogue: 0,0:22:58.43,0:23:05.30,Default,,0000,0000,0000,,whenever someone will try to use a virtual\Ntable, so it will instantiate our default Dialogue: 0,0:23:05.30,0:23:10.87,Default,,0000,0000,0000,,tokenizer, right. It will crash and burn.\NAnd this is pretty amazing. Let's have a Dialogue: 0,0:23:10.87,0:23:17.11,Default,,0000,0000,0000,,short recap. So, we've established that\NSQLite is a wonderful one-shot for many Dialogue: 0,0:23:17.11,0:23:21.54,Default,,0000,0000,0000,,targets, right? It's absolutely\Neverywhere. And it is a complex machine Dialogue: 0,0:23:21.54,0:23:26.72,Default,,0000,0000,0000,,that is written in C. Now, with query\Nhijacking, we can start triggering these Dialogue: 0,0:23:26.72,0:23:32.64,Default,,0000,0000,0000,,bugs, and we aim to write a full exploit,\Nimplementing all necessary primitives Dialogue: 0,0:23:32.64,0:23:40.14,Default,,0000,0000,0000,,using SQL queries. Our exploitation game\Nplan is as follows: We will leak some Dialogue: 0,0:23:40.14,0:23:45.99,Default,,0000,0000,0000,,pointers, and then we'll calculate some\Nfunction addresses. We'll then create a Dialogue: 0,0:23:45.99,0:23:51.65,Default,,0000,0000,0000,,fake tokenizer object with some pointer to\Nsystem(). We will override the default Dialogue: 0,0:23:51.65,0:23:57.77,Default,,0000,0000,0000,,tokenizer and trigger our malicious\Ntokenizer. Then something will happen, and Dialogue: 0,0:23:57.77,0:24:02.69,Default,,0000,0000,0000,,obviously by the end of the process we\Nshould be able to profit somehow, right? Dialogue: 0,0:24:02.69,0:24:08.62,Default,,0000,0000,0000,,So, starting with memory leak, an info\Nleak to libsqlite. So, you already know Dialogue: 0,0:24:08.62,0:24:13.30,Default,,0000,0000,0000,,how to do it, right? We've seen\Nfts3_tokenizer(), but we still have a tiny Dialogue: 0,0:24:13.30,0:24:19.29,Default,,0000,0000,0000,,problem of the little-endian pointer. So\Nwe need to flip it. Now, surely we can use Dialogue: 0,0:24:19.29,0:24:24.60,Default,,0000,0000,0000,,the SUBSTR function and read this pointer\Ntwo characters at a time in a reverse Dialogue: 0,0:24:24.60,0:24:30.18,Default,,0000,0000,0000,,fashion, and then simply concatenate\Neverything throughout the pointer. So, we Dialogue: 0,0:24:30.18,0:24:35.42,Default,,0000,0000,0000,,get a SELECT query that looks the\Nfollowing, but now we have our pointer. Dialogue: 0,0:24:35.42,0:24:39.81,Default,,0000,0000,0000,,This is great. What about an info leak to\Nthe heap? We want to know where the heap Dialogue: 0,0:24:39.81,0:24:44.59,Default,,0000,0000,0000,,is located. So, to do that trick, I'm\Ngoing to do something pretty similar to Dialogue: 0,0:24:44.59,0:24:49.48,Default,,0000,0000,0000,,the RTREE bug that we've found. So, again,\NI'm going to confuse some shadow table Dialogue: 0,0:24:49.48,0:24:57.74,Default,,0000,0000,0000,,interface. So, we created a virtual table\Nand inserted some values into it. And now Dialogue: 0,0:24:57.74,0:25:02.19,Default,,0000,0000,0000,,we're about to confuse the match\Ninterface. So, the match interface does Dialogue: 0,0:25:02.19,0:25:06.96,Default,,0000,0000,0000,,many things, but behind the scenes, it\Njust finds - it serves the pointer in Dialogue: 0,0:25:06.96,0:25:11.02,Default,,0000,0000,0000,,memory to where the text is located,\Nright. It's this metadata, cool things Dialogue: 0,0:25:11.02,0:25:16.03,Default,,0000,0000,0000,,that virtual table has. So we're going to\Nconfuse it, and instead of passing it to Dialogue: 0,0:25:16.03,0:25:21.19,Default,,0000,0000,0000,,another virtual table interface, we'll\Nsimply pass it to the hex decoder, so we Dialogue: 0,0:25:21.19,0:25:25.67,Default,,0000,0000,0000,,will decode this raw pointer. And you can\Nsee that, again in little-endian, but now Dialogue: 0,0:25:25.67,0:25:32.80,Default,,0000,0000,0000,,we have a link to the heap. We can cross\Nthat off the list. And before we go on to Dialogue: 0,0:25:32.80,0:25:39.32,Default,,0000,0000,0000,,unpacking this pointer, we have a very\Nbasic problem. How do we even save these Dialogue: 0,0:25:39.32,0:25:44.62,Default,,0000,0000,0000,,things? Because unlike browser WebSQL, we\Ndon't have JavaScript variables or arrays Dialogue: 0,0:25:44.62,0:25:49.69,Default,,0000,0000,0000,,to use and then abuse them later, but we\Nneed to create some complex logic, right? Dialogue: 0,0:25:49.69,0:25:54.91,Default,,0000,0000,0000,,We need to calculate the function address\Nand create things in memory, but how can Dialogue: 0,0:25:54.91,0:25:58.78,Default,,0000,0000,0000,,we do it? Obviously, with SQLite, when you\Nwant to save some values, you need to have Dialogue: 0,0:25:58.78,0:26:05.22,Default,,0000,0000,0000,,insert statements, but we can only create\Ntables and views and index and triggers. Dialogue: 0,0:26:05.22,0:26:10.52,Default,,0000,0000,0000,,Then we thought about chaining this view\Ntogether to use them sort of like a Dialogue: 0,0:26:10.52,0:26:16.37,Default,,0000,0000,0000,,pseudo-variable. So again, let me show you\Nan example. Here, I create a view, it's Dialogue: 0,0:26:16.37,0:26:20.93,Default,,0000,0000,0000,,called "little-endian leak", right? And\Nagain, I abuse the fts3_tokenizer() Dialogue: 0,0:26:20.93,0:26:25.53,Default,,0000,0000,0000,,function. Now I create another view on top\Nof it, and this one is called "leak", and Dialogue: 0,0:26:25.53,0:26:30.24,Default,,0000,0000,0000,,it's flipping it using the SUBSTR trick\Nthat you know from before. But notice how Dialogue: 0,0:26:30.24,0:26:34.36,Default,,0000,0000,0000,,I referred to the first view, I referred\Nto "little-endian leak". So again, I do it Dialogue: 0,0:26:34.36,0:26:39.78,Default,,0000,0000,0000,,throughout the pointer, and eventually\Nwhat I have is a pseudo-variable that's Dialogue: 0,0:26:39.78,0:26:46.71,Default,,0000,0000,0000,,called "leak". And when I select from it,\NI get the expected result. So now we can Dialogue: 0,0:26:46.71,0:26:51.06,Default,,0000,0000,0000,,really move forward. Now we can start\Nbuilding some more complex things based on Dialogue: 0,0:26:51.06,0:26:57.19,Default,,0000,0000,0000,,this logic. And now we can go to unpacking\Nthe pointers. So, we want to calculate a Dialogue: 0,0:26:57.19,0:27:02.61,Default,,0000,0000,0000,,base of an image, for example, or maybe\Nfind the beginning of the heap. So first Dialogue: 0,0:27:02.61,0:27:09.16,Default,,0000,0000,0000,,of all, we want to convert our pointers to\Nintegers. So, again, we're going to start Dialogue: 0,0:27:09.16,0:27:14.74,Default,,0000,0000,0000,,and read these pointers one character at a\Ntime and in reverse fashion using SUBSTR. Dialogue: 0,0:27:14.74,0:27:20.69,Default,,0000,0000,0000,,And to get the value of this hex\Ncharacter, we're going to use INSTR, that Dialogue: 0,0:27:20.69,0:27:26.11,Default,,0000,0000,0000,,is just like strchar, and using the\Nfollowing string we'll get the value of Dialogue: 0,0:27:26.11,0:27:31.45,Default,,0000,0000,0000,,the hex character. Now, because it is one-\Nbased, you have on the right the minus Dialogue: 0,0:27:31.45,0:27:39.97,Default,,0000,0000,0000,,one. Then I need to have some shifting,\Nlike, dark magic, and then I go and just Dialogue: 0,0:27:39.97,0:27:44.86,Default,,0000,0000,0000,,concatenate everything throughout the\Npointer. So the result is this monster Dialogue: 0,0:27:44.86,0:27:50.18,Default,,0000,0000,0000,,query. But eventually, when all of this is\Ndone, I get an integer that is the Dialogue: 0,0:27:50.18,0:27:56.88,Default,,0000,0000,0000,,unpacked version of our initial leak. So I\Nsuccessfully unpacked this pointer and we Dialogue: 0,0:27:56.88,0:28:02.17,Default,,0000,0000,0000,,now have integers at hand, so we can cross\Nthat off the list as well. We know how to Dialogue: 0,0:28:02.17,0:28:08.14,Default,,0000,0000,0000,,convert pointers to integers. Now, pointer\Narithmetics, right, because we want to Dialogue: 0,0:28:08.14,0:28:13.19,Default,,0000,0000,0000,,have the addresses of some functions in\Nmemory and actually, with integer, this is Dialogue: 0,0:28:13.19,0:28:19.06,Default,,0000,0000,0000,,super simple. All we need to do is use\Nsome more sub-queries. So, on the left you Dialogue: 0,0:28:19.06,0:28:22.49,Default,,0000,0000,0000,,can see that I'm referring to the, now,\Npseudo-variables that we have, the Dialogue: 0,0:28:22.49,0:28:28.76,Default,,0000,0000,0000,,unpacked leak, and on the right I can\Neither have, like, subtract a silly Dialogue: 0,0:28:28.76,0:28:32.57,Default,,0000,0000,0000,,constant like I did here, or I can\Nactually use another pseudo-variable to Dialogue: 0,0:28:32.57,0:28:39.87,Default,,0000,0000,0000,,make it a bit more dynamic, can make some\Na bit more reliable. So, eventually, what Dialogue: 0,0:28:39.87,0:28:47.49,Default,,0000,0000,0000,,I'm ending up with is the libsqlite base\Nin an integer form. So, we've read some Dialogue: 0,0:28:47.49,0:28:53.99,Default,,0000,0000,0000,,pointers and we manipulated them. Now it's\Na good time to write them back. And Dialogue: 0,0:28:53.99,0:29:00.51,Default,,0000,0000,0000,,obviously we're all used to "char" being\Nthe exact opposite of "hex". And you can Dialogue: 0,0:29:00.51,0:29:05.70,Default,,0000,0000,0000,,see that it works fairly well on most of\Nthe values, but bigger integers were Dialogue: 0,0:29:05.70,0:29:10.98,Default,,0000,0000,0000,,actually translated to their two-byte\Ncode-points. So this was a huge obstacle Dialogue: 0,0:29:10.98,0:29:20.18,Default,,0000,0000,0000,,for us. So, after bashing our head against\Nthe documentation for quite a while, we Dialogue: 0,0:29:20.18,0:29:25.37,Default,,0000,0000,0000,,suddenly had the strangest epiphany. We\Nrealized that our exploit is actually a Dialogue: 0,0:29:25.37,0:29:30.65,Default,,0000,0000,0000,,database. And if I want any conversion to\Ntake place, I can simply create, ahead of Dialogue: 0,0:29:30.65,0:29:37.78,Default,,0000,0000,0000,,time, this key-value map and simply query\Nit to translate whatever value I want to Dialogue: 0,0:29:37.78,0:29:43.53,Default,,0000,0000,0000,,another value with sub-queries. So this is\Nthe python function that I've used and you Dialogue: 0,0:29:43.53,0:29:48.49,Default,,0000,0000,0000,,can see that there's a very simple for\Nloop going from 0 to FF and just inserting Dialogue: 0,0:29:48.49,0:29:54.52,Default,,0000,0000,0000,,values to a table called "hex_map" with\Nits key-map value. And now our conversions Dialogue: 0,0:29:54.52,0:30:00.61,Default,,0000,0000,0000,,are using sub-queries. So again, let me\Nshow you by example. You can see that I'm Dialogue: 0,0:30:00.61,0:30:06.81,Default,,0000,0000,0000,,selecting "val" from hex map, this key-\Nvalue map, where "int" is equal to, and Dialogue: 0,0:30:06.81,0:30:11.37,Default,,0000,0000,0000,,then I go and then doing some more like\Nshifting and modulo dark magic, but Dialogue: 0,0:30:11.37,0:30:18.23,Default,,0000,0000,0000,,eventually, what I'm ending up with is a\Npacked version of our libsqlite base. Now Dialogue: 0,0:30:18.23,0:30:22.45,Default,,0000,0000,0000,,it's, we have a packed little-endian\Npointer, so we can cross that off the list Dialogue: 0,0:30:22.45,0:30:30.00,Default,,0000,0000,0000,,as well. As I've mentioned, writing a\Nsingle pointer is definitely useful, but Dialogue: 0,0:30:30.00,0:30:35.28,Default,,0000,0000,0000,,it's not enough. We want to be faking\Ncomplete objects, right? All the cool kids Dialogue: 0,0:30:35.28,0:30:40.13,Default,,0000,0000,0000,,are doing it and it's a pretty powerful\Nprimitive. And if you actually recall, we Dialogue: 0,0:30:40.13,0:30:45.97,Default,,0000,0000,0000,,have to do it because fts3_tokenizer()\Nrequires us to assign a tokenizer module. Dialogue: 0,0:30:45.97,0:30:50.51,Default,,0000,0000,0000,,Now, what is a tokenizer module? How does\Nit look? So, this is the beginning of its Dialogue: 0,0:30:50.51,0:30:54.74,Default,,0000,0000,0000,,structure and there is an "iVersion",\Nthat's an integer at the beginning, we Dialogue: 0,0:30:54.74,0:31:00.36,Default,,0000,0000,0000,,don't really care about it, but following\Nit are three function pointers. We have Dialogue: 0,0:31:00.36,0:31:04.84,Default,,0000,0000,0000,,"xCreate", which is the constructor of the\Ntokenizer, and "xDestroy", which is the Dialogue: 0,0:31:04.84,0:31:10.53,Default,,0000,0000,0000,,destructor. We need to have both of them\Nvalid so we don't crash during our Dialogue: 0,0:31:10.53,0:31:14.34,Default,,0000,0000,0000,,exploitation. The third function pointer\Nis really interesting, because this is Dialogue: 0,0:31:14.34,0:31:18.36,Default,,0000,0000,0000,,what actually tokenizes the string. So we\Nhave a function pointer that we are Dialogue: 0,0:31:18.36,0:31:23.55,Default,,0000,0000,0000,,passing a controllable string into. This\Nwould be a perfect place to put our system Dialogue: 0,0:31:23.55,0:31:33.00,Default,,0000,0000,0000,,gadget, right. So by now, I've used a fair\Nshare of my SQL knowledge, right. But I do Dialogue: 0,0:31:33.00,0:31:37.92,Default,,0000,0000,0000,,have one more trick up my sleeve and\Nthat's JOIN queries, right? Because I Dialogue: 0,0:31:37.92,0:31:43.73,Default,,0000,0000,0000,,learned about it at a time in the past. So\Nwe're now going to create a fake tokenizer Dialogue: 0,0:31:43.73,0:31:48.17,Default,,0000,0000,0000,,view and we're going to concatenate a\Nbunch of "A"'s and then, using a JOIN Dialogue: 0,0:31:48.17,0:31:53.32,Default,,0000,0000,0000,,query, we'll concatenate it with a pointer\Nto simple_create and a pointer to Dialogue: 0,0:31:53.32,0:31:58.04,Default,,0000,0000,0000,,simple_destroy and then a bunch of "B"'s.\NNow let's verify it from a low-level Dialogue: 0,0:31:58.04,0:32:02.86,Default,,0000,0000,0000,,debugger and you can actually see that at\Nsome place in memory, we have a bunch of Dialogue: 0,0:32:02.86,0:32:06.99,Default,,0000,0000,0000,,"A"'s followed by a pointer to\Nsimple_create, followed by a pointer to Dialogue: 0,0:32:06.99,0:32:14.28,Default,,0000,0000,0000,,simple_destroy, and a bunch of "B"'s. So,\Nwe're almost done. But we need one more Dialogue: 0,0:32:14.28,0:32:20.20,Default,,0000,0000,0000,,primitive for this exploit. And this is\Nbecause we already have our malicious Dialogue: 0,0:32:20.20,0:32:24.70,Default,,0000,0000,0000,,tokenizer, and we know where the heap is\Nlocated, but we are not quite sure where Dialogue: 0,0:32:24.70,0:32:31.14,Default,,0000,0000,0000,,our tokenizer is. So this is a great time\Nfor some heap spraying, right. And ideally Dialogue: 0,0:32:31.14,0:32:36.66,Default,,0000,0000,0000,,this would be some repetitive form of our\Nfake object primitive. So we've thought Dialogue: 0,0:32:36.66,0:32:45.36,Default,,0000,0000,0000,,about repeat, but sadly SQLite did not\Nimplement it like mySQL. So, like anyone Dialogue: 0,0:32:45.36,0:32:51.48,Default,,0000,0000,0000,,else, we went to Stack Overflow, and we\Nfound this really elegant solution. So Dialogue: 0,0:32:51.48,0:32:59.03,Default,,0000,0000,0000,,we're going to use the zeroblob function\Nthat simply returns a blob of N zeros. And Dialogue: 0,0:32:59.03,0:33:03.63,Default,,0000,0000,0000,,then we will replace each of that zeros\Nwith our fake tokenizer. And we're going Dialogue: 0,0:33:03.63,0:33:07.64,Default,,0000,0000,0000,,to do it ten thousand times, as you can\Nsee above. Again, let's verifiy it with a Dialogue: 0,0:33:07.64,0:33:12.62,Default,,0000,0000,0000,,debugger. So, you see a bunch of "A"'s and\Nit's kind of hard to see, because these Dialogue: 0,0:33:12.62,0:33:17.05,Default,,0000,0000,0000,,are really bad colors, but we also got\Nperfect consistency, because these Dialogue: 0,0:33:17.05,0:33:24.82,Default,,0000,0000,0000,,structures repeat themselves every 20 hex\Nbytes. So we created a pretty good heap Dialogue: 0,0:33:24.82,0:33:30.63,Default,,0000,0000,0000,,spraying capabilities and we are done with\Nour exploitation primitive wish list, so Dialogue: 0,0:33:30.63,0:33:37.71,Default,,0000,0000,0000,,we can go back to our initial target.\NAgain, this is the code snippet of a very Dialogue: 0,0:33:37.71,0:33:43.20,Default,,0000,0000,0000,,well known password stealer. And at the\Nbottom, you can see that it's trying to Dialogue: 0,0:33:43.20,0:33:49.09,Default,,0000,0000,0000,,SELECT to extract the secrets by selecting\Na column called "BodyRich" from a table Dialogue: 0,0:33:49.09,0:33:55.33,Default,,0000,0000,0000,,called "Notes". So, we're going to prepare\Na little surprise for him, right? We're Dialogue: 0,0:33:55.33,0:33:59.05,Default,,0000,0000,0000,,going to create a view that is called\N"Notes". And it has three sub-queries in a Dialogue: 0,0:33:59.05,0:34:04.29,Default,,0000,0000,0000,,column called "BodyRich". And each of\Nthese sub-queries is actually a QOP chain Dialogue: 0,0:34:04.29,0:34:09.02,Default,,0000,0000,0000,,on its own. So if you remember my\Nexploitation game plan, we're going to Dialogue: 0,0:34:09.02,0:34:14.50,Default,,0000,0000,0000,,start with heap spray, and then we will\Noverride the default tokenizer, and then Dialogue: 0,0:34:14.50,0:34:19.18,Default,,0000,0000,0000,,we will trigger our malicious tokenizer.\NAnd you might ask yourself, what is Dialogue: 0,0:34:19.18,0:34:25.16,Default,,0000,0000,0000,,heap_spray? Obviously, heap_spray is a QOP\Nchain that utilizes our heap spraying Dialogue: 0,0:34:25.16,0:34:33.11,Default,,0000,0000,0000,,capabilities, right. We are spraying ten\Nthousand instances of our fake tokenizer, Dialogue: 0,0:34:33.11,0:34:37.69,Default,,0000,0000,0000,,that is a JOIN query of a bunch of "A"'s\Nand then some pointers like Dialogue: 0,0:34:37.69,0:34:43.72,Default,,0000,0000,0000,,p64_simple_create. And the party goes on,\Nbecause p64_ simple_create is actually Dialogue: 0,0:34:43.72,0:34:52.40,Default,,0000,0000,0000,,derived from u64_simple_create, right,\Nwith our pointer-packing capabilities. And Dialogue: 0,0:34:52.40,0:34:56.79,Default,,0000,0000,0000,,this is just turtles all the way down,\Nbecause you have u64_simple_create, that Dialogue: 0,0:34:56.79,0:35:04.44,Default,,0000,0000,0000,,is derived from libsqlite_base plus some\Nconstant. And this goes back to the Dialogue: 0,0:35:04.44,0:35:09.62,Default,,0000,0000,0000,,unpacked leak version, right, minus some\Nconstant. So again, we're using our Dialogue: 0,0:35:09.62,0:35:16.41,Default,,0000,0000,0000,,pointer arithmetics capabilities. We can\Ncontinue with u64_leak being derived from Dialogue: 0,0:35:16.41,0:35:23.47,Default,,0000,0000,0000,,the almost initial leak. And we'll wrap up\Nby showing how the leak is actually Dialogue: 0,0:35:23.47,0:35:29.41,Default,,0000,0000,0000,,derived from the initial vulnerability\Nusing fts3_tokenizer. And this was just Dialogue: 0,0:35:29.41,0:35:35.04,Default,,0000,0000,0000,,one out of three QOP chains that we used\Nin this exploit. And by now, every time Dialogue: 0,0:35:35.04,0:35:40.49,Default,,0000,0000,0000,,that I described this exploit, this is how\NI must look. And to be honest, this is how Dialogue: 0,0:35:40.49,0:35:44.66,Default,,0000,0000,0000,,I feel. But luckily for you guys, you\Ndon't have to look and feel like me Dialogue: 0,0:35:44.66,0:35:50.34,Default,,0000,0000,0000,,because we created QOP.py, and it is\Navailable on Checkpoint Research GitHub. Dialogue: 0,0:35:50.34,0:35:56.65,Default,,0000,0000,0000,,And suddenly these crazy long chains can\Nnow be created with four easy lines of Dialogue: 0,0:35:56.65,0:36:01.29,Default,,0000,0000,0000,,python. And it feels like pwntools if you're\Nfamiliar with it, so you can go ahead and Dialogue: 0,0:36:01.29,0:36:08.64,Default,,0000,0000,0000,,play with it and not look crazy on stage.\NSo, we'll go to our first demo. We'll own Dialogue: 0,0:36:08.64,0:36:15.74,Default,,0000,0000,0000,,a password stealer backend running the\Nlatest PHP 7. So obviously that's a model Dialogue: 0,0:36:15.74,0:36:20.48,Default,,0000,0000,0000,,that we created with the leaked sources\Nand you can see all the infected victims, Dialogue: 0,0:36:20.48,0:36:30.34,Default,,0000,0000,0000,,right. Cool. Now we'll try to go to our\Nwebshell, to p.php. Obviously it still Dialogue: 0,0:36:30.34,0:36:35.77,Default,,0000,0000,0000,,does not exist, we get a 404. Moving to\Nthe attacker's computer. So, we see that Dialogue: 0,0:36:35.77,0:36:42.06,Default,,0000,0000,0000,,we have two scripts here. First, we're\Ngoing to use QOP.py, that will generate a Dialogue: 0,0:36:42.06,0:36:47.70,Default,,0000,0000,0000,,malicious database. Let's see, the\Ndatabase was created. Now we're going to Dialogue: 0,0:36:47.70,0:36:52.61,Default,,0000,0000,0000,,emulate an infection. We're going to send\Nour malicious database to the C2 server as Dialogue: 0,0:36:52.61,0:36:56.95,Default,,0000,0000,0000,,if we were infected by a password stealer.\NAnd because this process takes a bit of Dialogue: 0,0:36:56.95,0:37:01.49,Default,,0000,0000,0000,,time, we can look at all the cool DDL\Nstatements, right. So you see that we Dialogue: 0,0:37:01.49,0:37:06.62,Default,,0000,0000,0000,,started with some bin leak and heap leak\Nand then we unpacked them. And at the very Dialogue: 0,0:37:06.62,0:37:10.80,Default,,0000,0000,0000,,bottom, you can see that our end gadget is\Nechoing the simplest webshell to p.php, Dialogue: 0,0:37:10.80,0:37:19.31,Default,,0000,0000,0000,,right. And this is the same page that we\Njust tried to reach. So hopefully, yeah - Dialogue: 0,0:37:19.31,0:37:27.14,Default,,0000,0000,0000,,great, it's done. Now we go back to the\Npassword stealer backend. We go to p.php Dialogue: 0,0:37:27.14,0:37:35.21,Default,,0000,0000,0000,,and we got 200. Now, let's execute some\Ncode on it. whoami. www-data. And Dialogue: 0,0:37:35.21,0:37:44.22,Default,,0000,0000,0000,,obviously we need to go for /etc/password.\NYay. Dialogue: 0,0:37:44.22,0:37:55.41,Default,,0000,0000,0000,,{\i1}applause{\i0}\NSo, what just happened is that we've shown Dialogue: 0,0:37:55.41,0:38:02.11,Default,,0000,0000,0000,,that, given just the query to our\Nmalicious a database, we can execute code Dialogue: 0,0:38:02.11,0:38:07.92,Default,,0000,0000,0000,,on the querying process. Now, given the\Nfact that SQLite is so popular, this Dialogue: 0,0:38:07.92,0:38:13.32,Default,,0000,0000,0000,,really opens up the door to a wide range\Nof attacks. Let's explore another use case Dialogue: 0,0:38:13.32,0:38:21.06,Default,,0000,0000,0000,,that is completely different. And our next\Ntarget is going to be iOS persistency. So, Dialogue: 0,0:38:21.06,0:38:28.09,Default,,0000,0000,0000,,iOS uses SQLite extensively, and\Npersistency is really hard to achieve, Dialogue: 0,0:38:28.09,0:38:34.57,Default,,0000,0000,0000,,because all executable files must be\Nsigned. Yet, SQLite databases are not Dialogue: 0,0:38:34.57,0:38:40.44,Default,,0000,0000,0000,,signed, right, they're data-only. There is\Nno need to sign them. And iOS and MacOS Dialogue: 0,0:38:40.44,0:38:44.32,Default,,0000,0000,0000,,are both compiled with\NENABLE_FTS3_TOKENIZER. That's the Dialogue: 0,0:38:44.32,0:38:50.77,Default,,0000,0000,0000,,dangerous compile-time flag. So, my plan\Nis to regain code execution after reboot Dialogue: 0,0:38:50.77,0:38:56.60,Default,,0000,0000,0000,,by replacing an arbitrary SQLite DB. And\Nto do this, I'm going to target that Dialogue: 0,0:38:56.60,0:39:02.81,Default,,0000,0000,0000,,contacts database, and its name is\N"AddressBook.sqlite". So these are two Dialogue: 0,0:39:02.81,0:39:09.08,Default,,0000,0000,0000,,tables in the original database. They have\Nno significant meaning, right. Just for Dialogue: 0,0:39:09.08,0:39:15.05,Default,,0000,0000,0000,,example. And I'm going to create malicious\Ncontacts DB, and I'm going to start with Dialogue: 0,0:39:15.05,0:39:19.90,Default,,0000,0000,0000,,two malicious DDL statements that you're\Nalready familiar by now. First of all, Dialogue: 0,0:39:19.90,0:39:25.77,Default,,0000,0000,0000,,we'll override the default organizer\N"simple" to a bunch of "A"'s. Then, our Dialogue: 0,0:39:25.77,0:39:30.91,Default,,0000,0000,0000,,second DDL statement would actually\Ninstantiate this malicious trigger, so it Dialogue: 0,0:39:30.91,0:39:34.60,Default,,0000,0000,0000,,will actually crash the program, right,\Nbecause every time you create a virtual Dialogue: 0,0:39:34.60,0:39:40.00,Default,,0000,0000,0000,,table module, someone is trying to go to\Nthe constructor of the tokenizer. So then Dialogue: 0,0:39:40.00,0:39:45.29,Default,,0000,0000,0000,,it will crash. Now, what I'm doing next is\NI'm going to go over each and every of the Dialogue: 0,0:39:45.29,0:39:51.10,Default,,0000,0000,0000,,original table and rewrite them using our\Nquery hijacking technique, right. So, Dialogue: 0,0:39:51.10,0:39:56.36,Default,,0000,0000,0000,,instead of the columns that it expected,\Nwe are going to redirect the execution to Dialogue: 0,0:39:56.36,0:40:00.16,Default,,0000,0000,0000,,the override statement and the crash\Nstatement. So, we did it for one table, we Dialogue: 0,0:40:00.16,0:40:07.71,Default,,0000,0000,0000,,also do it for the others. Now we reboot\Nand voila, we get the following CVE and Dialogue: 0,0:40:07.71,0:40:12.20,Default,,0000,0000,0000,,secure boots was bypassed. And if you pay\Nclose attention, this is really cool, Dialogue: 0,0:40:12.20,0:40:19.42,Default,,0000,0000,0000,,because we see that the crash happened at\N0x414141...49. And this is exactly what we Dialogue: 0,0:40:19.42,0:40:24.47,Default,,0000,0000,0000,,expected to happen, right, because this is\Nwhere our constructor should be, at an Dialogue: 0,0:40:24.47,0:40:30.93,Default,,0000,0000,0000,,offset of eight after the first integer of\Nthe version. But actually, there is more. Dialogue: 0,0:40:30.93,0:40:35.71,Default,,0000,0000,0000,,We get a bonus here. Because the contacts\NDB is actually used by many, many Dialogue: 0,0:40:35.71,0:40:41.02,Default,,0000,0000,0000,,different processes. So Contacts and\NFacetime and Springboard and WhatsApp and Dialogue: 0,0:40:41.02,0:40:47.04,Default,,0000,0000,0000,,Telegram and XPCProxy and so many others.\NAnd a lot of these processes are way more Dialogue: 0,0:40:47.04,0:40:51.30,Default,,0000,0000,0000,,privileged than others. And we've\Nestablished that we can now execute code Dialogue: 0,0:40:51.30,0:40:56.56,Default,,0000,0000,0000,,on the process that queries our malicious\Ndatabase. So we also got a privilege Dialogue: 0,0:40:56.56,0:41:01.26,Default,,0000,0000,0000,,escalation in this process, right. And\Nthis is really cool. And there's nothing Dialogue: 0,0:41:01.26,0:41:06.00,Default,,0000,0000,0000,,special about the contacts database.\NActually, any shared database can be used. Dialogue: 0,0:41:06.00,0:41:11.82,Default,,0000,0000,0000,,All we need is something to be writeable\Nby a weak user and then being queried by a Dialogue: 0,0:41:11.82,0:41:16.97,Default,,0000,0000,0000,,stronger user, right. And obviously all\Nthese techniques and bugs were reported to Dialogue: 0,0:41:16.97,0:41:20.79,Default,,0000,0000,0000,,Apple and they're all fixed. And these are\Nthe CVEs if you want to go and read about Dialogue: 0,0:41:20.79,0:41:27.03,Default,,0000,0000,0000,,it later. Now, to wrap things up, if\Nyou'll take anything away from this talk, Dialogue: 0,0:41:27.03,0:41:33.72,Default,,0000,0000,0000,,I don't want it to be the crazy SQL\Ngymnastics or a bunch of CVE numbers. I Dialogue: 0,0:41:33.72,0:41:38.77,Default,,0000,0000,0000,,want it to be the following. Querying it\Ndatabase might not be safe, whether if Dialogue: 0,0:41:38.77,0:41:44.66,Default,,0000,0000,0000,,it's across reboots or between users or\Nprocesses, querying a database might not Dialogue: 0,0:41:44.66,0:41:50.81,Default,,0000,0000,0000,,be safe with query hijacking. And now,\Nwith query hijacking and query oriented Dialogue: 0,0:41:50.81,0:41:55.33,Default,,0000,0000,0000,,programing, these memory corruptions that\Nwe can trigger can actually be reliably Dialogue: 0,0:41:55.33,0:42:00.17,Default,,0000,0000,0000,,exploited with nothing but SQL. We don't\Nneed JavaScript anymore. We don't need Dialogue: 0,0:42:00.17,0:42:05.88,Default,,0000,0000,0000,,WebSQL. And we truly think that this is\Njust the tip of the iceberg. So far, Dialogue: 0,0:42:05.88,0:42:11.57,Default,,0000,0000,0000,,SQLite, super popular, yet it was only\Nassessed from the very narrow lands of Dialogue: 0,0:42:11.57,0:42:18.22,Default,,0000,0000,0000,,WebSQL, and as much as browser pwning is\Nexciting, SQLite has so much more Dialogue: 0,0:42:18.22,0:42:24.59,Default,,0000,0000,0000,,potential. So we do have some thoughts\Nabout possible future work with this. Dialogue: 0,0:42:24.59,0:42:29.53,Default,,0000,0000,0000,,Obviously, something really cool to do\Nwould be expanding our primitives to some Dialogue: 0,0:42:29.53,0:42:35.61,Default,,0000,0000,0000,,stronger primitives, right. We want to\Ngain things like absolute read and write. Dialogue: 0,0:42:35.61,0:42:43.51,Default,,0000,0000,0000,,And my sketchy POC exploit was pretty\Nsilly because it had many constants in it, Dialogue: 0,0:42:43.51,0:42:49.08,Default,,0000,0000,0000,,like you've seen, but actually if you used\Nthe internal function of SQLite, like, if Dialogue: 0,0:42:49.08,0:42:53.59,Default,,0000,0000,0000,,during the exploitation you use functions\Nlike sqlite3_version(), you ask the Dialogue: 0,0:42:53.59,0:42:57.56,Default,,0000,0000,0000,,interpreter, what version are you, what\Ncompile options where you compiled with, Dialogue: 0,0:42:57.56,0:43:03.53,Default,,0000,0000,0000,,you can dynamically build these QOP chains\Nas you go and actually target the specific Dialogue: 0,0:43:03.53,0:43:08.28,Default,,0000,0000,0000,,target environment that you are\Nexploiting. Like, actually utilizing the Dialogue: 0,0:43:08.28,0:43:12.09,Default,,0000,0000,0000,,fact that our exploit is a database, we\Ncan create this really cool exploit Dialogue: 0,0:43:12.09,0:43:17.10,Default,,0000,0000,0000,,polyglot, and we think that these\Ntechniques can be used to privilege Dialogue: 0,0:43:17.10,0:43:23.20,Default,,0000,0000,0000,,escalate so many situations, because the\Ndevelopers never had it in mind that now, Dialogue: 0,0:43:23.20,0:43:28.24,Default,,0000,0000,0000,,we can take any database that is writeable\Nby a weak user and queried by a strong Dialogue: 0,0:43:28.24,0:43:36.02,Default,,0000,0000,0000,,user, and suddenly we can try to privilege\Nour escalation. Another cool thing to do Dialogue: 0,0:43:36.02,0:43:40.33,Default,,0000,0000,0000,,would be to note that many of the\Nprimitives that I've shown you are not Dialogue: 0,0:43:40.33,0:43:44.71,Default,,0000,0000,0000,,exclusive to SQLite, right?\NThe pointer packing and unpacking and Dialogue: 0,0:43:44.71,0:43:49.74,Default,,0000,0000,0000,,heap spraying, and all these things are\Nnot exclusive to SQLite. So it would be Dialogue: 0,0:43:49.74,0:43:53.58,Default,,0000,0000,0000,,really interesting to take these\Nprimitives and see if we can go ahead and Dialogue: 0,0:43:53.58,0:44:00.07,Default,,0000,0000,0000,,exploit other memory corruption bugs in\Ndifferent database engines. Dialogue: 0,0:44:00.07,0:44:02.42,Default,,0000,0000,0000,,Thank you very much. Dialogue: 0,0:44:02.42,0:44:09.43,Default,,0000,0000,0000,,{\i1}Applause{\i0} Dialogue: 0,0:44:09.43,0:44:13.54,Default,,0000,0000,0000,,Herald Angel: Omer Gull, thank you very\Nmuch. That gives us a lot of time for Dialogue: 0,0:44:13.54,0:44:18.41,Default,,0000,0000,0000,,questions. So we do have three microphones\Nhere in the hall: Number one, Number two and Dialogue: 0,0:44:18.41,0:44:23.68,Default,,0000,0000,0000,,Number three, if you have questions,\Nplease line up. Do we have some questions Dialogue: 0,0:44:23.68,0:44:31.14,Default,,0000,0000,0000,,from the net already? No. All right. Then\Nwe're gonna start with microphone number Dialogue: 0,0:44:31.14,0:44:34.14,Default,,0000,0000,0000,,two.\NMicrophone two: Yeah. So the question is Dialogue: 0,0:44:34.14,0:44:42.52,Default,,0000,0000,0000,,regarding the hijacking of the CREATE \Nsomething. So you mentioned that at the Dialogue: 0,0:44:42.52,0:44:48.59,Default,,0000,0000,0000,,beginning of the research was assuming\Nthat CREATE was the first order of Dialogue: 0,0:44:48.59,0:44:54.72,Default,,0000,0000,0000,,checking and then a space following the\NCREATE word and then it could create all Dialogue: 0,0:44:54.72,0:44:59.88,Default,,0000,0000,0000,,of other things. Now, my question is, if\Nthat was changed following your report, Dialogue: 0,0:44:59.88,0:45:06.91,Default,,0000,0000,0000,,because this seems like a way to expose\Nlarger attack surface then. Well, most of Dialogue: 0,0:45:06.91,0:45:10.80,Default,,0000,0000,0000,,the other bugs. So I just wonder if they\Nchanged. And I mean, what basically what Dialogue: 0,0:45:10.80,0:45:14.19,Default,,0000,0000,0000,,was the mitigation if and if that was all\Nof it? Dialogue: 0,0:45:14.19,0:45:18.28,Default,,0000,0000,0000,,Omer Gull: Yeah. So the escalate people,\Nwe're really more concerned with specific Dialogue: 0,0:45:18.28,0:45:23.36,Default,,0000,0000,0000,,bugs and not exploitation techniques. And\Nthis is really sad because we all know Dialogue: 0,0:45:23.36,0:45:27.27,Default,,0000,0000,0000,,that you can kill bugs, but exploitation\Ntechniques is what sticks. So no, they Dialogue: 0,0:45:27.27,0:45:34.39,Default,,0000,0000,0000,,didn't change this verification. And\Nactually this validation of create space Dialogue: 0,0:45:34.39,0:45:38.74,Default,,0000,0000,0000,,was actually added not so long ago. Before\Nthat, you can have any DDL statement Dialogue: 0,0:45:38.74,0:45:42.55,Default,,0000,0000,0000,,that you want. So the situation is not\Nreally good over there. Dialogue: 0,0:45:42.55,0:45:46.33,Default,,0000,0000,0000,,Microphone two: Good for them and good\Nluck in the future. And that was the Dialogue: 0,0:45:46.33,0:45:49.06,Default,,0000,0000,0000,,question.\NHerald Angel: All right. We head over to Dialogue: 0,0:45:49.06,0:45:52.25,Default,,0000,0000,0000,,microphone one, please.\NMicrophone one: Did you, maybe by Dialogue: 0,0:45:52.25,0:45:56.34,Default,,0000,0000,0000,,accident, attack a server which was used\Nfor password stealing stealing? Dialogue: 0,0:45:56.34,0:46:00.22,Default,,0000,0000,0000,,Omer Gull: No, obviously, I would never do\Nthat. I would never attack anyone. This is Dialogue: 0,0:46:00.22,0:46:04.17,Default,,0000,0000,0000,,just in our lab on POC. Right.\NMicrophone one: Thank you. Dialogue: 0,0:46:04.17,0:46:08.13,Default,,0000,0000,0000,,Omer Gull: Your passwords are safe with\Nthe Stealers. Dialogue: 0,0:46:08.13,0:46:09.82,Default,,0000,0000,0000,,{\i1}laughter{\i0} Dialogue: 0,0:46:09.82,0:46:12.14,Default,,0000,0000,0000,,Herald Angel: Right. Nobody is queueing \Nanymore. Do we have questions from the Dialogue: 0,0:46:12.14,0:46:16.13,Default,,0000,0000,0000,,net? Nothing over there. Well, here we go.\NOmer Gull: Thank you. Dialogue: 0,0:46:16.13,0:46:18.38,Default,,0000,0000,0000,,Herald Angel: Omer Gull, thank you very much. Dialogue: 0,0:46:18.38,0:46:20.79,Default,,0000,0000,0000,,{\i1}applause{\i0} Dialogue: 0,0:46:20.79,0:46:24.98,Default,,0000,0000,0000,,{\i1}36c3 outro music{\i0} Dialogue: 0,0:46:24.98,0:46:47.00,Default,,0000,0000,0000,,subtitles created by c3subtitles.de\Nin the year 2019. Join, and help us!