热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

谈谈OfficeMoniker类漏洞和公式编辑器类漏洞

 在近几年出现的诸多office漏洞中,有两类漏洞是很值得谈谈的,第一类是Moniker导致的逻辑漏洞,第二类是公式编辑器漏洞。对于第一类漏洞,其重点在于攻击者和微软安全团队之间的攻防过程,了解这类漏

 

在近几年出现的诸多office漏洞中,有两类漏洞是很值得谈谈的,第一类是Moniker导致的逻辑漏洞,第二类是公式编辑器漏洞。

对于第一类漏洞,其重点在于攻击者和微软安全团队之间的攻防过程,了解这类漏洞攻防过程对威胁追踪与研究较有益处:


  1. 第一回合:CVE-2017-0199,用URL Moniker加载远程HTA文件实现远程代码执行;

  2. 第二回合:CVE-2017-8570,用CompositeMoniker、FileMoniker、NewMoniker、scriptletfile实现远程代码执行;

  3. 第三回合:CVE-2017-8759,用office文档加载.Net组件漏洞,实现远程代码执行;

  4. 第四回合:CVE-2018-8174,用office文档加载IE Vbscript组件漏洞,实现远程代码执行;

  5. 第五回合:CVE-2020-0674,用office文档加载IE Javascript组件漏洞,实现远程代码执行。

对于第二类漏洞,其难点在于对相似漏洞之间的区分。从CVE-2017-11882开始,到CVE-2018-0802,再到CVE-2018-0798,三个都是非常相似的漏洞,在静态层面不容易区分,本文将分享一个在动态层面区分它们的方法。

下面跟随笔者一起来看一下这两类漏洞。

 

Moniker类漏洞



第一回合:CVE-2017-0199

2017年4月7日,著名office漏洞研究员李海飞发布了一篇在野0day攻击预警,首度披露了CVE-2017-0199漏洞的在野攻击。随后,2017年4月11日和12日,FireEye连发两篇文章,披露了他们捕获到的CVE-2017-0199漏洞样本细节。后续的披露表明这几篇文章中披露的漏洞是一种借助URL Moniker特性加载远程hta文件的新型漏洞,这是一个由于开发者对office文件加载机制设计不合理导致的逻辑漏洞,且要求触发环境安装IE10/IE11。漏洞触发过程不需要用户交互,但在触发的过程中会弹出一个对话框,不点击或者点击任意该对话框的按钮都不影响执行过程,对话框样式如下:

该漏洞的发现者之一李海飞曾经在Syscan360 2017会议上做过题为《Moniker Magic: Running Scripts Directly in Microsoft Office》的演讲,里面详细介绍了CVE-2017-0199的细节,包括:


  1. 微软在CVE-2017-0199的补丁中修复了两个漏洞,分别是被在野利用的RTF URL Moniker加载远程HTA文件的远程代码执行漏洞,和李海飞独立发现的PPSX Script Moniker远程代码执行漏洞;

  2. office安全团队在这两个漏洞的基础上设计了一类针对Moniker的黑名单机制,禁用了一些他们觉得不安全的Moniker。

Moniker本身是office的一个特性,可以用来链接一些本地或远程对象,其本身不属于漏洞,漏洞发生在office软件对远程链接的文件的执行策略上。譬如,如果远程加载的是一个Excel文件,直接打开没问题;但如果加载的是HTA文件和Script这类脚本文件时,直接执行就存在问题了,导致了漏洞。


第二回合:CVE-2017-8570

在对CVE-2017-0199补丁的研究过程中,李海飞发现(上面也已经提到):


  • office安全团队在这CVE-2017-0199的补丁中设计了一类针对Moniker的黑名单机制,禁用了一些他们觉得不安全的Moniker。

于是他开始寻找那些还没有被禁用的Moniker,尝试用那些没有被禁用的Moniker构造出另一个逻辑漏洞,结果确实找到一个,即CVE-2017-8570。

在CVE-2017-0199中,用到的Moniker是下面这两个:

3050F4D8-98B5-11CF-BB82-00AA00BDCE0B // htafile
06290BD3-48AA-11D2-8432-006008C3FBFC // scriptlet(or ScriptMoniker)

而在CVE-2017-8570中,用到的Moniker是下面这几个:

