java安全编程.pdf

上传人:qwe****56 文档编号:70012418 上传时间:2023-01-14 格式:PDF 页数:55 大小:843.89KB
返回 下载 相关 举报
java安全编程.pdf_第1页
第1页 / 共55页
java安全编程.pdf_第2页
第2页 / 共55页
点击查看更多>>
资源描述

《java安全编程.pdf》由会员分享,可在线阅读,更多相关《java安全编程.pdf(55页珍藏版)》请在得力文库 - 分享文档赚钱的网站上搜索。

1、Java 安全编程(Bad Examples found in JDK)Marc Schnefeld,University of BambergIllegalaccess.org关于演讲者Marc Schnefeld,Diplom-WirtschaftsinformatikerFor Science:External doctoral student Lehrstuhl frpraktische Informatik at University of Bamberg,Bavaria,Germany课题项目:REFACTORING OF SECURITY ANTIPATTERNS INDISTR

2、IBUTED JAVA COMPONENTSFor Living:Department for Operational Security Management at computing site for large financial group in Germany Java,J2EE,CORBA CSMR 2002 设计和开发安全加固(代码审核)情形Java(我们这里讨论适用于J2SE,一些方面也适用于J2EE)被设计成一种具有与生俱来安全特性的编程语言 Gong,Oaks JVM 级:类型安全(Type Safety),字节码完整性检测(Bytecodeintegrity checks)

3、API 级:SecurityManager,ClassLoader,CertPath,JAAS加密支持:JCA/JCE,JSSE所以,什么会是问题呢所以,什么会是问题呢?一些2003/2004年的 Java 安全警告Java 运行时环境运行时环境(Runtime Environment)可能允许非受信可能允许非受信Applets 提升权限提升权限Java Media Framework(JMF)中的一个漏洞中的一个漏洞,可能导致可能导致Java 虚拟虚拟机机(JVM)崩溃崩溃Java Runtime Environment 远程拒绝服务攻击漏洞远程拒绝服务攻击漏洞(DoS)尽管存在尽管存在JA

4、VA安全体系的先天防护安全体系的先天防护,还是有许多潜在的攻击可能性还是有许多潜在的攻击可能性是什么原因导致的呢?FL2FL3幻灯片幻灯片 4FL2 警告Flier Lu,2005-8-16FL3 不被信任Flier Lu,2005-8-16问题一个平台(象Java runtime environment)只能提供对程序员意图的支持什么是程序员的意图?表现出不同的观点 功能功能 应用程序员Java 有一套很强大的预定义的API函数(sockets,files,)质量质量 和 重用重用 中间件程序员Java在不同的语义级别提供通讯和编组(marshalling)能力(Sockets,RMI,CO

5、RBA,Raw-Serialisation,XML-Serialisation,)安全性安全性 安全架构师Java 在沙箱(sandbox)外提供隔离、加密和安全Sockets等支持恶意的意图恶意的意图 敌人 通过找到 弱点弱点 来破坏安全Java VM 和核心的lib库有(许多?)漏洞漏洞Classloaders 和保护域为什么在JAVA代码中找安全漏洞?基于组件的软件开发基于组件的软件开发第三方的中间件组件(web服务器,图像库,PDF生成,)随处可见我们在受信任的地方(根类型加载器 boot classloader)重用它们但是我们真的能信任它们吗?疑问:我的第三方图像库中是否存在可能被

6、攻击者利用的存在漏洞的对象实现?JDK是否把我隔离存放的机密XML数据,与其他存在恶意代码的applets加载到同一个JVM中?对象序列化(serialisation)真的安全么?J2EE 多层应用类型J2EE 多层攻击类型Evil Twin Attack数据注入攻击数据注入攻击(SQL,遗留格式遗留格式)拒绝服务攻击拒绝服务攻击,恶意序列化数据恶意序列化数据Java 安全模式Sun 的安全编码指导方针(最后更新于最后更新于2000年年2月月2日!日!):1.小心使用 特权代码特权代码2.小心处理 静态字段静态字段3.最小化作用域(scope)4.小心选择 公共公共(public)方法和字段方

