zoukankan      html  css  js  c++  java
  • jdbc问题解决

    SPI机制

    SPI,全称为Service Provider Interface,是一种服务发现机制。它通过在ClassPath路径下的META-INF/services文件夹查找文件,自动加载文件里所定义的类。

    这一机制为很多框架扩展提供了可能,比如在Dubbo、JDBC中使用SPI机制。

    Java SPI实际上是“基于接口的编程+策略模式+配置文件”组合视线的动态加载机制。

    Java SPI

    当服务的提供者提供一种接口的实现之后,需要在classpath下的META-INF/services/目录里创建一个以服务接口命名的文件,这个文件里的内容就是这个接口的具体的实现类。当其他的程序需要这个服务的时候,就可以通过查找这个jar包的META-INF/services/中的配置文件,配置文件中有接口的具体实现类名,可以根据这个类名进行加载实例化,就可以使用该服务。

    JDK中查找服务实现的工具类是:java.util.ServiceLoader。

    简单来说,SPI机制等于是当我们为一个接口写了实现类之后,就会在META-INF/services这个目录下创建一个文件,这个文件里面的内容就是我们之前写的这个接口的实现类。当我们需要再次调用这个实现类的时候,就不需要很麻烦的再去自己写,而是可以直接调用。

    代码演示

    暂无,有坑未排
    

    SPI机制的安全问题

    个人猜测

    因为网上没有找到类似的介绍文章,对于SPI机制我也没有进行过多的研究,所以如果说SPI机制可能存在安全问题的话,那应该是之前为了方便用户的特点可以被利用。

    简单来说,就是,SPI机制在我们写好了一个实现接口的实现类之后,放到指定目录下,然后利用java.util.ServiceLoader方法就可以直接调用,而不需要重复的去写实现类。所以,当java的网站出现信息泄露,文件下载等问题之后,我们可以去指定的目录下下载其中的文件,就可以获取到足够多的网站实现类信息,如果能修改其中一些实现类的内容,获取可以通过这个方法直接getshell 。

    反射

    定义

    Java反射机制是指在运行状态,对于任何一个类,都能知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取信息以及动态调用对象的方法的功能被称为java的反射机制。

    反射机制很重要的一点就是“运行时”,这让我们可以在运行程序时加载、探索和使用编译期间完全未知的.class文件。一句话总结就是,反射可以实现在运行时可以知道的任意一个类的属性和方法

    安全问题

    跟反射机制联系最深的就是反序列化问题,简单来说,反射机制允许程序在运行的时候被修改方法。把方法修改成什么样子,其实全靠我们希望完成什么目的。

    简单来说,想要完成执行命令的时候,有两个方向可以努力:

    1. 控制代码、函数:就像命名注入等注入类漏洞一样,数据被当做代码执行;或者重写代码中的某一个方法,加入自定义代码。
    2. 控制输入、数据、变量:利用代码中已有的函数和罗杰,通过改变输入内容的形态视线流程的控制。

    对于Java反序列化漏洞来说,这属于控制数据输入异类。在调用反射机制出发漏洞是,有两个条件必须满足:

    1. 有一个可序列化的类,并且该类是重写了readObject()方法的(由于不存在代码注入,只能查找已有的代码逻辑中是否有这样的类。)
    2. 在重写的readObject()方法的逻辑中有method.invoke函数出现,而且参数可控。

    数据库连接时安全问题

    在正式的代码中,我们一般不会在每次需要连接数据库的时候,才在代码中注册驱动,填写账号密码,以及获取connection连接对象。而是提前把这些内容填写到配置文件中,当我们需要其中的信息时,再去从配置中读取。

    这样做的好处是,当我们的连接信息需要修改的时候,没有代码基础的人也能很轻易的从配置文件中修改账号密码。并且也减少了一些书写。

    但是这样就会出现一个问题,如果java站点存在文件泄漏问题,攻击者就可以通过搜索配置文件类型以及其他可能存在配置信息的名称来下载数据库连接配置文件,以此获取数据库root账户的账号密码(一般配置文件中都会写root账户信息。)数据库配置文件可能是properties类型的,也可能是conf.xml等。

    用JDBC写一个简单的数据库密码爆破模块

    简单逻辑如下:

    首先,我们知道,获取和数据库连接,我们首先要注册驱动,然后输入数据库连接地址,用户名,密码然后再获取connection对象。

    这个时候,如果我们的用户名密码输入正确,connection对象里面是有一个数据的,而账号密码错误,程序会报错。我们可以通过这一点进行判断。

    因为爆破是重复的进行同一个操作,变换的数据只有密码。所以我们可以利用循环来完成这个重复的操作。

    那当connection里面有数据的时候,就证明登录成功,那就需要一个if判断,当程序不报错之后,就说明登录成功,在这种情况下,记录下当时正在使用的密码。

    难点

    1. 导入字典
    2. 捕获异常,修改成我需要的字段
    3. 记录正确密码,打印

    代码实现

    暂无,有坑未排
    
  • 相关阅读:
    Python学习系列之类与对象(二十三)
    面向过程和面向对象的异同点
    js 数值精确运算使用math.js
    js实现复制 、剪切功能-clipboard.min.js 示例
    css div嵌套层中button的margin-top不起作用解决方法
    IPhone中H5页面用on绑定click无效的解决方法
    This is a good start.
    element之input输入搜索联想框
    vue + element-ui 国际化实现
    async/await 处理多个网络请求同步问题
  • 原文地址:https://www.cnblogs.com/Xiaoming0/p/14111665.html
Copyright © 2011-2022 走看看