00000309-0000-0000-C000-000000000046 // CompositeMoniker
00000303-0000-0000-C000-000000000046 // FileMoniker
ECABAFC6-7F19-11D2-978E-0000F8757E2A // NewMoniker
06290BD2-48AA-11D2-8432-006008C3FBFC // scriptletfile(or ScripletFactory)

可以看到CVE-2017-8570利用未被加入黑名单的Moniker绕过了CVE-2017-0199的补丁。

不过,许多分析过CVE-2017-8570的读者可能会观察到一个奇怪的现象:漏洞中触发时script脚本中的代码会被执行两次。这是为什么呢?原来,在这个漏洞的触发逻辑中,会涉及到wwlib.dll库中的一个函数调用,该函数内部会顺序调用ole32!CDefLink::BindToSource和ole32!CDefLink::Update两个函数,如下(以office 2010为例):

而这两个函数最终都会调用kernel32!CreateProcessW创建进程,所以script脚本中的代码会被执行两次。其中ole32!CDefLink::BindToSource创建进程的栈回溯如下:

0:000> k 50
ChildEBP RetAddr
0013a5b4 729cd2f5 kernel32!CreateProcessW
0013a63c 729cd5f7 wshom!CreateNewProcessW+0x6f
0013a69c 76da3e75 wshom!CWshShell::Exec+0x19a
0013a6bc 76da3cef OLEAUT32!DispCallFunc+0x165
0013a74c 729d0267 OLEAUT32!CTypeInfo2::Invoke+0x23f
...cut...
0013ae9c 7705b5dc comsvcs!CNewMoniker::BindToObject+0x14f
0013aed0 770c3cc6 ole32!CCompositeMoniker::BindToObject+0x105 [d:\w7rtm\com\ole32\com\moniker2\ccompmon.cxx @ 1104]
0013af3c 68ee87ce ole32!CDefLink::BindToSource+0x1bf [d:\w7rtm\com\ole32\ole232\stdimpl\deflink.cpp @ 4637]
0013af80 68a61429 wwlib!wdGetApplicationObject+0x69230 // 第一处调用
0013b010 68a23b2c wwlib!DllGetLCID+0x4753b3
...cut...

而ole32!CDefLink::Update创建进程的栈回溯如下:

0:000> k 50
ChildEBP RetAddr
0013a57c 729cd2f5 kernel32!CreateProcessW
0013a604 729cd5f7 wshom!CreateNewProcessW+0x6f
0013a664 76da3e75 wshom!CWshShell::Exec+0x19a
0013a684 76da3cef OLEAUT32!DispCallFunc+0x165
0013a714 729d0267 OLEAUT32!CTypeInfo2::Invoke+0x23f
...cut...
0013ae68 7705b5dc comsvcs!CNewMoniker::BindToObject+0x14f
0013ae9c 770c3c55 ole32!CCompositeMoniker::BindToObject+0x105 [d:\w7rtm\com\ole32\com\moniker2\ccompmon.cxx @ 1104]
0013af08 7710f7ee ole32!CDefLink::BindToSource+0x14e [d:\w7rtm\com\ole32\ole232\stdimpl\deflink.cpp @ 4611]
0013af30 7710f42a ole32!CDefLink::Update+0x62 [d:\w7rtm\com\ole32\ole232\stdimpl\deflink.cpp @ 5347]
0013af44 68ee8830 ole32!CDefLink::Update+0x33 [d:\w7rtm\com\ole32\ole232\stdimpl\deflink.cpp @ 2695]
0013af80 68a61429 wwlib!wdGetApplicationObject+0x69292 // 第二处调用
0013b010 68a23b2c wwlib!DllGetLCID+0x4753b3
...cut...


第三回合:CVE-2017-8759

在CVE-2017-8570漏洞被修复后,累计有如下这些Moniker被加入黑名单:

3050F4D8-98B5-11CF-BB82-00AA00BDCE0B // htafile
06290BD3-48AA-11D2-8432-006008C3FBFC // scriptlet(or ScriptMoniker)
00000309-0000-0000-C000-000000000046 // CompositeMoniker
00000303-0000-0000-C000-000000000046 // FileMoniker
ECABAFC6-7F19-11D2-978E-0000F8757E2A // NewMoniker
06290BD2-48AA-11D2-8432-006008C3FBFC // scriptletfile(or ScripletFactory)

