首先要了解什么是联合注入,联合查询注入是回显注入的一种,也可以说联合注入的前提是,页面上要有回显位。那又引出了另一问题,什么是回显位?
在一个网站的正常页面,服务端执行SQL语句查询数据库中的数据,客户端将数据展示在页面中,这个展示数据的位置就叫回显位。
联合注入通常是有一定的步骤:
1. 判断注入点
2. 判断注入类型(数字型型or字符型)
3. 判断字段数
4. 判断回显位
5. 确定数据库名
6. 确定表名
7. 确定字段名
8. 拿到数据
下面是结合实列演示的一个完整的联合注入过程:
1. 判断注入点
我们通过在变量后加payload来判断注入点:
and 1=1 /and 1=2 /' 通过输入这些payload后的回显页面,我们轻松看出是否存在注入;
另外MYSQL有三种常用的注释符:
-- 该注释符后面有一个空格;
/* */ 注释符号内的内容;
# 对该行#后面的内容进行注释。
2. 判断注入类型
数字型的sql语句大概是下面这这类型:
select * from 【表名】 where id = 1
测试步骤:
1. 加单引号,这时sql语句后面多了一个单引号,会报错;
2. 加and 1=1,语句正常执行,页面与原始页面相同;
3. 加and 1=2,语句也可以正常执行,但页面会与原始网页存在差距
如满足以上三点,可以判断此处存在数字型注入
字符型注入的sql语句为:
select * from 【表名】where name = 'zhangsan’
同样加单引号,但后面要带上注释符来注释掉后面多余的单引号,具体还是拿sql语句直观看一下:
select * from 【表名】where name = 'zhangsan’ and 1=1 #'
第二个单引号是我们自己加的,用来'闭合前一个引号以便我们在后面继续加代码,#用来注释掉最后面多余的'
当回显正常时我们可以判断此处为字符型注入。
3. 判断字段数
order by 函数是对MySQL中查询结果按照指定字段名进行排序,除了指定字段名还可以指定字段的栏位进行排序,第一个查询字
段为1,第二个为2,依次 类推。若输入数值为n时报错,那么表示没有n个字段,总的字段数为n-1。
4. 判断回显位置
通过上一步我们可以知道字段数,然后通过union select 1,2,3 ······n (n的数值为字段数)来判断回显位置
代码写的比较粗糙,四个字段都有回显,而一般情况下只有个别位置会有回显,我们要利用的就是这些位置
5. 确定数据库名
database() 显示当前数据库
在有回显的位置写入命令
6. 确定表名
http://127.0.0.1/727/index.php?id=1 union select 1,group_concat(table_name),3,4 from information_schema.tables where table_schema=database();
7. 确定字段名
http://127.0.0.1/727/index.php?id=1 union select 1,group_concat(column_name),3,4 from information_schema.columns wheretable_name='users' and table_schema=database();
8. 拿到数据
http://127.0.0.1/727/index.php?id=1 union select 1, user,pass,4 from users where id =1