7、法和字段5.适当的 包包(package)保护性保护性6.尽可能使用 不可变不可变(immutable)对象对象7.永远不要返回对包含敏感数据的内部数组的引用不要返回对包含敏感数据的内部数组的引用8.永远不要直接存储用户提供不要直接存储用户提供(user-supplied)的数组的数组9.小心使用序列化(Serialization)10.小心使用本地方法(native methods)11.清除敏感信息http:/ 安全反模式忽略那些安全模式的代码不经意间就会造成漏洞典型的 Java 安全编码反模式(Antipatterns):忽略语言特性(例如整数溢出溢出(Integer Overflow)

8、不注意使用序列化序列化,不注意使用 特权代码特权代码将字段和方法定义到不适当的可见性作用域在非终态(non-final)静态字段中的隐蔽通道(Covert Channels)他们隐藏在你自己的代码和你使用的库中出于学术兴趣,我们审查了Sun JDK 1.4.x 的部分代码,下面将介绍我们的发现:如何在JAVA代码中找安全隐患?测试程序是否需要已指定的许可权限,在逆向分析受保护域时很有用。jChains(http:/)策略评估工具字节码检测器(访问者模式):预定义(软件质量)自定义(安全审计)Findbugs(基于基于 Apache BCEL)字节码审计分析器耗时的分析工作,且需要经验JAD(!

9、),JODE反编译器只在源代码完全可用情况下有用大部分情况不是这样的 PMD,Checkstyle源代码检测工具字节码分析器以下讨论基于JVM 字节码分析器Findbugs(http:/)针对java代码检测bug模式的静态检测器(detector)由马里兰大学开发(Puth 和 Hovemeyer)开源项目基于BCEL(Apache Bytecode Engineering Library)通过访问者模式分析:类的结构与继承控制和数据流GUI/命令行界面可扩展,允许编写自己的检测器允许编写自己的检测器Java 安全反模式反模式反模式(错误,缺陷)在受信代码中(例如 rt.jar)导致漏洞出现

10、可用性可用性:AP1:整数溢出,未知类型(java.util.zip.*)AP2:序列化(Serialisation)的副作用(java.io.*)完整性完整性:AP3:特权代码副作用(引诱打破沙箱的攻击)AP4:不恰当的作用域(违反访问控制)AP5:非终态静态变量(在applets之间的隐蔽通道)机密性机密性:AP6:重用非安全组件(org.apache.*,在applets间嗅探私有的XML数据)目标目标:定义一个二进制审计工具集,用来在你自己的代码和你使用的库中检测 反模反模式式 以修复安全漏洞。Java 反模式 1:整数溢出如blexim(Phrack#60)所述,整数溢出在C/C+中

11、是个严重的问题,在Java中也同样如此:所有Java 整数被限制在-231,+231-1 的范围内在 Java中,以下成立:-231=231+1沉默溢出(SilentOverflow)是问题所在:因为符号改变不会被报告给用户,也没有JVM 标志被设置JDK 1.4.1_01 代码是基于这样一个错误的假设:java 整数是极大的。这将导致在java.util.zip 包产生一系列的安全问题Java 反模式 1:整数溢出下列调用当参数xy x,y0时,会导致崩溃tuple(new byte 0,x,Integer.MAX_VALUE-y)可通过愚弄参数检查,来使在受信JDK 函数中的数据沉默溢出(

12、silent overflow),所以核心lib库和JVM都检测不到该溢出。本地方法调用updateBytes 访问字节数组将导致一个非法内存访问错误.通常JVM会崩溃。D:java CRCCrashAn unexpected exception has been detected in native code outside the VM.Unexpected Signal:EXCEPTION_ACCESS_VIOLATION occurred at PC=0 x6D3220A4Function=Java_java_util_zip_ZipEntry_initFields+0 x288Lib

13、rary=c:java1.4.101jrebinzip.dllCurrent Java thread:at java.util.zip.CRC32.updateBytes(Native Method)at java.util.zip.CRC32.update(CRC32.java:53)at CRCCrash.main(CRCCrash.java:3)Dynamic libraries:0 x00400000-0 x00406000 c:java1.4.101jrebinjava.exe.lines omitted.0 x76BB0000-0 x76BBB000 C:WINDOWSSystem

14、32PSAPI.DLLLocal Time=Mon Mar 17 14:57:47 2003Java 反模式 1:整数溢出CRC32 类允许计算缓冲区的校验和:假如有一个字节缓冲区(1,2,3,4),要计算它的校验和,你需要调用:CRC32 c=new java.util.zip.CRC32();c.update(new byte 1,2,3,0,3);但是,在你做以下操作的时候:c.update(new byte 0,4,Integer.MAX_VALUE-3);将导致 JDK 1.4.1_01 和JDK 1.3.1等版本的JVM 崩溃Java 反模式 1:整数溢出,风险和范围风险风险:假如

15、攻击者能在一个多用户共享JVM的环境中(例如 Domino 服务器或 Tomcat HTTP 服务器)利用那些函数的话,那么就能造成拒绝服务攻击范围范围:更多受信函数被发现有漏洞:java.util.zip.Adler32().update();java.util.zip.Deflater().setDictionary();java.util.zip.CRC32().update();java.util.zip.Deflater().deflate();java.util.zip.CheckedOutputStream().write();java.util.zip.CheckedInput

16、Stream().read();java.text.Bidi.;http:/ bugnr=4811913,4812181,4812006,4811927,4811917,4982415,4944300,4827312,4823885Java 反模式 1:整数溢出,重构public void update(byte b,int off,int len)if(b=null)throw new NullPointerException();if(off 0|len b.length-len)throw new ArrayIndexOutOfBoundsException();crc=updateBy

17、tes(crc,b,off,len);AfterJDK 1.4.102public void update(byte b,int off,int len)if(b=null)throw new NullPointerException();if(off 0|len b.length)throw new ArrayIndexOutOfBoundsException();crc=updateBytes(crc,b,off,len);BeforeJDK 1.4.101Java 反模式 1:整数溢出,重构(字节码)12:iload_213:iflt2816:iload_317:iflt2820:ilo

18、ad_221:aload_122:arraylength23:iload_324:isub25:if_icmple36After(1.4.1_02)12:iload_213:iflt 2816:iload_317:iflt 2820:iload_221:iload_322:iadd23:aload_124:arraylength25:if_icmple 36Before(1.4.1_01)整整数数溢出溢出字节码模字节码模式式重重构后字节码构后字节码Java 反模式 1:对有害的整数溢出,如何在审核过程中发现它?1.通过侦测iadd 指令来找潜在的问题方法2.iadd 是否使用用户提供的数据(使

19、用的堆栈数据是否来源于iload?)来执行一个范围检查3.是否随后用同样的数据调用一个本地方法(invokevirtual,invokestatic)该过程可以使用 Findbugs 字节码检测器来实现AP1:结论和建议不象一般的x86处理器那样(设计于1978年),JVM 没有提供一个溢出标志,所以没有办法在运行的时候侦测这种情况。而在27年后设计的Java 1.5中(aka 5.0 aka Tiger),JVM仍没有解决这个问题对JDK 6.0的建议:为了避免给程序员(没有安全意识的)增加负担,有界基本整数类型(bounded primitive integer)会非常有帮助(象ada那样

20、)。subtype Month_Type is Integer range 1.12;如果这对java编译器的处理来说太复杂的话,至少也应提供编译警告列出潜在的溢出威胁。(是否可能在Java 6.0中出现?)反模式 2:序列化的副作用创建一个java对象的一般方法是使用 new 指令,它将调用类的构造函数。但是:Java 序列化 API(java.io 包的一部分)允许跳过构造函数来创建此对象类型的新实例,只需要简单的将数据发送到一个与socket,文件或字节数组绑定的java.io.ObjectInputStream(OIS)OIS 对象一般被远程通讯(如RMI)或持久化框架,用于将预先构建

21、的对象导入到JVM当一个对象从一个OIS中被读出的时候,大部分继承的readObject 方法会被调用。AP 2:风险和范围风险风险读取序列化后的对象可能 迫使JVM进入一个复杂的,容易出现漏洞代码的区域,而此过程会在 readObject 方法中被所调用。readObject methods 可能位于在你自己的代码,JDK 类中以及你所使用到的任何的第三方库中。攻击者可能准备了手工处理过的数据包作为序列化数据。范围范围在WIN32平台上导致JVM 崩溃崩溃java.awt.font.ICC_Profile触发一个未处理的 OutOfMemoryError 错误,它将终止当前监听的线程使服务失

22、效。(作为一个错误,它将跳过 try/catch 的检查)java.util.HashMap触发复杂的计算,JVM may become unresponsive“Sun Alert 57707java.util.regex.PatternAP 2:风险和范围http:/ void readObject(java.io.ObjectInputStream s)throws s.defaultReadObject();/Initialize countsgroupCount=1;/if length 0,localCount=0;/使使用用延后延后(lazily)编译编译的的模模式式compil

23、ed=false;if(pattern.length()=0)root=new Start(lastAccept);matchRoot=lastAccept;compiled=true;AfterJDK 1.4.206private void readObject(java.io.ObjectInputStream s)throws s.defaultReadObject();/Initialize countsgroupCount=1;localCount=0;/Recompile object treeif(pattern.length()0)compile();/so we compil

24、e for the next 1600 yearselseroot=new Start(lastAccept);BeforeJDK 1.4.205AP2:如何在审核过程中发现它?1.通过侦测 readObject 定义来找到潜在的问题类型。2.对于那些类来说,看是否控制流落入到有害的代码中I.搜寻算法复杂度。(是否要用800年来编译一个正则表达式?)II.搜寻无穷循环(bytecode backward branches)III.代码是否调用了易受攻击的native code 并且把全部或者部分的负荷传给了它?Findbugs bytecode detector 可实现该过程。AP2:结论和建

25、议readObject方法主要被设计用来接受和检查 序列化(Serializable)的数据嵌套的Serializable类型会发生嵌套的readObject调用,所以恶意符合(payload)不必一定要在根对象中。尝试将复杂操作从创建时推迟到第一次使用时同样的规则也适用于readExternal方法,该方法实现Externalizable接口的接收部分。AP3:特权代码的副作用基本的Java 访问逻辑:在在如下情况如下情况,访访问问请求才被请求才被允许允许:当前执行上下文中,每个保护域都已经获得许可指定权限;换句话说,每每一个一个保保护护域域中中的的代码和主代码和主体体都获得指定都获得指定权

26、限权限。只有当所有的保护域Di包含权限p的时候,权限才能被获得=iniDp1IAP3:特权代码的副作用特权代码(doPrivileged)可被用来跳过堆栈逻辑检查在应用/用户(user classes)级需要的许可,跟在执行必要的中间件/系统级(rt.jar)的许可是不一样的。AP3:特权代码的副作用:风险和范围风险风险一个attacker可能滥用该条件来提升权限并且脱离受限的保护域(例如JNLP 或 applet 沙箱)他知道JDK中的特权代码块,并且给应用程序的codesources以特权.通过一个引诱,攻击者试着诱骗控制到特权的代码块并且让该特权块使用他注射进来的payload范围范围.

27、把临时文件(例如可执行文件)传输到客户端的机器上,然后在合适的时候去执行(http:/ 沙箱并测试客户端机器是否存在某文件.java.awt.font.ICC_ProfileAP3:特权代码的副作用:风险和范围AP3:重构没有可用的修复前面描述的bugs依然存在在于JDK中,所以很不幸,没有可用的修复尽管在 Q2/2004 或者更早,那些漏洞就已报告给SunAP3:特权代码的副作用:如何审核?1.通过检查doPrivileged调用找出潜在的问题类型2.对于那些类,确认用户提供数据是否传递到特权代码块中?假如是的话会导致I.非受信任的代码访问到受保护资源II.把秘密数据泄露给非受信任的代码II

28、I.让非受信任代码执行不希望的修改Findbugs 字节码检测器可以部分实现这个过程。AP3:结论和建议结论结论doPrivileged 对保护域来说是 强大强大的的 但是危险危险的的 双刃剑建议建议对 Sun:请修复在JDK特权代码中的bugs对组件用户:在使用前,请检查第 三方库中的doPrivileged 块,因为他们可能打破你制订的安全策略对中间件开发者:使你代码中的特权代码尽可能短小http:/ 作用域(Scope)作为一条规则,尽可能的减小方法和字段的作用域范围尽可能的减小方法和字段的作用域范围.检查包私有(package-private)成员是否应该是私有(private),保护

29、(protected)成员是否应该是 包私有或私有等等.Sun Security Code Guidelines当你设计一个受信的JDK扩展(例如Java Media Framework(JMF)的时候,该规则由为重要。AP4:不恰当的作用域:风险和范围风险风险攻击者能利用受信的保护域(jre/lib/ext 中的java扩展)的AllPermissions来提升权限,例如 JMF安装额外受信的类到 jre/lib/ext通过本地(native)方法访问系统内存公共的 JMF 类 com.sun.media.NBA 暴露了一个指向物理内存的公共指针 long value data 所以不受信任

30、的applets也可以读你的系统内存AP4:不恰当的作用域:风险和范围http:/ final class NBA protected final synchronized void finalize()public synchronized Object getData()public synchronized Object clone()public synchronized void copyTo(NBA nba)public synchronized void copyTo(bytejavadata)private long data;private int size;private

31、Class type;After(JMF 2.1.1e)public class NBA public void finalize()public Object getData()public Object clone()public void copyTo(NBA nba)public void copyTo(bytejavadata)public long data;public int size;public Class type;Before(JMF 2.1.1c)1)应该禁止对此应该禁止对此类类的的继承继承,以防,以防止新方法止新方法去泄露去泄露机机密密数据数据.2)public的的

32、finalize方法方法的的作作用用域被域被降为降为protected,所以所以没没有有类类能能覆盖它覆盖它3)数据数据字段被字段被移到了适当移到了适当的的private(class级别级别)作作用用域域AP4:不恰当作用域的副作用:如何审查?1.通过探测public 类型 来找潜在的问题类型2.对于那些类型,判定:I.数据字段定义为 publicII.方法定义为 publicIII.public 方法返回一个 private,protected 内部数据的引用Findbugs 的预定义检测器可实现定位潜在的问题类型。AP4:结论和建议结论结论在方法和字段上不恰当的作用域可能导致跳过访问控制机

33、制建议建议 http:/ security checks)。确认任何确认任何public方法方法访问并/或修改任何敏感内部数据的时候包括包括安全检查安全检查.AP5:非终态静态变量避免使用非终态(non-final)公共静态变量(static variables)尽可能不使用非终态公共静态变量,因为没有机制来检测改变此变量的代码是否有适当的权限。一般情况下,小心对待任何易变的静态状态,它能导致在两个设计上相互独立的子系统间出现不希望的交互。Sun Security Code Guidelines根据Sun Microsystems http:/ 术语 covert channel 定义如下:设