在前面几个Moniker不能使用之后,攻击者又注意到了下面这个Moniker:

ecabb0c7-7f19-11d2-978e-0000f8757e2a // SOAPMoniker

SOAP Moniker可以用来加载一个远程的SOAP配置文件,当Word进程远程加载这个配置文件时,.Net组件会被加载用来解析对应的配置文件,并按照配置自动生成一个C#文件,再自动将该C#文件编译得到一个动态链接库并执行。攻击者借助.Net SOAP WSDL模块中的一个代码注入漏洞(CVE-2015-8759),将恶意脚本代码注入到了待编译的C#文件中,从而让编译得到的动态链接库包含恶意代码并自动执行。

从CVE-2017-8759开始,攻击者开始借助office组件与其他Windows组件之间的交互进行攻击。.Net的漏洞本身不属于office的范围,却可以借助office文档进行触发,这种攻击方式当时给笔者留下了深刻的印象。


第四回合:CVE-2018-8174

CVE-2017-8759被修复后,Moniker黑名单又得到了更新:

3050F4D8-98B5-11CF-BB82-00AA00BDCE0B // htafile
06290BD3-48AA-11D2-8432-006008C3FBFC // scriptlet(or ScriptMoniker)
00000309-0000-0000-C000-000000000046 // CompositeMoniker
00000303-0000-0000-C000-000000000046 // FileMoniker
ECABAFC6-7F19-11D2-978E-0000F8757E2A // NewMoniker
06290BD2-48AA-11D2-8432-006008C3FBFC // scriptletfile(or ScripletFactory)
ecabb0c7-7f19-11d2-978e-0000f8757e2a // SOAPMoniker

在上面这些Moniker都不可用之后,攻击者又想出了一种新的攻击方式:借助URL Moniker去加载远程html文件,这样就可以借助office加载IE漏洞。攻击者首先用URL Moniker+CVE-2014-6332的组合试了一下该方案的可行性,笔者追溯到的这方面的最早样本为2018年1月17日的下面这个文件(以及相关文件):

// CVE-2014-6332
Document MD5: A9D3F7A1ACD624DE705CF27EC699B6B6
URL Moniker: hxxp://s.dropcanvas[.]com/1000000/940000/939574/akw.html
akw.html MD5: C40A128AE7AEFFA3C1720A516A99BBDF

到了2018年4月,攻击者终于按捺不住了,借助URL Moniker+IE Vbscript 0day的方式对特定目标进行了攻击,这次攻击所用漏洞就是著名的CVE-2018-8174,相关样本如下:

// CVE-2018-8174
Document MD5: b48ddad351dd16e4b24f3909c53c8901
URL Moniker: hxxp://autosoundcheckers[.]com/s2/search[.]php?who=7
search.htm MD5: 15eafc24416cbf4cfe323e9c271e71e7

CVE-2018-8174出现后,微软安全团队并未直接将office加载Vbscript脚本的功能进行限制。随后,在2018年7月,攻击者又借助另一个IE Vbscript 0day(CVE-2018-8173),用相同的方式实施了攻击。

这下微软不淡定了,赶紧对Office加载Vbscript脚本进行了限制。


第五回合:CVE-2020-0674

故事到这里就结束了吗?当然没有。此时,微软依然没有限制office加载Javascript脚本,所以IE浏览器的两个Javascript引擎:JScript和JScript9依然可以通过此种方式进行攻击。

其一,据笔者所知,在2018年的天府杯上,针对office项目的攻击采用了URL Moniker + IE JScript9 0day的组合。

其二,2019年-2020年,由于几个JScript漏洞被相继披露,陆续有APT攻击组织使用URL Moniker + JScript 1day的方式实施攻击,相关样本如下:

// CVE-2020-0674
Document MD5: 90403dfafa3c573c49aa52c5fe511169
URL Moniker: hxxp://tsinghua.gov-mil[.]cn/images/A96961AA/36604/1836/65449576/ab8feee
ab8feee MD5: 1892D293030E81D0D1D777CB79A0FDBE
// CVE-2020-0968
Document MD5: 60981545a5007e5c28c8275d5f51d8f0
URL Moniker: hxxp://94.156.174[.]7/up/a1a.htm
a1a.htm MD5: 293916af3a30b3d7a0dc2949115859a6

于是微软在高版本office中(office2016及以上版本)也加入了对JScript9脚本和JScript脚本的加载限制。

