Sky's blog

sql注入的一些技巧原理

Word count: 1,080 / Reading time: 4 min
2017/07/19 Share

前言

本篇文章大致上是基于mysql数据库……
提及的问题和技巧都比较基础,望大佬勿喷……

基础函数

user() :当前使用者的用户名
database():当前数据库名
version():数据库版本
datadir:读取数据库的绝对路径
@@vasedir:mysql安装路径
@@version_compile_os:操作系统
concat():连接一个或者多个字符串
group_concat():连接一个组的所有字符串,并以逗号分隔每一条数据
length():返回字符串的长度
substr():截取字符串
mid():截取字符串
ascii():返回字符的ascii码
sleep(): 函数延迟代码执行若干秒

基础注入语句

爆库:
select SCHEMA_NAME from information_schema.SCHEMATA limit 0,1
爆表:
select TABLE_NAME from information_schema.TABLES where TABLE_SCHEMA=数据库(十六进制)limit 0,1
爆字段:
select COLUMN_NAME from information_schema.COLUMNS where TABLE_NAME=表名(十六进制) limit 0,1
在报错注入、盲注等不同注入方式中应灵活运用

基础的注入Bypass

推荐这篇网站:http://www.cnblogs.com/joy-nick/p/5774462.html
简直是注入新手的神器!

报错注入

floor(rand(0)*2)报错

select count(*) from admin group by floor(rand(0)*2);
执行这条语句即会报错得到数据库信息
但是是有前提的,对于floor(rand(0)*2)
必须要有大于等于3条数据才可以成功使用
原理:
floor(rand(0)*2)
产生的随机数是十分有规律的,为

1
2
3
4
5
6
7
8
9
0
1
1
0
1
1
0
1
1

可见floor(rand(0)*2)的随机数是定性的,而floor(rand(0)*2)的报错则是被它的计算多次导致的
1.查询前默认会建立空的虚拟表
2.取第一条记录,执行floor(rand(0)*2),发现结果为0(第一次计算),查询虚拟表,发现0的键值不存在,则floor(rand(0)*2)会被再计算一次,结果为1(第二次计算),插入虚表,这时第一条记录查询完毕
3.查询第二条记录,再次计算floor(rand(0)*2),发现结果为1(第三次计算),查询虚表,发现1的键值存在,所以floor(rand(0)*2)不会被计算第二次,直接count(*)加1,第二条记录查询完毕
4.查询第三条记录,再次计算floor(rand(0)*2),发现结果为0(第4次计算),查询虚表,发现键值没有0,则数据库尝试插入一条新的数据,在插入数据时floor(rand(0)*2)被再次计算,作为虚表的主键,其值为1(第5次计算),然而1这个主键已经存在于虚拟表中,而新计算的值也为1(主键键值必须唯一),所以插入的时候就直接报错了。
5.整个查询过程floor(rand(0)*2)被计算了5次,查询原数据表3次,所以这就是为什么数据表中需要3条数据,使用该语句才会报错的原因。
用法:

1
2
select 1,2 union select count(*),concat(version(),floor(rand(0)*2))x from 
information_schema.tables group by x;

其中:count(),floor(rand(0)2),group by缺一不可(局限性较大,只适用于满足特定条件的数据库)

updatexml()报错

首先了解一下updatexml:
UPDATEXML (XML_document, XPath_string, new_value);
第一个参数:XML_document是String格式,为XML文档对象的名称,文中为Doc
第二个参数:XPath_string (Xpath格式的字符串) ,如果不了解Xpath语法,可以在网上查找教程。
第三个参数:new_value,String格式,替换查找到的符合条件的数据

用法:
updatexml(1,concat(0x7e,version(),0x7e),1)
注:这里的0x7e只是用来分隔而已,因为用了concat()这个函数,两个0x7e中间的才是我们需要的内容,所以这个16进制没什么特别意义
报错原理:
通过version()函数,返回版本。
然后CONCAT将其字符串化。因为UPDATEXML第二个参数需要Xpath格式的字符串,所以不符合要求,然后报错。
然后就可以根据报错得到我们需要的信息了。

Extractvalue()报错



注:现在就很清楚了,我们只需要不满足XPath_string(Xpath格式)就可以了,但是由于这个方法只能爆出32位,所以可以结合mid来使用
原理和用法上和updatexml()报错异曲同工

CATALOG
  1. 1. 前言
  2. 2. 基础函数
  3. 3. 基础注入语句
  4. 4. 基础的注入Bypass
  5. 5. 报错注入
    1. 5.1. floor(rand(0)*2)报错
    2. 5.2. updatexml()报错
    3. 5.3. Extractvalue()报错