34、计上并非用来进行数据通讯的通讯通道。它允许进程以违背安全策略意图的方式间接的传递信息。我们将展示 粗心粗心的的使使用用静态变静态变量量 这样一个反模式的情景,可能导致恶意代码利用保保护护域域间隐蔽通道间隐蔽通道 进行通讯。AP5:非终态静态变量,风险与范围风险风险Static Variables(被boot classloader(like the ones in rt.jar)或者是扩展的classloader装载)在一个JVM中是一个单件(singleton)Non-final static String 字段字段可能会可能会把把序列化序列化好好的的java对象对象传给传给 没有权没有权限

35、访问它们的其他保护域。限访问它们的其他保护域。Browser VMApplet from site AApplet from site BProtection Domain BProtection Domain AProtection Domain/lib/rt.jar AllPermissions“org.apache.xalan.processor.XSLProcessorVersion.LANGUAGEorg.apache.xalan.processor.XSLProcessorVersion.S_VERSIONjavax.swing.JDesktopPane.LIVE_DRAG_MOD

36、E.Serial obj.Serial obj.AP5:非终态静态变量,风险与范围http:/www.heise.de/newsticker/meldung/41308Unsigned Java-Applets jump out of Sandboxhttp:/www.heise.de/newsticker/meldung/41308Unsigned Java-Applets jump out of SandboxAP5:非终态静态变量:重构public class org.apache.xalan.processor.XSLProcessorVersion public static fin