至此,攻击者针对Moniker的所有尝试都被微软进行了封堵,此后未观察到针对Moniker的新攻击方式。

 

公式编辑器漏洞

2017年11月补丁日,国外安全公司_embedi发表了一篇《SKELETON IN THE CLOSET: MS Office vulnerability you didn’t know about》详细描述了他们发现office公式编辑器漏洞CVE-2017-11882的整个过程(笔者发现这家公司的官网已经挂了…)。

属于office公式编辑器漏洞的时代至此开启。

由于组件源码的丢失,微软的补丁开发人员花了较长时间来修复这一漏洞,并且以一种近乎炫技的方式,直接在二进制层面对程序作了修补,在没有重新编译源码的情况下修复了漏洞,并添加了ASLR支持。

然而,一时激起千层浪,CVE-2017-11882出现后,广大安全研究员蜂拥而至,都开始关注office公式编辑器这一组件,这直接导致微软在2018年1月的更新中砍掉了公式编辑器组件。

在第二次修复的诸多office公式编辑器漏洞中,有两个漏洞比较值得注意,这两个漏洞分别为CVE-2018-0802和CVE-2018-0798,三个漏洞并称为office公式编辑器漏洞领域的“三驾马车”,

由于笔者经常看到分析人员对这三个漏洞的样本进行误判,所以这里分享一种在动态层面区分这三个漏洞的方法。

首先跟随笔者来了解一下这三个漏洞的具体成因,下文中的汇编代码基于以下公式编辑器组件:

eqnedt32.exe 2000.11.9.0

在office中,公式编辑器的数据被存储在一个OLE文件的“Equation Native”流中,三个公式编辑器漏洞都是在处理这个流的数据时出现的问题。


CVE-2017-11882

首先来看一下CVE-2017-11882。

该漏洞的成因为:在读入“Equation Native”流中的Font Name Record数据时,在将Name拷贝到某个局部变量的时候没有对Name的长度做校验,从而造成栈缓冲区溢出,漏洞发生点如下图所示:

从下图可以看出,函数给SrcStr变量分配的大小是0x24个字节,Name长度超过该大小就会造成栈溢出。

CVE-2017-11882的触发逻辑如下所示:


CVE-2018-0802

再来看一下CVE-2018-0802。

该漏洞的成因为:在将“Equation Native”流中的Font Name Record数据拷贝到一个LOGFONT结构体(位于栈上)内的lfFaceName成员(它是一个以空结尾的char型字符串,最大长度为0x20,其中包含终止符NULL),没有对Name的长度做校验,从而造成栈缓冲区溢出,漏洞发生点如下图所示:

CVE-2018-0802漏洞的触发路径和CVE-2017-11882有很大的重叠,下图可以做一个直观的比对:

由于某些限制,CVE-2018-0802在未打CVE-2017-11882补丁的版本上只会造成crash,但在打了补丁的版本上可以实现远程代码执行。


CVE-2018-0798

最后看一下CVE-2018-0798。

该漏洞的成因为:在读入“Equation Native”流中的Matrix Record数据时,存在一处while循环内的数据读取操作,由于未对Matrix的行和列两个参数进行校验,从而使攻击者可以控制由此计算得到的拷贝长度,导致栈缓冲区溢出:

上述汇编片段描述了一个while循环,反汇编成伪代码如下,攻击者可以控制伪码中v2的大小,从而导致了数据读写越界:

上述代码位于sub_443F6C函数内,所以理论上只要调用sub_443F6C函数的地方均存在CVE-2018-0798漏洞。作为与之前两个漏洞的对比,在之前两个漏洞的基础上加入CVE-2018-0798的触发路径如下:


动态区分三个公式编辑器漏洞

以上笔者已经介绍了三个公式编辑器漏洞的成因,借助上述知识,很容易在调试器中确认特定样本使用的漏洞,判定方式如下:

