天天看点

记一次sql注入实践

今天开发代码的时候发现自己的sql全是拼接的,不是where a = ?的那种,细思恐极啊,于是进行了一场sql注入实践。虽然失败了,但是还是得出了一些宝贵的经验。

首先从一个基础的分页查询语句开始分析:

Select r.a,r.b  from role r where r.name like ‘role%’  order by r.create_time desc liimit 0,10;

说明:用户在界面输入的是role,其他都是stringbuilder拼接的。

一开始尝试使用如下输入:’delete from x ‘

那sql语句变成如下形式:

Select r.a,r.b  from role r where r.name like ‘’delete from x ’%’  order by r.create_time desc liimit 0,10;

看到的现象是前端没有查询到数据,给了弹框提示,但是分页条显示undefined.

后来从网上查到sql 的like 注入可以是下面的形式:

%' AND 1=1 AND '%'='

那sql语句则变成如下形式:

SELECT r.a,r.b  FROM role r WHERE r.name LIKE '%' AND 1=1 AND '%'='%'  ORDER BY r.create_time DESC liimit 0,10;

这样的话一眼就看出来这是个正常的sql语句,并且可以被注入,是不是有点小儿科或者感到惊恐。放到数据库里执行应该是没有问题的。

那怎么才能更有威胁性呢,看如下sql语句:

SELECT r.a,r.b  FROM role r WHERE r.name LIKE '%' AND 1=1 ;DELETE FROM rule  WHERE 1=1 ; AND '%'='%'  ORDER BY r.create_time DESC liimit 0,10;

那现在只要稍加修改就可以变成下面的形式:

SELECT r.a,r.b  FROM role r WHERE r.name LIKE '%' AND 1=1 ;DELETE FROM rule  WHERE 1=1 ;SELECT * FROM role r WHERE 1=1 AND '%'='%'  ORDER BY r.create_time DESC liimit 0,10;

到此一个sql注入语句就出现了,这样的sql在可视化界面里是可以执行通过的,那用户实际输入的内容是什么呢,如下:

%' AND 1=1 ;DELETE FROM rule  WHERE 1=1 ;SELECT * FROM role r WHERE 1=1 AND '%'='

当这个构造好的sql到应用程序里面会发生什么呢?

当然在我的服务器里报错了,报错日志显示sql语法不对,从delete开始到后面的构造部分。原因就在于PreparedStatement在起作用,具体原理不再叙述。

到这里就结束了,我没有在前端发起的注入内容删除数据。

为啥用户会这么输入呢??

当然是有人恶意攻击咯,如果真猜出你的数据库表名并准备实施攻击的话,那是不是要过一遍自己写的代码或者检查一下有没有用PreparedStatement预编译呢?

或者这是你自己进行的测试,如果你想有PreparedStatement的话是不是就万事大吉了。

答案是否定的,黑客可不会这么low.他们想这么做的话一定有办法。

虽然你的系统在内网,你的应用访问量不多,等等,但是我们必须要知道这种威胁的存在,并且防患于未然。

那最好的方式是什么呢?

1.从产品层面来说要规避用户输入特殊字符(不要相信前端输入的数据),因为正常用户不会输入这么复杂的文本来测试你的程序,我们要做的就是正常请求,正常返回。

2.从技术上来说可以将输入的特殊字符转译。(这个工作可以在前端做,也可在后端)

3.从技术组件来说要从底层使用PreparedStatement进行预编译。

继续阅读