37、al java.lang.StringPRODUCT;public static final java.lang.StringLANGUAGE;public static final int VERSION;public static final int RELEASE;public static final int MAINTENANCE;public static final int DEVELOPMENT;public static final java.lang.StringS_VERSION;After(JDK1.42_05)public class org.apache.xalan

38、.processor.XSLProcessorVersion public static final java.lang.StringPRODUCT;public static java.lang.String LANGUAGE;public static int VERSION;public static int RELEASE;public static int MAINTENANCE;public static int DEVELOPMENT;public static java.lang.String S_VERSION;Before(JDK1.42_04)final 修饰符修饰符的的

39、变变量在量在初始初始化化后后就就不不允许允许修改修改。最最初初,他们仅他们仅使使用用它来它来保保护护他们他们的的产品名称产品名称 JAP5:非终态静态变量:如何审核?1.findbugs 内建的检测器通过查询public 类型来找潜在的问题类型2.对于那些类,我们需要找出I.基础数据字段和String定义为public static,non-final II.对象类型数据字段,数组,容器定义为 public static III.允许访问(I+II)中的non-public 实例的方法AP5:结论和建议结论结论Non-final static 字段允许在两个保护域间建立隐蔽通道,跳过诸如app

40、let 沙箱(sanbox)这样的约束。建议建议 http:/ public static variables,因为没有机制来检查改变该变量的代码是否有适当的权限。一般的,小心的对待那些易变的static states,因为它可以在两个本来独立子系统间触发希望的交互。反模式 6:重用非安全组件分布式基于组件的应用可以由不同提供商提供的软件组件所组成。因此必须区分应用本身和软件组件提供商,他们需要有不同的保护策略“:Hermann,Krumm 第三方的组件可能是根据程序员想要的功能的;然而,JDK的限制执行模型的控制管理需要安全,而不单单是功能。JDK(作为一个component-structu

41、red 中间件应用)从Apache foundation那里拿来了许多XML的功能。对于嵌入到JDK中的第3方组件,是否有足够的保护来对抗弱点呢?AP6:重用非安全组件:风险与范围风险风险嵌入到JDK中的XSLT parser是直接从原先 apache XALAN 独立版本拿过来的,可从 http:/xml.apache.org 下载此版本具有很强的可配置性,特别是允许自定义函数,在 XSLT(extensible stylesheet language transformations)中被调用.在受信的在受信的库库中的中的Non-final static 数组可能数组可能包含对象包含对象,允