// CVE-2017-11882
.text:00411655 C1 E9 02 shr ecx, 2 // 获取此偏移处的ecx值,若ecx的值位于(0x20, 0x94]区间,即为CVE-2017-11882
.text:00411658 F3 A5 rep movsd
.text:0041165A 8B C8 mov ecx, eax
.text:0041165C 83 E1 03 and ecx, 3
// CVE-2018-0802
.text:00421E5B C1 E9 02 shr ecx, 2 // 获取此偏移处的ecx值,若ecx的值大于0x94,即为CVE-2018-0802
.text:00421E5E F3 A5 rep movsd
.text:00421E60 8B C8 mov ecx, eax
.text:00421E62 83 E1 03 and ecx, 3
.text:00421E65 F3 A4 rep movsb
// CVE-2018-0798
.text:00443F79 8D 04 45 02 00 00 00 lea eax, ds:2[eax*2]
.text:00443F80 83 C0 07 add eax, 7
.text:00443F83 C1 F8 03 sar eax, 3
.text:00443F86 66 89 45 08 mov [ebp+arg_0], ax // 获取此偏移处的eax值,若eax的值大于4,即为CVE-2018-0798

有些样本会同时满足上述两个或三个条件,因为这些样本中内嵌多个公式编辑器漏洞利用。


延伸

细心的读者会发现2020年极棒大赛上使用的某国产软件公式编辑器漏洞和CVE-2018-0798基本一样,有兴趣的读者可以自行对比研究。

 

参考链接

https://www.mcafee.com/blogs/other-blogs/mcafee-labs/critical-office-zero-day-attacks-detected-wild/
https://www.fireeye.com/blog/threat-research/2017/04/cve-2017-0199-hta-handler.html
https://www.fireeye.com/blog/threat-research/2017/04/cve-2017-0199_useda.html
https://0b3dcaf9-a-62cb3a1a-s-sites.googlegroups.com/site/zerodayresearch/Moniker_Magic_final.pdf
http://justhaifei1.blogspot.com/2017/07/bypassing-microsofts-cve-2017-0199-patch.html
https://www.fireeye.com/blog/threat-research/2017/09/zero-day-used-to-distribute-finspy.html
https://securelist.com/root-cause-analysis-of-cve-2018-8174/85486/
https://ti.dbappsecurity.com.cn/blog/index.php/2020/07/13/sidewinder-new-attack-target-cn/
https://ti.dbappsecurity.com.cn/blog/index.php/2020/09/18/operation-domino/
https://support.microsoft.com/en-us/help/4058123/security-settings-for-com-objects-in-office
https://www.anquanke.com/post/id/87311
https://www.anquanke.com/post/id/94210
https://www.freebuf.com/vuls/160409.html


