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

MD5碰撞的演化之路

        2016年1月20日        主编  白名单分析组        0x1概述自从王小云破解MD5算法后,国内外对MD5碰撞的相关研究与恶意利用从未停止。MD5算法的应用领域很多,

http://p5.qhimg.com/t016420f0012a22be6b.png

        2016年1月20日

        主编  白名单分析组

        0x1概述

自从王小云破解MD5算法后,国内外对MD5碰撞的相关研究与恶意利用从未停止。MD5算法的应用领域很多,就软件安全方面来说,陆续发现了一批利用MD5碰撞对抗安全软件的恶意样本。这些样本中,大部分采用早期的一种较为成熟的快速MD5碰撞利用方式,然而有一部分比较特殊,因其采用了新型的碰撞方式。

这种新型的碰撞样本在2014年初开始出现,当时还处于测试阶段,所以只有少数样本在传播。直到2015年初,新型碰撞样本大规模爆发,经过分析和追踪,可以确定采用新型碰撞手法的大批量样本是由同一团伙制做,后续称为碰撞作者。2015年9月,对抗升级,碰撞作者开始结合数字签名利用技术与安全软件对抗。2015年11月,碰撞作者进行新的尝试,利用双签名对抗查杀。下图是该碰撞作者近两年对抗手法的演化的过程:

http://p9.qhimg.com/t0161eca4b080dbeaab.jpg

图1-1 碰撞作者近两年的攻击演化过程

根据上面的演化过程,本文将围绕碰撞作者各阶段的利用手法展开详细的分析。首先,介绍新型MD5碰撞的特点,通过与早期版本的对比来认识新型碰撞手法的“先进性”。接着,进一步介绍新型MD5碰撞与数字签名结合的高级利用手法,以及碰撞作者放弃碰撞方法而采用双签名进行对抗的新尝试。然后,通过一例样本的行为分析介绍碰撞作者的典型攻击流程。最后,对碰撞作者的恶意软件传播和影响进行统计与信息挖掘。

        0x2新型碰撞特点

早期的碰撞样本,主要采用“前缀构造法”,以同一个给定的前缀程序A为基础,在尾部添加不同的附加数据,得到两个具有相同MD5的样本B和C,如下图所示:

http://p0.qhimg.com/t01022c1619dc8746dd.jpg

图2-1 早期MD5碰撞的利用手法

前缀构造法碰撞后的两个样本只有尾部少量字节不同,而程序代码是相同的。通过判断尾部数据的差异,两个样本可以执行不同的程序流程。由于这种碰撞手法是通过同一前缀程序碰撞生成的两个样本,如果其中有恶意代码流程则两个样本均包含恶意代码,所以比较容易被安全软件识别,隐蔽性较差。

而采用新型的MD5碰撞手法,得到两个MD5校验值相同的样本,一个是恶意程序,另一个则是正常程序,它们在功能和代码上完全不同。由两个不同的前缀程序A和B分别在尾部添加附加数据,构造出具有相同MD5的程序C和D,如下图所示:

http://p0.qhimg.com/t01c274ba7cb028ebb0.jpg

图2-2 新型MD5碰撞的利用手法

这一阶段,碰撞作者主要是通过正常程序与恶意程序两种不同程序碰撞相同的MD5来对抗安全软件。比如这样一组样本,正常程序是一个dll程序,恶意程序则是一个加了vmp强壳的流氓日历exe程序:

http://p0.qhimg.com/t017a4757f926dda155.jpg

图2-3 一组新型碰撞样本的静态特征

而这两款毫不相关的程序MD5值校验却神奇的一致:

http://p8.qhimg.com/t01e4972a5db624f63f.jpg

图2-4 一组新型碰撞样本的MD5计算结果

通过图2-3和图2-4,证实了两种不同格式的程序,其文件MD5是可以相同的。然而这种现象并非偶然,而是碰撞作者能够大批量制造的真实案例。为了深究其技术手法,仔细比较一下这两个文件的数据如下:

http://p4.qhimg.com/t0131deff55081795c2.jpg

