 This talk is Max Exploitation and I'm the Rook. What we're talking about today is remote code execution vulnerabilities, specifically against PHP Nuke. In this case, we have a PHP Nuke installed running on a virtual machine and we'll be breaking into it. Okay. My exploit was released back in May. This is the code here. It's very simple. It's in this case where it's not PHP. It's Fire and Forget. We give it a domain name. In this case, we have to give it a cookie. The reason why we're giving it a cookie is because we'll go into it in a bit. In earlier versions, this exploit spans three different versions. 7.0, 8.135, 8.1, 8.0. It's very simple. Hit enter. I apologize. One moment. The configuration was incorrect. It's using the cookie that we provided it, which is a user cookie. Fuck. Fuck. Anyway. It's uploading a backdoor. Finally exploits it. Right now, it uploaded a very simple eval into frontend.php. The reason I chose this is because there's a backend.php and I figured it would be fitting to have a frontend. Now, what we're going to do is recently, just after I released this exploit, Metasploit released a very nice reverse shell for PHP. So in this case, it's the exploit, such Unix, such web app, PHP eval. We set a local host and our host and our port and you are a path to the frontend we just dropped. And then type exploit. Now, it's dropping to a shell, so you name dash A. And cat slash CTC slash PASWD. Thank you. So what was the fallout from this attack? What I really wanted was a very simple to use exploit that affected many systems. Here is a Malaysian government website and I'm going to try and pronounce that. But about a week after releasing my exploit, it showed up on zone H, defaced. Popping a shell on a dot gov. The very next day defaced again by the same crew. So then what would they do? They would go to the vendor's website to get a patch, correct? Vendor got hacked. PHP nuke.org. Thank you. So what happened here, the vendor's website wasn't defaced like the others. Instead, it added an iframe. In fact, most of the websites, they added this iframe to the bottom of the page. And what this is doing is it's a part of the Eleanor exploit pack. And in Eleanor, it tries a number of exploits trying to exploit flash, IE or Java. It is believed, from some of the write up of these antivirus companies, it's believed that a few days after PHP nuke.org was owned, the US Treasury website was also owned. And it's believed that these were the same people behind this attack. Eleanor, recently there was the Mariposa botnet, which was using the Eleanor exploit pack. And it was 1.2 million in size. This is how modern systems are broken into. You deface websites, you add an iframe, and you start hacking in the clients. So why do this? There's a very important quote by Richard Feynman. He is a Nobel prize winning physicist, one of the fathers of the bomb. What I cannot understand, what I cannot create, I do not understand. So the problem with security today is that there are a lot of white hats that don't understand the exploitation process, yet they're building systems to stop it. These systems are fundamentally flawed. I don't care if you're the most Aryan of white hats, you must understand the exploitation process. So there are two other quotes. Layers of security. I mean, this is something that's a part of nature and something that's been probably prehistory. And then there's Bruce Schneier. Complexity is the worst enemy of security. Now, these two ideas are at conflict. Because by adding layers, you're also adding complexity to the system. And this level of complexity is vulnerable to attack. For instance, there are buffer overflows found in antiviruses and even firewalls are vulnerable to attack. In this case, manage engine firewall analyzer five. I found two vulnerabilities in the software, CSRF and XSS. The problem is is that on this firewall, you're able to execute SQL queries, very similar to PHP My Admin. So in this same request, I could execute SQL on the database and the results from that SQL could be JavaScript and could be executed on the client. This is one request that fails twice. But they're not alone. There's ProFence web application firewall. And their catch line is defenses against all of the OWASP top 10. Well, someone should tell them that CSRF and XSS is a part of the OWASP top 10 because they're vulnerable to it. You can do stuff like change what server it's going through. It acts as an intermediary between the internet and the web application. So you can just change what website it's being hosted at. Or you could shut it down altogether. But what we're talking about is PHP Nuke. And one thing that I, this exploit spans almost 10 years now of releases from November 2004 until now. Currently, this is unpatched. Although the vendor's website hasn't been hacked, so there may be a patch in existence, the patch has not been made public. So anyone running PHP Nuke is currently vulnerable to this exploit. And the exploit code is on your DEF CON CD. So one thing to note though is that in the PHP Nuke 7.0 branch, there were less exploits required, less vulnerabilities required in order to gain remote code execution. If you can see on the right, there was more level of complexity. As time goes by, the application itself has gotten more secure. But what we're going to focus on is this chain here, affecting 8.135. We're using SQL injection to obtain administrative credentials out of the database. We use those administrative credentials to leverage a broken authentication and session management, OWASP-A3. And ultimately to get, well, then to get information disclosure about the system, which is required for later exploits. So for these three steps, I can do manually. I'm going to do in a web browser. So let's do it, demo. I'm going to clear out my cookies real quick, just from the beginning. Okay. Currently, we're logged in as a user. We're going to go to the journal module. We're going to list all journals. Okay. We're going to add a new entry. Test body. And we're going to use the evil face for this one. Now, we're going to fire up tamper data. So often what will happen is if you run a web application scanner, what it's going to tell you is it's going to give you the variable name that's vulnerable to SQL injection and what page it's on. Sometimes you can't modify that variable directly. So we have to use tamper data to modify it. So tamper data is set. And it's going to capture the next query. We're going to tamper that. Mood, devilish. Well, that's where the SQL injection is. So we're going to start off and we need to figure out how many variables are in this insert statement. So one, two, three. I know that it's five, but you can count this up. This can be exploited completely black box. You don't really have to know what's going on behind it. In this case, I'm just counting up one, two, three, four, five, and then a comment to finish off the rest of the query. So as we fire it off, I've modified this application to print out the query for educational purposes, but it's not required. It does help sometimes when you're exploiting SQL to print out the query. So I'm going to fire off this query on PHP Mydmin. And it's been very slow. VMware can be a bit slow at times, although it is very useful. One thing about VMware that was very helpful in this is that it allowed me to break into a virtual system and to be able to fine tune my exploit so that ultimately it could work on the vendor. Although I stress this, I never tested this on a remote system. Only in virtual environments. And I recommend that you do the same. Wow. Okay. Now, here's the important part. Let me zoom in on this. So this is the part that we injected into the query. And notice our comment here at the end. And this is commenting off the rest of the query. What's important to note here is that when you're in, when you're exploiting an insert statement under MySQL, you can't simply just stack a new query. We can't just say, hey, we want to do an insert or we want to do a, we have an insert and we want to turn into a delete. We can't do that. Instead, we have to use a different form of exploitation. So another, an important thing to note is that here are the number of columns and we have to have the number of values to correspond to these columns. So we're going to add a new entry now. And this time, we want to, we want to pull out the administrative credentials in the, in the data. Okay. One moment. Okay. So the, okay. Now the first query that we entered, we entered one, two, three, four, five. So how did that respond? How did the data change? Notice here are the first record and we have one and two that we overwrite the date and the time. And when we click on that, when we actually click on the title itself, we see one and two and four and five. Three wins somewhere. We don't know where it is. But what this is, the significance of this is that we know it's not blind sequel injection. We know that we can control some of these fields. And specifically, one and two look like great places to put our data. So instead of putting in one and two, we're going to select the username. In this case, it's AID from, we have to do a limit one because we can only have one piece of data come out, only one row come out from this subselect statement. Subselects are limited. You don't have full access to all of the operators available. But what we can do, it allows us to pull data from a different table. Correct. This is the query that we injected. If we go back to our, it should look something like this, where we would have the admin username and the password. What this allows us to do is then move on to the next step, which is be able to create an administrative credential, a cookie for this user. So we're going to make cookie. And what this is is a very simple script that allows us to create this cookie. Basically, all I'm doing is concatenating the two values together and sending it to base 64 encode. Now, if we go into the min.php, it's asking for a username and password. What we're going to do is using JavaScript in the URL, we can set the administrative credential. Admin equals this value. Hit enter. Basically, this is just telling us, yes, we've set that variable. It's still asking us for the username and password. Refresh. Now we're the administrator. Now, if we move into the preferences, what we can do is, by default, what PHP Nuke is doing is it's preventing all errors from reaching the user. This is actually an important step. Because errors give us important information about the application. In some cases, like if you're testing for SQL injection, it's vital that error reporting is turned on because it's a very good way to detect the SQL injection is there. It also allows us to get something even more important in this case, which is the local path. So we're going to enable error reporting. And it immediately vomits up on us. But the most important part is here. Is this. Now, there is actually a problem with this install, and that's why it's displaying so many errors. It shouldn't normally do this. Instead, what we would have to do is trigger the error. And in that case, what we have to do is, there is an easy way to trigger error under a PHP. And that is, by passing an array to many functions, such as, in this case, we're going to use MD5, but it could be HTML special characters or a number of functions. If you pass an array and it's expecting to see a string, it'll vomit up and throw an error. So we're going to make a bunk user. We're going to use tamper data again. Start tamper. We're going to add a new user. We only want to tamper this one request. So admin add pass is going to be passed to MD5. Instead, we're going to create a new. We're going to say add pass, and then we're going to add the brackets to it, which now makes it an array. Chunk. Click OK. So, warning, MD5 and expects parameter one to be a string array given, and it gives us the path, which is vital. So, now, something about PHP Nuke, it's been hacked a lot. It has had a very poor history of security, but because it's been hacked so many times, that it has progressed. It has been made better. Although I'm not the first to exploit at least the administrative credentials part, the administrative area has been locked down. In earlier versions of PHP Nuke, there was the ability to just modify the HTML on the front page. So you could just add a malicious iframe. Currently, we don't have that ability. There was even the ability to just upload PHP files and execute them. Well, that was also removed because so many people were gaining administrative access. In this analogy, the lowest hanging fruit represented by the apple at the bottom of the tree is a vulnerability that doesn't require much user interaction. It allows you to just, and in fact, in 7.0 to 8.0 all the way up to 8.1, there was an ability to get blind SQL injection in the refer parameter. You didn't have to create a user account. You just fire off the exploit. In my exploit, you just type in the IP address and you hit enter. It is a bit slow, so I didn't choose to use that method while I was on stage. Now, in the center of the tree is the user area. These vulnerabilities are less valuable but are still useful for exploiting the system. This level, there are a number of vulnerabilities here, but it's not as rich. At the very top of the tree is the administrative area, and that is ripe with vulnerabilities. There are very few researchers have gone after vulnerabilities in this area because it requires a lot to build off of. So in this case, OOSP-A1 injection, exploitability, easy. Yes, very easy. Impact severe. Yes, it is also severe. I agree. Detectability average. In this case, detectability, if you fire off a CAN tool like Acunetics or the open source WAPID, you will not find this vulnerability. Instead, I had to find it using more of a manual source code analysis. It turns out they have a function call called filter. If you pass in filter with one, a filter handles both XSS and SQL injection, which is terrible. When I see this behavior, it's an immediate red flag. These two vulnerabilities have very little in common and there is, they share almost no control characters. You should not be mixing these two filters. So if someone is doing this, then they probably don't understand what's going on. In this case, that is very true. By passing in one, it would still prevent XSS, but it made it vulnerable to SQL injection. I wrote up a simple regular expression in order to find any case of where a filter was being passed one. And that's how I was able to find this. Now, another thing, broken authentication session management. Technical impact, severe. Yes, we're able to get administrative access. Exploitability, average. I'd say it's very easy. Detectability, average. That could also be easy. How I found this law is I was searching the code base for set cookie. Any time I see set cookie, about nine times out of ten, when an application is doing a set cookie, it's vulnerable. You should not be handling your own session identifier. In PHP, there's session start, which is a far more secure approach. There have been vulnerabilities found in PHP's session management even this year, but they were more minor and they were easy to patch. Whereas if you write your own session, such as what PHP Nuke did, you're going to get hacked. Nine times out of ten. So this is what it looks like. In the code at the top, PHP Nuke is pulling out the password and doing a comparison, or pulling out the password based on the username, and just doing this raw string comparison. This is equivalent of having a plain text username and password. We don't actually have to break the hash in order to log in. They are using MD5. And MD5 is proven to be insecure. It's no longer supported by NIST, and it's easy to generate collisions. Collisions have been generated. Shot one, on the other hand, is still approved by NIST, but, and that's because no one has generated collision. Although there have been vulnerabilities found against it. Shot 256 is an ideal choice. And in this case, at the bottom, an example of a secure logon, we're doing assaulted shot 256 hash and using parameterized queries. And this is a very good approach. This is the code I used to generate the, the cookie. It's very simple. Like I said, it's concatenating the user ID and the password with a colon and then base 64 encoding it. Now, another thing. PHP's default configuration is horribly insecure. One thing that it has is display errors equals on. And this allows the attacker to test your application for SQL injection or even find remote paths. There are other problems with PHP's default config on every platform I've ever looked at. So on for, for, for development system, in the most cases, that's okay. However, on a production level system, you must run PHP second foe. PHP second foe is a very simple PHP script. It goes through and looking at your configurations and tells you what's wrong. If there are any red, if there's any red in, in your PHP second foe, you have to remove it. You should remove as much yellow as possible. And in most cases, you can remove all yellow to, all together. But okay. Now, there's another thing. I needed two SQL injection exploits in order to ultimately get remote code execution. Why do I need two SQL injection exploits? Also, filter bypassing. In order to exploit some of these vulnerabilities, there is actually a makeshift web application firewall built in. And I had to, I had to bypass that as well. So we're going to go to my VM. Okay. First thing I'm going to show you is a trick on filter bypassing. So oftentimes, there are regular expressions used to try and match bad input. In this case, this regular expression was being used to match input. And it's kind of cryptic what's being used, although it's simplistic. You could, you could figure this out. But RejectsBuddy makes it really easy. What it's doing is it's matching this code in the center. So, but what part of that is being matched? Using the debug feature, using the debug feature, it literally allows us to step through a regular expression. So it starts off and it shows us a number of fails, but ultimately when we get to step 32, it actually finds, it finds a part of the string that is being matched. So we notice that it's the parentheses that's being matched. And ultimately, at the very end, it matches, it even shows us what part of the query is being matched. So for instance, when we're selecting the center, it shows that part. When we actually select the parentheses, it's showing the very beginning of the regular expression. Ultimately, at the end, we have what's actually being matched. Now, in this case, we can use some encoding to bypass this. Specifically, URL and code. What's happening with the variable is it's calling a URL decode prior to its use. So what we can do is we can paste in the original code that's being matched and URL encoded again. What's happening with all PHP requests is there's an implicit URL and code, or URL decode. All input is URL decoded at least once in order to preserve HTTP protocol. This is also useful for bypassing magic quotes GPC because if there's any case of URL encode, it's simple to decode it again. Or it's simple to, in this case, at the very beginning, we have just reprinting out a quote mark. We URL encode it once and then URL encode it twice. So in this case, the URL encode of a single quote is 27 and then it turns into a 2527. The 25 is the percent mark that's actually URL encoded. Now, so one important thing to note is that with MySQL exploitation, you can both read and write files sometimes. There's the file privileges in MySQL which is the most devastating privilege you can give. It's more devastating than grant. The reason why is because you can't turn a select or insert into a grant statement. However, you can turn, you can use file IO. So in this case, we have a very simple select statement and then we can tack on a union and we can union a very simple backdoor such as PHP, VAL, GitE, which is a simple, it's very similar to our front end. Then we can say into add file. Now under, now this is, this is an important point. Under Ubuntu, there's app armor and so historically the bread and butter for exploiting lamp systems was to union select some PHP code into the web route. Well, there's no longer works. If you go to slash var slash www and say some random file dot PHP, we're going to get an error. Not a syntax error but error code 13. That's pretty cryptic but basically it's a general error, it's a fail. It's saying that we can't write to that directory. But why? Well, if we pull up the app armor rule set for MySQL, MySQL D, what this is doing is it's adding another layer of permissions on top of your usual CH mod. In this case, it's pretty simple. It's just saying it's giving it read write or read access. Now what important thing to note are these includes at the very top. What these includes are doing is it's allowing this particular include is user temp. This is giving it read write access to slash TMP. This is a safe location where we can write files. This vulnerability in app armor is systemic. It affects as far as I know all installs of app armor are affected by this. It is very common that a process needs to write to temp because it is a common requirement. So it's commonly that processes will be including this user temp file. But this whole idea, app armor is trying to separate processes. But by creating header files, you're creating unions or places where two processes have an overlap where we can write to a directory slash temp and then we can execute that file. So in our union select, if we change it to, if we change the location to slash temp, the query succeeds. We're able to upload PHP code, but now what? Well, using a local file include vulnerability, we're able to execute this code. Basically, with a local file include, we're able to give it a path of PHP code and have it executed. So using this very simple chain, we use SQL injection to be able to drop a file and then we can use a local file include in order to execute that file. This bypasses app armor. So far, I haven't heard back from the app armor team, but Ubuntu is canonical, it's very interesting in this vulnerability. Their bug response team is fantastic. I just like talking to them. There are cases where it's hard to say who has a better bug response, either Google or canonical. Ten minutes. But I would audit their software for free just to talk to their bug team. It's that good. So now there's another filter in this case. It's looking for union, simple cases of union, %20, union with comment marks or just union. Well, there's one thing that's very simple. What about union with only a comment on one side of the union, of the actual union statement? This is very simple. It's literally just a very minor, very minor change to the, to my query. I was able to bypass this very simple filter. Now, there's other cases. So what if this application didn't have a broken authentication and session management? There are other ways to gain access to the administrative administrative area. That is using CSRF. Using CSRF, if we can trick the administrator to click on a link while he's logged in, then we can force, force him to, we can force him to carry out the request. So we can force him to carry out both the SQL injection and the local and file include without having to worry about, without having to worry about the consequence, without having to worry about the first part of the chain, which I did manually. Now, there's another thing. This application doesn't have any CSRF protection in the entire, anywhere, absolutely anywhere. But if it did, you can use XSS in order to gain CSRF. And this, this attack was actually used by the SAMI worm, where I was able to use XML HTTP request to pull out the CSRF token to forge the request. Now, there's another attack is DNS rebinding, which is very popular from Dan Kaminsky. This would also allow us to attack this administrative interface. So I wrote an exploit against PHP My Admin in which I, they were, they did have very good CSRF protection for most variables. They did however have a white list here, where any, any variable name on this list could be sent from any domain. You did, it was exempt from the CSRF token. So in this case, DB and table I used, I used, were actually vulnerable to SQL injection. This is not, I couldn't just execute any query, but I was able to influence a query that was being built. So in this case, DB has to be set to any database, in this case, information schema and table I'm filling off the, the query. This is doing a union select into out file. So using local file include, we can gain remote code execution or remote system. App arm will not allow us to write to slash far. Anyway, there's another thing to note. SELinux is far more secure than app armor. And SELinux will throw this error when trying to, when trying to pull off this attack. Although it will allow MySQL to write to slash temp. What it does is it looks at the source, it looks at the owner of the file. So it's saying, hey, MySQL owns this file, but it's trying to be executed by HGPD and throws an error. Now there's an important thing to note. SELinux throws a whole lot of errors. It throws errors against, in fact, it will not even let you install PHP Nuke because of, because of errors. You have to add an exception. It's common because of this restriction that people just get upset with SELinux and install it all together. And that, that is a flaw in this, that is a flaw in SELinux. I will admit that. Although it breaks my exploits and it breaks this exploit in particular. But under the 7.0 branch, there was a very nice eval remote code execution. I was running an old version of PHPBB using prgplace slash e. With the slash e modifier allows you to eval whatever parameters are passed to it. So in this case, this actually does work with SELinux. We don't have to introduce new code. It's already there. We can just, we can just access it. Now there's a very cool paper, a study in Scarlet. This paper is a bit old, but when I read this, it was a precursor to writing my first exploit. I highly recommend that you grab a copy of this paper. It goes over a lot of the syncs and problems with PHP, such as prgplace slash e. Anyway, end. That is my talk. Thank you.