42、许把该对象传递到JVM的各个地方。下面我们将展示 重用非安全组件重用非安全组件 这样一个反模式,允许恶意允许恶意代码代码通过插通过插入恶意入恶意回回调函调函数数获得获得受信受信代码代码权限权限AP5:Non-Final Static Variables,Risk&Extendhttp:/ class piler.FunctionTable privatestatic piler.FuncLoader m_functions;.After(JDK1.42_06)public class piler.FunctionTable public static piler.FuncLoader m_fu

43、nctions;.Before(JDK1.42_05)该重构把组件的增强功能调整到这样的水平:在受限的执行模式中能够安全的运行。技术上来说,该重构修复了反模式 4 和反模式 5 的问题。private 修饰阻止恶意代码对XSLT 解析器内建函数表的修改.AP6:重用非安全组件:如何审查?1.第三方组件可能包括所有类型的反模式,以我们的经验至少应该检查下列的现存反模式1.检查 Integer 溢出2.检查正确的序列化,注意其副作用3.检查特权代码的使用,特别是当使用特权或“AllPermission”保护域(protection domains).4.调整不合适的作用域,给公共可用的字段和功能加安全检查.5.在static non-final 字段和static mutable 容器类型上关闭隐蔽通道(也包括间接使用)。AP6:结论和建议结论即使你自己的代码是安全的,第 3rd方的组件可以摧毁你的安全堡垒建议向你要重用的提供商询问,是否有用过findbugs或者类试的工具检查过他们的组件在你购买之前要求一个findbugs的报告,这可能增加对组件的信任.许多开源的项目已经包括了类试这样一个报告,一些闭源软件的开发者应该学习下.finally下下载载www.illegalaccess.org发布的检测器给我给我发发 eMailmarcmarc-联系方式

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 技术资料 > 其他杂项

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知得利文库网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号-8 |  经营许可证:黑B2-20190332号 |   黑公网安备:91230400333293403D

© 2020-2023 www.deliwenku.com 得利文库. All Rights Reserved 黑龙江转换宝科技有限公司 

黑龙江省互联网违法和不良信息举报
举报电话:0468-3380021 邮箱:hgswwxb@163.com