图2-5 一组新型碰撞样本的文件数据比较

从图中可以看出,两个文件绝大部分数据不同,但尾部数据高度相似,而且文件大小一致,这种构造方式是基于“选择前缀碰撞法”(Chosen-prefix collsion[[1]])实现的,其原理图大致如下:

http://p3.qhimg.com/t018ac81e6578107a6c.jpg

图2-6 “选择前缀碰撞法”原理

通过选择不同的前缀,计算生日数和碰撞块添加到文件尾部,即可得到两个具有相同的MD5的文件。不过,要计算出这些尾部数据并不容易,直接使用hashclash[[2]]的工具需要相当大的时间成本,但是碰撞作者对该工具进行改进后已经能够高效完成大量正常程序与恶意程序的碰撞了,以下为此阶段样本的典型样例(每组正常程序与恶意程序对照),由于碰撞的原理与文件格式无关,所以样本形态呈现了多样化的特点。

https://img8.php1.cn/3cdc5/15d29/711/c6a657a6bb3f161c.png

图2-7 此阶段碰撞样本的典型样例

其中,碰撞的样本对中,恶意程序主要为桌面软件的组件[[3]],而正常程序则是任意的软件。由于每组样本都对应同一个MD5指纹,碰撞作者便借此来对抗安全软件对其恶意程序的查杀。

        0x3签名利用

数字签名具有校验程序是否被非法篡改的功能,针对签名的攻击形式多样,比如Flame病毒曾利用哈希碰撞伪造微软的数字证书[[4]]。一般情况下在带签名的程序后面任意添加数据,签名会显示无效。在前一阶段被使用的前缀程序都没有数字签名,但九月初,我们捕获到了MD5碰撞样本的新版本,碰撞作者巧妙的使碰撞后的样本延用了前缀程序的有效签名。

http://p5.qhimg.com/t015dda68f656dc2dac.jpg

图3-1 加入签名利用的MD5碰撞手法

这阶段碰撞样本的显著特点是,前缀程序中的正常程序大部分是带有签名的msi程序,在其尾部添加了碰撞数据后签名却还是有效的,这主要是利用了msi程序的特性——对任意带签名的msi程序,在其尾部可以任意添加修改附加数据而不影响签名的有效性,如下图所示。于是,MD5碰撞多了数字签名这个保护伞,大大提高了与安全软件的对抗强度。

http://p9.qhimg.com/t01660ad797d0491205.jpg

图3-2 MD5碰撞对中的带签名msi程序添加附加数据后签名仍有效

以下是被利用的msi程序的部分签名列表:



Adobe Systems, Incorporated

Amazon Services LLC

Apple Inc.

IObit Information Technology

March Hare Software Ltd

Microsoft Corporation

Mozilla Corporation

Realtek Semiconductor Corp

TAOBAO (CHINA) SOFTWARE CO.,LTD.

Tencent Technology(Shenzhen) Company Limited

图3-3 部分被利用的msi程序的签名列表

比较特别的是,在此阶段后期发现了一对特殊的碰撞样本,分别是具有有效微软签名的msi程序和腾讯签名的exe程序(如下图)。可见,除了带签名的msi程序外,该碰撞作者也实现了对带签名PE程序的碰撞。

http://p3.qhimg.com/t015888ebc336312fbc.jpg

图3-4 两个程序都带数字签名的碰撞样本

对比一下碰撞后的腾讯exe文件和原始程序:

http://p5.qhimg.com/t01617b4afc3766f144.jpg

图3-5 带签名PE程序碰撞后的文件与原始文件的对比

可以看出,碰撞作者对PE文件结构的Security数据目录进行了修改,说明其改变了签名信息的大小,扩充了尾部签名串的数据长度,并且修改了对应的签名数据以保证签名的有效性,从而达到和msi程序的签名“漏洞”一样的效果。

        0x4双签名验证

2015年11月初,发现了碰撞作者的新动向,他给一个程序构造两种不同的数字签名。如图,这个恶意样本在未打补丁的win7系统只看到一个无效的签名,而在更新过补丁[[5]]的win7系统中却显示了两个不同的数字签名,第一个签名仍是无效签名,而第二个则是正常的签名。

