SQL Injection : Syntax error - sql-injection

I have an essay on SQL injection ( what it is - how its done and how can it be avoided ). I get what it is and how it works. But i dont seem to be able to reproduce an injection on my database.
I made a pretty simple database ,using mysql workbench, meant for a video club. movies - stock - price - customers shopping cart etc.
I also made a pretty simple html page from which i can add movies - view what i have in stock etc.
So i have a txt field in which i enter a movie name and i get back some info for this specific movie.
The code that gets the name i type and makes the query is ::
$name = $_POST ['txtfld'];
$sql = ("SELECT * FROM test_table WHERE adad = '$Mname'");
if ($result = mysqli_query($dbc,$sql))
Now when i give 'a' as an input everything works as expected. I get back the one entry that has pk equal to [a].
Query becomes :: SELECT * FROM test_table WHERE adad= 'a'.
Next step was to see if i can get the whole table or some random entry from it.
Input was : [ a' OR 'x'='x ]
Query becomes :: SELECT * FROM test_table where adad = ' a' OR 'x' = 'x '
Everything works as expected and i get back the whole table contents.
Next step was to try inject a second query. I tried to update the test_table.
Input was :: [ a;' update test_table set asda = '123456' where adad = 'u ]
Query now becomes :: SELECT * FROM test_table WHERE adad= ' a;' UPDATE test_table SET asda ='123456' WHERE adad = 'u '
I got a syntax error so i tried every syntax i could think of including
[ a;' UPDATE test_table SET asda = '123456' where adad = 'u';# ]
. None of them worked.
Thing is, i dont really get why i get a syntax error.
For the input given above mysqli_error returns this message
error: You have an error in your SQL syntax; check the manual that corresponds to your
MySQL server version for the right syntax to use near 'update test_table set asda =
'123456' where adad = 'u'' at line 1
while an echo i inserted returns this
SELECT * FROM test_table WHERE adad = 'a;' UPDATE test_table SET asda = '123456' WHERE
adad = 'u'
I dont see any syntax error in the echo return and i dont get where the second [ ' ] character in the end of the mysqli_error return, comes from.
From what i understand this is rather a failure in executing a second query ( no matter what the query is - drop, insert, update )
Do i miss something?
Thanks in advance.
Michael.

mysql's PHP driver does NOT allow multiple queries in a single ->query() call, exactly for this reason. It's an anti-injection defense, to prevent the classic Bobby Tables attack. This true for all PHP db interfaces (mysql, mysqli, pdo), as they all use the same underlying mysql C api library to actually talk to the db. Any attempt to run 2+ queries in a single query call results in the syntax error.
Note that it does NOT protect against your ' or 1=1 injection, however.

In order for your stacked query injection technique to work, you will need to use the "mysqli_multi_query()" function:
http://php.net/manual/en/mysqli.multi-query.php
http://www.websec.ca/kb/sql_injection#MySQL_Stacked_Queries
MsSQL is the only database that supports stacked queries by default.
Also possibly a better injection technique, and a more reliable one, would be a UNION attack, and then dump the MySQL credentials from the "mysql.user" table, then use these to compromise the database.

Related

Postgres - Pull results from multiple tables based on declared variable

I am new to Postgres. I have 7 tables that have a common field (AcctID). I would like to pull results from each of the tables (without joining) based on the AcctID that I set (e.g. AcctID = '2352').
DO $$
Declare
AcctID := '2352';
BEGIN
Select * from pbx.users where acct = AcctID;
Select * from pbx.transactions where acct = AcctID;
Select * from pbx.logs where acct = AcctID;
....
END;
$$;
I get error message that query has no destination. Any recommendation is greatly appreciated.
The error message is essentially telling you: "okay, so you want to pull these results, but then what?"
It is unclear to me why a join is inadequate for you, it would make things so much easier.
For this purpose, you can create a stored procedure, using a composite out parameter, such as the one proposed as an answer to this question: Composite Array Type as OUTPUT parameter in PostgreSQL
Yet, instead of that I really recommend the use of joins, such as
Select *
from pbx.users
join pbx.transactions on pbx.users.acct = '2352' and pbx.users.acct = pbx.transactions.acct
join pbx.logs on pbx.transactions.acct = pbx.logs.acct;

how to get full statement in PostgreSQL

i wonder how to get full query statement in postgresql, when i set log_statement = 'all' in data/postgresql.conf, i can track the query record in log/ directory, but they log the query is:
LOG: Select * from table where id = $1
DETAIL: parameters: $1 = 55,
when there just a small amount param, that is clear. But if many params exist in that query,
that maybe frastrated me. if any some setting in postgresql that i need set, so i can directly get full statement such as
Select * from table where id = 55
No, there is no way to get that in the log, because that is not what arrives at the server. However, it should be easy to write a Perl (or other) script that reformats a log like that.

Get the ResultSet of an SQL injection

Suppose the server side code is something like that:
String id = getIdFromHttpRequest();
String value = getValueFromHttpRequest();
ResultSet rs = new ResultSet();
String query = "INSERT INTO users VALUES ('" + id + "', '" + value + "');"
rs = SQL.doQuery(query); // i know it's not the syntax, but the point is clear
Well, the injection is easy, I can make it execute an SQL command, but the problem is I want to see the result set (I inject SELECT command).
Is there a way of doing so?
You probably cannot achieve this.
As you know, an INSERT statement has no result set, even if you use SQL injection. At best, you could make it execute a SELECT as a scalar subquery. It's not hard to spoof your example to execute the following:
INSERT INTO users VALUES ('8675309', '' || (SELECT ...blah blah...) || '');
But that still would not return a result set, because INSERT never has a result set.
You would need to execute a second query to do that. Some query interfaces do support multi-query in a single call to doQuery(), but this is not always true (depends on the brand of database you use, and possibly some configuration options).
INSERT INTO users VALUES (...whatever...);
SELECT * FROM secure_table WHERE (id = '8675309');
With SQL injection, you can manipulate the SQL, but you can't manipulate the rest of the code in the application that runs the SQL. In the example you show, the app is designed to run an INSERT query, not an INSERT followed by a SELECT. The app would have no reason to fetch a result set after executing an INSERT.
It's hard to imagine how you could use SQL injection alone to trick the code you show into fetching and displaying a result set.
I don't think it is possible to use SQL injection do read data by exploiting a non-reading query.

DB2 - If table is empty for date X, insert, else go on

--DB2 version 10 on AIX
I have a stored procedure, which I need to update. And want to check if there is data for a certain date. If data exists, go on, else run insert and then go on.
IF (SELECT COUNT(*)
FROM SCHEMA1.TABLE1_STEP1
WHERE XDATE = '9/27/2014' < 1)
THEN (INSERT INTO SCHEMA1.TABLE1_STEP1 (SELECT * FROM SCHEMA2.TABLE2 FETCH FIRST 2 ROWS ONLY))
END IF;
This errors-out.
DB2 Database Error: ERROR [42601] [IBM][DB2/AIX64] SQL0104N An unexpected token "(" was found following "/2014') < 1) THEN". Expected tokens may include: "". SQLSTATE=42601
Any thoughts on what's wrong?
I'm guessing you probably want the less than sign outside of the parenthesis...
However, as an aside, you can also do this kind of statement without an IF (although, I don't have an AIX DB2 available to check for sure. It worked on DB2 for z/OS and LUW, however):
INSERT INTO SCHEMA1.TABLE1_STEP1
SELECT *
FROM SCHEMA2.TABLE2
WHERE NOT EXISTS (
SELECT *
FROM SCHEMA1.TABLE1_STEP1
WHERE XDATE = '9/27/2014'
)
FETCH FIRST 2 ROWS ONLY
Also, you're not providing an ORDER BY on the SCHEMA2.TABLE2 select, so your results could come back in any order (whatever is "easiest" for the database engine)... order is not guaranteed unless you provide the ORDER BY statement.

How to get data from specific column in firebird using rdb$field_name

how to get data from a specific column in fire bird? something like.
select from rdb$relation_fields
where rdb$relation_name = 'table' and rdb$field_name = 'code'
Your question doesn't quite make sense to me - if you already know the table and field name (as you do in your example) then why not select directly from the table? Anyway, you can create SQL statement dynamically in PSQL as string and then execute it using EXECUTE STATEMENT. The EXECUTE BLOCK might also be of intrest, depends where and what exactly youre tring to achieve.
EDIT after reading the comment
So just build the SELECT statement at the client side, selecting the field currently selected in combobox. You don't mention the language you use but generaaly it something like
query.SQL := 'SELECT '+ comboField.Text +' FROM '+curTableName;
query.Open();
// read the resultset