推荐阅读
  • 这是原文链接:sendingformdata许多情况下,我们使用表单发送数据到服务器。服务器处理数据并返回响应给用户。这看起来很简单,但是 ... [详细]
  • 本文讨论了在Windows 8上安装gvim中插件时出现的错误加载问题。作者将EasyMotion插件放在了正确的位置,但加载时却出现了错误。作者提供了下载链接和之前放置插件的位置,并列出了出现的错误信息。 ... [详细]
  • 本文介绍了南邮ctf-web的writeup,包括签到题和md5 collision。在CTF比赛和渗透测试中,可以通过查看源代码、代码注释、页面隐藏元素、超链接和HTTP响应头部来寻找flag或提示信息。利用PHP弱类型,可以发现md5('QNKCDZO')='0e830400451993494058024219903391'和md5('240610708')='0e462097431906509019562988736854'。 ... [详细]
  • 在Xamarin XAML语言中如何在页面级别构建ControlTemplate控件模板
    本文介绍了在Xamarin XAML语言中如何在页面级别构建ControlTemplate控件模板的方法和步骤,包括将ResourceDictionary添加到页面中以及在ResourceDictionary中实现模板的构建。通过本文的阅读,读者可以了解到在Xamarin XAML语言中构建控件模板的具体操作步骤和语法形式。 ... [详细]
  • 导出功能protectedvoidbtnExport(objectsender,EventArgse){用来打开下载窗口stringfileName中 ... [详细]
  • 本文介绍了RxJava在Android开发中的广泛应用以及其在事件总线(Event Bus)实现中的使用方法。RxJava是一种基于观察者模式的异步java库,可以提高开发效率、降低维护成本。通过RxJava,开发者可以实现事件的异步处理和链式操作。对于已经具备RxJava基础的开发者来说,本文将详细介绍如何利用RxJava实现事件总线,并提供了使用建议。 ... [详细]
  • EPPlus绘制刻度线的方法及示例代码
    本文介绍了使用EPPlus绘制刻度线的方法,并提供了示例代码。通过ExcelPackage类和List对象,可以实现在Excel中绘制刻度线的功能。具体的方法和示例代码在文章中进行了详细的介绍和演示。 ... [详细]
  • 本文介绍了如何在Azure应用服务实例上获取.NetCore 3.0+的支持。作者分享了自己在将代码升级为使用.NET Core 3.0时遇到的问题,并提供了解决方法。文章还介绍了在部署过程中使用Kudu构建的方法,并指出了可能出现的错误。此外,还介绍了开发者应用服务计划和免费产品应用服务计划在不同地区的运行情况。最后,文章指出了当前的.NET SDK不支持目标为.NET Core 3.0的问题,并提供了解决方案。 ... [详细]
  • OpenMap教程4 – 图层概述
    本文介绍了OpenMap教程4中关于地图图层的内容,包括将ShapeLayer添加到MapBean中的方法,OpenMap支持的图层类型以及使用BufferedLayer创建图像的MapBean。此外,还介绍了Layer背景标志的作用和OMGraphicHandlerLayer的基础层类。 ... [详细]
  • 知识图谱——机器大脑中的知识库
    本文介绍了知识图谱在机器大脑中的应用,以及搜索引擎在知识图谱方面的发展。以谷歌知识图谱为例,说明了知识图谱的智能化特点。通过搜索引擎用户可以获取更加智能化的答案,如搜索关键词"Marie Curie",会得到居里夫人的详细信息以及与之相关的历史人物。知识图谱的出现引起了搜索引擎行业的变革,不仅美国的微软必应,中国的百度、搜狗等搜索引擎公司也纷纷推出了自己的知识图谱。 ... [详细]
  • GPT-3发布,动动手指就能自动生成代码的神器来了!
    近日,OpenAI发布了最新的NLP模型GPT-3,该模型在GitHub趋势榜上名列前茅。GPT-3使用的数据集容量达到45TB,参数个数高达1750亿,训练好的模型需要700G的硬盘空间来存储。一位开发者根据GPT-3模型上线了一个名为debuid的网站,用户只需用英语描述需求,前端代码就能自动生成。这个神奇的功能让许多程序员感到惊讶。去年,OpenAI在与世界冠军OG战队的表演赛中展示了他们的强化学习模型,在限定条件下以2:0完胜人类冠军。 ... [详细]
  • 恶意软件分析的最佳编程语言及其应用
    本文介绍了学习恶意软件分析和逆向工程领域时最适合的编程语言,并重点讨论了Python的优点。Python是一种解释型、多用途的语言,具有可读性高、可快速开发、易于学习的特点。作者分享了在本地恶意软件分析中使用Python的经验,包括快速复制恶意软件组件以更好地理解其工作。此外,作者还提到了Python的跨平台优势,使得在不同操作系统上运行代码变得更加方便。 ... [详细]
  • PL2303HXD电路图(USB转UART)介绍及应用
    本文介绍了PL2303HXD电路图(USB转UART)的特性和应用,该电路图可以实现RS232和USB信号的转换,方便嵌入到手持设备中。PL2303HXD作为USB/RS232双向转换器,可以将USB数据转换为RS232信息流格式发送给外设,并将RS232外设的数据转换为USB数据格式传送回主机。通过利用USB块传输模式和自动流量控制,PL2303HXD能够实现更高的数据传输吞吐量比传统的UART端口。 ... [详细]
  • 本文介绍了JavaScript进化到TypeScript的历史和背景,解释了TypeScript相对于JavaScript的优势和特点。作者分享了自己对TypeScript的观察和认识,并提到了在项目开发中使用TypeScript的好处。最后,作者表示对TypeScript进行尝试和探索的态度。 ... [详细]
  • 项目运行环境配置及可行性分析
    本文介绍了项目运行环境配置的要求,包括Jdk1.8、Tomcat7.0、Mysql、HBuilderX等工具的使用。同时对项目的技术可行性、操作可行性、经济可行性、时间可行性和法律可行性进行了分析。通过对数据库的设计和功能模块的设计,确保系统的完整性和安全性。在系统登录、系统功能模块、管理员功能模块等方面进行了详细的介绍和展示。最后提供了JAVA毕设帮助、指导、源码分享和调试部署的服务。 ... [详细]
author-avatar
手机用户2502876057
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有