http://p7.qhimg.com/t01b3b3b6599b2cca25.jpg

图4-1 双签名样本在不同的系统环境中的签名显示

碰撞作者这是有意识的利用双签名对抗安全软件的签名验证,因为那些在旧系统中运行正常的签名验证程序,在升级到支持双签名后的系统中可能会爆发出严重的验证逻辑漏洞。

为了说明这个手法,用两个小工具[[6]],分别在旧系统和支持双签名的系统中进行签名校验。

http://p7.qhimg.com/t01026aa8359c4ee2eb.jpg

图4-2 在未打补丁的win7系统中对双签名样本进行校验

上图是在未打补丁的win7系统中对样本进行签名校验的结果,第一步验证签名有效性时就出错,即使第二步获取的签名串真实存在,签名验证的结果也是失败。而如果是在更新了补丁的Win7系统下使用同一套工具对同一个样本进行签名校验:

http://p1.qhimg.com/t0142da70e015d87558.jpg

图4-3 在更新过补丁的win7系统中对双签名样本进行校验

如图,第一步验证签名完整性时显示签名正常,第二步获取签名信息的时候只获取了第一个签名串的信息,从而这个原本无效的伪造签名可能会被认为是有效的。之所以这样是因为,旧系统中不支持双签名,编写签名验证程序时一般就默认一个程序只有一个数字签名。

同样,如果安全软件在系统升级后没有考虑到双签名验证的情况,很有可能按照类似“正常”的逻辑判定这个恶意样本伪造的签名有效。可见,碰撞作者是想钻双签名验证这个空子来绕过签名验证。

        0x5典型攻击流程分析

下面以2015年12月的样本为例分析恶意程序的攻击流程。

首先查看样本的数字签名,发现具有一个伪造的无效签名,但是当程序运行触发恶意行为之后,签名的状态却神奇般地变成有效的:

http://p8.qhimg.com/t0105e553ba05e0450f.jpg

图5-1 安装样本运行前后数字签名的状态对比

为了找出这种现象的原因,具体分析该样本的代码。此样本是经过NSIS打包的安装程序,解包得到脚本和其他资源文件。分析安装脚本,该恶意程序首先对运行环境进行检测:

http://p0.qhimg.com/t01da8f5aebfab0e874.jpg

图5-2 安装脚本对运行环境进行检测

通过系统调用遍历进程,检测的部分进程列表如下图所示,其中大部分是网吧或分析调试的系统环境,猜测是为了控制样本传播的范围:

http://p3.qhimg.com/t01f5c4debdc71dff64.jpg

图5-3 安装程序检测的部分进程列表

然后程序会判断自身的文件名是否为“s*.exe”,并且检测启动该程序的父进程是否为桌面进程,目的是避免下载该程序的用户直接点击运行触发恶意行为引起注意,而只让该程序作为被其他程序推广启动时才触发:

http://p8.qhimg.com/t01de979e87399044d6.jpg

http://p3.qhimg.com/t01e90d584e81ae52f5.jpg

图5-4 安装程序判断程序文件名与父进程

当文件名判断不通过时,程序作为桌面日历安装包运行,不触发恶意行为。

http://p6.qhimg.com/t01f624b1c6bf58e24d.jpg

图5-5 安装程序不触发恶意行为的运行界面

当符合所有触发条件时,就可以触发恶意行为:安装程序会静默下载碰撞作者服务器上的加密压缩文件update003.zip,使用特殊密码解压后执行其中的gpmc.msi程序,最后又清理了作案现场。恶意行为的主要程序代码如下图所示:

http://p3.qhimg.com/t01b95baa04d6a50352.jpg

图5-6 安装程序的主要恶意代码

从update003.zip解密得到的两个文件gpmc1.msi和gpmc1.cab,gpmc1.msi程序负责解压gpmc1.cab文件并调用其中的正常编译工具NMAKE.exe,gpmc1.cab文件解压如下:

http://p2.qhimg.com/t018e877e67f6db718a.jpg

图5-7 gpmc1.cab压缩包内文件列表

NMAKE.exe被运行后,makefile文件中的命令就会执行,通过这种特殊的方式实现由正常的程序连续调用外部的恶意程序:

http://p4.qhimg.com/t0137bbd24440c0bf41.jpg

图5-8 makefile文件的调用命令

这里关注u.exe这个程序,它其实是微软官方的根证书列表更新工具updroots:

http://p5.qhimg.com/t01fda8b7c3fdecf48e.jpg

图5-9 数字签名根证书数据导入工具

利用该工具导入事先伪造好的一份CA根证书数据文件u,结果会在系统注册表的根证书路径添加一个信任项,并导入伪造的CA证书公钥等相关数据:

http://p4.qhimg.com/t014212d252a784b501.jpg

图5-10 用户系统被导入的根证书数据路径

恶意程序通过这样的方式在系统种下了一颗种子,这颗种子将导致共用这一个CA认证的伪造签名被验证为信任状态,如果不清除该数据项,被感染的系统将从此对碰撞作者所有具有伪造签名的程序信任。

就本例样本来说,在后面会被调用的日历主程序DesktopGoodCalendar.exe的签名也变为有效的:

http://p5.qhimg.com/t01c7c0fc57167a7731.jpg

图5-11 主程序的另一个数字签名前后状态对比

DesktopGoodCalendar.exe是个加了强壳的delphi程序,运行之后仍先检测运行环境,通过临时目录下的两个文件日志判断安装程序的文件名和父进程:

http://p3.qhimg.com/t017ee84ab570c591b8.png

图5-12 主程序的通过两个文件内容判断运行环境

当恶意条件满足,先把用户机器的信息回传服务器:

http://p9.qhimg.com/t018ddf21dfe35d79a9.png

图5-13 回传用户机器的信息

接着依次从不同的url下载几张画面相同的图片:

http://p6.qhimg.com/t0154c9b416a0f1fbae.png

图5-14 碰撞作者使用的加密图片

每次下载一张如上的图片,都会使用同一个算法解密其中的附加数据,并使用解密数据进行下一步操作,大致的操作过程如下:

1、解密“http://www.ci***k.com/images/if.jpg”得到一个进程列表进行分析环境检测:

http://p7.qhimg.com/t011809189034b16f28.png

图5-15 第一张图片解密后的内容

2、解密“http://www.ci***k.com/images/before*.jpg”得到下一张图片下载地址:

http://p6.qhimg.com/t0173e9a0b86ae7998a.png

图5-16 第二张图片解密后的内容

3、根据上一步得到的下载地址解密其图片得到一个恶意的PE程序,如下为解密得到PE程序的示意图,以及分别从两例地址的图片解密得到的程序图标:

http://p2.qhimg.com/t0191fb05812e47f752.jpg

http://p7.qhimg.com/t01a718330e9479ccc7.png

图5-17 第三张图片解密后的得到恶意程序2例

经过上述的下载、解密,最后将得到的PE程序注入一个svchost的傀儡进程中并启动:

http://p6.qhimg.com/t016d22649ee6ef8417.jpg

http://p1.qhimg.com/t015169ebaac66e9b99.png

图5-18 主程序将恶意程序注入傀儡进程的过程跟踪

由此,新的一个恶意程序悄然在系统进程中运行起来,后续的动作也全凭碰撞作者布局控制,可以方便、隐蔽地进行各种流氓活动。历史上曾从受害用户现场发现过其会劫持浏览器主页,使之跳转到带有商业推广渠道标识的某导航网站,从而为碰撞作者达到盈利的目的。

以下为整体攻击行为的流程图:

http://p6.qhimg.com/t01146ac590ff83c170.jpg

图5-19 整体攻击流程图

        0x6传播及影响

新型MD5碰撞样本在2015年初开始大规模传播,经过统计发现,仅2015年受该类恶意软件影响的用户数量就达到5584939个,下图为在全国各地区受影响的用户分布,主要集中在人口密集地区,其中广东省是重灾区,传播量达到60多万。

