 So we're going to go ahead and start the talk with Lance from 801 and with that he's going to be talking about his SQL injection. Thank you. Hello. My name is Lance. I also go by the handle Nemus. A little bit about myself. I'm part of the local DEFCON group in Salt Lake City, Utah. DC801. We hang out at the pound DC801 on free note if you want to come chat with us during the day. I also help out with the hacker space in downtown Salt Lake. I help organize and plan events and things like that. That's my hobbies during the day. I write software for payment solutions. I code in PHP and Python mostly. I also do a little bit of C and basically just the whole gambit of programming languages. Also if you're interested in listening to me more, I'm part of the web security warrior podcast. It's a general new podcast that we're putting together for people who are interested in security. It's mostly focused towards web developers and focuses on introduction security related topics. Quick disclaimer. I am not responsible for anything you do with what I teach you. That's you. I am not a lawyer so I cannot tell you what is legal and what is not legal. That's what lawyers are for. Pre-rex. This is a one-on-one talk so it's geared towards beginners but you do need to understand basic Linux operating systems, basic PHP coding techniques. Basically you need to understand how to set up a lamp server and get PHP working on it and write PHP code. Just a little bit. Not a lot. Just a little bit. I wrote this talk. It's geared towards beginning PHP developers so they can learn the basics of PHP injection, SQL injection security. If you're looking to get into coding or just want to learn more about SQL injection, you can just study up a little bit and come back to this talk. So if you don't have the pre-rex, well, I'll have a lot of fun coming back to it later. So why do we study attacks? You always hear the best defense is a good offense, right? But we can't attack other systems. We can't go out and defend against the world. It's basically the world against us with our code, right? We want to have our code visible and available to our users and our clients and basically the world. That's the way web apps work for the most part, right? You set up a web application and you want as many customers as you can possibly find. But the only way you can secure it is if you study how your system is coming under attack. You're not going to be able to attack the attackers, but if you attack yourself, you'll be able to understand your weaknesses and find good solutions to mitigate those issues. So basics of SQL injection. What causes a SQL injection? Any time you have one programming language or you have one language writing code or writing executable instructions for another language, you're going to have an injection flaw. It's just an inheritance, the nature of the beast. In this case, we're going to focus on PHP writing SQL queries. But when you have two languages, like if I had PHP writing PHP, which I'll talk about when we go to over web shells, you're going to have an injection problem. And so with that, you have to validate user input and you have to make sure that you're parameterizing queries correctly. Otherwise, the user is going to be able to manipulate the string that's being generated by the middleware and take advantage of the code that's being executed on the second layer. So in this scenario, what I'm going to do is I'm going to walk you through some vulnerable PHP code. I've posted the code in the slide that's very simple, broken down. I try to make it very concise so that you can see, oh, okay, here's where the vulnerability is. Here's the input from the user and here's the system, the code being executed on the system. And you can also use it to debug why your query is not working. But we'll start off with identifying the vulnerability, fingerprinting the server, enumerating data from the database. And then once we're finished with that, we're going to explore ways of uploading code and taking advantage of the server. So this is just the basic lab setup. I'll go over this real quick. You guys can come back to this later. I always design my talks as a lab. So later, if you want to come through and learn something and work through it. So we're going to use Curl. Curl is just going to do our HTTP requests. It's going to format it for, I like command line stuff. There's also ZED and Burp Suite you can use if you like a GUI system. I don't have time to go over these tools, but just let you know that they're available and they do basically the same thing. We just need something to help us craft the HTTP request so that we aren't, you know, hand coding it each time. So this is my simple Curl test script. And what we're doing here is we're just taking parameter from the command line and feeding it into the variable ID, which is going to be passed to this git.php script. And see the command example there? We just do git curl one and then it builds the HTTP request URL. And we're also going to have it do data URL encoding, which is just how we want the input formatted so that all of our attacks will be formatted correctly and won't have issues with spacing and special characters in the URL. So when we're attacking LAMP, we have to think about the architecture, right? Most basic LAMP applications when they start off are probably going to start off on a single system. The web application might be running on a server, on one server. We might have the PHP code running on one server and then database code running on another. Or sometimes in most cases it will all be running on the same server. This makes it a lot easier for attacking because we know that once we've found a vulnerability, we can leverage the database or we can leverage the web server and we're working within one system. It gets more complicated when you get into like an enterprise solution. So on this point we see we have load balancers, we have a web server and we have database clusters. So if I run a SQL injection attack, it might be going against the first server, the second server, the third server and it might be cycling and I'm not going to have a way of knowing where my code is being executed. So you have to keep this in mind because you might have a vulnerability and you might be pushing code or you might be doing something to the operating system and if you're attacking the web server aspect, you're attacking the PHP code, it's going to be on one of these web servers and you have to figure out which web server it is in the loop. The load balancer is going to send it to different servers, different databases. The web servers are going to send the different requests to different databases. So if you have a SQL injection query and you're writing uploading shells, it could be pushing the shells to each one of those databases and you have to figure out how to execute that code or those web shells on the different web servers. So here's our test database, it's just a simple orders database with some columns, we're going to create another database with login users and put some users in there using MD5 hashes and so here's our vulnerable code and this is a simple code. At the top I'm showing the request as the first sees it. The middle there we're just connecting, we're going to connect. I've designed this to be what I would interpret would be out there when people first start writing PHP code. So the easiest thing they do is they connect to their MySQL databases route, probably using local host, no password, just to get it running. We have some code to check to see if the connection fails, then we run the query and here we have the vulnerability is that we're concatenating the query string. This is what the vulnerability is, because we're taking two strings and concatenating them and we're not filtering any of the user input, we have just created a SQL injection problem that will allow a user to take advantage of our database which we did not attend. So how does the attacker test for the SQL injection? Before we really do anything, we want to verify that the injection actually exists. So we're going to, on this presentation I'm going to focus on blind SQL. I think for the most part most web administrators have been turning off errors, error reporting, which is a good thing, but it makes a SQL injection more difficult. Non blind injection is where you have error messages that are printed to the screen and you can use those to help you figure what you need to do to build your query. So there's three different types of SQL injection attacks and what you're going to be doing is manipulating the strings, our numeric values or we're going to do an evaluation. So the classic example is where you take advantage of the evaluation of a login where the username and password is sent to the database, if we get a result we know that that user is a valid user on our web application. So like I said we'll be doing numeric injection. So here's our first test. What we're going to do here is we're going to pass it to my get curl script. The script is going to generate the URL that's going to pass the ID forward and we're going to do a select orders from order numbers where one and one and we get the first results. We do it again and we do one and zero. We get no results. So what the and is doing is it's doing a binary and saying if it's one and one it's true so that's one so return the first results. If it's one and zero that's zero so look for the zero results. There's no data there. So with this we can say huh it seems like there could be a possible SQL injection vulnerability. To do further testing we do one and true. True will be evaluated as one and it with one comes back as one. We get the first record. One and false. False is zero and it come back with the record. Do the same with minus. If it's minus one minus true we see the results. We don't zero record. And then the dead giveaway here is if we can use multiplication against the SQL database we know that we have a numeric injection flaw. So we use our curl string. We do one times three and if we get the third record we know the vulnerability exists. And so on this example I didn't have a third record. I don't have the third record displayed there so you don't see it. But if we got the first results back we know okay this probably might not be a SQL injection within this code. So now that we verified that the injection exists what we're going to do next is we need to verify that the web application is actually running lamp stack or whatever. We need to figure out what the web application is running so that we can attack it. So what we're going to do is we're going to fingerprint the server by looking at web requests and figuring out the architecture so that we can craft our queries. So the easiest thing you can do is you can use curl dash V and look at the headers. And the headers will tell you a lot about the web application and the database. It won't tell you about the database. It will tell you about the middleware and the Apache or the web application or sorry the web server. So it will tell you the web server and possibly the middleware code that's being run. This is the default settings. These are things that you can turn off so that it makes it more difficult for the attacker to guess what's going on on your architecture. But here we're just blindly telling people hey I'm running Apache on CentOS and I'm running PHP 5.5.17. We can also run an end map scan, verify the operating system and the web server. We see the end map is identified as Apache and CentOS. We run the dash A command and do the OS fingerprinting Apache CentOS. Another tool we can use is the HTT print. It uses signatures to identify web servers. So here we run the command against our web server on port 80 and it tells us with a probability score saying 76% confidence that this is a Apache web server. So at this point we can say with some confidence that the web server is running Apache and we know what we're going up against. So next we need to identify the database. We've identified that we're running the Linux operating system and we're running Apache as the web server. Next we're going to do is identify what the database version is or determine if it's MySQL, Postgres, Oracle, it could even be MS SQL. We can see some weird stuff out there. But for the most case if you're using PHP you can guess with a high probability they're running MySQL on the back end. So to do this we're going to use a union select poisoning query and the way this works is we're going to take the original query that the developer wrote and we're going to mirror it with our own code and we're going to match those up so that the result set is returned together. And so what you do is you write a select ID and then you do union select and then you got to figure out how many columns that are in that query so that the union will match the original query. So you just start with one and you enumerate and you go two, you enumerate three, four, five and once you get a valid result back you can then know how many parameters there need to be in that union select so that it matches the original queries column count. So here we have our union select. I just used nulls. You could use ones. You basically want to avoid things that use special characters so that it can get past filters and other things. That's a more complicated subject bypassing web filters but just to keep in mind don't use ticks, use pretty safe SQL queries. So here what we're doing is we're doing union select with the original query and we're going to match it up with version. So the last column there we're going to have the version and we get the database version which is 5.540. So next what we're going to do is we're going to use the concat function in SQL which is different between all of the different databases. And so my SQL and Oracle are similar so we need to just verify that it is a MySQL database and not an Oracle database. So here we want an union select to do 1.1.1.1 here I am using ticks and then we get back here on the line order when it merges the query A, B so we know the concat worked. We run the Oracle test, we do B, B or concat, we don't get results, return zero so we're fairly certain that we have a MySQL database on the back end. So at this point we can Google the version number and verify that all that version seems to correlate to MySQL. We have a good understanding of what we're up against and now we can start pulling data from the architecture. So at this point you have a select statement and we're just going to try and get as much data as we possibly can out of the database. If you're attacking it, an attacker might pick selective items that might go over username and passwords. For the most part at this point I'm going to show you how all of your data will be stolen out of your database just from this one flaw. So the first thing we're going to do is we're going to enumerate the user database of the MySQL database, not the web application, the programmer row. This is the database that maintains access to the connections to the database. So we're going to use a union select, we're going to select host user password and then we're just going to know out the rest from MySQL.user. So if the credentials that were originally set up on the PHP code are root, we'll have access to this database. If they secure their credentials and put a least privileged user account in the MySQL database we won't have access to this table. But you can see here I was able to determine that the local host connection has a user root and then there's the password hash from the database, the MySQL database. Here we can get the host name, just using a union select. Here we can, so if you need to have more data in your union select than the column count has, you can use concat to get more columns from different tables into one column and get that returned with the union. Another interesting thing is you can use the UUID function to get the MAC address. I did verify this. I don't know if it works on all architectures. But the last part of the UUID returns the MAC address so that might be useful for attacking other infrastructures. You can use the database command to return which database the connection is connected to. And then with this command here, you can see it gets pretty complicated. But what this does is it dumps all the tables and columns from the MySQL database that has access to. There's more information there. And then see we have our output when we have the order details, order number, tells us all the column names so we can go through this and see where our interesting points of data might be. So next what we're going to do is we're going to pull all of the users from the web application. So this is usually a table called logins or users or something like that in the web application itself that's going to contain either a clear text password or hopefully a salted hash password. But what we're going to do is we're going to pull that data and get users that we can use to log into the web application. So we do that by just doing union select and pulling that information from this login table that we had earlier. So now that we have hashes and we have user names, one thing that we can do to attack this web application is crack these hashes. And before you can do that, you need to identify what these hashes are. And one tool you can use to do that is hash ID. And hash ID is running in Python 3 so you'll need to set up a Python 3 environment to identify the hashes. So just a quick thing on password hashing, don't use MD5, right? Easy reversible, it's been around forever. The guy who wrote it said that you stop using it. To this day, I still find MD5 hashes. If you can use password hash, it's a PHP function. In the newer versions of PHP, it will be included by default. If you're running an older version, you can get PHP pass. It uses Bcrypt and it uses a salted password for you. It takes all the magic and difficulty out of it. And you can see here we've used the same password twice and generated a unique password each time. So if you're interested in hashing passwords or cracking, here's some information on it. You can use, you can reference some information. A hash cat is pretty good. John Ripper is great. SQL map, which I'll talk about a little bit later, has a password cracker in itself. And so just a quick touch on rainbow tables. Rainbow tables are like password crackers, but the hashes are stored in a database and indexed, so you're not generating a new password each time or generating a new hash each time to compare it against. So you want to use a combination of both password cracking and rainbow tables when you're testing the security of your hashes. And just a quick example, I ran my MD5s through hash cat on my GPU miner. And with four GPUs, I was able to get these passwords using the rock U list within two or three minutes. All right. Now for some more interesting stuff. So we've attacked the database, but now what we're going to do is we're going to attack the operating system of the database. And we're going to do that by looking at files on that system. So going back to our architecture, if the database and the web server are both sitting on the same system, you might be able to look at the code files on the system using your SQL injection technique. So by doing this, I take a look at, I load the file and then I use a union select to push that file out and I can view, hey, here's the username and password for the database. And I've just gotten credentials that way. So this goes back to your web server set up. Your web server set up. Nothing's working, right? Did you change to mod 777? Right? Get it to work. This is why you don't want to do that because if that's 777 and the MySQL user is the same, the MySQL user can touch that. If there's a SQL injection vulnerability, I can overwrite that, which we'll show later. So this comes down to if you have a MySQL database and a web application running on the same server, you want to make sure that the web application is not running with the same privilege as the database. You want to have them in completely separated isolated environments. By default, CentOS and Ubuntu and all the other Linux distros appear to have that separation, but a lot of times administrators will just push everything as the root user. When you have everything as root, then everything can touch and cross-contaminate and you can modify files. So here, by default, so this is my attack against the operating system. And by default, I was able to pull Etsy password was readable with the MySQL injection as the root user on the MySQL database. And I got a list of users from the Etsy password file. Luckily, I was not able to read the Etsy shadow file, which would have all the hashes for the database or how the hashes for the operating system passwords. So that's at least secure and blind for me on a default configuration. But I now have user names that I can use to brute force or attack or go against other servers. So here's a list of interesting readable files. You can get the resolve.conf, the message of the day, SSHD config, and other places, you know, or even the patchy config so you can figure out how the server is configured. So at this point, you'll be thinking, okay, I've got this SQL, I've got the select vulnerability. And so I want to modify the database so it can be much easier to just rewrite the hash on the login table and then login with a password that I already know. So if you have a SQL injection and you're using Union Select, I was not able to find a way to do an insert and update in using a sub query or a nesting query. And what a sub and nesting query are is when you have a query inside a query where you have the where statement that's the selecting item is the query result returned from our future query. So just a little bit more about sub queries. Like I said, I wasn't able to figure it out. So if someone can do that, I'd be really interested in seeing your results. So Bobby drop tables, right? We cannot have a talk about SQL injection without Bobby drop tables. It's just not possible. So you're like, oh, I can modify the database just using a semi colon and then terminating the query and running another query. Well, with the up to date version of my SQL I query on this version of PHP, I was not able to use nest sub query stacking, excuse me. So no Bobby drop tables unfortunately. There is a my SQL multi query that does give you this functionality. But why would you use it? I don't know. But it's one of the problems of PHP is it lets you do all kinds of things you probably shouldn't. Okay, some fun stuff. So we're going to go on to remote code execution. And so at this point we've got user names, we've got passwords and we're going to look at a couple of scenarios on how we can attack this architecture. Web shells. Web shells are great. So what we're going to do with web shells is we're going to demonstrate how you can use PHP code to put a simple back door that will be executed by the web server and possibly by the web server operating system. And these are web shell functions that PHP has. So this is a good idea to disable these if you don't need them. And I can guarantee that you don't need them. So we don't need execute, shell execute. If you're running shell execute, the only real example is if you're writing code for like Netgear or something like that. Or one of those small home office networking appliances where you have to run operating system code. And to do that you need to make sure that you're properly escaping and parameterizing your code or you're going to have injection problems. But as an attacker we can take advantage of this function to run code on the operating system. Eval. Eval. I hate eval. Don't use it. If you're a PHP coder please do not use eval. I can't think of a reason to do it. What eval does is it takes a string of code and executes it. So you can write PHP code that executes PHP code. I've seen some weird stuff. I've seen developers put PHP code that they pull from strings in the database and then execute it. Don't use eval. I can't stress this enough. It's a dangerous function. Disable it. Get rid of it. One of the more hidden ones is assert. Assert basically does the same thing but it's used by developers to test code and make sure that operations are running correctly and that their conditions are what they expect them to be. So you got to make sure if you're using assert that you're doing it correctly and that you're not providing user input into the assert that isn't sanitized or cleaned. And we have the create function. Create functions create takes a string of code and turns it into a function that you can call later and then using dynamic variables here in PHP we can call any function in the code. Another couple of dangerous functions is occlude. By default PHP will include files remotely. So you can store PHP code on a remote server. If you have access to the include function by a dynamic variable you can manipulate it to actually pull code remotely. So that's a good thing to disable that functionality. So here's our example web shell. It's pretty basic. We're just going to call the system and we're going to pass in a get parameter called command. We call the URL via curl or just through the web browser. We pass it command ls. We get out the output and we can see that these files, you know, shell.php is on that server. Then we can use a PHP code eval to run PHP commands and then do a little bit more discreet back door by running preg replace. Because preg replace looks pretty benign, right? You're looking through the code, oh, yeah, preg replace. I'm doing some operation I can't remember. So you can sneak that in there and it might get passed a code review and you have a possible back door inside your code. I don't have time to go into super detail about web shells but there's more information on iron geek and then Londium library of web shells is great resource. It has all kinds of web shells for pretty much any architecture you can think of. So remote code execution. There exists a multiple avenues of attack that we can attempt. First we're going to try and upload a PHP script by the MySQL write function like I said earlier. If the web server has 7777 on every variable or every file I can overwrite those files if the MySQL server and the web server on the same system. The other possibility is I can try and upload code using an upload feature. So if the web application itself has like a file up like a picture upload, I can take advantage of that and see if I can get it to pass my PHP code and write it to a file and then later execute it through the URL. Third it's kind of a last ditch effort. It's kind of a social engineering attack. I'm going to talk about wild card poisoning. This has kind of been like a vulnerability feature that's been in Linux for a very long time. It's been on the full disclosure list. That's where I found it. But basically it just takes advantage of the Linux star commands to run commands. And it's kind of an injection attack in and of itself. So writing files. Here we're going to use the into out file which is going to take our PHP code and push it to slash temp. I know by default most web applications can write to slash temp. So I send it out there, see if the query runs, look at the file, see if it's actually there yet. It is. If I can find possible write points, a good place to look is temp, cache, images, files. Basically just trying to enumerate the web application, see if you can find a place where there's weak permissions. Writeable files by MySQL. So this is the default. These are the only ones of interest I could find. So on a default install, it's kind of secure in the fact that the MySQL user is a different user that doesn't have permissions on the web server. Like I said again, if the web server and the database are running on the same system and they have the same permissions, then at this point I can change those files. Like I said, this is what I talked about earlier. Here's some more detail about a black hat presentation that was done a couple years ago. It's got more detail on remote code execution and file writing. So application upload feature. What we're going to do is if it's not filtered, we'll just upload a PHP file. If not, we'll try and manipulate the PHP file so that it can be uploaded. So here's some example vulnerable code. And here all it does is just take files from the user and upload them. So that's one way. There's other examples on there. You can look in and dig deeper on getting past filters and stuff like that. That's a little bit more advanced. So if you can't get files on the web server and you can't upload files, one thing you could try is doing a wild card poisoning attack on the system. So if my SQL user can write files, it can write to var log my SQL, right? So one thing that you could do to attack the system is just fill up the operating system, fill up the disk with my SQL general logs, right? Most database administrators, they might go in there and they'll just log full and delete it. Some of them might go in there and try and be like, well, why is it so big? Well, it's so big, I don't want to work with it on the web server, so I'm going to S copy it off the system. So using wild card poisoning is basically it works like this. So we have the LS command, the LS-L, the LS-star. If I have a file on the operating system that's dash L and I do an LS-star, that dash L is interpreted as a command that's being passed to the LS command. So we can take advantage of that. And the proof of concept is here on the defensive code down below. I've provided the link. And what this does is in this example is it takes advantage of S copy or no, this one takes advantage of tar, that one's S copy. So the administrator might tar up the file. Well, tar has a parameter that you can pass it that will actually execute code. So you can upload a bunch of file names, set them up correctly. This is something you want to test because the order is important, so you need to make sure that the file is in the correct order. And then when the administrator comes in to S copy out this file or tar up this file, they're going to run this vulnerable code and you could possibly get a shell or get access to the system. And then here's the S copy example that uses the dash O command to run a script. And so a little bit about reverse shell. So last year I did a DEF CON talk on intro to back doors and we talked about reverse shells and that cat and stuff like that. So if you're interested, this is just a basic PHP reverse shell that's taken from pentestmonkey.net. And you can just do a PHP dash R and it'll do a reverse connection and you'll be able to get remote code execution on the system. And you just set up a net cat listener, bam, you've got commands that you can run. All right, so what we've seen from this is that they're just a simple vulnerability. So someone just barely learning PHP code has completely left their system unsecured. And we were able to steal a lot of data. We were able to take advantage of the operating system. We've been able to manipulate it and even possibly gain control of the system. Just a little bit of recap, get the Etsy user password. So what's next? So at this point you have a pretty good understanding of SQL injection. A lot of this research has already been done and built into the SQL map tool. With this knowledge you can build better queries and run the tool better. So I encourage you guys to just get in there and play with SQL map and learn how it works. Here's some injection resources too if you're interested. Another thing that you might want to research too is privilege escalation because by default these systems, the Apache service and the MySQL service are not running with root privileges. So if you want to get full access and root the system you'll need to do privilege escalation. Here's some examples of PHP secure code. If you want to write PHP secure code, filter input, PHP has a great filter input library. Just set your variable length so when you're taking data in, one thing you can really do to limit the damage that someone could do is just if you have a string that's not supposed to be more than nine characters, cut it off. MySQL also has user defined functions. This is pretty cool stuff if you want to get more advanced stuff. It lets you kind of write modules and other things to take advantage of the MySQL system. Here's some security guides on how to harden your lamp stack and then for some code review and analysis here are some free tools. A lot of the RIP scanners kind of old but it kind of gives you an insight of where you might have vulnerabilities in your PHP code. Here's my credits. Icons were from Icon Archive and the background was from PPT backgrounds. Thank you.