 Thanks very much for coming to this talk. We are going to be looking at hacking and forensicating an Oracle database server. Although I just gave this talk at Black Hat, and I had an hour and a half to do it. I've just found out I've got 50 minutes. So I've had to slice some of the talk. So I think the boring forensic side can go, and the hacking side is the fun part, especially for this audience. So we'll concentrate on that. So who am I? If you're wondering who I am, I'm a vulnerability researcher. I started out in Buffer Overflow Exploitation. The last bit of work I did that I'm really proud of was back in 2003. That was defeating the stack-based protection built into Windows 2003 server. I then started moving into database security. If anyone remembers the SQL slammer worm, I was partly responsible for that, unfortunately. And when Oracle turned around and said their products were unbreakable, I laughed a little bit and did some research and proved it wasn't unbreakable by any stretch of the imagination. So I've been concentrating on the C&E side of things, or had been up until about 2007, 2008, and started looking to the forensic side because obviously it was so trivial to break into database servers and continue to this day to be trivial to break into database servers. Read Oracle. The whole idea of, well, if someone is breaking in, how do we find out what they did when they got there and what we can do to work out what we can do to prevent them from doing the same thing? So that led on to the forensic side. I recently, well, recently, a couple of years ago, I solved my company, so I get to do free stuff now. I have no commercial presses, which is great, so everything presented here is all the white papers are free, all the tools which I probably won't have time for, but you can go to the Verity website and download them. They're all free, there's no commercial version of it or anything like that. So if you want to follow my research, I can be found on d-litchfield on Twitter, or email me at davidatverity.com with a three for an E. So database breaches are common, much as a given these days, I don't think I need to convince many people here that databases are where the goodies are at. I recently did a survey on the Oracle L mailing list, which is like for DBAs and programmers and stuff like that. It's a fairly good list. And I asked who's doing checks on their logs, like security logs and so on. And only one third of DBAs are actually checking their stuff, and most of those are using grep. And I find that astonishing, because let's face it, grep's not going to work on binary-based B-spoke custom file formats that most databases have. Forensics seems to be this, or database forensics, specifically seems to be this no-man's land where the incident response people are saying, well, you know, I understand that I ask stuff really well, like analyzing hard drives and so on. But databases, well, that's this whole other extra stuff I need to learn. And right now, I'm working with too many other cases. And the database guys are like, whoa, I know all about how to improve the speed of a database and so on. But when it comes to IR stuff, yeah, that's way over my head, I'll stick to the stuff I know. So there seems to be this no-man's land where no one seems to be doing any work. And as a consequence, it lags behind on the forensics front. So getting to the good stuff, compromising the database. So in a typical database compromise, there are several stages. First off, there's gaining access, obviously. Once they've managed to gain access, they obviously then need to elevate privileges if they want to have full control of that database server. Once they've got the privileges, the requisite privileges to do whatever they want, they might want to modify data. They might want to exfiltrate data. There's a whole number of things that they want to do. And thereafter, they might want to use that database server as a staging platform to attack the rest of the network. So that might include breaking up the database to run operating system commands, and then download their toolkits, and so on. So we'll look at each of these sections individually. OK. So I've been playing with Oracle for 10 years, give or take a year or so. And yeah, it all started when Larry Ellison announced at his conference that Oracle was unbreakable. And you say that to a hacker, and that's like a red bull to a flag, a red flag to a bull. And I was drinking red bull earlier, and I think that's why I'm speaking so fast as well. And I've got red bull in the brain, not red flags. So yeah, my brother and I did quite a bit of research. And my brother, Mark, found a really interesting floor. And this is, remember, an EAL4 plus certified products under the common criteria. And Mark found a floor, basically, where if you entered an overly long username, there was a stack-based buffer overflow, which was trivial to exploit. So a product which, under the common criteria, is supposedly secure could, in the authentication mechanism alone, be trivially compromised. And of course, that wasn't the only floor. There were a number of issues. Buffer overflows in the TNS listener. I'll explain in a minute. In fact, let's explain what the TNS listener is. OK. So you have the Oracle Database Server. The first port of call a client connects to is the TNS listener. The TNS listener is responsible for communication on the Oracle Database Server. This is really disconcerting, by the way. I can't see anyone's faces. So I also can see these bright lights. But anyway, the TNS listener is responsible for communication. So when a client connects to the TNS listener, it hands off the connection to the Oracle database process and communication takes place thereafter. Now, the TNS listener itself has had a number of buffer overflows in the past. So again, without a user ID and password, an attacker can exploit these to trivially gain control. But a much more interesting attack, one that doesn't require exploitation of buffer overflows, was a thing known as external procedures exploitation, XPROC. So I'll go into that very, very quickly. So let's say you're using the database normally, and you want to execute PLSQL code. PLSQL code is like the way you extend the Oracle database server and can execute stuff that basically allows business logic to take place and so on. Now, let's say PLSQL, which is a fairly substantial language, doesn't do what you require it to do. What you can do is write a we-see program, a we-see library, and hook that into the database server by using external procedures. Now, what happens is once we compile our library, we then tell the database server about it by doing a create library statement. And we wrap that library within a procedure, basically, which then calls the function within that library. Now, what happens is the Oracle process connects back to the TNS listener and says, will you load this library, execute this function, and pass it these parameters? And the TNS listener goes, well, I won't do it for you, but I'll tell you what. I know a program that will. And it launches this program called xproc and tells the Oracle process to connect to xproc. And xproc, sorry, the Oracle database process then says to xproc, load this library, execute this function, and pass it these parameters. And xproc goes and does that for it. Now, normally this happens over name pipes, but it turns out that you can use TCP as well, which is great, because me on the other side of the internet can connect to a TNS listener, providing, of course, the firewall allows access. And there are unfirewalled Oracle servers out there. And say to the TNS listener, I'm the Oracle process, wink, wink, nudge, nudge. Will you load this library for me? And the TNS listener sends back me a message over TCP and says no, but if you connect to this port, xproc will do it for you. So I then connect to that TCP port that xproc is now listening on. And then I say to xproc, hey, do me a favor, will you? Load this library, execute this function, and pass it these parameters. And xproc goes, yeah, no worries. And there you go. Without a user item password, we can load any library we want, execute any function and pass it any parameters. So of course, we could use load MSV, crt.dll, the Microsoft Visual C runtime, and execute the system function. Or if it's a Unix system, we could call libc and do exactly the same thing. So we now are running code as the user account that Oracle runs under. So on Windows, that's going to be a local system. Or Linux, it's going to be the Oracle user. Either way, as far as the database is concerned, you are God. So Oracle fixed that. And it's a really funny, yeah, it is actually funny, fix whereby they said, OK, what we're going to do now is limit where you can load libraries from. And any attempt to load a library outside of the designated place will log that, just so there's some forensics information there. And they did that by using Sprint F to pass the library name into a stack-based buffer. And anyone who programs and see here, and with a fixed size buffer on the stack without any length checking done, you immediately know, well, Sprint F is going to lead to a stack-based buffer overflow of vulnerability. So even though they limited where the library could be loaded from, or as I needed to do, to regain control without user ID and password, was exploit this new buffer overflow in the logging process. So Oracle, we were informed about that, and they fixed it by putting a length check before calling Sprint F. Why they didn't call SNPrintF, I don't know, but they decided to remain with the Sprint F. Now, it turns out that any environment variable names within the library name are expanded. But that's expanded after the length check now. So if I go $path, and let's face it, a path is maybe 200, 500 characters or something like that, suddenly we get to exploit this buffer overflow again. Just by going $path, $path, $path, we find the sweet spot, because to be honest, the path might be different on one system against another system. But when we find that sweet spot where the communication is just reset because the X-Proc dies, we can then move backwards, byte, byte, byte, byte, byte, overwrite the save return address. And we have an expression in the UK, Bob's your uncle, I don't know if you've got it over here. Bob's your uncle, you own the process again. So yeah, the thing is, even to this day, if you are local to an Oracle database server, in other words, let's say you've got SSH access, if you're local, you can still do this trick locally to get code to run as someone else. So 10 years after the fact, we can still do this Oh, and incidentally, of course, if UTL TCP is available, once we're connected to the database server as a privileged user, we can use UTL TCP to create the right packets. And because we're now suddenly local, so from the Oracle process, we are communicating directly with the listener and X-Proc. So again, we can still affect this kind of attack. And today, Oracle is still vulnerable to this kind of thing. Now, one would think that dropping msvcrt.dll in the directory where Oracle allows you to load libraries from is a bad idea, right? Well, guess what's in there? It should be in the Windows System 32 directory, but for some reason, they thought, well, we don't want it in there as well. Sorry, we need it in the Oracle Home directory, in the Bin directory. So they make all these fixes to prevent you from calling the system function in msvcrt.dll. But they go ahead and then dump the DLL in the same directory. So it's all for naught. So I really don't understand what kind of security questions are being asked at that organization. Like, we're about to do this. Is it a good idea? If not, let's not do it and find another solution. That's the minimum kind of security question that should be going on. And it's clearly not going on as far as I'm concerned. So anyway, there's a whole bunch of ways that we can use to gain access without a user ID and password. And of course, Oracle is one of these great database servers that has, depending upon the applications you install, a number of default accounts with default user IDs and passwords installed. Now, this has changed. Obviously, in 10G, you now have to set a username and password, sorry, the password for the key accounts, sys, sysman, db and smp, and sorry, sysman, system, db and smp during the install process. Whilst you're installing, though, the default passwords are in place. So sys has a passwords of change on install by default. But during the installation of the Oracle server, the password is still change on install. So if you can find someone installing Oracle at that particular moment, you can obviously still connect as sys with the password of change on install and do unifary stuff whilst the server's being installed. Obviously, you have to hit the moment right. It's probably never going to happen in the real world. It's just one of those things you observe in the background. But there's a whole bunch of accounts out there that are typically locked but still have a default password in place. And you'll find in the wild there are instances of servers out there with a db and smp still with its db and smp password. ctxys still has its password of ctxys. In fact, there are about 600 to 700 accounts, depending upon what products have been installed with default usernames and passwords. So even if you can't exploit any buffer overflows, trying a username with the username as its password is a good guess. And so yeah, there's a whole number of weak passwords and account compromises available. And if we have access to the file system, what you'll find is that the passwords are often logged. They're encrypted, but they can be decrypted because we know what the keys are. On the file system, there are certain log files where we can snuff the passwords out. And they're world readable, of course, as well. And so yeah, even if we don't have a user ID and password and we have local access to the box, we can still gain access by snuffing these passwords. And of course, if we're dealing with a web-based application, then we can just piggyback. If it's vulnerable to SQL injection, we can just piggyback the whole account authorization process. Sorry, authentication process is handled for us by the application. So we just piggyback out our SQL injection off the back of it. OK, so assuming we get access, I'm just going to create an account, create user defcon identified by password. Great, quit. So I'm going to give this defcon user a grant create session, rather, to defcon. The only privilege required to connect to the database server is create session. I'm then going to connect as this guy. I create defcon password. OK, so this is the account we're going to use to run out nefarious stuff, select staff from session privs, we'll see. That's all he's got. OK, create session. So basically, this user, the only privilege he's been granted directly is the create session privilege. So he can connect to the database server, and he can't do anything himself from here on in. But there's a special user account called public, which means everyone on the database server, essentially. So whatever public can do, defcon user can do as well. Now, I spoke about PLSQL earlier on it when I was referencing external procedures. The default security mechanism for executing PLSQL objects such as procedures, packages, and functions, and so on is the definer's privileges are used to execute the object. So if the sys user creates a PLSQL package, he is the definer. Any vulnerabilities in that, as the definer, will execute with sys privileges. That's the default. You can also specify, using the auth ID keyword, the current user's privileges should be used. But by default, it's the definer's privileges. So any package which is owned by a highly privileged user and is vulnerable to PLSQL injection can be abused by an attacker to gain full control. Well, not full controlled. It depends on who owns the package. But in the case of sys, sys has all the privileges that's required. So yeah, if sys owns a vulnerable package, then an attacker with only great sys and privileges can exploit this floor to gain full control of the database server. Now, Oracle has probably had about three to 400 such issues found in sys-owned packages. So we're not just talking about a one and two case scenario kind of thing. This is the achilles floor in the Oracle database server and continues to be. So every three months, Oracle releases a critical patch update. Sometimes they fix five critical floors. Sometimes 20 to 30 critical floors. More often than not, there are at least one or two, if not more, PLSQL injection vulnerabilities in Oracle. So I'm going to show you a fake one because I don't want to put, I'm just going to show you one that I made. So if you want real ones, look at the critical patch update from last time. Or if you want a brand spanking new one, wait for the next one to critical patch update to come out. They're too penny these kind of floors. So as an attacker, let's say, remember, we only have the crate session privileges. If we wanted to do things like delete the audit trail, we obviously need the privileges to do that. We can use these SQL injection floors in high privileged packages to do things like that. Or we might alternatively just say, grant ourselves DBA. Now that would be a very noisy thing to do, obviously, in a real world attack. And you probably wouldn't want to do that. So what you might find is people inserting directly into the SysOrth table, which essentially does the same thing as the DDL statement for grant DBA. But it uses an insert instead to grant those privileges. And even then, all of this kind of stuff is making noise, and probably won't be done. But for the sake of argument, it's a nice demonstration here. So let's do it. So there was a nice little attack previously, or a way of facilitating attack, where we could generate our own cursor that we would pass our nefarious SQL on. And we would inject the dbms underscore sql.execute function into the vulnerable procedure, and that would go ahead and execute with the higher privileges. So whatever SQL we pass, be it grant DBA, would execute with the higher privileges. But Oracle went ahead and fixed that. So what we need now is another way of looking for ways of running arbitrary SQL. With Microsoft SQL server, you can batch SQL statements. So you can just do a select, then an insert, then a grant, and a crate, whatever you want, one after the other in any kind of SQL injection situation. With Oracle, you can't batch statements. So if we wanted to say something like grant DBA to public, and it's in the middle of a select statement, that's where the vulnerable, actually, let's talk about that quickly. Here's the sample that we're going to use. Can everyone see that at the back? Is the font big enough? Yeah, it should be. So all we're doing is the procedure owned by Sys, in this case, I've called it Vonprock. And it takes the user input str and concatenates it into this query select object name from all objects where owner equals user input, and then executes that query. Now this here is an example of PL SQL injection. But because it's a select statement, we're injecting into a select statement, we would be limited to, without an additional hack, we'd be limited to doing another select statement, like a union select, or something like that. But that doesn't get us DBA privileges. So what we need to do is work out another way of doing that. So we have our auxiliary inject function. In this case, it's the new context function on the dbms underscore xmalquery package. Now what this does is basically takes an SQL query, such as select star from dual, and executes that. But it doesn't have to be a select statement. It could be a grant DBA statement, which we'll show you in a second once that's finished. I've just freshly started the Oracle database service. So things need to load into memory. Right, great. That's it done. And that will return very well. So now we're going to use this to exploit the floor. And let me put a sys in front of that. So before doing that, let's show you it's vulnerable to SQL injection. So we're going to execute foo. That's how you would execute it normally. So what would happen is foo would be placed into str. And the query would execute. If I put a single query in there, we see SQL command not properly ended. So that's indicative of a SQL injection floor. Go minus minus. And that minus minus basically chops off the rest of the statement. And yeah, so we're all good there. So now we can go ahead and exploit that to gain, did you? Sorry, I thought someone said something behind my back. There was a ghost or something. Lost my train of thought. Right, if I do set role DBA, first off, you'll see we've not been given the DBA role. DBA role hasn't been granted or does not exist. So now we're going to gain DBA privileges. So what we've done there is injected. This is our little trick, by the way. Remember I said, if we're in a select statement, we can't do anything other than a union select or whatever, or a sub-select. Well, this declare pragma autonomous transaction basically tells the PL SQL compiler, this query is fine to execute on its own. It's its own transaction. Go ahead, everything will be safe. Now, as a consequence, we can execute arbitrary PL SQL. And in this case, it's begin, execute immediate, grant DBA to public, and we end that. And we get the message it's successfully completed. So if we go set role DBA now, DBA, role has been set. And if we do select staff from session privileges. Honestly, it's so easy to break into our Oracle, you don't need to applaud me on that. Select staff from session. But thank you. It is appreciated. I'm here all week. Try the steak. So we've now got all these session privileges. So we've gone from create session only through to exploiting a PL SQL injection flaw, which there are three to 400 of, depending upon the version of Oracle that you're looking at. And suddenly, we're gone, as far as this database is concerned. So now I'm going to do auto user sys identified by password. So I'm now changing the password for the sys user. And as you'll see in a minute, logging in as sys is going to give us some fun stuff. Connect sys password at rcl as sys DBA. OK. So we're now connected as the sys user. We're going to start playing with a thing called already bug, which is a nice little facility that allows us to read from the Oracle Process Memory right to the Oracle Process Memory, and also execute arbitrary functions and so on. So let's, before we do that, yeah, breaking out of the database, how are we doing for time? We're doing OK. Great. Breaking out of the database, running arbitrary code. Well, obviously, if there are buffer overflows, and again, maybe each CPU, one buffer overflow, sometimes there's zero buffer overflows being fixed. But actually, I think there's at least one or more being fixed in every critical patch update. Sometimes there's lots. Yeah, sometimes they get a slew of flaws coming in. But we're specifically going to look at the already bug stuff here. Now, what already bug does is, basically, as I said, it allows us to peek and poke at memory or debug. Already bug has been documented before, by the way. So this is nothing new. People have been speaking about using already debug as a hacking facility for a long, long time. So yeah, this isn't like Odey I'm dropping by any stretch of the imagination. So if I go already debug help. So here's the help options. Some of them are very interesting. Some of them are not so interesting. But we're going to be looking at these two, peek and poke, and call, which basically takes a function name, and you can call that function. So here's one I made earlier. OK, so first off, we need to set the process ID we want to debug, and we're just going to use the process ID of my given process. So set myPID. So one of the great things about already bug, well, let me rephrase that. It's bad that we can do this with already bug. But one of the good things thereafter is any time you use already bug, a trace file is created. cd dr, actually find str, forward slash i, forward slash c, already bug. I just want to find the current slash od. 628. OK, so this is current one type. So we can see, remember the first already bug command I should was help? That's written to this trace file. And then I did set my PID and so on. That's written to the trace file. So any time you use already bug, it's being written to a trace file, which is great when it comes to forensics. So what we're going to do here is we're going to run an operating system command. Because remember on Windows, Oracle runs as the local system user. So any arbitrary code I execute is going to execute with the privileges of the local system user. And in this case, I'm going to create a user account called or a hack with a password of pwd and add it. And I'm going to call the system function. So what I'm going to do first is write to this memory address four bytes, which is net space. So that's the net space of the net user add command. And then so all this here is basically net user add pwd slash sorry, net user or a hack pwd slash add. And I'm going to write that into memory. And you can see here I increment the address obviously by four. Because if I didn't do that, obviously we just overwrite the same bit of memory. So what you'll see here, let's clear the screen. So oh, don't do that to me. Give me two secs. Because I restarted the system, the memory's gone. So I'm just going to fudge one. We can do this, by the way, again, using or a debug. We can dump a stack trace. And then using utl file, we can read that in. But I'm just going to cheat because that takes a wee bit longer, 3, 4, 3, 7, 2. VADump, minus p, 4, 3, 7, 2. OK, pick one at random. OK, we don't need execute read write. We just need read write. Reserve, that will do. 1, E, 2, 3. Edit, bind, replace. 1, DDF, bling, replace all. OK, home and control C. Right, let's try this again. OK, great. So what we've done there is written the net space part. So let's add the rest of it. So I now have written in memory the net user or a hack pwd slash add. That's the operating system command I want to execute. Now I basically call the system function here and pass to it the address at which can be found the operating system command, the net user add stuff. So before I do that, if I go net user, whoops, net user, we can see I've got VMware user administrator David and guest. There's no or a hack account right now. But I'm going to get Oracle to now create the user by calling the system function return zero as it should do. So net user now shows us we've got this or a hack account in there. So thank you. So what we've done is from a lowly create session privileged user account, jump privileges to DBA, change the sys password. And now we're connected to sys. We can then start poking and peeking into memory and running arbitrary functions. Now of course, we're only limited by our imagination in terms of what we want to do as far as executing arbitrary code is concerned. We could use this to send us back a reverse shell or anything we want. We just obviously need to create the right structures and memory, get the right addresses, and send them to the function basically. And one of the great things, of course, is when you call a function, the value, the return value, whatever is returned in EX, is basically dumped in here. So if we call the socket function, we can get the socket handle by looking at whatever the function returns and so on in there. OK, and then we can then add that in and so on. But I think the key takeaway from there is every time you use our debug, it's in that trace file. So what we can do is look in that trace file. You can see the stuff I've written to memory I can now extract. And then as a forensic investigator, I can go ahead and start working out what the attacker attempted to do. So if they indeed try to spawner of our shell or something like that, their code is going to be in memory, not in memory, in this trace file. So we can build up a very good picture, so anything they're doing is in there. But you do have to remember, of course, that we're connected as sys. We, as far as that database is concerned, we are God. So if we wanted to, we could delete that trace file. Suffice it to say, though, if they don't delete the trace file, it's a wonderful source of information. And of course, we can run operating system commands in other ways. We spoke about external procedures earlier. Let's do that. First off, I'm going to do one that will fail. And the reason I'm doing that is because I want to show you another useful bit of information. Remember, I said it was logged. The name of the library is logged. That's actually Ron Prokman in the back now. Because I've just specified MSVCRT.jl. I haven't specified a path or anything like that. It will look through the system path for the right DLL and decide that it's not in the right location. It's not in the Oracle home. So we'll get a message being logged saying that it's an invalid DLL path. So remember, I said you have to wrap it. This bit of code at the bottom wraps the call. So let's create that. And remember that this is going to fail when I execute the function. So and we'll get the invalid DLL path. But if we look here, HS. OK, we can see in there someone tried to load MSVCRT.jl. And it was sys. And the library name was this and everything like that. So again, useful forensics information worth looking at that directory. But let's make it work now. Remember, I said they dropped MSVCRT.jl in the bin directory in Oracle home. So we can now go ahead and recreate that. If I do net user, we've got the Oracle hack user. We're now going to create our hack to the password. So we get that successfully and net user. We've now got the our hack to user in there and so on. So dropping MSVCRT.jl in there wasn't a smart idea. But to be fair, if you think about it, watch this. CD backslash at CD bin. OK, this is the Oracle home directory. That's all attack surface. These are in there by default. Any function on there, we can obviously call. And if they are susceptible to things like overflow or whatever, then we can still use this external library thing. What Oracle should do is have an area where there are no DLLs by default. There are no code objects by default. And if you want to add your own stuff, you can put it in there. Having it as the Oracle home is too lax as far as I'm concerned. So yeah, all of this is attack surface, basically, from an external procedure point of view. So yeah, it should be tightened up considerably. We're doing time. OK, OK. So I've really run through the hacking side of things. So we've got a couple more minutes left for a wee bit of the forensic side. So the database has been breached. And what do we do now? Where is the evidence? With Oracle, the evidence is everywhere. It's great. There's so much redundancy built into the Oracle database server. It's wonderful. Security, not so wonderful. If we look at Microsoft SQL Server, SQL Server 2005 I think has had three critical patches required since 2005. So what? That's pushing six years. And it's had three critical patches. Microsoft SQL Server 2008 I think has had zero. If we look at Oracle, each every three months, patches are coming out time and time again. As I said, sometimes they're patching up to 20 to 30 issues. Sometimes it's only five or six. But every three months, you have to worry about Oracle security all the time. But every three months, it's patch day. But SQL Server is pretty crap when it comes to logging stuff that's useful to an investigator. Obviously, you've got the transaction log and you've got the error log file. But as far as useful information goes, that's pretty much it. Oracle is great. It's wonderful. So let's look at some of these locations. So obviously, the system metadata itself, the information that makes up the database server is a wonderful source of information. The data files, when a record is updated or deleted, the data is left intact. It's just, well, each row of data has a three-byte header. How are we doing? OK. Each row of data has a three-byte header. The first byte of that three-byte header has its flags, basically. And the fifth bit, if you flip that bit, it says it's deleted. If you flip it again, it says it's not deleted. So we can very, very quickly find deleted data by looking at that first bit of the three-byte header to say, is the bit set or on set and whether it's deleted or not. So if you delete data, if you think, I'm hiding my tracks, so I've deleted all my stuff and everything like that, it's still in there, it's just that bit's been flipped. Or if you update data, that bit is flipped and everything and a new row is created. So it's really useful when it comes to that information. There's a thing called the active session history. I wrote a couple of papers on this a few years ago. So what active session history is, when the Oracle server is running, there's a sub-process running in the background, basically polling the database server every three seconds to find out what's going on at that particular time. It takes a snapshot. These snapshots are recorded in memory. And then every half hour or so, one in 10 of the snapshots are recorded on disk, basically. So if you have a query that lasts for, say, three seconds, you're going to have a snapshot in it, definitely in memory somewhere. If the query lasts for more than 30 seconds, chances are there's going to be a snapshot written to the disk. So this active session history becomes a really useful source of information for looking at select attacks. Select attacks, obviously, are just getting access to data. So if you're downloading a customer database that, say, has five million records, that's going to take longer than 30 seconds, probably. If you're using something like UTL HTTP or UTL Intdra to exfiltrate data over an out-of-band method across the network, that's going to take a long time. And so there will be calls to these SQL statements will be logged in the active session history. And as a forensic investigator, we can go back and look for evidence of even select attacks. The transaction logs, like the redo logs in Oracle, anything that requires a transaction is logged in the redo log. So that's another great source of information. So that's things like deletes, inserts updates, select for updates, any DDL, like grant crates, and drops, and so on. All that information can be found in the transaction logs. Undo segments, if you make a change, an undo segment is created that has information pertaining to that change. So again, we can query that. The memory itself, in a live response situation, we can start querying certain key tables for a key virtual views, rather, for information. So one of them is VDAR SQL. It has about 3,000 to 5,000 queries that have the most recent ones that have been executed. So if we can find an attack in progress or an attack which happened just like half an hour ago on a fairly quiet database server, there might be evidence of attacks in there. VDAR DB object cache is another great source of information. So again, a couple of years ago, I wrote a paper on hacking the Java virtual machine built into Oracle and looking through the source code of the default Java objects, there's this UTL wrapper that basically takes user input and passes it to the system function, basically. So if there is no reference to this UTL wrapper anywhere else in the Oracle code, and I think it's left over there from development days, so no real world code should be using it. So if it's in, if it exists in this DB object cache, one can infer from that that an attack has probably taken place. So again, there's these virtual tables which are a wonderful source of information. And obviously, the log files themselves, like the TNS listener log file, is the first port of call. Any kind of connection is going to be logged in there. Caviar emptor, though, when it comes to the TNS listener log files, when a client connects, they pass the program name and stuff like that, and that's all logged in the TNS listener. But because it's under the control of the client, they could say whatever they wanted. They could pretend to be a JDBC client, whereas in actual fact, they're a C hacking tool. So don't fully trust the information in there. Use it for pattern recognition and so on, perhaps. Or another one, for example, when you authenticate to Oracle, what happens is you connect to the TNS listener, the TNS listener, OK, great. The TNS listener then passes you off to the Oracle process and you authenticate or attempt to authenticate. And if authentication fails, the client tears down the connection and you start the whole process again, connect to the listener. The listener passes you off to Oracle and so on. Now, as a consequence of the client being the one responsible for tearing down that session, if we don't choose to, if we fail authentication and we don't choose to tear down that session, we can continue to authenticate once we've got that connection to the Oracle process. So we can make one connection to the TNS listener, which passes off to the Oracle server. We then say to the Oracle server, is the password for sys this? And if the Oracle server says, no, no, that's not the password, we don't tear down the connection. We just say to it, well, how's this for a password for sys? And we keep on firing multiple attempts down the same TCP pipe so we're not having to go through that whole setting up the communication again. So what would take typically a minute to go through a couple of hundred passwords? We can go through a couple of hundred passwords in a second so we speed up brute forcing. Obviously, later versions of Oracle account locking is enabled by default, so we would just go for the sys account because you can't lock out that account anyway. And obviously, the trace files, we looked at ROD bug earlier. I'm not going to have time to show you any of the tools and stuff. If you are interested in the tools, they're free. Go to the Verity website, download them, play with them, have fun, and everything like that. So thanks for listening. Are there any questions before I disappear? I can barely see you. So if you do have a question, shout out. OK, no questions then? Great. Thank you very, very much for coming. Thank you. Thank you.