So I have a project with work to try and teach my boss to start using prepared SQL statements, but he could care less and says it's not a big deal. I want to know how to prove to him it is a big deal, but I just can't figure out how to inject a drop table command on the development test server we have set up. I developed an application for a company that is in its testing phase and I want to take it down (have back up) to present to him the issue, as I am using his SQL code. I am trying to get the company to get in habit of using prepared statements, but I seem to be the only one wanting change and they don't. Can someone help me "crack" this database with SQL injection? Thanks!!
There is a comment box on the form to be submitted and when it sees an apostrophe it throws the error:
Unable to Make Query: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 's";', '100', '100')' at line 78
foo'); DROP TABLE cabletypes;--
but gives same error. How can I make it inject successfully when I am typing in the textarea prior to form submission? The textarea submits to the 'comments' column and value.
$sql="INSERT INTO cabletypes (cable_type, sample_no, sample_date, section_lg, wet_dry, avgofppf, sheath_type, plastic_wt, inner_sheath, inner_al_wt, inner_steel_wt, cable_guard, guard_al_wt, guard_steel_wt, guard_other_wt, total_pairs_a, pair_count_gauge_a, copper_wt_a, total_pairs_b, pair_count_gauge_b, copper_wt_b, total_pairs_c, pair_count_gauge_c, copper_wt_c, total_pairs_d, pair_count_gauge_d, copper_wt_d, sum_pairs, copper_wt, copper_percent, lead_wt, lead_percent, contains_lead, waste_wt, sampler, supervisor, comments, cable_no, section_no) VALUES ( '$cable_type', '$sample_no', '$sample_date', '$section_lg', '$wet_dry', '$avgofppf', '$sheath_type', '$plastic_wt', '$inner_sheath', '$inner_al_wt', '$inner_steel_wt', '$cable_guard', '$guard_al_wt', '$guard_steel_wt', '$guard_other_wt', '$total_pairs_a', '$pair_count_gauge_a', '$copper_wt_a', '$total_pairs_b', '$pair_count_gauge_b', '$copper_wt_b', '$total_pairs_c', '$pair_count_gauge_c', '$copper_wt_c', '$total_pairs_d', '$pair_count_gauge_d', '$copper_wt_d', '$sum_pairs', '$copper_wt', '$copper_percent', '$lead_wt', '$lead_percent', 0, '$waste_wt', '$sampler', '$supervisor', '$comments', '$cable_no', '$section_no')"; } mysql_query($sql) or die ("Unable to Make Query:" . mysql_error()); print("Sample Sheet Submitted Successfully!");
You can't issue multi-query SQL in PHP's ext/mysql interface. So you can't do the
; DROP TABLE Students trick at all. This one of the few points in favor of the deprecated mysql extension.
Ironically, PDO supports multi-query by default for all queries. And Mysqli supports it only if you explicitly call mysqli::multi_query().
But DROP TABLE is not the only illicit thing an attacker may try to do with SQL injection. In fact, an attack that does DROP TABLE is malicious, but gains the attacker nothing of value. Most SQL injection attacks are more methodical.
I can think of an exploit for your example INSERT statement:
http://yourapp.example.com/cable_types.php?supervisor=jflay',(SELECT GROUP_CONCAT(CONCAT(table_name,'.',column_name)) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema=DATABASE()), NULL, NULL) --
Voilà! I have just created a cable type whose comment tells me all the tables and columns in your database. I can then use this knowledge in subsequent attempts to exploit other pages in your site.
(Actually, this may not be a sure example, because GROUP_CONCAT has a length limit of 1024 characters by default, and your full set of columns is probably longer than that. You can use this exploit to get the same information but perhaps it'll take several INSERT queries.)
Anyway, your boss really should use parameterized queries for the sake of security, and also for the sake of supporting strings containing apostrophes, but also ease of coding and for performance. Tell him that prepared statements perform 14% faster than non-prepared statements.
Send him the old story of Exploits of a Mom:
<img src="https://i.stack.imgur.com/R6WxZ.png" alt="enter image description here">
There's a nice example of numerous MySQL injection attacks here: http://www.rackspace.com/knowledge_center/article/sql-injection-in-mysql
(Modern?) PHP prevents multiple statements being issued qith mysql_query, which helps stop some types of SQL injection: https://stackoverflow.com/a/10663100/74585
The old book CGI Programming with Perl, 2nd Edition is worth a read, even if you don't use CGI or perl, as its security chapter brilliantly demonstrates that the essence of avoiding things like SQL injection attacks is to <strong>never trust input from the user</strong>.
If you store your customers in a database, try using
Tom O'Brian as a customer name, and watch the insert statement fail. Then explain that he's losing business because of it.