http://p1.qhimg.com/t0188f60b3d036f3558.png

图6-1 2015年全国各地区受影响的用户数量分布图

从传播时间来看,该类恶意软件以5月份传播量最高,达到130万左右的量级,如下图所示。

http://p4.qhimg.com/t014c64d5aa688b121c.png

图6-2 2015年各月份受影响用户量

通过对该类恶意软件的种类和来源进一步梳理,发现碰撞作者的主营软件是以天气、日历类软件的形式,通过各种渠道在网络中传播,其业务链及主要传播途径如下所示:

http://p4.qhimg.com/t01af7eb3d651cdf30b.jpg

图6-3 碰撞作者的主要业务软件及传播途径

1、借助流氓软件推广渠道进行传播。经统计,视频聊天、下载器、外挂辅助和影音播放器等类型的软件都推广过碰撞作者的恶意软件。它们在推广时,会主动连接碰撞作者的服务器下载最新的恶意程序到用户电脑进行安装,整理2015年碰撞作者使用的主要传播服务器如下:

https://img8.php1.cn/3cdc5/15d29/711/b13dfe9adf55b371.png

图6-4 碰撞作者2015年使用的主要传播服务器

2、上传到正规软件下载站提供给用户搜索和下载。以下为在某下载站发现的碰撞样本:

http://p3.qhimg.com/t0126930f7ec61b19e3.jpg

图6-5 下载站传播

3、伪装成热门资料分享到网盘中诱导用户主动下载安装。恶意软件用炒股技巧、考研英语等诱惑性的文件名打包,如下图所示:

http://p9.qhimg.com/t0102e90a46a82eed1b.jpg

图6-6 网盘分享传播

4、官网和其他渠道传播。2015年9月份碰撞作者软件官网截图如下:

http://p1.qhimg.com/t019cfa8686c0bdc4d3.jpg

图6-7 恶意软件官网传播

通过以上各种传播渠道,碰撞作者的恶意软件最终到达用户电脑潜伏下来,每次用户电脑启动也跟着运行,并伺机进行主页劫持等推广行为进行盈利,即使一些用户想要将之完全卸载也很难,给广大普通用户造成了无尽的烦恼。网上搜索相关的恶意软件名称,会发现很多普通用户的反馈,如下图:

http://p5.qhimg.com/t01aa2ec268bcff8a75.jpg

图6-8 用户在网上反馈的声音

从上述的恶意软件演化、传播过程可以看出,碰撞作者费尽心思提高对抗技术、扩展传播渠道,其目的只有一个:金钱至上。虽然碰撞作者为了自己的私利,不顾广大群众的用户体验而利用互联网来污染用户的电脑,但是好在用户的身后还有一批与之不懈对抗的安全软件来保驾护航,以下为360安全卫士对此类碰撞恶意软件进行拦截查杀的截图。在这场没有硝烟的战争中,对抗还将继续,感谢广大用户一直以来对360的支持。

http://p1.qhimg.com/t01c994b8df7571bef4.jpg

图6-9 360安全卫士对新型碰撞类恶意软件的拦截查杀


[[1]] 早在2007年就由Marc Stevens提出并实现了该方法的MD5碰撞。

[[2]] 开源的hash碰撞工具,具体可参见project hash clash的开源代码:https://marc-stevens.nl/p/hashclash/

[[3]]下文将介绍到碰撞作者主营软件为桌面天气、日历类软件,其组件包括安装包、主程序和动态连接库等

[[4]] Freebuf曾对此做过报导,参见http://www.freebuf.com/news/3482.html

[[5]] 详见微软对多签名支持的安全公告:https://technet.microsoft.com/zh-cn/library/security/3033929.aspx

[[6]] 签名校验相关的开源代码编译的小工具,一个为校验签名的有效性,另一个则是提取签名字符串


