 SQL injection presentation. Give it up. Hi everybody. I'm Cameron Hodgkes. I'm here from hexany.org and I'd like to thank you for coming. It's the hardcore DEF CON that shows up to the last talk on the Sunday. Some people were coming in with their luggage, so that's pretty awesome. So thanks to you guys for showing up. I'm going to be talking about automating blind SQL exploitation. So I'm not going to focus on detecting blind SQL injections, more on getting the goodies from a blind SQL injection. So we're going to start off pretty basic. Start off with what is a SQL injection. Hopefully most of you have encountered the term at least before. It comes down to pretty much just one thing. It's client supplied data and it's passed to a web application and it's not appropriately validated for bad stuff. And once this stuff goes on, because it wasn't validated, it goes on to be processed by commands, by the database, and that's when you have your fun. SQL injection. Every type of SQL injection you're probably going to encounter can be used to do one of a couple things which comes down to performing operations on the database. So when I say that I mean you could use it to bypass authentication mechanisms. You could use it to read information that you probably shouldn't have privileges to and people are assuming you don't have privileges to, but you do. And writing information to the database such as new accounts or bogus data, stuff that's really going to mess up the DBA and make them cry in a sleep. So SQL injection comes down to roughly three main forms, breaking things down as we go along. The first form, well, it's three main forms when you're reading information you're not supposed to get. And that's what we're going to be focusing on. That's what I mean by when we go on to exploit it. So the first method is redirection and reshaping of the query. That's where the web applications, displaying stuff in tables, and you can reshape the query to dump everything beautifully formatted for you, print it out, show your friends, like, look at this, they even formatted nicely. Usually you'll need to know some of the schema to go about doing that, but if you're lucky you can dump the schema in the tables and go from there. The second method, and the method a lot of people are familiar with, is the error-based injection. And that's predominantly in Microsoft SQL server. You'll put in a SQL query that's poorly formed, you'll create an error message, and through the error message you can reverse engineer that query that it was called with, then reverse engineer the schema of the database, and then start to pull out the actual information by forming bogus queries that says, oh, I can't convert the password to an integer but it displays the password right there for you. And the third method, the method we're going to be using for the rest of this talk is blind injection. Now, when I say blind injection, there's a couple different definitions of that as well, so I'm just going to focus on the one that I mean. And when I say blind injection, I mean, you can pass data to the web application and it's still going to pass information back to you, but it's going to pass it very, very subtly. It's simply going to be able to respond to yes or no questions. So you send a question to the database and it responds somehow and it says the answer is yes. But the problem is that any form of SQL injection can result in significant data leakage or data modification attacks. So it's not that it's better or worse than another type of injection. They all have the same end result, which is the person running the web application getting screwed. So with blind attacks, we're playing 20 questions with the web server. I'm sure everybody's played 20 questions when they were younger. It's like, are you a mineral? Yes. Are you a tank? Excellent. But why focus on blind SQL injections? Well, the thing is blind is just as common as almost any other form of SQL injection out there. And in fact, even the other SQL injections can be treated as blind if you'd want to. Most of the time you wouldn't want to because you actually want the information now. But the other problem with blind is that blind involves a false sense of security on the host. The $4 an hour visual basic programmer who put up that web application who heard of SQL injection once in some class decided, oh, there's error messages. They're bad. I'll hide them from everybody. And then I'm okay. He's not. So there's a false sense of security going on where they think they're safe, yet they're still just as vulnerable except through a slightly modified attack. The big problem with blind SQL injections though, the part of people who still are aware of them, they don't take them as seriously because they take far too long to perform manually. It's a large investment of time and it's very time consuming, tedious, painful to actually implement them. Has anybody in the room here actually performed a blind SQL injection by hand before it? All right. But when I was thinking. So at hex 90, we decided this was a pain in the ass. So we're going to write a tool to do it for us because we're really, really lazy up there. So we figured we needed an automated tool because we know we're playing 20 questions. But the reason we stopped playing 20 questions when we were four was the fact that it's really, really boring. But we can ask as many as we want. We don't have to stop at 20 and just keep on asking. As long as we have questions, the database will still answer as long as we haven't dusted to oblivion. But if we want the username, the username of the database, say it's SQL server database, and they changed the username away from SA. They did something right. So we want to find out what the first letter of the username actually is. Well, that's going to take seven requests back and forth to the web server. But if there's eight characters in this username that you're using, that's going to be 56 requests in total. Eight times 56 is not that hard. But to find out that it was an eight letter username in the first place, that's another six requests to the web server. Just asking yes or no questions. So we're already at 62 questions for the username. The username really doesn't do us any good. It was just sort of, oh, I wonder what it is. So we're at 62 requests and that's already starting to add up. So a fairly conservative estimate is typing this into a web browser. This is going to take about 10 seconds for query to the web server. And assuming you don't make any mistakes, you haven't had too much coffee while you're doing it, then you're already looking at over 10 minutes just to get that eight character username sitting there at your computer. And the username's value is greater than whatever. It's very, very painful to do. But as I said, the username isn't our goal. Probably you're not going to run off to your friends without the username. You're going to want to go and you're going to want to get the schema, you're going to want to get the entire database, you're going to want to get basically the goal that's locked in the database. So if you want to perform a non-trivial penetration off of a web application, you're going to want the table names, you're going to want the column names, you're going to want the data types of the columns, you're going to want the actual data stored in the database. And all of a sudden you've gone from 10 minutes to two hours or days or months, possibly years depending on the size of the database. Now, writing a tool might sound simple, but for an effective and comprehensive tool, I can assure you it is slightly more complex than a few shell scripts in Netcap. Now, just I've got a couple examples for you to ease the boredom here. This is Bob's Bike Shop, probably the ugliest web application you've ever seen. We designed it as well. We were focusing more on the tool though. But it's got everything that a web application vaguely should have. It's got a pretty banner at the top. It's got a menu along the side where you can choose different types of stuff you're going to buy. It's got an ugly green table that shows you the bike information that you're looking at. Apparently the Schwinn bike that this customer was looking at is going for $30, so these guys are going out of business. But it's got everything that a standard web application might have, including a SQL injection. So if you probably can't see it, hopefully you can notice that it changed a little there. Watch the address bar. It grows a little. What I've appended onto that is simply and one equals one. One equals one is true. It's fairly straightforward logical statement. So it didn't change the page after we added that to the product ID field in the address bar. That's a very simplistic basic building block of a blind SQL injection there because we've asked it what it true is and it returned the same page. Now if we changed the one equals one in the address bar to one equals zero, it's telling us it couldn't find any information anymore. So it's safe to assume at this point that we've got the product ID field there is directly sent to the database where it says send us all the bikes where the product ID is equal to, in this case two, and then this is where we append our extra logical statement and one is equal to zero. So it sends back all the bikes where the product ID is two, when one is equal to zero, it never sends anything back. We've got a false statement. Therefore we know that the database is sending us back wheeling values of true and false. I'm going to take a little sidestep here for a minute. When I was talking about getting the username, it takes seven requests and eight requests. I wasn't pulling those numbers out of my ass. There's actually a method to it. What we do is you can convert anything in the SQL server to an integer. What you do in this case is once you've converted it to an integer, it's very easy to pull it down just using logical statements. You can create a recursive routine to select a range, start off maybe at zero, nice middle area, and then increase the value, start off increase it by two, increase it by four, increase it by eight, until you find a value that's higher than the integer you're dealing with. Once you've found that range, basically the last one you stopped at in the previous one before, you start cutting that in half and exponentially drop it until you've zeroed in on the actual integer you're searching for. What you could do if it's not an integer that you're actually searching for, if it's a character, search for the ASCII value. That's an integer. If it's a binary field, you can convert each element to the ASCII value and then grab that number. If it's a date, you can convert it to text which then goes to ASCII which is an integer. Everything can be converted to an integer and pulled out, albeit slowly, can be pulled out through this method. Now that we know we can pull the information out of the web server, we found the whole, we figured out how we're going to go about pulling all the data, we just have one more problem. That's how do we recognize a true page and a false page from the web server? For us, it was pretty simple. For a true page, there was an ugly green table with an undervalued bike and a price there. For the false page, it just said no rose found. You can spot it like that, but the problem is a computer can't do it as easily. There might be other stuff going on. It just sees a collection of ASCII values. It's a bit harder for the pattern recognition to take place. It's not that complex to understand the computer doesn't see what things we do. We're pretty much used to that. So big thing is a lot of people want to just do a straight-string comparison. You've got the true page, you've got the false page, and then just copy those strings, compare the strings, if they're equal, then move on with that. But web applications aren't getting less complex, they're getting more complex. Everybody wants to show off, everybody wants to add extra bells and whistles. So there's going to be more dynamic content as you go around. You might find a lot of web applications currently you can just do a string compare on, but it's growing really, really quickly the fact that there's going to be extra stuff going on. There's going to be an increasing chance that the dynamic content on the page is unrelated to the actual dynamic content you're viewing. So there's a lot of extra stuff going on. The string comparison might work for something along the lines of an error-based injection, but where you've got constant strings you can sort of target in on, but not for a blind injection such as this. Back to the false page that I showed you earlier. If you look right above the no-rose found, there's if you're in the back it looks like a gray bar. It's basically a date and it's including the time. So that means that section is changing every second. So every time you do a query you've got a little bar there that's changing. We can say that the date doesn't matter, but it's going to be something that's changing in terms of the overall string. Then underneath the no-rose found it's telling you what page you requested. Now that seems a bit contrived, but if you've ever gone to a new site or any site where somebody wants you to refer to a friend, well the refer to a friend is just a link to the URL you requested, and if you're injecting over the get request then that's going to change every time that you hit the site as well. So first possible solution for dealing with the true pages versus the false pages versus the pages you want to know whether the true or the false is use an MD5 sum. Take an MD5 of the true, take an MD5 of the false, then the unknown and which one's the closest. Well as I said earlier, over and over web applications are designed to be dynamic. There's going to be a lot of extra stuff going on and the way MD5 was designed, it's a message digest which means it was designed to highlight small changes by making large changes in the actual sum. So take a look at this. It took the home page of Google, very, very simple page and I saved it, took the MD5 sum of it, then I changed the title tag, changed from Google to Google, increased the ASCII value of the entire thing just by one. And this is a different MD5 sum. So the original is the blue, the changed one is the red, it only changed by one character which went up by one value and they're nothing similar. You can't even tell where they changed, it should be at point two. I know that because I did it, but the numbers don't even line up to the actual lines because an MD5 sum is always going to be the same size. So overall we know that MD5 sums can't handle the changes well for something like this where there's going to be small incremental changes that we want to sort of filter out and we don't really care about them and it might work for the same applications where the straight string comparison might work, but it's not going to be comprehensive and if the string comparison worked, then why bother with the extra time with the MD5? So another possible solution would be to parse the actual HTML into a tree data structure. You go on and you represent the HTML entities as nodes in the data structure and you look for differences in the shape of the tree, you write recursive traversal algorithms, but a couple problems with that and the first one is I'm lazy. That's a bit more complex than what I wanted to do when I was writing a tool, but a big problem with it is that if non markup data is changing, then it's not going to change the shape of the tree. If it's just the textual content, which is altogether possible, it happens somewhat regularly, then you're going to have to find a different way to figure out what's going on in the actual nodes of the tree and the other thing is it's easier to implement an XHTML parser than a realistic HTML parser. By that I mean that auto-generated crap that front page spewed up for years and years and the auto-generated crap that lots of people still write through their web applications, the kind of stuff where it's just chunks and chunks and chunks and to actually read it if you had to fix it for some reason, you're like pulling out your hair, it's just as bad to go through and parse with the tree data structure. So the third solution, the one I actually ended up using was linear representation of ASCII sums. Now what I mean by that is take the HTML file that you get for each response and delimit it by carriage returns. So you basically split it up by lines, take the ASCII sum of each character in the lines and so now you have a single value for each line in the HTML file. From here it's just one array that you can work with and because of the magnitude of the sums that you're dealing with, small changes by like one or two characters aren't going to make that much of a difference. This is the same graph of Google versus Google that I showed you earlier with the MD5 sums. It's section two down there, down there, down there that you can't even see it just because you're dealing with the closest range is 20,000, that's the notch there so a change of one isn't going to show up too much. So we figured out how we're going to get the signatures. We still have to do comparisons, figure out how we can recognize the truths versus the falses since we found a way to represent them and to do this we're going to need base cases. This is, you do this initially anyways when you're trying to figure out and learn the web application. So you know you can find a true page versus a false page at this point. You always know that one is going to be equal to one. I can guarantee that to you and you know that one is never going to be equal to zero hopefully. So once you do this you use known true pages, known false pages and you found a base set of cases to work with for your HTML comparisons. So from Bob's Bike Shop the web app I showed you earlier this is the true page versus a false page compared to the monograph with the linear representation of the ASCII sums. So the blue you can see it follows the same as the brown as it starts at about 10 that's where the difference takes place where the no rose found versus the green table shows up. So the green table takes up more space on the blue and then it eventually tails off and finishes the same way that the brown does because it has a single line and it's a bit shorter. Just in case you think that was a bit too contrived this is a realistic signature this is a real commercial web application that's somewhere out on the web that has a blind sequel injection. I don't remember which page I took this from so don't ask me after the talk but it's still vulnerable as far as I know. So I said earlier that this linear representation, small changes in the input means small changes in the output but the fact is there are still small changes in the output so you can't do a straight up comparison. So when these changes take place such as the time changing by one increasing the value in very small increments it's going to make notice or very very minor changes that we would sort of ignore and we can actually use a tolerance instead of a straight comparison for comparing these values. If you've done any numerical analysis and you never used equals you always use a subtraction for a tolerance you do the same thing here so you just take the sum of the known minus the sum of the unknown take the absolute value toss it over the sum of the known and if that value is equal to your preset tolerance or less than your preset tolerance then you treat it as an equivalency oops there we go and this is the same thing with the tolerance bands just sort of illustrating what I meant by you can see that as it starts off they're in the same tolerance because they are the exact same but once it gets to the parts where it's supposed to diverge the tolerance at this point isn't enough to create a false negative or false positive it would be a false positive so there's no problems with that the tolerance shown here is about 10% if you're ever doing this on your own I wouldn't recommend anything higher than 0.01% or you're going to get a lot of false positives on that one the realistic one I showed you would trip up if it was higher than 0.01% so tolerance works for the most part it'll work a good chunk of the time but there's better ways to go about it it doesn't it does extra calculations comparisons it doesn't really need to be doing and it doesn't take advantage of stuff that is known to be bogus data we don't care about so we decided to create a filter to the data that we're dealing with on the left is the Bob Spikes true signature you've seen it on graph now this is the array form and on the right is the false page know that because it's a bit shorter and if we identify every element between the two that are in the same position that are equivalent to each other then we know that those values have nothing to do with the injection they have nothing to do with the actual information being presented to us so if they're the same at this point they should be the same at every other point and we know they don't matter to what we're doing so get rid of them at this point we have the data that we're comparing against each other and this saves us a bit of time if we're small in a larger page it cuts out an even larger chunk but why stop there there's still extra stuff we know is crap we know we'll trip up our web application the stuff we filter out by eye think of the time or the referral to a friend we want to still get rid of that so we have a second filter we apply and this allows the application we're attacking to be profiled a little bit more before we go on to proceed with the actual attack so we want to remove the junk data that's going to screw up the results the only thing is we have to get more than the initial set of base cases but really overall we're going to be doing thousands and thousands and thousands of queries against the web server if it is then your attack wasn't going to happen anyways so we've already applied the subtractive filter to these two and they're supposed to be all we've asked is one is equal to one which is true this is true equal to two yes it is so the pages should be the same because it's the same answer but they aren't so anything that's changed over this two queries and we ask a couple more just to be sure anything that's changed at this point we know this has nothing to do with our injection this is changing on its own and it's going to come back to bite us later now don't even look at it later because it just will screw us up so we clear that out and what we do is we save in memory which elements of the signature that are actually used for the comparison so it's like hit element 12, hit element 13 hit element 14 if that's what we're looking for then and we know it's a good signature otherwise we assume it's a false so the benefits of using the second filter is at this point we're pretty sure we can get rid of the tolerance you don't have to if you're not a hundred percent on it but I've been pretty comfortable not using the tolerance anymore when I've been doing my comparisons works out pretty safely at this point if something doesn't exactly line up that means I have to read read just my filters and move on from there and it will remove a large portion of the dynamic content that's unrelated to the actual injection we're performing so this is the part where I introduce squeal squeal is a tool that we created sort of I've been presenting how squeal actually works here and we created it to perform blind seagull exploitation automatically for us we wrote it in C sharp I wrote it in C sharp in linux which annoys some people but it works in windows and linux if you want to use linux get mono 1.0 or later it's monos become pretty stable recently there's windows.forms version for 132 and the GTK sharp version they should both be on the CD but I haven't had a chance to look yet and it's free for non-commercial use free for educational if you're presenting it to people check out what I can do with this and the fun stuff is any data you pull through squeal it'll save to XML so it's very easy for you to read you don't need squeal to work with the data again later you can do it any way you want so here's a sort of example of the XML that squeal uses it's the actual signature of the attack that we use so it's got the target address the method that you're using, whether you're using SSL there's some extra parameters that might get stored there depending on if you're using them or not every parameter that's required for the injection whether or not it's the injection point every time once you initialize which is gathering your base cases then it will actually save the signature sets for you so you only have to do that once and you can play again later and here is the actual tool this is the windows version pretty windows XP version and basically what you would do is you select the type of injection which is the only choice you have is blind so that's right now and enter the target URL right around here running a local host test just because we're going to show you a demo shortly and choose whether you want to do a post or a get whether you want to use SSL if you want to comment at the end of the query squeal only runs for SQL server at the moment so that just means it's depending on a dash dash to the end and this is fun over here this is for people who want to send it through proxy if you want to do this anonymously don't know why you'd want to do that because nobody would want to be anonymous while running this but it's fun stuff and once you fill out that information go on to enter the information about the actual parameters the stuff that goes after the question mark usually or if it's a post any of the stuff that's being returned so you enter the name, the default value whether or not it's injectable if it's a string injection you're doing simply put the closing tick on the end and it'll recognize the apostrophe and work with it from there you also have the option to add HTTP headers aka cookies so if you have to squeeze by authentication with your own cookies you can do that and once you've got that setup you click the initialized injection and it gathers your base cases once you've done all that it only takes about a second to gather the base cases unless you're running through a really slow proxy you can move on to do stuff like grab the username takes a couple seconds, comes back we're running as SA anyone see a problem with that? no? alright but um yeah, SA then once you've got that you don't even need the username it doesn't help you, you don't use it later since you're just asking yes or no questions you don't have to authenticate they've already done that for you those friendly web app coders but you can load the table information and that means the name the ID stored internally the number of records in each table once you've got the table information load the field information and for the customers table it takes a little bit longer than what I'd like it to take right here it takes about 5 to 10 minutes to grab all this information but it's better than doing it by hand so you can go make yourself a coffee while it's doing it so we know we've got the field's customer number customer name, customer address customer phone, customer facts customer CC number fun stuff what are we going to do with this? so we want your name we want this CC number don't know what that might be and we want to save it so and we start downloading now it's not instantaneous because you're doing a ton of queries right now so we'll go back to the slides so what it does when it gathers the table information this is just basically batch stored procedures so if you've done this by hand right now and this is probably the last thing you want to see but what Squill does is it goes through and it gathers the ID numbers for every table it wants the numerical ID numbers because those are easier to work with and they're already integers for us so start off, get the count, which is the number of tables in the database it's fairly small integer go up, down, find it then you want the smallest ID go up, down, find it then you work through, get the next smallest until you've found all the IDs in the table so once you've grabbed the table IDs which means you don't have to worry about apostrophes getting filtered out anymore because you're not working with strings, you're working with numbers you get the length of the name matching that ID then you get each ASCII value you just basically choose the ASCII value for the first letter second letter, third letter and work your way through until you've got the entire table name and all that information is saved gathering the field information is very, very similar you get the number of columns that are in each table which you reference by the table ID you already got once you've found these you get the column number now unlike the table IDs which are long integers so don't use 32-bit integers because it will crash on you you're going to want a long integer that's fairly weird the column IDs are different for SQL Server at least they start at one, they end up whatever the last column is it's always sequential, it's just an ordering internally so really you could probably guess but this is just for complete and sick so once you've got the ID numbers which it does reference it by do the same thing to grab the length of the name, grab each character in the name then once you've done that you're going to want the data type because that's going to change how you're pulling the information from the database later because in an integer you just grab if it's a text string you grab the ASCII value otherwise convert to text then grab the ASCII value then convert back when you've got it so the X type is the data type that they actually mean when they reference the columns which is stored conveniently for us as an integer and this is taken from MSDE just pulled it out by hand earlier and save you guys some time if you want to work on something like this later these are just the numerical values that match up to each data type that you probably encounter okay, running time, it looks like it's done so we will go to Fun Explorer and where did I put it that's embarrassing my documents not even my laptop this looks like it so hopefully you guys can see that from the back, can everybody see that this is the information we pulled out from the database looks like I'm the victim of my own blind sequel injection here but I'm not alone, some people should have known better than to buy from Bob's Bike Shop that's not really DT's credit card number so you can stop writing over there but it basically pulls all the information out it stores it in XML it'll store it with the primary key from the table whether or not you asked for it because it needed it to grab it anyways so if you need to work with it later when you're messing around and decide to change somebody's expiry date on them for fun so back to PowerPoint and running time so to grab all the information to grab the username that was there there was only two characters to grab the table names the table contents the field information plus just those four records that's already over 2700 HTTP request to the server if you use the 10 second rule we talked about earlier that I claim is fairly conservative this would have taken over 7.5 hours non-stop really quick that means not stopping to get coffee that's 7.5 hours non-stop so who was it that said that they'd done this by hand before all the way through what size t should you guys have where extra large, medium I don't know if they're pulling one over on me but I'm feeling generous extra large bear with the I can't find anything and it goes afterwards it's a nice fancy internet villain t-shirt hexagonia gear represent but in reality that would have taken 7.5 hours to do by hand in reality it's going to take a lot longer in a real production database it's going to be more than four records you're pulling down hopefully otherwise you're wasting your time attacking them I mean testing against them we're all good guys here so nothing's perfect I don't claim to be I don't claim the tool is there are still problems with squeal as it stands right now the first big problem is noise generation and server log denial of service when you're doing thousands and thousands and thousands of requests against your web server chances are they're going to notice at some point just this string of sequel statements in their logs if they don't then they're going to admit but chances are they're going to notice and if it's a big database there's a chance that you might fill up their hard drive before you pull out all the information from the database because they might have decided oh yeah 100 mags is enough for the web server but I need a 5 gig database falls apart also if it's a very small web server experimentally we've kind of noticed that it can knock out the web server a second or two resulting in a real denial of service so run this on your own systems the other problem is has a couple of problems it has issues at the moment with if there's no carriage returns in the auto generated html that means the guy who wrote it didn't think of putting in the carriage return character so that means if you were to view it by hand I'm sure everybody's seen one long string nobody likes to work with that not even squeal but there's ways to possibly get around that too so one of the first options that people immediately think of is why not just force the carriage return after a certain number of characters but if you've got random stuff changing changing in length as well then all of a sudden your signatures are going to be offset and it doesn't seem to make much sense anymore because they don't match up the filters don't work anymore because things are shifting because of that one force carriage return and it throws off the comparison techniques at this point you need an html parser of some kind it might be the tree parser I discussed earlier another option would be to run something along the lines of html tidy you'd have to double check to make sure it's deterministic which means I'm going to be double checking that it's deterministic make sure the same thing comes out every time and at that point it's filtered out and cleaned up so that squeal can read it and work from there or an option that was suggested to black hat was to instead of doing something along those instead of always delimiting by carriage returns give the use of the options to delimit by other characters which is something we're looking at rolling into the next version so where do we go from here well same techniques could be utilized in other types of applications that still interpret results from html responses so as long as you're trying to read values, read information subtly from what comes back you can use a similar signature set to work from there and filter it out similarly even if it's more than two you can just filter out the three and do comparisons but you guys want to know fun stuff, right? so we know that we've been able to automate blind sql injection which means we've been able to automate the process of putting stuff on reading stuff off of the sql server so fun stuff sql IRC yay could be idle, could be lag, nobody's really sure but everybody loves IRC so why not implement it that way another possible option that could be used for something like this sql FTP and if you guys can't read the almost Linus Torvald's quote there that means only whimsies take it back up real men just upload their import stuff to somebody else's sql server something else you could possibly do I don't know if you can even see that sql quake now that wouldn't work but if you missed Johnny Long's talk not really sure where you might be able to find sites you just want to test but you want to find stuff and you want to play around where would you go about finding sites you could play around with that are possibly injectable well you're going to break it to you nobody's going to email you randomly out of the blue just doesn't happen in this day and age nobody's going to email you unsolicited it's not going to be a stranger that emails you you know the guy that's emailing you random stuff that you don't care about and if they do email you they're not going to email you a sql injection yeah I'm not joking but then again if they did email you and they did email you a sql injection it's not like they're the kind of people that want to remain anonymous and don't want to be tracked down so just closing up here a couple suggested papers if you don't have a lot of experience with sql injection yet and you're looking at learning more about it the first two are from NGS Systems by Chris Ann Lee very good papers both related to sql server primarily the error based stuff the third one is the blind sql injection paper from spy dynamics by Kevin Spett another very good paper detailing the processes that I was talking about automating here and the fourth one is another one on blind sql injection from Imperva I don't have the actual link to it at the moment but it's easy to find off of Imperva.com they take a couple different approaches than the spy dynamics guys do so you might want to check that out so I'm going to open it up to questions right now if you're looking for this tool it's not up yet it should be on the CD it will be available at this website there's a couple other tools that are available there as well so does anybody have any questions? I see you at the moment we just took sql server because we were kind of short on time and most of the examples are for that but as long as you have access to the equivalent of the sys objects table or read access to the schema you should be able to do it we're looking at trying to figure out how to do it with Oracle although Oracle DBAs are usually a bit better looking down their systems than sql server DBAs so as long as there is a sys objects table that you can get access to there's a way to exploit it that way the question is do I have any experience attacking Java applications in terms of sql injections I don't myself I basically pick on the week which is the ASP coders out there do you have any? I'm told it's doable by people who know more than I do is there a specific question related to it? basically as far as languages go you're going to find that as long as a language supports parameterized queries that's the big thing if you're looking at locking down a database make sure you're using parameterized queries and if you have the option to use stored procedures that's another layer that makes it more complex for the attacker to get through and chances are they're just going to move on because it's not worth their time but parameterized queries I can't stress this enough .NET has it, Java has it later versions of PHP should have it and if you're not using it you really should be if the language you're using isn't using it find a different one there's a lot of ones to choose from at the moment unfortunately a lot of textbooks out there tend to start off with this is your database code bad examples right off the bat and even really good books are still doing bad examples for SQL connections right off the bat and it's not till three chapters later where you stop reading at this point that it gets into safer database calls so look for parameterized queries of some kind or another where you actually identify the name of the each element that you're hitting and the data type that it's going to is there any more questions? yes the question was can you insert a delay the current version of SQL doesn't support throttling as far as the delay I believe that's what you're asking it could be done sort of having it paused before it does the next one and paused before it does the next one the current version doesn't do this there's something I'm looking at putting into the next version because of that other denial of service problem that happened so the next version will have that but currently it doesn't support it right now it's just simply that when it just fires them off as fast as it can so it's about three or four per second I think it fires it off right now you can you can only stop in between where the buttons are in this version so it's like you can load the tables, load the table information and then stop that, come back load the field information so the general answer to what you were wanted was no I think oh basically well you have to grab all the table names at once but you just grab the fields for each table as you need it so then you can just grab the specific information you need any more questions it's a binary search because it's all the integer searches that take place are binary searches because even for an alphabet you're looking at 14 at the maximum for a binary search I believe whereas if you do it by a non-binary search it's going to be longer than 14 on average so it's faster for even if it's just an alphabet with a limited range you're still going to want to do a binary search I think the only difference with that is that we know the top and the end point we start between zero and 255 and then go from there for ASCII values when we're doing it that way any more questions well thanks everybody for sticking around my name is Cameron Atchee thank you