JAVA安全成长之路随笔

0x00:JAVA反序列化

0x01:JNDI注入,主要应用在FASTJSON注入

Java命名和目录接口 (Java Naming and Directory Interface,缩写JNDI)是Java的一个目录服务应用程序接口(API),它提供一个目录系统,井将服务名称与对象关联起来,从而使得开发人员在开发过程中可以使用名称来访问对象。(类似于一个电话簿)

注入特征

InitialContext.lookup(param)看看param可不可控

JNDI注入利用工具

JNDI-Injection-Exploit

利用命令:java -jar [工具名称].jar -C cacl[执行的命令cmd]

同时我们在截图可以看到受影响的版本

RMI:

RMI是Java Remote Method Invocation的缩写,是一种Java平台的远程方法调用技术。RMI允许Java程序在网络上调用其他Java程序中的方法,就像调用本地方法一样。

使用RMI需要进行以下步骤:

  1. 定义远程接口:定义一个接口,其中包含可以在远程计算机上调用的方法。
  2. 实现远程接口:实现远程接口的类,该类必须扩展Java RMI提供的RemoteObject类。
  3. 创建RMI注册表:RMI注册表是用于存储远程对象引用的服务。
  4. 注册远程对象:将实现远程接口的类注册到RMI注册表中。
  5. 启动RMI服务器:在远程计算机上启动RMI服务器,以便客户端可以连接并调用远程方法。
  6. 编写客户端代码:在本地计算机上编写Java客户端代码,该代码连接到远程计算机并调用远程方法。

RMI提供了一个方便的方式,可以让开发人员在不同的Java虚拟机之间进行方法调用。它广泛应用于分布式系统中,例如在Java EE应用程序中使用EJB组件:

Demo:

1)远程接口

import java.rmi.Remote;
import java.rmi.RemoteException;

public interface MyRemoteInterface extends Remote {
    public String sayHello() throws RemoteException;
}

2)实现远程接口的类

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

public class MyRemoteObject extends UnicastRemoteObject implements MyRemoteInterface {
    public MyRemoteObject() throws RemoteException {
        super();
    }

    public String sayHello() throws RemoteException {
        return "Hello, world!";
    }
}

3)创建RMI注册表和注册远程对象:

import java.rmi.Naming;
import java.rmi.registry.LocateRegistry;

public class MyRMIServer {
    public static void main(String[] args) {
        try {
            MyRemoteObject obj = new MyRemoteObject();
            LocateRegistry.createRegistry(1099); // 启动RMI注册表
            Naming.rebind("MyRemoteObject", obj); // 将远程对象注册到RMI注册表中
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

4)客户端代码:

import java.rmi.Naming;

public class MyRMIClient {
    public static void main(String[] args) {
        try {
            MyRemoteInterface obj = (MyRemoteInterface) Naming.lookup("//localhost/MyRemoteObject");
            String result = obj.sayHello();
            System.out.println(result);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}


在以上代码中,我们创建了一个远程接口MyRemoteInterface,其中包含一个方法sayHello(),它可以在远程计算机上调用。接着,我们创建了一个实现远程接口的类MyRemoteObject,它必须扩展Java RMI提供的UnicastRemoteObject类。然后,我们编写了一个RMI服务器MyRMIServer,它启动RMI注册表并将远程对象注册到RMI注册表中。最后,我们编写了一个客户端程序MyRMIClient,它连接到远程计算机并调用远程方法sayHello(),将结果打印出来。

LDAP

Java中的LDAP是指Java LDAP API,它是Java平台提供的一组用于访问和操作LDAP目录服务的API。Java LDAP API允许开发者在Java应用程序中使用LDAP协议,访问LDAP服务器上的目录信息和实现LDAP客户端。

使用Java LDAP API进行LDAP操作一般包括以下步骤:

  1. 连接LDAP服务器:使用LDAP连接工厂创建LDAP连接,连接LDAP服务器。LDAP连接工厂是Java LDAP API中的一个接口,用于创建LDAP连接对象。
  2. 鉴权LDAP服务器:连接LDAP服务器后,使用LDAP认证信息对服务器进行鉴权,以获得授权访问目录服务。
  3. 操作LDAP目录服务:连接LDAP服务器成功后,可以使用LDAP操作对象实现LDAP目录服务的增删改查等操作。
  4. 断开LDAP连接:当LDAP操作完成后,需要关闭LDAP连接以释放资源。

以下是一个Java LDAP API实现的示例代码:

import javax.naming.*;
import javax.naming.directory.*;

// 连接LDAP服务器
Hashtable<String, String> env = new Hashtable<String, String>();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, "ldap://localhost:389");
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, "cn=admin,dc=example,dc=com");
env.put(Context.SECURITY_CREDENTIALS, "password");
DirContext ctx = new InitialDirContext(env);

// 查询LDAP目录
String searchBase = "dc=example,dc=com";
String searchFilter = "(objectClass=inetOrgPerson)";
SearchControls searchControls = new SearchControls();
searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
searchControls.setReturningAttributes(new String[] { "cn", "mail" });
NamingEnumeration<SearchResult> searchResults = ctx.search(searchBase, searchFilter, searchControls);

// 遍历LDAP搜索结果
while (searchResults.hasMoreElements()) {
    SearchResult searchResult = searchResults.nextElement();
    Attributes attributes = searchResult.getAttributes();
    String cn = attributes.get("cn").get().toString();
    String mail = attributes.get("mail").get().toString();
    System.out.println("cn: " + cn + ", mail: " + mail);
}

// 关闭LDAP连接
ctx.close();

0x02:Weblogic历史漏洞

WebLogic挖掘思路:

sink———寻找新的gadget

source——寻找在其readObject中创建自己的InputStream的对象,并且不是使用黑名单中类的readObject进行的反序列化的新入口类。

0x03:fastJson

fastjson在反序列化时,会根据@type传入的 class建立javabean,并调用满足条件的get/set 方法。当方法中存在危险函数时,则会触发漏洞。

fastjson修复方式:

黑名单。 autotype开关,safemode模式

挖掘思路:(一般在第三方依赖中存在javaBean Class,且在get/set方法中存在寻址或加载类的操作)

 

posted @ 2023-03-27 15:51  Arrest  阅读(19)  评论(0编辑  收藏  举报