推荐阅读
  • 超级简单加解密工具的方案和功能
    本文介绍了一个超级简单的加解密工具的方案和功能。该工具可以读取文件头,并根据特定长度进行加密,加密后将加密部分写入源文件。同时,该工具也支持解密操作。加密和解密过程是可逆的。本文还提到了一些相关的功能和使用方法,并给出了Python代码示例。 ... [详细]
  • 本文介绍了Java工具类库Hutool,该工具包封装了对文件、流、加密解密、转码、正则、线程、XML等JDK方法的封装,并提供了各种Util工具类。同时,还介绍了Hutool的组件,包括动态代理、布隆过滤、缓存、定时任务等功能。该工具包可以简化Java代码,提高开发效率。 ... [详细]
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • 本文介绍了H5游戏性能优化和调试技巧,包括从问题表象出发进行优化、排除外部问题导致的卡顿、帧率设定、减少drawcall的方法、UI优化和图集渲染等八个理念。对于游戏程序员来说,解决游戏性能问题是一个关键的任务,本文提供了一些有用的参考价值。摘要长度为183字。 ... [详细]
  • Linux服务器密码过期策略、登录次数限制、私钥登录等配置方法
    本文介绍了在Linux服务器上进行密码过期策略、登录次数限制、私钥登录等配置的方法。通过修改配置文件中的参数,可以设置密码的有效期、最小间隔时间、最小长度,并在密码过期前进行提示。同时还介绍了如何进行公钥登录和修改默认账户用户名的操作。详细步骤和注意事项可参考本文内容。 ... [详细]
  • 生成式对抗网络模型综述摘要生成式对抗网络模型(GAN)是基于深度学习的一种强大的生成模型,可以应用于计算机视觉、自然语言处理、半监督学习等重要领域。生成式对抗网络 ... [详细]
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • [译]技术公司十年经验的职场生涯回顾
    本文是一位在技术公司工作十年的职场人士对自己职业生涯的总结回顾。她的职业规划与众不同,令人深思又有趣。其中涉及到的内容有机器学习、创新创业以及引用了女性主义者在TED演讲中的部分讲义。文章表达了对职业生涯的愿望和希望,认为人类有能力不断改善自己。 ... [详细]
  • 本文详细介绍了MysqlDump和mysqldump进行全库备份的相关知识,包括备份命令的使用方法、my.cnf配置文件的设置、binlog日志的位置指定、增量恢复的方式以及适用于innodb引擎和myisam引擎的备份方法。对于需要进行数据库备份的用户来说,本文提供了一些有价值的参考内容。 ... [详细]
  • sklearn数据集库中的常用数据集类型介绍
    本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ... [详细]
  • 集成电路企业在进行跨隔离网数据交换时面临着安全性问题,传统的数据交换方式存在安全性堪忧、效率低下等问题。本文以《Ftrans跨网文件安全交换系统》为例,介绍了如何通过丰富的审批流程来满足企业的合规要求,保障数据交换的安全性。 ... [详细]
  • GreenDAO快速入门
    前言之前在自己做项目的时候,用到了GreenDAO数据库,其实对于数据库辅助工具库从OrmLite,到litePal再到GreenDAO,总是在不停的切换,但是没有真正去了解他们的 ... [详细]
  • Nginx使用AWStats日志分析的步骤及注意事项
    本文介绍了在Centos7操作系统上使用Nginx和AWStats进行日志分析的步骤和注意事项。通过AWStats可以统计网站的访问量、IP地址、操作系统、浏览器等信息,并提供精确到每月、每日、每小时的数据。在部署AWStats之前需要确认服务器上已经安装了Perl环境,并进行DNS解析。 ... [详细]
  • 本文介绍了在Windows环境下如何配置php+apache环境,包括下载php7和apache2.4、安装vc2015运行时环境、启动php7和apache2.4等步骤。希望对需要搭建php7环境的读者有一定的参考价值。摘要长度为169字。 ... [详细]
  • 本文介绍了关系型数据库和NoSQL数据库的概念和特点,列举了主流的关系型数据库和NoSQL数据库,同时描述了它们在新闻、电商抢购信息和微博热点信息等场景中的应用。此外,还提供了MySQL配置文件的相关内容。 ... [详细]
author-avatar
小--瑜Gg
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有